From e56e8caff26d7eb63dbc74d93ee02330401480fc Mon Sep 17 00:00:00 2001 From: Antti Harri Date: Sat, 9 Jul 2011 22:59:49 +0300 Subject: [PATCH 001/334] Fix previous FLAC pkg-config commit that had some typos. While there, restructure and remove duplicate code. --- config.d/compression.m4 | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/config.d/compression.m4 b/config.d/compression.m4 index 293c996ce..7d624a18c 100644 --- a/config.d/compression.m4 +++ b/config.d/compression.m4 @@ -4,15 +4,12 @@ AC_ARG_ENABLE(flac, HAVE_FLAC=no if test "x$enable_flac" != "xno"; then if test "x$PKG_CONFIG" != "x"; then - PKG_CHECK_MODULES([FLAC], [flac], HAVE_FLAC=yes, HAVE_JACK=no) - if test "x$HAVE_FLAC" = "xyes"; then - AC_DEFINE(HAVE_JACK, 1, [Define if you have libFLAC]) - fi + PKG_CHECK_MODULES([FLAC], [flac], HAVE_FLAC=yes, HAVE_FLAC=no) else AM_PATH_LIBFLAC(HAVE_FLAC=yes, HAVE_FLAC=no) - if test "x$HAVE_FLAC" = xyes; then - AC_DEFINE(HAVE_FLAC, 1, [define this if you have flac libs]) - fi + fi + if test "x$HAVE_FLAC" = xyes; then + AC_DEFINE(HAVE_FLAC, 1, [define this if you have flac libs]) fi fi AM_CONDITIONAL(HAVE_FLAC, test "x$HAVE_FLAC" = "xyes") From f8d8395cf0488d4110f322cccb82a249a44001a9 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 23 Jul 2011 09:55:27 +0900 Subject: [PATCH 002/334] Clean up the ipv6 check a little. --- config.d/networking.m4 | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/config.d/networking.m4 b/config.d/networking.m4 index 09a15f69a..1ed5a9d52 100644 --- a/config.d/networking.m4 +++ b/config.d/networking.m4 @@ -5,8 +5,10 @@ dnl ================================================================== LIBCURL_CHECK_CONFIG([], [], [CURL=yes], []) AC_ARG_WITH(ipv6, -[ --with-ipv6=DIR enable IPv6 support. Optional argument specifies - location of inet6 libraries.], + AS_HELP_STRING([--with-ipv6=DIR], + [Eenable IPv6 support.] + [Optional argument specifies location of inet6 libraries.]), + [ if test "x$withval" = xno ; then NETTYPE_IPV6=no else @@ -16,8 +18,8 @@ AC_ARG_WITH(ipv6, LIBS="$LIBS -L${withval}" fi fi - , - NETTYPE_IPV6=no + ], + [NETTYPE_IPV6=no] ) AM_CONDITIONAL(NETTYPE_IPV6, test "x$NETTYPE_IPV6" = "xyes") From b17e37f802b1ab0bafd1b9d61aa5dad8a484d351 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 23 Jul 2011 14:58:45 +0900 Subject: [PATCH 003/334] Remove uneccessary differences between ip4 and ip6 code --- libs/net/nc/net_udp.c | 156 ++++++++++++++++++++++------------------- libs/net/nc/net_udp6.c | 19 +++-- 2 files changed, 91 insertions(+), 84 deletions(-) diff --git a/libs/net/nc/net_udp.c b/libs/net/nc/net_udp.c index f91786ead..1bf689885 100644 --- a/libs/net/nc/net_udp.c +++ b/libs/net/nc/net_udp.c @@ -25,13 +25,22 @@ Boston, MA 02111-1307, USA */ +/* Sun's model_t in sys/model.h conflicts w/ Quake's model_t */ +#define model_t quakeforgemodel_t + #ifdef HAVE_CONFIG_H # include "config.h" #endif -static __attribute__ ((used)) const char rcsid[] = +static __attribute__ ((used)) const char rcsid[] = "$Id$"; +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif #ifdef HAVE_UNISTD_H # include #endif @@ -45,9 +54,7 @@ static __attribute__ ((used)) const char rcsid[] = # include #endif #ifdef HAVE_NETINET_IN_H -# define model_t sun_model_t # include -# undef model_t #endif #ifdef HAVE_NETDB_H # include @@ -62,27 +69,25 @@ static __attribute__ ((used)) const char rcsid[] = # include #endif -#include -#include -#include -#include -#include - -#include "QF/cvar.h" -#include "QF/dstring.h" -#include "QF/msg.h" -#include "QF/sys.h" -#include "QF/qargs.h" - -#include "compat.h" -#include "netchan.h" - #ifdef _WIN32 # include # undef EWOULDBLOCK -# define EWOULDBLOCK WSAEWOULDBLOCK +# define EWOULDBLOCK WSAEWOULDBLOCK #endif +#include +#include +#include + +#undef model_t + +#include "QF/dstring.h" +#include "QF/msg.h" +#include "QF/qargs.h" +#include "QF/sys.h" + +#include "netchan.h" + #ifndef MAXHOSTNAMELEN # define MAXHOSTNAMELEN 512 #endif @@ -99,10 +104,10 @@ static __attribute__ ((used)) const char rcsid[] = # endif #endif -int net_socket; +netadr_t net_from; netadr_t net_local_adr; netadr_t net_loopback_adr; -netadr_t net_from; +int net_socket; static sizebuf_t _net_message_message; static qmsg_t _net_message = {0, 0, &_net_message_message}; @@ -115,29 +120,36 @@ byte net_message_buffer[MAX_UDP_PACKET]; WSADATA winsockdata; #endif +#define ADDR_SIZE 4 + +typedef union address { + struct sockaddr_storage ss; + struct sockaddr sa; + struct sockaddr_in s4; +} AF_address_t; + static void -NetadrToSockadr (netadr_t *a, struct sockaddr_in *s) +NetadrToSockadr (netadr_t *a, AF_address_t *s) { memset (s, 0, sizeof (*s)); - s->sin_family = AF_INET; + s->s4.sin_family = AF_INET; - memcpy (&s->sin_addr, &a->ip, 4); - s->sin_port = a->port; + memcpy (&s->s4.sin_addr, &a->ip, ADDR_SIZE); + s->s4.sin_port = a->port; } static void -SockadrToNetadr (struct sockaddr_in *s, netadr_t *a) +SockadrToNetadr (AF_address_t *s, netadr_t *a) { - memcpy (&a->ip, &s->sin_addr, 4); - a->port = s->sin_port; + memcpy (&a->ip, &s->s4.sin_addr, ADDR_SIZE); + a->port = s->s4.sin_port; } qboolean NET_CompareBaseAdr (netadr_t a, netadr_t b) { - if (a.ip[0] == b.ip[0] && a.ip[1] == b.ip[1] && a.ip[2] == b.ip[2] - && a.ip[3] == b.ip[3]) + if (memcmp (a.ip, b.ip, ADDR_SIZE) == 0) return true; return false; } @@ -145,13 +157,12 @@ NET_CompareBaseAdr (netadr_t a, netadr_t b) qboolean NET_CompareAdr (netadr_t a, netadr_t b) { - if (a.ip[0] == b.ip[0] && a.ip[1] == b.ip[1] && a.ip[2] == b.ip[2] - && a.ip[3] == b.ip[3] && a.port == b.port) + if (memcmp (a.ip, b.ip, ADDR_SIZE) == 0 && a.port == b.port) return true; return false; } -const char * +const char * NET_AdrToString (netadr_t a) { static char s[64]; @@ -162,7 +173,7 @@ NET_AdrToString (netadr_t a) return s; } -const char * +const char * NET_BaseAdrToString (netadr_t a) { static char s[64]; @@ -186,31 +197,31 @@ NET_StringToAdr (const char *s, netadr_t *a) static dstring_t *copy; char *colon; struct hostent *h; - struct sockaddr_in sadr; + AF_address_t sadr; if (!copy) copy = dstring_new (); memset (&sadr, 0, sizeof (sadr)); - sadr.sin_family = AF_INET; + sadr.s4.sin_family = AF_INET; - sadr.sin_port = 0; + sadr.s4.sin_port = 0; dstring_copystr (copy, s); // strip off a trailing :port if present for (colon = copy->str; *colon; colon++) if (*colon == ':') { *colon = 0; - sadr.sin_port = htons ((unsigned short) atoi (colon + 1)); + sadr.s4.sin_port = htons ((unsigned short) atoi (colon + 1)); } if (copy->str[0] >= '0' && copy->str[0] <= '9') { int addr = inet_addr (copy->str); - memcpy (&sadr.sin_addr, &addr, 4); + memcpy (&sadr.s4.sin_addr, &addr, ADDR_SIZE); } else { if (!(h = gethostbyname (copy->str))) return 0; - memcpy (&sadr.sin_addr, h->h_addr_list[0], 4); + memcpy (&sadr.s4.sin_addr, h->h_addr_list[0], ADDR_SIZE); } SockadrToNetadr (&sadr, a); @@ -218,14 +229,14 @@ NET_StringToAdr (const char *s, netadr_t *a) return true; } -// Returns true if we can't bind the address locally--in other words, +// Returns true if we can't bind the address locally--in other words, // the IP is NOT one of our interfaces. qboolean NET_IsClientLegal (netadr_t *adr) { #if 0 int newsocket; - struct sockaddr_in sadr; + AF_address_t sadr; if (adr->ip[0] == 127) return false; // no local connections period @@ -254,25 +265,25 @@ NET_GetPacket (void) { int ret; socklen_t fromlen; - struct sockaddr_in from; + AF_address_t from; fromlen = sizeof (from); - ret = - recvfrom (net_socket, (void *) net_message_buffer, - sizeof (net_message_buffer), 0, (struct sockaddr *) &from, - &fromlen); + memset (&from, 0, sizeof (from)); + ret = recvfrom (net_socket, (void *) net_message_buffer, + sizeof (net_message_buffer), 0, &from.sa, &fromlen); if (ret == -1) { #ifdef _WIN32 int err = WSAGetLastError (); if (err == WSAEMSGSIZE) { - Sys_Printf ("NET_GetPacket Warning: Oversize packet from %s\n", + Sys_Printf ("Warning: Oversize packet from %s\n", NET_AdrToString (net_from)); return false; } if (err == 10054) { - Sys_Printf ("NET_GetPacket: error 10054 from %s\n", NET_AdrToString (net_from)); + Sys_Printf ("NET_GetPacket: error 10054 from %s\n", + NET_AdrToString (net_from)); return false; } #else // _WIN32 @@ -283,8 +294,7 @@ NET_GetPacket (void) #endif // _WIN32 if (err == EWOULDBLOCK) return false; - Sys_Printf ("NET_GetPacket: %d: %d: %s\n", net_socket, err, - strerror (err)); + Sys_Printf ("NET_GetPacket: %s\n", strerror (err)); return false; } @@ -297,8 +307,8 @@ NET_GetPacket (void) return false; } - if (from.sin_addr.s_addr==INADDR_ANY || from.sin_addr.s_addr == - INADDR_BROADCAST) { + if (from.s4.sin_addr.s_addr == INADDR_ANY + || from.s4.sin_addr.s_addr == INADDR_BROADCAST) { Sys_Printf ("Warning: Packet dropped - bad address\n"); return false; } @@ -316,29 +326,27 @@ void NET_SendPacket (int length, const void *data, netadr_t to) { int ret; - struct sockaddr_in addr; + AF_address_t addr; NetadrToSockadr (&to, &addr); - ret = sendto (net_socket, data, length, 0, (struct sockaddr *) &addr, - sizeof (addr)); + ret = sendto (net_socket, data, length, 0, &addr.sa, sizeof (addr)); if (ret == -1) { #ifdef _WIN32 int err = WSAGetLastError (); if (err == WSAEADDRNOTAVAIL) Sys_Printf ("NET_SendPacket Warning: %i\n", err); -#else // _WIN32 +#else /* _WIN32 */ int err = errno; if (err == ECONNREFUSED) return; -#endif // _WIN32 +#endif /* _WIN32 */ if (err == EWOULDBLOCK) return; - Sys_Printf ("NET_SendPacket: %d: %d: %s\n", net_socket, err, - strerror (errno)); + Sys_Printf ("NET_SendPacket: %s\n", strerror (err)); } } @@ -346,7 +354,7 @@ static int UDP_OpenSocket (int port) { int newsocket, i; - struct sockaddr_in address; + AF_address_t address; #ifdef _WIN32 #define ioctl ioctlsocket @@ -358,21 +366,21 @@ UDP_OpenSocket (int port) memset (&address, 0, sizeof(address)); if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) - Sys_Error ("UDP_OpenSocket: socket:%s", strerror (errno)); + Sys_Error ("UDP_OpenSocket: socket: %s", strerror (errno)); if (ioctl (newsocket, FIONBIO, &_true) == -1) - Sys_Error ("UDP_OpenSocket: ioctl FIONBIO:%s", strerror (errno)); - address.sin_family = AF_INET; + Sys_Error ("UDP_OpenSocket: ioctl FIONBIO: %s", strerror (errno)); + address.s4.sin_family = AF_INET; // ZOID -- check for interface binding option if ((i = COM_CheckParm ("-ip")) != 0 && i < com_argc) { - address.sin_addr.s_addr = inet_addr (com_argv[i + 1]); + address.s4.sin_addr.s_addr = inet_addr (com_argv[i + 1]); Sys_Printf ("Binding to IP Interface Address of %s\n", - inet_ntoa (address.sin_addr)); + inet_ntoa (address.s4.sin_addr)); } else - address.sin_addr.s_addr = INADDR_ANY; + address.s4.sin_addr.s_addr = INADDR_ANY; if (port == PORT_ANY) - address.sin_port = 0; + address.s4.sin_port = 0; else - address.sin_port = htons ((short) port); + address.s4.sin_port = htons ((short) port); if (bind (newsocket, (void *) &address, sizeof (address)) == -1) Sys_Error ("UDP_OpenSocket: bind: %s", strerror (errno)); @@ -384,17 +392,18 @@ NET_GetLocalAddress (void) { char buff[MAXHOSTNAMELEN]; socklen_t namelen; - struct sockaddr_in address; + AF_address_t address; - gethostname (buff, MAXHOSTNAMELEN); + if (gethostname (buff, MAXHOSTNAMELEN) == -1) + Sys_Error ("Net_GetLocalAddress: gethostname: %s", strerror (errno)); buff[MAXHOSTNAMELEN - 1] = 0; NET_StringToAdr (buff, &net_local_adr); namelen = sizeof (address); if (getsockname (net_socket, (struct sockaddr *) &address, &namelen) == -1) - Sys_Error ("NET_Init: getsockname: %s", strerror (errno)); - net_local_adr.port = address.sin_port; + Sys_Error ("NET_GetLocalAddress: getsockname: %s", strerror (errno)); + net_local_adr.port = address.s4.sin_port; Sys_Printf ("IP address %s\n", NET_AdrToString (net_local_adr)); } @@ -412,6 +421,7 @@ NET_Init (int port) if (r) Sys_Error ("Winsock initialization failed."); #endif /* _WIN32 */ + // open the single socket to be used for all communications net_socket = UDP_OpenSocket (port); diff --git a/libs/net/nc/net_udp6.c b/libs/net/nc/net_udp6.c index a88f5a339..fc8e60541 100644 --- a/libs/net/nc/net_udp6.c +++ b/libs/net/nc/net_udp6.c @@ -34,7 +34,7 @@ # include "config.h" #endif -static __attribute__ ((used)) const char rcsid[] = +static __attribute__ ((used)) const char rcsid[] = "$Id$"; #ifdef HAVE_STRING_H @@ -102,7 +102,6 @@ static __attribute__ ((used)) const char rcsid[] = #include "QF/dstring.h" #include "QF/msg.h" #include "QF/qargs.h" -#include "QF/qtypes.h" #include "QF/sys.h" #include "netchan.h" @@ -136,9 +135,9 @@ byte net_message_buffer[MAX_UDP_PACKET]; typedef union address { struct sockaddr_storage ss; - struct sockaddr sa; - struct sockaddr_in s4; - struct sockaddr_in6 s6; + struct sockaddr sa; + struct sockaddr_in s4; + struct sockaddr_in6 s6; } AF_address_t; @@ -235,7 +234,7 @@ NET_AdrToString (netadr_t a) /* Yes, this duplication is lame, but we want to know the real address family of the address so that we can know whether or not to put a - bracket around it, and this is less ugly than trying to check the + bracket around it, and this is less ugly than trying to check the string returned from NET_BaseAdrToString() */ memset (&ss, 0, sizeof (ss)); @@ -416,7 +415,7 @@ NET_GetPacket (void) fromlen = sizeof (from); memset (&from, 0, sizeof (from)); - ret = recvfrom (net_socket, (void *) net_message_buffer, + ret = recvfrom (net_socket, (void *) net_message_buffer, sizeof (net_message_buffer), 0, &from.sa, &fromlen); if (ret == -1) { @@ -464,10 +463,8 @@ NET_SendPacket (int length, const void *data, netadr_t to) #ifdef _WIN32 int err = WSAGetLastError (); -#ifndef SERVERONLY if (err == WSAEADDRNOTAVAIL) Sys_Printf ("NET_SendPacket Warning: %i\n", err); -#endif #else /* _WIN32 */ int err = errno; @@ -533,7 +530,7 @@ UDP_OpenSocket (int port) Sys_Error ("UDP_OpenSocket: getaddrinfo: %s", gai_strerror (Error)); if ((newsocket = socket (res->ai_family, - res->ai_socktype, + res->ai_socktype, res->ai_protocol)) == -1) Sys_Error ("UDP_OpenSocket: socket: %s", strerror (errno)); @@ -562,7 +559,7 @@ static void NET_GetLocalAddress (void) { char buff[MAXHOSTNAMELEN]; - unsigned int namelen; + socklen_t namelen; AF_address_t address; if (gethostname (buff, MAXHOSTNAMELEN) == -1) From efa0105748845ee22aa2bc7f7f3c9b08a1272337 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 23 Jul 2011 15:56:22 +0900 Subject: [PATCH 004/334] Rename some headers to fix doxygen warnings. --- include/Makefile.am | 18 +++++++++--------- include/{view.h => clview.h} | 8 ++++---- include/{snd_render.h => snd_internal.h} | 8 ++++---- libs/audio/cd_file.c | 2 +- libs/audio/renderer/flac.c | 2 +- libs/audio/renderer/midi.c | 2 +- libs/audio/renderer/snd_channels.c | 2 +- libs/audio/renderer/snd_dma.c | 2 +- libs/audio/renderer/snd_jack.c | 2 +- libs/audio/renderer/snd_mem.c | 2 +- libs/audio/renderer/snd_mix.c | 2 +- libs/audio/renderer/snd_resample.c | 2 +- libs/audio/renderer/snd_sfx.c | 2 +- libs/audio/renderer/vorbis.c | 2 +- libs/audio/renderer/wav.c | 2 +- libs/audio/targets/snd_alsa.c | 2 +- libs/audio/targets/snd_disk.c | 2 +- libs/audio/targets/snd_dx.c | 2 +- libs/audio/targets/snd_oss.c | 2 +- libs/audio/targets/snd_sdl.c | 2 +- libs/audio/targets/snd_sgi.c | 2 +- libs/audio/targets/snd_sun.c | 2 +- libs/audio/targets/snd_win.c | 2 +- libs/video/renderer/gl/gl_mod_alias.c | 1 - libs/video/renderer/gl/gl_rmain.c | 2 +- libs/video/renderer/gl/gl_screen.c | 2 +- libs/video/renderer/gl/gl_sky.c | 1 - libs/video/renderer/gl/gl_sky_clip.c | 1 - libs/video/renderer/sw/screen.c | 2 +- libs/video/renderer/sw/sw_rmain.c | 2 +- libs/video/targets/vid.c | 1 - nq/source/cl_view.c | 2 +- nq/source/host.c | 2 +- nq/source/sv_ded.c | 2 +- nq/source/sv_user.c | 2 +- qw/source/cl_ents.c | 2 +- qw/source/cl_input.c | 2 +- qw/source/cl_main.c | 2 +- qw/source/cl_parse.c | 2 +- qw/source/cl_view.c | 2 +- 40 files changed, 50 insertions(+), 54 deletions(-) rename include/{view.h => clview.h} (94%) rename include/{snd_render.h => snd_internal.h} (99%) diff --git a/include/Makefile.am b/include/Makefile.am index 11a240922..7d6f0a41e 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -2,16 +2,16 @@ AUTOMAKE_OPTIONS= foreign SUBDIRS = QF EXTRA_DIST = asm_i386.h alsa_funcs_list.h adivtab.h anorm_dots.h anorms.h \ - asm_draw.h block16.h block8.h buildnum.h compat.h context_sdl.h \ + asm_draw.h block16.h block8.h buildnum.h clview.h compat.h context_sdl.h \ context_x11.h d_iface.h d_ifacea.h d_local.h dga_check.h exp.h fbset.h \ - garbage.h getopt.h gib_buffer.h gib_builtin.h gib_classes.h gib_execute.h gib_function.h \ - gib_handle.h gib_object.h gib_parse.h gib_process.h gib_regex.h gib_semantics.h \ - gib_thread.h gib_tree.h gib_vars.h gl_draw.h gl_warp_sin.h in_win.h \ - logos.h net_dgrm.h net_loop.h net_udp.h net_vcr.h net_wins.h netchan.h \ - netmain.h old_keys.h ops.h qstring.h quakeasm.h regex.h r_cvar.h \ - r_dynamic.h r_local.h r_screen.h r_shared.h rua_internal.h sbar.h \ - skin_stencil.h snd_render.h sv_console.h varrays.h vgamodes.h view.h \ - vregset.h winquake.h world.h \ + garbage.h getopt.h gib_buffer.h gib_builtin.h gib_classes.h gib_execute.h \ + gib_function.h gib_handle.h gib_object.h gib_parse.h gib_process.h \ + gib_regex.h gib_semantics.h gib_thread.h gib_tree.h gib_vars.h gl_draw.h \ + gl_warp_sin.h in_win.h logos.h net_dgrm.h net_loop.h net_udp.h net_vcr.h \ + net_wins.h netchan.h netmain.h old_keys.h ops.h qstring.h quakeasm.h \ + regex.h r_cvar.h r_dynamic.h r_local.h r_screen.h r_shared.h \ + rua_internal.h sbar.h skin_stencil.h snd_internal.h sv_console.h \ + varrays.h vgamodes.h vregset.h winquake.h world.h \ \ qw/bothdefs.h qw/msg_backbuf.h qw/msg_ucmd.h qw/pmove.h qw/protocol.h \ \ diff --git a/include/view.h b/include/clview.h similarity index 94% rename from include/view.h rename to include/clview.h index eb5b42a3d..72027157c 100644 --- a/include/view.h +++ b/include/clview.h @@ -1,5 +1,5 @@ /* - view.h + clview.h (description) @@ -27,8 +27,8 @@ */ // view.h -#ifndef __view_h_ -#define __view_h_ +#ifndef __clview_h_ +#define __clview_h_ #include "QF/mathlib.h" @@ -53,4 +53,4 @@ void V_CalcBlend (void); extern float v_blend[4]; -#endif // __view_h_ +#endif // __clview_h_ diff --git a/include/snd_render.h b/include/snd_internal.h similarity index 99% rename from include/snd_render.h rename to include/snd_internal.h index e8cb10f00..a69a4b51e 100644 --- a/include/snd_render.h +++ b/include/snd_internal.h @@ -1,5 +1,5 @@ /* - snd_render.h + snd_internal.h Sound renderer plugin stuff @@ -29,8 +29,8 @@ $Id$ */ -#ifndef __snd_render_h -#define __snd_render_h +#ifndef __snd_internal_h +#define __snd_internal_h /** \defgroup sound_render Sound rendering sub-system. @@ -571,4 +571,4 @@ sfxbuffer_t *SND_GetCache (long samples, int rate, int channels, sfxblock_t *block, cache_allocator_t allocator); //@} -#endif//__snd_render_h +#endif//__snd_internal_h diff --git a/libs/audio/cd_file.c b/libs/audio/cd_file.c index 618d3e19c..29ac282e3 100644 --- a/libs/audio/cd_file.c +++ b/libs/audio/cd_file.c @@ -66,7 +66,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "QF/va.h" #include "compat.h" -#include "snd_render.h" +#include "snd_internal.h" /* Generic plugin structures */ static general_data_t plugin_info_general_data; diff --git a/libs/audio/renderer/flac.c b/libs/audio/renderer/flac.c index c1af83ecc..a27c05344 100644 --- a/libs/audio/renderer/flac.c +++ b/libs/audio/renderer/flac.c @@ -64,7 +64,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "QF/sound.h" #include "QF/sys.h" -#include "snd_render.h" +#include "snd_internal.h" #ifdef LEGACY_FLAC #define FLAC__StreamDecoder FLAC__SeekableStreamDecoder diff --git a/libs/audio/renderer/midi.c b/libs/audio/renderer/midi.c index a123cf60c..e78d0b662 100644 --- a/libs/audio/renderer/midi.c +++ b/libs/audio/renderer/midi.c @@ -45,7 +45,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "QF/sys.h" #include "QF/quakefs.h" -#include "snd_render.h" +#include "snd_internal.h" #define FRAMES 1024 #define CHANNELS 2 diff --git a/libs/audio/renderer/snd_channels.c b/libs/audio/renderer/snd_channels.c index 8b2df1a62..b7eedaa68 100644 --- a/libs/audio/renderer/snd_channels.c +++ b/libs/audio/renderer/snd_channels.c @@ -50,7 +50,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "QF/quakefs.h" #include "QF/sys.h" -#include "snd_render.h" +#include "snd_internal.h" static channel_t *free_channels; channel_t snd_channels[MAX_CHANNELS]; diff --git a/libs/audio/renderer/snd_dma.c b/libs/audio/renderer/snd_dma.c index 99551acb0..65731cfcc 100644 --- a/libs/audio/renderer/snd_dma.c +++ b/libs/audio/renderer/snd_dma.c @@ -53,7 +53,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "QF/va.h" #include "QF/quakefs.h" -#include "snd_render.h" +#include "snd_internal.h" static qboolean snd_initialized = false; static int snd_blocked = 0; diff --git a/libs/audio/renderer/snd_jack.c b/libs/audio/renderer/snd_jack.c index 820db42eb..f6d28d8de 100644 --- a/libs/audio/renderer/snd_jack.c +++ b/libs/audio/renderer/snd_jack.c @@ -48,7 +48,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "QF/sys.h" #include "QF/va.h" -#include "snd_render.h" +#include "snd_internal.h" static int sound_started = 0; static int snd_blocked = 0; diff --git a/libs/audio/renderer/snd_mem.c b/libs/audio/renderer/snd_mem.c index d211948dc..6452657a4 100644 --- a/libs/audio/renderer/snd_mem.c +++ b/libs/audio/renderer/snd_mem.c @@ -50,7 +50,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "QF/quakefs.h" #include "compat.h" -#include "snd_render.h" +#include "snd_internal.h" #define SAMPLE_GAP 4 diff --git a/libs/audio/renderer/snd_mix.c b/libs/audio/renderer/snd_mix.c index c5a902684..dbf347d12 100644 --- a/libs/audio/renderer/snd_mix.c +++ b/libs/audio/renderer/snd_mix.c @@ -45,7 +45,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "QF/sys.h" #include "compat.h" -#include "snd_render.h" +#include "snd_internal.h" #define VOLSCALE 512.0 // so mixing is less likely to overflow // note: must be >= 255 due to the channel diff --git a/libs/audio/renderer/snd_resample.c b/libs/audio/renderer/snd_resample.c index 21bfba61c..7c708134f 100644 --- a/libs/audio/renderer/snd_resample.c +++ b/libs/audio/renderer/snd_resample.c @@ -48,7 +48,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "QF/quakefs.h" #include "compat.h" -#include "snd_render.h" +#include "snd_internal.h" typedef struct { float *data; diff --git a/libs/audio/renderer/snd_sfx.c b/libs/audio/renderer/snd_sfx.c index 97d06ceb9..e2924c6ac 100644 --- a/libs/audio/renderer/snd_sfx.c +++ b/libs/audio/renderer/snd_sfx.c @@ -49,7 +49,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "QF/sys.h" #include "QF/va.h" -#include "snd_render.h" +#include "snd_internal.h" #define MAX_SFX 512 static sfx_t snd_sfx[MAX_SFX]; diff --git a/libs/audio/renderer/vorbis.c b/libs/audio/renderer/vorbis.c index 4236c406b..0d66b5d4f 100644 --- a/libs/audio/renderer/vorbis.c +++ b/libs/audio/renderer/vorbis.c @@ -49,7 +49,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "QF/sound.h" #include "QF/sys.h" -#include "snd_render.h" +#include "snd_internal.h" #define FRAMES 1024 diff --git a/libs/audio/renderer/wav.c b/libs/audio/renderer/wav.c index 4cbea5be3..c29a66e4d 100644 --- a/libs/audio/renderer/wav.c +++ b/libs/audio/renderer/wav.c @@ -46,7 +46,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "QF/quakefs.h" #include "QF/riff.h" -#include "snd_render.h" +#include "snd_internal.h" #define FRAMES 1024 diff --git a/libs/audio/targets/snd_alsa.c b/libs/audio/targets/snd_alsa.c index b544bd703..8c778a40a 100644 --- a/libs/audio/targets/snd_alsa.c +++ b/libs/audio/targets/snd_alsa.c @@ -41,7 +41,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "QF/qargs.h" #include "QF/sys.h" -#include "snd_render.h" +#include "snd_internal.h" static int snd_inited; static int snd_blocked = 0; diff --git a/libs/audio/targets/snd_disk.c b/libs/audio/targets/snd_disk.c index 27b178f71..1c8d36f39 100644 --- a/libs/audio/targets/snd_disk.c +++ b/libs/audio/targets/snd_disk.c @@ -52,7 +52,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "QF/qargs.h" #include "QF/sys.h" -#include "snd_render.h" +#include "snd_internal.h" static int snd_inited; static QFile *snd_file; diff --git a/libs/audio/targets/snd_dx.c b/libs/audio/targets/snd_dx.c index 5b41357c5..0d5721ded 100644 --- a/libs/audio/targets/snd_dx.c +++ b/libs/audio/targets/snd_dx.c @@ -40,7 +40,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "QF/qargs.h" #include "QF/sys.h" -#include "snd_render.h" +#include "snd_internal.h" #define iDirectSoundCreate(a,b,c) pDirectSoundCreate(a,b,c) diff --git a/libs/audio/targets/snd_oss.c b/libs/audio/targets/snd_oss.c index d4c2dbfe6..5e5ad5320 100644 --- a/libs/audio/targets/snd_oss.c +++ b/libs/audio/targets/snd_oss.c @@ -72,7 +72,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "QF/qargs.h" #include "QF/sys.h" -#include "snd_render.h" +#include "snd_internal.h" #ifndef MAP_FAILED # define MAP_FAILED ((void *) -1) diff --git a/libs/audio/targets/snd_sdl.c b/libs/audio/targets/snd_sdl.c index 2fd86e6be..211471068 100644 --- a/libs/audio/targets/snd_sdl.c +++ b/libs/audio/targets/snd_sdl.c @@ -49,7 +49,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "QF/qargs.h" #include "QF/sys.h" -#include "snd_render.h" +#include "snd_internal.h" static dma_t sn; static int snd_inited; diff --git a/libs/audio/targets/snd_sgi.c b/libs/audio/targets/snd_sgi.c index 15e8c0c03..478c524f6 100644 --- a/libs/audio/targets/snd_sgi.c +++ b/libs/audio/targets/snd_sgi.c @@ -42,7 +42,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "QF/qtypes.h" #include "QF/sys.h" -#include "snd_render.h" +#include "snd_internal.h" static int snd_inited = 0; static ALconfig alc; diff --git a/libs/audio/targets/snd_sun.c b/libs/audio/targets/snd_sun.c index ec7a54492..493f37cb0 100644 --- a/libs/audio/targets/snd_sun.c +++ b/libs/audio/targets/snd_sun.c @@ -53,7 +53,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "QF/qtypes.h" #include "QF/sys.h" -#include "snd_render.h" +#include "snd_internal.h" static int audio_fd; static int snd_inited; diff --git a/libs/audio/targets/snd_win.c b/libs/audio/targets/snd_win.c index 11b56f77f..80d5beb04 100644 --- a/libs/audio/targets/snd_win.c +++ b/libs/audio/targets/snd_win.c @@ -39,7 +39,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "QF/qargs.h" #include "QF/sys.h" -#include "snd_render.h" +#include "snd_internal.h" // 64K is > 1 second at 16-bit, 22050 Hz #define WAV_BUFFERS 64 diff --git a/libs/video/renderer/gl/gl_mod_alias.c b/libs/video/renderer/gl/gl_mod_alias.c index aa29022c3..69d65368e 100644 --- a/libs/video/renderer/gl/gl_mod_alias.c +++ b/libs/video/renderer/gl/gl_mod_alias.c @@ -62,7 +62,6 @@ static __attribute__ ((used)) const char rcsid[] = #include "r_cvar.h" #include "r_dynamic.h" #include "r_local.h" -#include "view.h" typedef struct { vec3_t normal; diff --git a/libs/video/renderer/gl/gl_rmain.c b/libs/video/renderer/gl/gl_rmain.c index 77bd52b05..e7427b161 100644 --- a/libs/video/renderer/gl/gl_rmain.c +++ b/libs/video/renderer/gl/gl_rmain.c @@ -65,7 +65,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "r_dynamic.h" #include "r_local.h" #include "varrays.h" -#include "view.h" +#include "clview.h" //FIXME entity_t r_worldentity; diff --git a/libs/video/renderer/gl/gl_screen.c b/libs/video/renderer/gl/gl_screen.c index 839949808..61dd871f6 100644 --- a/libs/video/renderer/gl/gl_screen.c +++ b/libs/video/renderer/gl/gl_screen.c @@ -62,7 +62,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "r_local.h" #include "r_screen.h" #include "sbar.h" -#include "view.h" +#include "clview.h" //FIXME /* SCREEN SHOTS */ diff --git a/libs/video/renderer/gl/gl_sky.c b/libs/video/renderer/gl/gl_sky.c index 4b9abecd4..c29989cc5 100644 --- a/libs/video/renderer/gl/gl_sky.c +++ b/libs/video/renderer/gl/gl_sky.c @@ -55,7 +55,6 @@ static __attribute__ ((used)) const char rcsid[] = #include "compat.h" #include "r_cvar.h" #include "r_shared.h" -#include "view.h" const char *suf[6] = { "rt", "bk", "lf", "ft", "up", "dn" }; int solidskytexture; diff --git a/libs/video/renderer/gl/gl_sky_clip.c b/libs/video/renderer/gl/gl_sky_clip.c index 67e51856f..836754f61 100644 --- a/libs/video/renderer/gl/gl_sky_clip.c +++ b/libs/video/renderer/gl/gl_sky_clip.c @@ -59,7 +59,6 @@ static __attribute__ ((used)) const char rcsid[] = #include "r_cvar.h" #include "r_shared.h" -#include "view.h" #include "compat.h" diff --git a/libs/video/renderer/sw/screen.c b/libs/video/renderer/sw/screen.c index 63422abc9..0e2fa4622 100644 --- a/libs/video/renderer/sw/screen.c +++ b/libs/video/renderer/sw/screen.c @@ -56,7 +56,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "r_local.h" #include "r_screen.h" #include "sbar.h" -#include "view.h" +#include "clview.h" //FIXME static void SCR_ApplyBlend (void) // Used to be V_UpdatePalette diff --git a/libs/video/renderer/sw/sw_rmain.c b/libs/video/renderer/sw/sw_rmain.c index 102eb1ed1..1d280a4a4 100644 --- a/libs/video/renderer/sw/sw_rmain.c +++ b/libs/video/renderer/sw/sw_rmain.c @@ -56,7 +56,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "r_cvar.h" #include "r_dynamic.h" #include "r_local.h" -#include "view.h" +#include "clview.h" //FIXME #ifdef PIC # undef USE_INTEL_ASM //XXX asm pic hack diff --git a/libs/video/targets/vid.c b/libs/video/targets/vid.c index 6968757cb..dcc83f2d3 100644 --- a/libs/video/targets/vid.c +++ b/libs/video/targets/vid.c @@ -47,7 +47,6 @@ static __attribute__ ((used)) const char rcsid[] = #include "QF/vid.h" #include "compat.h" -#include "view.h" /* Software and hardware gamma support */ VISIBLE byte gammatable[256]; diff --git a/nq/source/cl_view.c b/nq/source/cl_view.c index a13294c98..786892ae9 100644 --- a/nq/source/cl_view.c +++ b/nq/source/cl_view.c @@ -43,7 +43,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "compat.h" #include "host.h" #include "r_local.h" -#include "view.h" +#include "clview.h" /* The view is allowed to move slightly from it's true position for bobbing, diff --git a/nq/source/host.c b/nq/source/host.c index 79476b91d..a7efdcc63 100644 --- a/nq/source/host.c +++ b/nq/source/host.c @@ -62,7 +62,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "sbar.h" #include "server.h" #include "sv_progs.h" -#include "view.h" +#include "clview.h" /* diff --git a/nq/source/sv_ded.c b/nq/source/sv_ded.c index b804585be..b11ea8c55 100644 --- a/nq/source/sv_ded.c +++ b/nq/source/sv_ded.c @@ -52,7 +52,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "r_dynamic.h" #include "sbar.h" #include "server.h" -#include "view.h" +#include "clview.h" //FIXME client_state_t cl; client_static_t cls; diff --git a/nq/source/sv_user.c b/nq/source/sv_user.c index 3ab3c7a28..9708aef25 100644 --- a/nq/source/sv_user.c +++ b/nq/source/sv_user.c @@ -48,7 +48,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "host.h" #include "server.h" #include "sv_progs.h" -#include "view.h" +#include "clview.h" //FIXME #include "world.h" extern cvar_t *cl_rollangle; //FIXME diff --git a/qw/source/cl_ents.c b/qw/source/cl_ents.c index e7b081545..37b1118dd 100644 --- a/qw/source/cl_ents.c +++ b/qw/source/cl_ents.c @@ -60,7 +60,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "qw/pmove.h" #include "r_cvar.h" #include "r_dynamic.h" -#include "view.h" +#include "clview.h" static struct predicted_player { int flags; diff --git a/qw/source/cl_input.c b/qw/source/cl_input.c index af30cae14..4b842d018 100644 --- a/qw/source/cl_input.c +++ b/qw/source/cl_input.c @@ -57,7 +57,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "client.h" #include "compat.h" #include "host.h" -#include "view.h" +#include "clview.h" cvar_t *cl_nodelta; cvar_t *cl_maxnetfps; diff --git a/qw/source/cl_main.c b/qw/source/cl_main.c index 5697187dd..4ada2d6a2 100644 --- a/qw/source/cl_main.c +++ b/qw/source/cl_main.c @@ -112,7 +112,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "r_cvar.h" #include "r_dynamic.h" #include "sbar.h" -#include "view.h" +#include "clview.h" CLIENT_PLUGIN_PROTOS static plugin_list_t client_plugin_list[] = { diff --git a/qw/source/cl_parse.c b/qw/source/cl_parse.c index b46a7c4b8..3312f04fd 100644 --- a/qw/source/cl_parse.c +++ b/qw/source/cl_parse.c @@ -79,7 +79,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "qw/pmove.h" #include "qw/protocol.h" #include "sbar.h" -#include "view.h" +#include "clview.h" const char *svc_strings[] = { "svc_bad", diff --git a/qw/source/cl_view.c b/qw/source/cl_view.c index e648c7bbb..e8a9de14c 100644 --- a/qw/source/cl_view.c +++ b/qw/source/cl_view.c @@ -46,7 +46,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "compat.h" #include "host.h" #include "qw/pmove.h" -#include "view.h" +#include "clview.h" /* The view is allowed to move slightly from it's true position for bobbing, From b0c93aa24fa2a7c154a838edae62978475f7289e Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 23 Jul 2011 15:56:43 +0900 Subject: [PATCH 005/334] Remove an annoying comment. --- include/netmain.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/netmain.h b/include/netmain.h index bfd9a5677..5622aebfd 100644 --- a/include/netmain.h +++ b/include/netmain.h @@ -64,7 +64,7 @@ struct qsockaddr // // General notes: // game_name is currently always "QUAKE", but is there so this same protocol -// can be used for future games as well; can you say Quake2? +// can be used for future games as well // // CCREQ_CONNECT // string game_name "QUAKE" From e15771f4a4d0ec88e7ec3e4b444d4a365878c43a Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 23 Jul 2011 15:57:32 +0900 Subject: [PATCH 006/334] Nuke a dead function. --- include/netchan.h | 1 - libs/net/nc/net_udp.c | 32 -------------------------------- libs/net/nc/net_udp6.c | 31 ------------------------------- 3 files changed, 64 deletions(-) diff --git a/include/netchan.h b/include/netchan.h index cc756d984..2a0f3d151 100644 --- a/include/netchan.h +++ b/include/netchan.h @@ -71,7 +71,6 @@ qboolean NET_CompareBaseAdr (netadr_t a, netadr_t b); const char *NET_AdrToString (netadr_t a); const char *NET_BaseAdrToString (netadr_t a); qboolean NET_StringToAdr (const char *s, netadr_t *a); -qboolean NET_IsClientLegal(netadr_t *adr); int Net_Log_Init (const char **sound_precache); diff --git a/libs/net/nc/net_udp.c b/libs/net/nc/net_udp.c index 1bf689885..88ecac68f 100644 --- a/libs/net/nc/net_udp.c +++ b/libs/net/nc/net_udp.c @@ -229,37 +229,6 @@ NET_StringToAdr (const char *s, netadr_t *a) return true; } -// Returns true if we can't bind the address locally--in other words, -// the IP is NOT one of our interfaces. -qboolean -NET_IsClientLegal (netadr_t *adr) -{ -#if 0 - int newsocket; - AF_address_t sadr; - - if (adr->ip[0] == 127) - return false; // no local connections period - - NetadrToSockadr (adr, &sadr); - - if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) - Sys_Error ("NET_IsClientLegal: socket:", strerror (errno)); - - sadr.sin_port = 0; - - if (bind (newsocket, (void *) &sadr, sizeof (sadr)) == -1) { - // It is not a local address - close (newsocket); - return true; - } - close (newsocket); - return false; -#else - return true; -#endif -} - qboolean NET_GetPacket (void) { @@ -422,7 +391,6 @@ NET_Init (int port) Sys_Error ("Winsock initialization failed."); #endif /* _WIN32 */ - // open the single socket to be used for all communications net_socket = UDP_OpenSocket (port); // init the message buffer diff --git a/libs/net/nc/net_udp6.c b/libs/net/nc/net_udp6.c index fc8e60541..8b261db2e 100644 --- a/libs/net/nc/net_udp6.c +++ b/libs/net/nc/net_udp6.c @@ -375,37 +375,6 @@ NET_StringToAdr (const char *s, netadr_t *a) return true; } -// Returns true if we can't bind the address locally--in other words, -// the IP is NOT one of our interfaces. -qboolean -NET_IsClientLegal (netadr_t *adr) -{ -#if 0 - int newsocket; - struct sockaddr_in sadr; - - if (adr->ip[0] == 127) - return false; // no local connections period - - NetadrToSockadr (adr, &sadr); - - if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) - Sys_Error ("NET_IsClientLegal: socket: %s", strerror (errno)); - - sadr.sin_port = 0; - - if (bind (newsocket, (void *) &sadr, sizeof (sadr)) == -1) { - // It is not a local address - close (newsocket); - return true; - } - close (newsocket); - return false; -#else - return true; -#endif -} - qboolean NET_GetPacket (void) { From 24a50982ac0785fd44099c3e08bc8f36d02d3531 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 23 Jul 2011 15:58:06 +0900 Subject: [PATCH 007/334] Document the public interface to QW's net_udp --- include/netchan.h | 90 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 80 insertions(+), 10 deletions(-) diff --git a/include/netchan.h b/include/netchan.h index 2a0f3d151..98de36561 100644 --- a/include/netchan.h +++ b/include/netchan.h @@ -60,18 +60,88 @@ extern struct cvar_s *qport; extern int net_socket; -void NET_Init (int port); -void NET_Init (int port); -void NET_Shutdown (void); -qboolean NET_GetPacket (void); -void NET_SendPacket (int length, const void *data, netadr_t to); +/** Initialize the UDP network interface. -qboolean NET_CompareAdr (netadr_t a, netadr_t b); -qboolean NET_CompareBaseAdr (netadr_t a, netadr_t b); -const char *NET_AdrToString (netadr_t a); -const char *NET_BaseAdrToString (netadr_t a); -qboolean NET_StringToAdr (const char *s, netadr_t *a); + Opens a single socket to be used for all communications. + \param port The port to which the socket will be bound. +*/ +void NET_Init (int port); + +/** Shutdown the UDP network interface. +*/ +void NET_Shutdown (void); + +/** Read a single packet from the network into net_message. + + \return True if successfully read, otherwise false. +*/ +qboolean NET_GetPacket (void); + +/** Send a data packet out to the network. + + \param length The length of the data to be sent. + \param data The data to be sent. + \param to The address to which the data will be sent. +*/ +void NET_SendPacket (int length, const void *data, netadr_t to); + +/** Compare two network addresses. + + Compare the port number too. + + \param a The first address to compare. + \param b The second address to compare. + \return True of the addresses match, otherwise false. +*/ +qboolean NET_CompareAdr (netadr_t a, netadr_t b); + +/** Compare two network addresses. + + Ignore the port number. + + \param a The first address to compare. + \param b The second address to compare. + \return True of the addresses match, otherwise false. +*/ +qboolean NET_CompareBaseAdr (netadr_t a, netadr_t b); + +/** Convert an address to a string. + + Include the port number in the string. + + \warning The return value is a pointer to a static buffer. The returned + string must be saved if mixing calls with different addresses. + + \param a The address to convert + \return The address in human readable form. +*/ +const char *NET_AdrToString (netadr_t a); + +/** Convert an address to a string. + + Do not include the port number in the string. + + \note The return value is a pointer to a static buffer. The returned + string must be saved if mixing calls with different addresses. + + \param a The address to convert + \return The address in human readable form. +*/ +const char *NET_BaseAdrToString (netadr_t a); + +/** Convert a human readable address to a quake address. + + Accepts both host names (full or partial) and numeric form. + + If a port is specified, the port value in the address will be set to that + value, otherwise it will be set to 0. + + \param[in] s The human readable address to be converted. + \param[out] a The resulting address of the conversion. + \return True if the conversion is successful, otherwise false. +*/ +qboolean NET_StringToAdr (const char *s, netadr_t *a); int Net_Log_Init (const char **sound_precache); void Net_LogPrintf (const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); From adce93a2de262a450f3b272e7bba3f8fdeaf52e2 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 23 Jul 2011 16:02:10 +0900 Subject: [PATCH 008/334] Change a note to a warning. --- include/netchan.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/netchan.h b/include/netchan.h index 98de36561..88ea2e484 100644 --- a/include/netchan.h +++ b/include/netchan.h @@ -122,8 +122,8 @@ const char *NET_AdrToString (netadr_t a); Do not include the port number in the string. - \note The return value is a pointer to a static buffer. The returned - string must be saved if mixing calls with different addresses. + \warning The return value is a pointer to a static buffer. The returned + string must be saved if mixing calls with different addresses. \param a The address to convert \return The address in human readable form. From 2035e65bad2cf05ee5ced55f8f44c4fd7fe4900f Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 23 Jul 2011 17:51:07 +0900 Subject: [PATCH 009/334] Make the qport flags a little more doc friendly. --- include/netchan.h | 12 +++++++----- libs/net/net_chan.c | 6 +++--- qtv/source/client.c | 2 +- qtv/source/server.c | 4 ++-- qw/include/sv_qtv.h | 4 ++-- qw/source/cl_demo.c | 2 +- qw/source/cl_main.c | 2 +- qw/source/sv_main.c | 8 +++++--- qw/source/sv_qtv.c | 6 +++--- 9 files changed, 25 insertions(+), 21 deletions(-) diff --git a/include/netchan.h b/include/netchan.h index 88ea2e484..8b4b8a05d 100644 --- a/include/netchan.h +++ b/include/netchan.h @@ -162,6 +162,11 @@ qboolean ServerPaused (void); #define MAX_LATENT 32 +typedef enum { + NC_QPORT_SEND = 0x01, + NC_QPORT_READ = 0x02, +} ncqport_e; + typedef struct netchan_s { qboolean fatal_error; @@ -177,7 +182,7 @@ typedef struct netchan_s { int good_count; // cleared each level netadr_t remote_address; - int qport; + ncqport_e qport; int flags; // bandwidth estimator @@ -217,10 +222,7 @@ void Netchan_Transmit (netchan_t *chan, int length, byte *data); void Netchan_OutOfBand (netadr_t adr, int length, byte *data); void Netchan_OutOfBandPrint (netadr_t adr, const char *format, ...) __attribute__((format(printf,2,3))); qboolean Netchan_Process (netchan_t *chan); -void Netchan_Setup (netchan_t *chan, netadr_t adr, int qport, int flags); - -#define NC_SEND_QPORT 0x01 -#define NC_READ_QPORT 0x02 +void Netchan_Setup (netchan_t *chan, netadr_t adr, ncqport_e qport, int flags); qboolean Netchan_CanPacket (netchan_t *chan); qboolean Netchan_CanReliable (netchan_t *chan); diff --git a/libs/net/net_chan.c b/libs/net/net_chan.c index 2298fe941..d79afb75d 100644 --- a/libs/net/net_chan.c +++ b/libs/net/net_chan.c @@ -187,7 +187,7 @@ Netchan_OutOfBandPrint (netadr_t adr, const char *format, ...) called to open a channel to a remote system */ void -Netchan_Setup (netchan_t *chan, netadr_t adr, int qport, int flags) +Netchan_Setup (netchan_t *chan, netadr_t adr, ncqport_e qport, int flags) { memset (chan, 0, sizeof (*chan)); @@ -286,7 +286,7 @@ Netchan_Transmit (netchan_t *chan, int length, byte *data) MSG_WriteLong (&send, w2); // send the qport if we are a client - if (chan->flags & NC_SEND_QPORT) + if (chan->flags & NC_QPORT_SEND) MSG_WriteShort (&send, chan->qport); // copy the reliable message to the packet first @@ -343,7 +343,7 @@ Netchan_Process (netchan_t *chan) sequence_ack = MSG_ReadLong (net_message); // read the qport if we are a server, but drop it - if (chan->flags & NC_READ_QPORT) + if (chan->flags & NC_QPORT_READ) MSG_ReadShort (net_message); reliable_message = sequence >> 31; diff --git a/qtv/source/client.c b/qtv/source/client.c index 5bc526a6b..a93384d30 100644 --- a/qtv/source/client.c +++ b/qtv/source/client.c @@ -1148,7 +1148,7 @@ client_connect (connection_t *con, void *object) cl = calloc (1, sizeof (client_t)); client_count++; - Netchan_Setup (&cl->netchan, con->address, qport, NC_READ_QPORT); + Netchan_Setup (&cl->netchan, con->address, qport, NC_QPORT_READ); cl->clnext = clients; clients = cl; cl->userinfo = userinfo; diff --git a/qtv/source/server.c b/qtv/source/server.c index 253fbf119..3ef69e1e3 100644 --- a/qtv/source/server.c +++ b/qtv/source/server.c @@ -358,7 +358,7 @@ server_connect (connection_t *con, void *object) return; qtv_printf ("connection from %s\n", sv->name); - Netchan_Setup (&sv->netchan, con->address, sv->qport, NC_SEND_QPORT); + Netchan_Setup (&sv->netchan, con->address, sv->qport, NC_QPORT_SEND); sv->netchan.outgoing_sequence = 1; sv->connected = 1; sv->playermodel = -1; @@ -461,7 +461,7 @@ sv_new_f (void) Hash_Add (server_hash, sv); sv->con = Connection_Add (&adr, sv, server_challenge); - Netchan_Setup (&sv->netchan, sv->con->address, sv->qport, NC_SEND_QPORT); + Netchan_Setup (&sv->netchan, sv->con->address, sv->qport, NC_QPORT_SEND); server_getchallenge (sv->con, sv); } diff --git a/qw/include/sv_qtv.h b/qw/include/sv_qtv.h index 5c9936b85..ff1cb1035 100644 --- a/qw/include/sv_qtv.h +++ b/qw/include/sv_qtv.h @@ -33,8 +33,8 @@ #define __sv_qtv_h struct info_s; -void SV_qtvConnect (int qport, struct info_s *info); -int SV_qtvPacket (int qport); +void SV_qtvConnect (ncqport_e qport, struct info_s *info); +int SV_qtvPacket (ncqport_e qport); void SV_qtvCheckTimeouts (void); void SV_qtvSendMessages (void); void SV_qtvFinalMessage (const char *message); diff --git a/qw/source/cl_demo.c b/qw/source/cl_demo.c index 5248ae25f..5f2cb114c 100644 --- a/qw/source/cl_demo.c +++ b/qw/source/cl_demo.c @@ -902,7 +902,7 @@ CL_StartDemo (void) Sys_Printf ("qwd\n"); } CL_SetState (ca_demostart); - Netchan_Setup (&cls.netchan, net_from, 0, NC_SEND_QPORT); + Netchan_Setup (&cls.netchan, net_from, 0, NC_QPORT_SEND); realtime = 0; cls.findtrack = true; cls.lasttype = 0; diff --git a/qw/source/cl_main.c b/qw/source/cl_main.c index 4ada2d6a2..7527126be 100644 --- a/qw/source/cl_main.c +++ b/qw/source/cl_main.c @@ -874,7 +874,7 @@ CL_ConnectionlessPacket (void) Sys_Printf ("Dup connect received. Ignored.\n"); return; } - Netchan_Setup (&cls.netchan, net_from, cls.qport, NC_SEND_QPORT); + Netchan_Setup (&cls.netchan, net_from, cls.qport, NC_QPORT_SEND); MSG_WriteByte (&cls.netchan.message, clc_stringcmd); MSG_WriteString (&cls.netchan.message, "new"); CL_SetState (ca_connected); diff --git a/qw/source/sv_main.c b/qw/source/sv_main.c index def3f6fad..1069d583b 100644 --- a/qw/source/sv_main.c +++ b/qw/source/sv_main.c @@ -767,7 +767,8 @@ SVC_DirectConnect (void) info_t *userinfo = 0; const char *s; client_t *cl, *newcl; - int challenge, qport, version, i, qtv = 0; + int challenge, version, i, qtv = 0; + ncqport_e qport; netadr_t adr; qboolean spectator; client_frame_t *frames; @@ -908,7 +909,7 @@ SVC_DirectConnect (void) Netchan_OutOfBandPrint (adr, "%c", S2C_CONNECTION); - Netchan_Setup (&newcl->netchan, adr, qport, NC_READ_QPORT); + Netchan_Setup (&newcl->netchan, adr, qport, NC_QPORT_READ); newcl->backbuf.netchan = &newcl->netchan; newcl->backbuf.name = newcl->name; @@ -1754,7 +1755,8 @@ SV_ReadPackets (void) { //NOTE star volatile, not volatile star client_t *volatile cl; // * volatile for longjmp - int qport, i; + int i; + ncqport_e qport; double until; while (NET_GetPacket ()) { diff --git a/qw/source/sv_qtv.c b/qw/source/sv_qtv.c index 037af83d6..436dcbeb1 100644 --- a/qw/source/sv_qtv.c +++ b/qw/source/sv_qtv.c @@ -398,7 +398,7 @@ qtv_reliable_send (sv_qtv_t *proxy) } void -SV_qtvConnect (int qport, info_t *info) +SV_qtvConnect (ncqport_e qport, info_t *info) { sv_qtv_t *proxy; @@ -413,7 +413,7 @@ SV_qtvConnect (int qport, info_t *info) while (!(proxy->name_key = Hash_Find (proxy->info->tab, "name"))) Info_SetValueForKey (proxy->info, "name", "\"unnamed proxy\"", 1); - Netchan_Setup (&proxy->netchan, net_from, qport, NC_READ_QPORT); + Netchan_Setup (&proxy->netchan, net_from, qport, NC_QPORT_READ); proxy->backbuf.netchan = &proxy->netchan; proxy->backbuf.name = proxy->name_key->value; proxy->datagram.data = proxy->datagram_buf; @@ -424,7 +424,7 @@ SV_qtvConnect (int qport, info_t *info) } int -SV_qtvPacket (int qport) +SV_qtvPacket (ncqport_e qport) { int i; From 3678b610eb3574a11a0d6e3daae0194dd5de0704 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 23 Jul 2011 17:53:06 +0900 Subject: [PATCH 010/334] Make a start on documenting netchan. --- include/netchan.h | 155 +++++++++++++++++++++++++++++++++++--------- libs/net/net_chan.c | 46 ------------- 2 files changed, 123 insertions(+), 78 deletions(-) diff --git a/include/netchan.h b/include/netchan.h index 8b4b8a05d..97378ea8a 100644 --- a/include/netchan.h +++ b/include/netchan.h @@ -34,6 +34,13 @@ #include "QF/qdefs.h" #include "QF/sizebuf.h" +/** \defgroup network Network support +*/ + +/** \defgroup qw-net QuakeWorld network support. + \ingroup network +*/ +//{ #define MAX_MSGLEN 1450 // max length of a reliable message #define MAX_DATAGRAM 1450 // max length of unreliable message @@ -60,6 +67,25 @@ extern struct cvar_s *qport; extern int net_socket; +int Net_Log_Init (const char **sound_precache); +void Net_LogPrintf (const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); +void Log_Incoming_Packet (const byte *p, int len, int has_sequence); +void Log_Outgoing_Packet (const byte *p, int len, int has_sequence); +void Net_LogStop (void); +void Analyze_Client_Packet (const byte * data, int len, int has_sequence); +void Analyze_Server_Packet (const byte * data, int len, int has_sequence); + +extern struct cvar_s *net_packetlog; + +extern qboolean is_server; +qboolean ServerPaused (void); +//@} + +/** \defgroup qw-udp QuakeWorld udp support. + \ingroup qw-net +*/ +//@{ + /** Initialize the UDP network interface. Opens a single socket to be used for all communications. @@ -143,21 +169,61 @@ const char *NET_BaseAdrToString (netadr_t a); */ qboolean NET_StringToAdr (const char *s, netadr_t *a); -int Net_Log_Init (const char **sound_precache); -void Net_LogPrintf (const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); -void Log_Incoming_Packet (const byte *p, int len, int has_sequence); -void Log_Outgoing_Packet (const byte *p, int len, int has_sequence); -void Net_LogStop (void); -void Analyze_Client_Packet (const byte * data, int len, int has_sequence); -void Analyze_Server_Packet (const byte * data, int len, int has_sequence); +//@} -extern struct cvar_s *net_packetlog; +/** \defgroup netchan Netchan + \ingroup qw-net -extern qboolean is_server; -qboolean ServerPaused (void); + + + + + + + + +
Packet Header
Bits Meaning
31 sequence
1 this message contains a reliable payload
31 acknowledge sequence
1 acknowledge receipt of even/odd message
16 qport
-//============================================================================ + The remote connection never knows if it missed a reliable message, the + local side detects that it has been dropped by seeing a sequence + acknowledge higher than the last reliable sequence, but without the + correct even/odd bit for the reliable set. + If the sender notices that a reliable message has been dropped, it will + be retransmitted. It will not be retransmitted again until a message + after the retransmit has been acknowledged and the reliable still failed + to get there. + + If the sequence number is -1, the packet should be handled without a + netcon. + + The reliable message can be added to at any time by doing + MSG_Write* (&netchan->message, data). + + If the message buffer is overflowed, either by a single message, or by + multiple frames worth piling up while the last reliable transmit goes + unacknowledged, the netchan signals a fatal error. + + Reliable messages are always placed first in a packet, then the unreliable + message is included if there is sufficient room. + + To the receiver, there is no distinction between the reliable and + unreliable parts of the message, they are just processed out as a single + larger message. + + Illogical packet sequence numbers cause the packet to be dropped, but do + not kill the connection. This, combined with the tight window of valid + reliable acknowledgement numbers provides protection against malicious + address spoofing. + + The qport field is a workaround for bad address translating routers that + sometimes remap the client's source port on a packet during gameplay. + + If the base part of the net address matches and the qport matches, then + the channel matches even if the IP port differs. The IP port should be + updated to the new value before sending out any replies. +*/ +//@{ #define OLD_AVG 0.99 // total = oldtotal*OLD_AVG + new*(1-OLD_AVG) #define MAX_LATENT 32 @@ -168,59 +234,82 @@ typedef enum { } ncqport_e; typedef struct netchan_s { - qboolean fatal_error; + qboolean fatal_error; ///< True if the message overflowed - float last_received; // for timeouts + float last_received; ///< Time the last packet was received. -// the statistics are cleared at each client begin, because -// the server connecting process gives a bogus picture of the data - float frame_latency; // rolling average + /// \name statistics + /// the statistics are cleared at each client begin, because + /// the server connection process gives a bogus picture of the data + ///@{ + float frame_latency; ///< rolling average float frame_rate; - int drop_count; // dropped packets, cleared each level - int net_drop; //packets dropped before this one - int good_count; // cleared each level + int drop_count; ///< dropped packets, cleared each level + int net_drop; ///< packets dropped before this one + int good_count; ///< cleared each level + ///@} netadr_t remote_address; ncqport_e qport; int flags; -// bandwidth estimator - double cleartime; // if realtime > nc->cleartime, free to go - double rate; // seconds / byte + /// \name bandwidth estimator + ///@{ + double cleartime; ///< if realtime > nc->cleartime, + ///< free to go + double rate; ///< seconds / byte + ///@} -// sequencing variables + /// \name sequencing variables + ///@{ int incoming_sequence; int incoming_acknowledged; - int incoming_reliable_acknowledged; // single bit + int incoming_reliable_acknowledged; ///< single bit - int incoming_reliable_sequence; // single bit, maintained local + int incoming_reliable_sequence; ///< single bit, maintained local int outgoing_sequence; - int reliable_sequence; // single bit - int last_reliable_sequence; // sequence number of last send + int reliable_sequence; ///< single bit + int last_reliable_sequence; ///< sequence number of last send + ///@} -// reliable staging and holding areas - sizebuf_t message; // writing buffer to send to server + /// \name reliable staging and holding areas + ///@{ + sizebuf_t message; ///< writing buffer to send to server byte message_buf[MAX_MSGLEN]; int reliable_length; - byte reliable_buf[MAX_MSGLEN]; // unacked reliable message + byte reliable_buf[MAX_MSGLEN]; ///< unacked reliable message + ///@} -// time and size data to calculate bandwidth + /// \name time and size data to calculate bandwidth + ///@{ int outgoing_size[MAX_LATENT]; double outgoing_time[MAX_LATENT]; + ///@} } netchan_t; +/** Disable packet choking. +*/ extern int net_nochoke; // don't choke packets + +/** Disable packet sending. + + Used by clients in demo playback mode. +*/ extern int net_blocksend; // don't send packets (used by client for demos) + +/** Pointer to variable holding the current time in seconds. +*/ extern double *net_realtime; void Netchan_Init (void); void Netchan_Init_Cvars (void); void Netchan_Transmit (netchan_t *chan, int length, byte *data); void Netchan_OutOfBand (netadr_t adr, int length, byte *data); -void Netchan_OutOfBandPrint (netadr_t adr, const char *format, ...) __attribute__((format(printf,2,3))); +void Netchan_OutOfBandPrint (netadr_t adr, const char *format, ...) + __attribute__ ((format (printf,2,3))); qboolean Netchan_Process (netchan_t *chan); void Netchan_Setup (netchan_t *chan, netadr_t adr, ncqport_e qport, int flags); @@ -229,4 +318,6 @@ qboolean Netchan_CanReliable (netchan_t *chan); void Netchan_SendPacket (int length, const void *data, netadr_t to); +//@} + #endif // _NET_H diff --git a/libs/net/net_chan.c b/libs/net/net_chan.c index d79afb75d..f3a6c93b9 100644 --- a/libs/net/net_chan.c +++ b/libs/net/net_chan.c @@ -56,52 +56,6 @@ static __attribute__ ((used)) const char rcsid[] = #define PACKET_HEADER 8 -/* - packet header - ------------- - 31 sequence - 1 does this message contain a reliable payload - 31 acknowledge sequence - 1 acknowledge receipt of even/odd message - 16 qport - - The remote connection never knows if it missed a reliable message, the - local side detects that it has been dropped by seeing a sequence acknowledge - higher thatn the last reliable sequence, but without the correct evon/odd - bit for the reliable set. - - If the sender notices that a reliable message has been dropped, it will be - retransmitted. It will not be retransmitted again until a message after the - retransmit has been acknowledged and the reliable still failed to get there. - - if the sequence number is -1, the packet should be handled without a netcon - - The reliable message can be added to at any time by doing - MSG_Write* (&netchan->message, ). - - If the message buffer is overflowed, either by a single message, or by - multiple frames worth piling up while the last reliable transmit goes - unacknowledged, the netchan signals a fatal error. - - Reliable messages are always placed first in a packet, then the unreliable - message is included if there is sufficient room. - - To the receiver, there is no distinction between the reliable and unreliable - parts of the message, they are just processed out as a single larger message. - - Illogical packet sequence numbers cause the packet to be dropped, but do - not kill the connection. This, combined with the tight window of valid - reliable acknowledgement numbers provides protection against malicious - address spoofing. - - The qport field is a workaround for bad address translating routers that - sometimes remap the client's source port on a packet during gameplay. - - If the base part of the net address matches and the qport matches, then the - channel matches even if the IP port differs. The IP port should be updated - to the new value before sending out any replies. -*/ - int net_nochoke; int net_blocksend; double *net_realtime; From 9ccd5701053350b42e803921638aa984af25b216 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 23 Jul 2011 21:37:34 +0900 Subject: [PATCH 011/334] Fix a problem with linking FLAC libs. --- libs/audio/renderer/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/audio/renderer/Makefile.am b/libs/audio/renderer/Makefile.am index 162519015..abc37e600 100644 --- a/libs/audio/renderer/Makefile.am +++ b/libs/audio/renderer/Makefile.am @@ -39,12 +39,12 @@ snd_common=snd_channels.c snd_mem.c snd_mix.c snd_resample.c snd_sfx.c snd_render_default_la_LDFLAGS= $(plugin_ldflags) snd_render_default_la_SOURCES= snd_dma.c $(snd_common) $(format_src) -snd_render_default_la_LIBADD= $(SAMPLERATE_LIBS) $(VORBISFILE_LIBS) $(VORBIS_LIBS) $(LIBFLAC_LIBS) $(OGG_LIBS) $(WM_LIBS) $(top_builddir)/libs/util/libQFutil.la $(top_builddir)/libs/models/libQFmodels.la +snd_render_default_la_LIBADD= $(SAMPLERATE_LIBS) $(VORBISFILE_LIBS) $(VORBIS_LIBS) $(FLAC_LIBS) $(OGG_LIBS) $(WM_LIBS) $(top_builddir)/libs/util/libQFutil.la $(top_builddir)/libs/models/libQFmodels.la snd_render_default_la_DEPENDENCIES= EXTRA_snd_render_default_la_SOURCES= $(extra_format_src) snd_render_jack_la_LDFLAGS= $(plugin_ldflags) snd_render_jack_la_SOURCES= snd_jack.c $(snd_common) $(format_src) -snd_render_jack_la_LIBADD= $(SAMPLERATE_LIBS) $(VORBISFILE_LIBS) $(VORBIS_LIBS) $(LIBFLAC_LIBS) $(OGG_LIBS) $(WM_LIBS) $(JACK_LIBS) $(top_builddir)/libs/util/libQFutil.la $(top_builddir)/libs/models/libQFmodels.la +snd_render_jack_la_LIBADD= $(SAMPLERATE_LIBS) $(VORBISFILE_LIBS) $(VORBIS_LIBS) $(FLAC_LIBS) $(OGG_LIBS) $(WM_LIBS) $(JACK_LIBS) $(top_builddir)/libs/util/libQFutil.la $(top_builddir)/libs/models/libQFmodels.la snd_render_jack_la_DEPENDENCIES= EXTRA_snd_render_jack_la_SOURCES= $(extra_format_src) From 688e5c7e24705615ee2ed19e0ce23a922530befc Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 23 Jul 2011 21:39:13 +0900 Subject: [PATCH 012/334] Use ncqport_e on the right field. Well, now, that was incredibly silly, wasn't it? :P --- include/netchan.h | 6 +++--- libs/net/net_chan.c | 2 +- qw/include/sv_qtv.h | 4 ++-- qw/source/sv_main.c | 4 ++-- qw/source/sv_qtv.c | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/include/netchan.h b/include/netchan.h index 97378ea8a..5fa7e97c5 100644 --- a/include/netchan.h +++ b/include/netchan.h @@ -251,8 +251,8 @@ typedef struct netchan_s { ///@} netadr_t remote_address; - ncqport_e qport; - int flags; + int qport; + ncqport_e flags; /// \name bandwidth estimator ///@{ @@ -311,7 +311,7 @@ void Netchan_OutOfBand (netadr_t adr, int length, byte *data); void Netchan_OutOfBandPrint (netadr_t adr, const char *format, ...) __attribute__ ((format (printf,2,3))); qboolean Netchan_Process (netchan_t *chan); -void Netchan_Setup (netchan_t *chan, netadr_t adr, ncqport_e qport, int flags); +void Netchan_Setup (netchan_t *chan, netadr_t adr, int qport, ncqport_e flags); qboolean Netchan_CanPacket (netchan_t *chan); qboolean Netchan_CanReliable (netchan_t *chan); diff --git a/libs/net/net_chan.c b/libs/net/net_chan.c index f3a6c93b9..c50651913 100644 --- a/libs/net/net_chan.c +++ b/libs/net/net_chan.c @@ -141,7 +141,7 @@ Netchan_OutOfBandPrint (netadr_t adr, const char *format, ...) called to open a channel to a remote system */ void -Netchan_Setup (netchan_t *chan, netadr_t adr, ncqport_e qport, int flags) +Netchan_Setup (netchan_t *chan, netadr_t adr, int qport, ncqport_e flags) { memset (chan, 0, sizeof (*chan)); diff --git a/qw/include/sv_qtv.h b/qw/include/sv_qtv.h index ff1cb1035..5c9936b85 100644 --- a/qw/include/sv_qtv.h +++ b/qw/include/sv_qtv.h @@ -33,8 +33,8 @@ #define __sv_qtv_h struct info_s; -void SV_qtvConnect (ncqport_e qport, struct info_s *info); -int SV_qtvPacket (ncqport_e qport); +void SV_qtvConnect (int qport, struct info_s *info); +int SV_qtvPacket (int qport); void SV_qtvCheckTimeouts (void); void SV_qtvSendMessages (void); void SV_qtvFinalMessage (const char *message); diff --git a/qw/source/sv_main.c b/qw/source/sv_main.c index 1069d583b..4f8b2a102 100644 --- a/qw/source/sv_main.c +++ b/qw/source/sv_main.c @@ -768,7 +768,7 @@ SVC_DirectConnect (void) const char *s; client_t *cl, *newcl; int challenge, version, i, qtv = 0; - ncqport_e qport; + int qport; netadr_t adr; qboolean spectator; client_frame_t *frames; @@ -1756,7 +1756,7 @@ SV_ReadPackets (void) //NOTE star volatile, not volatile star client_t *volatile cl; // * volatile for longjmp int i; - ncqport_e qport; + int qport; double until; while (NET_GetPacket ()) { diff --git a/qw/source/sv_qtv.c b/qw/source/sv_qtv.c index 436dcbeb1..898b18d8c 100644 --- a/qw/source/sv_qtv.c +++ b/qw/source/sv_qtv.c @@ -398,7 +398,7 @@ qtv_reliable_send (sv_qtv_t *proxy) } void -SV_qtvConnect (ncqport_e qport, info_t *info) +SV_qtvConnect (int qport, info_t *info) { sv_qtv_t *proxy; @@ -424,7 +424,7 @@ SV_qtvConnect (ncqport_e qport, info_t *info) } int -SV_qtvPacket (ncqport_e qport) +SV_qtvPacket (int qport) { int i; From 9d2a3d254576d366802181094443b1b492685a1b Mon Sep 17 00:00:00 2001 From: Jeff Teunissen Date: Mon, 11 Jul 2011 12:58:56 -0400 Subject: [PATCH 013/334] Docs: Re-enable bolding also, make CODE tags bold, to help them stand out a little more. --- doc/doxygen.css | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/doc/doxygen.css b/doc/doxygen.css index f03f5179c..ff65ff378 100644 --- a/doc/doxygen.css +++ b/doc/doxygen.css @@ -5,6 +5,11 @@ body, table, div, p, dl { font-size: 12px; } +/* Make code fragments in doc text stand out */ +code { + font-weight: bold; +} + /* @group Heading Levels */ h1 { @@ -125,17 +130,17 @@ a.elRef { a.code { color: #4444cc; -/* font-weight: bold;*/ + font-weight: bold; } a.code:visited { color: #444488; -/* font-weight: bold;*/ + font-weight: bold; } a.codeRef { color: #6666ff; -/* font-weight: bold;*/ + font-weight: bold; } /* @end */ From 49b5940cd5b876db803ed725347ae22c779547e7 Mon Sep 17 00:00:00 2001 From: Jeff Teunissen Date: Fri, 15 Jul 2011 13:12:26 -0400 Subject: [PATCH 014/334] VM doc cleanups Clarify that the "return value" macros all access the same location in memory, and are just casting it (after a fashion) to the desired type. --- include/QF/progs.h | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/include/QF/progs.h b/include/QF/progs.h index a70d039fb..c3e4ab387 100644 --- a/include/QF/progs.h +++ b/include/QF/progs.h @@ -674,10 +674,14 @@ void PR_Undefined (progs_t *pr, const char *type, const char *name) __attribute_ #define P_STRUCT(p,t,n) (*(t *)P_GPOINTER (p, n)) //@} -/** \defgroup prda_return Return value +/** \defgroup prda_return Return Values \ingroup progs_data_access - Typed return value access marcos. No checking is done against the QC type, - but the appropriate C type will be used. + These macros are used to access the value returned by an interpreted VM + function, and to return values from engine functions into progs space + (that is, builtins). + \warning No checking is performed against progs types; for example, if you + ask for an \c int from a function that returned a \c float, you're asking + for trouble. */ //@{ @@ -690,7 +694,7 @@ void PR_Undefined (progs_t *pr, const char *type, const char *name) __attribute_ */ #define R_var(p,t) ((p)->pr_return->t##_var) -/** Access the float return value. +/** Access the VM function return value as a \c float \par QC type: \c float @@ -701,78 +705,78 @@ void PR_Undefined (progs_t *pr, const char *type, const char *name) __attribute_ */ #define R_FLOAT(p) R_var (p, float) -/** Access the integer return value. +/** Access the VM function return value as a \c ::pr_int_t (AKA int32_t) \par QC type: \c integer \param p pointer to ::progs_t VM struct - \return int lvalue + \return ::pr_int_t lvalue \hideinitializer */ #define R_INT(p) R_var (p, integer) -/** Access the unsigned integer return value. +/** Access the VM function return value as a \c ::pr_uint_t (AKA uint32_t) \par QC type: \c uinteger \param p pointer to ::progs_t VM struct - \return unsigned int lvalue + \return ::pr_int_t lvalue \hideinitializer */ #define R_UINT(p) R_var (p, uinteger) -/** Access the vector return value. +/** Access the VM function return value as a \c ::vec3_t vector. \par QC type: \c vector \param p pointer to ::progs_t VM struct - \return vec3_t lvalue + \return ::vec3_t lvalue \hideinitializer */ #define R_VECTOR(p) R_var (p, vector) -/** Access the quaternion return value. +/** Access the VM function return value as a \c ::quat_t quaternion. \par QC type: \c quaternion \param p pointer to ::progs_t VM struct - \return quat_t lvalue + \return ::quat_t lvalue \hideinitializer */ #define R_QUAT(p) R_var (p, quat) -/** Access the string index return value. +/** Access the VM function return value as a ::string_t (a VM string reference). \par QC type: \c string \param p pointer to ::progs_t VM struct - \return string_t lvalue + \return ::string_t lvalue \hideinitializer */ #define R_STRING(p) R_var (p, string) -/** Access the function return value. +/** Access the VM function return value as a ::func_t (a VM function reference) \par QC type: \c void() \param p pointer to ::progs_t VM struct - \return func_t lvalue + \return ::func_t lvalue \hideinitializer */ #define R_FUNCTION(p) R_var (p, func) -/** Access the pointer return value. +/** Access the VM function return value as a ::pointer_t (a VM "pointer") \par QC type: \c void * \param p pointer to ::progs_t VM struct - \return pointer_t lvalue + \return ::pointer_t lvalue \hideinitializer */ From 6fad9bc777b1dd64567b12b79ddef785deae1fec Mon Sep 17 00:00:00 2001 From: Jeff Teunissen Date: Mon, 25 Jul 2011 15:52:24 -0400 Subject: [PATCH 015/334] Misc. doc sanitation Slightly document some of the vector types, and fix some typos. --- include/QF/progs.h | 10 +++++----- include/QF/qtypes.h | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/QF/progs.h b/include/QF/progs.h index c3e4ab387..7affaaf2a 100644 --- a/include/QF/progs.h +++ b/include/QF/progs.h @@ -296,7 +296,7 @@ void PR_Undefined (progs_t *pr, const char *type, const char *name) __attribute_ /** \defgroup prda_globals Globals \ingroup progs_data_access - Typed global access marcos. No checking is done against the QC type, but + Typed global access macros. No checking is done against the QC type, but the appropriate C type will be used. */ //@{ @@ -486,7 +486,7 @@ void PR_Undefined (progs_t *pr, const char *type, const char *name) __attribute_ /** \defgroup prda_parameters Parameters \ingroup progs_data_access - Typed parameter access marcos. No checking is done against the QC type, but + Typed parameter access macros. No checking is done against the QC type, but the appropriate C type will be used. */ //@{ @@ -843,7 +843,7 @@ void PR_Undefined (progs_t *pr, const char *type, const char *name) __attribute_ /** \defgroup prda_entity_fields Entity Fields \ingroup progs_data_access - Typed entity field access marcos. No checking is done against the QC type, + Typed entity field access macros. No checking is done against the QC type, but the appropriate C type will be used. */ //@{ @@ -1077,7 +1077,7 @@ int PR_RelocateBuiltins (progs_t *pr); Strings management functions. All strings accessable by the VM are stored within the VM address space. - These functions provide facilities to set permanent, dynamic and + These functions provide facilities to set permanent, dynamic and temporary strings, as well as mutable strings using dstrings. Permanent strings are either supplied by the progs (+ve string index) or @@ -1175,7 +1175,7 @@ void PR_MakeTempString(progs_t *pr, string_t str); string_t PR_NewMutableString (progs_t *pr); /** Make a dynamic progs string from the given C string. Will not create a - duplicate permanent string (temporary, dynamic and mutable strings are + duplicate permanent string (temporary, dynamic and mutable strings are not checked). \param pr pointer to ::progs_t VM struct \param s C string to be made into a permanent progs string diff --git a/include/QF/qtypes.h b/include/QF/qtypes.h index 7a866e15f..a5a92cd45 100644 --- a/include/QF/qtypes.h +++ b/include/QF/qtypes.h @@ -67,10 +67,10 @@ typedef enum {false, true} qboolean; #endif // From mathlib... -typedef float vec_t; -typedef vec_t vec3_t[3]; +typedef float vec_t; ///< The basic vector component type +typedef vec_t vec3_t[3]; ///< A 3D vector (used for Euler angles and motion vectors) typedef vec_t vec4_t[4]; -typedef vec_t quat_t[4]; +typedef vec_t quat_t[4]; ///< A quaternion. typedef vec_t vec5_t[5]; typedef int fixed4_t; typedef int fixed8_t; From 5ef92009f0a94e8356a0fc4fb8f85aee8862993e Mon Sep 17 00:00:00 2001 From: Jeff Teunissen Date: Mon, 25 Jul 2011 16:56:27 -0400 Subject: [PATCH 016/334] Switch to SVG images for docs. Doxygen 1.7.3 added support for SVG output from dot, so let's use it. --- doc/doxygen.css | 6 ++++++ doc/quakeforge.dox.in | 4 ++-- ruamoko/Doxyfile.in | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/doc/doxygen.css b/doc/doxygen.css index ff65ff378..3f471a8b8 100644 --- a/doc/doxygen.css +++ b/doc/doxygen.css @@ -257,6 +257,12 @@ div.center img { background-color: #bec3d9; } +div.center iframe { + border: 2px solid #737b9c; + margin: 10px 2px; + background-color: #bec3d9; +} + address.footer { text-align: right; padding-right: 12px; diff --git a/doc/quakeforge.dox.in b/doc/quakeforge.dox.in index e0d96872b..ad34a66cc 100644 --- a/doc/quakeforge.dox.in +++ b/doc/quakeforge.dox.in @@ -1389,7 +1389,7 @@ DOT_NUM_THREADS = 0 # DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory # containing the font. -DOT_FONTNAME = FreeSans.ttf +DOT_FONTNAME = Arial # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. @@ -1479,7 +1479,7 @@ DIRECTORY_GRAPH = NO # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. -DOT_IMAGE_FORMAT = png +DOT_IMAGE_FORMAT = svg # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. diff --git a/ruamoko/Doxyfile.in b/ruamoko/Doxyfile.in index 0c6a234a8..a3e3ab315 100644 --- a/ruamoko/Doxyfile.in +++ b/ruamoko/Doxyfile.in @@ -1443,7 +1443,7 @@ DIRECTORY_GRAPH = NO # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. -DOT_IMAGE_FORMAT = png +DOT_IMAGE_FORMAT = svg # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. From 30040d4d14e799937ecadb1451d72ff5e7ed2b2e Mon Sep 17 00:00:00 2001 From: Jeff Teunissen Date: Mon, 25 Jul 2011 16:59:39 -0400 Subject: [PATCH 017/334] update doxygen 1.7.4 layout format They added an "intro" key, which I don't grok yet. When I find out WTF it means, I'll probably add some text. --- doc/ruadoc-layout.xml | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/doc/ruadoc-layout.xml b/doc/ruadoc-layout.xml index 875ae76e9..06ea3383f 100644 --- a/doc/ruadoc-layout.xml +++ b/doc/ruadoc-layout.xml @@ -2,24 +2,24 @@ - - + + - - + + - - - - - + + + + + - - + + - - + + @@ -154,6 +154,7 @@ + From c7c646a53f7fcaab03ef1b88e942b56212e797b7 Mon Sep 17 00:00:00 2001 From: Jeff Teunissen Date: Mon, 25 Jul 2011 17:19:43 -0400 Subject: [PATCH 018/334] Makefile portability fixes Allow our makefiles to build with non-GNU 'make' implementations. Required some renaming of not-really-QuakeC source to .r to get it right. --- doc/Makefile.am | 5 +++-- ruamoko/cl_menu/Makefile.am | 17 +++++++------- .../cl_menu/{client_menu.qc => client_menu.r} | 0 .../cl_menu/{controls_o.qc => controls_o.r} | 0 ruamoko/cl_menu/{options.qc => options.r} | 0 .../{options_util.qc => options_util.r} | 0 ruamoko/cl_menu/{servlist.qc => servlist.r} | 0 ruamoko/game/Makefile.am | 13 +++++------ ruamoko/gui/Makefile.am | 6 ++--- ruamoko/lib/Makefile.am | 6 ++--- ruamoko/scheme/Makefile.am | 22 +++++++++---------- ruamoko/scheme/{defs.qc => defs.r} | 0 ruamoko/scheme/{main.qc => main.r} | 0 13 files changed, 33 insertions(+), 36 deletions(-) rename ruamoko/cl_menu/{client_menu.qc => client_menu.r} (100%) rename ruamoko/cl_menu/{controls_o.qc => controls_o.r} (100%) rename ruamoko/cl_menu/{options.qc => options.r} (100%) rename ruamoko/cl_menu/{options_util.qc => options_util.r} (100%) rename ruamoko/cl_menu/{servlist.qc => servlist.r} (100%) rename ruamoko/scheme/{defs.qc => defs.r} (100%) rename ruamoko/scheme/{main.qc => main.r} (100%) diff --git a/doc/Makefile.am b/doc/Makefile.am index 15e4a58aa..a976c72ec 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -16,11 +16,12 @@ EXTRA_DIST= qf.ico \ progs/vm-exec.c progs/vm-mem.fig \ qtv/qwtv.fig -%.png: %.fig +SUFFIXES=.eps .fig .png +.fig.png: @mkdir -p `dirname $@` fig2dev -L png $< $@ -%.eps: %.fig +.fig.eps: @mkdir -p `dirname $@` fig2dev -L ps $< $@ diff --git a/ruamoko/cl_menu/Makefile.am b/ruamoko/cl_menu/Makefile.am index e3cc7e793..be09a6ace 100644 --- a/ruamoko/cl_menu/Makefile.am +++ b/ruamoko/cl_menu/Makefile.am @@ -13,7 +13,9 @@ GZ=.gz else GZ= endif -STRIP=$(shell echo `echo -n $(srcdir)/ | sed -e 's/[^/]//g' | wc -c`) +# BSD make can't handle $(shell foo) directives, and GNU make can't handle |= +# so we have to bite the bullet and pass this to the shell every time. +STRIP=`echo -n $(srcdir)/ | sed -e 's/[^/]//g' | wc -c` menu_data=menu.dat$(GZ) menu.sym$(GZ) menu.plist @@ -27,7 +29,7 @@ pkgdata_DATA= $(data) EXTRA_DATA= $(menu_data) menu_src= \ - client_menu.qc controls_o.qc options.qc options_util.qc servlist.qc \ + client_menu.r controls_o.r options.r options_util.r servlist.r \ Frame.r menu.r HUD.r plistmenu.r ../lib/debug.r \ \ CrosshairCvar.r CrosshairView.r CvarColor.r CvarColorView.r \ @@ -35,13 +37,10 @@ menu_src= \ CvarToggle.r CvarToggleView.r \ MenuGroup.r MouseToggle.r ProxyView.r RunToggle.r SubMenu.r -%.qfo: %.r - $(QFCC) $(QCFLAGS) $(QCPPFLAGS) -c -o $@ $< - -%.qfo: %.qc - $(QFCC) $(QCFLAGS) $(QCPPFLAGS) -c -o $@ $< - -menu_obj=$(addsuffix .qfo,$(basename $(menu_src))) +SUFFIXES=.qfo .r +.r.qfo: + $(QFCC) $(QCFLAGS) $(QCPPFLAGS) -p $(STRIP) -c -o $@ $< +menu_obj=$(menu_src:.r=.qfo) menu.dat$(GZ): $(menu_obj) $(QFCC_DEP) ../lib/libcsqc.a ../lib/libr.a ../gui/libgui.a $(QFCC) $(QCFLAGS) -p $(STRIP) -o menu.dat $(menu_obj) ../gui/libgui.a ../lib/libcsqc.a ../lib/libr.a diff --git a/ruamoko/cl_menu/client_menu.qc b/ruamoko/cl_menu/client_menu.r similarity index 100% rename from ruamoko/cl_menu/client_menu.qc rename to ruamoko/cl_menu/client_menu.r diff --git a/ruamoko/cl_menu/controls_o.qc b/ruamoko/cl_menu/controls_o.r similarity index 100% rename from ruamoko/cl_menu/controls_o.qc rename to ruamoko/cl_menu/controls_o.r diff --git a/ruamoko/cl_menu/options.qc b/ruamoko/cl_menu/options.r similarity index 100% rename from ruamoko/cl_menu/options.qc rename to ruamoko/cl_menu/options.r diff --git a/ruamoko/cl_menu/options_util.qc b/ruamoko/cl_menu/options_util.r similarity index 100% rename from ruamoko/cl_menu/options_util.qc rename to ruamoko/cl_menu/options_util.r diff --git a/ruamoko/cl_menu/servlist.qc b/ruamoko/cl_menu/servlist.r similarity index 100% rename from ruamoko/cl_menu/servlist.qc rename to ruamoko/cl_menu/servlist.r diff --git a/ruamoko/game/Makefile.am b/ruamoko/game/Makefile.am index ac735dbd2..e955caa1c 100644 --- a/ruamoko/game/Makefile.am +++ b/ruamoko/game/Makefile.am @@ -15,7 +15,9 @@ GZ=.gz else GZ= endif -STRIP=$(shell echo `echo -n $(srcdir)/ | sed -e 's/[^/]//g' | wc -c`) +# BSD make can't handle $(shell foo) directives, and GNU make can't handle |= +# so we have to bite the bullet and pass this to the shell every time. +STRIP=`echo -n $(srcdir)/ | sed -e 's/[^/]//g' | wc -c` if BUILD_RUAMOKO data=game.dat$(GZ) @@ -28,14 +30,11 @@ EXTRA_DATA= game.dat game_src= Axe.r GameEntity.r World.r tempent.r -%.qfo: %.r +SUFFIXES=.qfo .r +.r.qfo: $(QFCC) $(QCFLAGS) $(QCPPFLAGS) -p $(STRIP) -c -o $@ $< -%.qfo: %.qc - $(QFCC) $(QCFLAGS) $(QCPPFLAGS) -p $(STRIP) -c -o $@ $< - -game_obj=$(addsuffix .qfo,$(basename $(game_src))) - +game_obj=$(game_src:.r=.qfo) game.dat$(GZ): $(game_obj) ../lib/libr.a ../lib/libqw.a $(QFCC) $(QCFLAGS) -p $(STRIP) -o game.dat $(game_obj) ../lib/libr.a ../lib/libqw.a ../lib/libr.a $(GZIP) diff --git a/ruamoko/gui/Makefile.am b/ruamoko/gui/Makefile.am index baa9cddea..2debef885 100644 --- a/ruamoko/gui/Makefile.am +++ b/ruamoko/gui/Makefile.am @@ -20,10 +20,8 @@ endif pkglib_LIBRARIES= $(libs) EXTRA_LIBRARIES= $(gui_libs) -%.qfo: %.r - $(QFCC) $(QCFLAGS) $(QCPPFLAGS) -c -o $@ $< - -%.o: %.r +SUFFIXES= .qfo .r .qc +.r.o: $(QFCC) $(QCFLAGS) $(QCPPFLAGS) -c -o $@ $< libgui_a_SOURCES= \ diff --git a/ruamoko/lib/Makefile.am b/ruamoko/lib/Makefile.am index 5e441769e..92ede7a79 100644 --- a/ruamoko/lib/Makefile.am +++ b/ruamoko/lib/Makefile.am @@ -23,10 +23,10 @@ endif pkglib_LIBRARIES= $(libs) EXTRA_LIBRARIES= $(ruamoko_libs) -%.qfo: %.r +SUFFIXES= .o .r .qc +.r.o: $(QFCC) $(QCFLAGS) $(QCPPFLAGS) -c -o $@ $< - -%.o: %.r +.qc.o: $(QFCC) $(QCFLAGS) $(QCPPFLAGS) -c -o $@ $< libr_a_SOURCES=\ diff --git a/ruamoko/scheme/Makefile.am b/ruamoko/scheme/Makefile.am index c0648d836..ad9f40894 100644 --- a/ruamoko/scheme/Makefile.am +++ b/ruamoko/scheme/Makefile.am @@ -13,7 +13,9 @@ GZ=.gz else GZ= endif -STRIP=$(shell echo `echo -n $(srcdir)/ | sed -e 's/[^/]//g' | wc -c`) +# BSD make can't handle $(shell foo) directives, and GNU make can't handle |= +# so we have to bite the bullet and pass this to the shell every time. +STRIP=`echo -n $(srcdir)/ | sed -e 's/[^/]//g' | wc -c` RANLIB=touch @@ -39,15 +41,13 @@ EXTRA_DIST = \ SchemeObject.h SchemeString.h Scope.h Symbol.h Void.h builtins.h \ debug.h defs.h state.h \ \ - main.qc defs.qc + main.r defs.r -%.qfo: %.r - $(QFCC) $(QCFLAGS) $(QCPPFLAGS) -c -o $@ $< - -%.o: %.r - $(QFCC) $(QCFLAGS) $(QCPPFLAGS) -c -o $@ $< -%.o: %.qc - $(QFCC) $(QCFLAGS) $(QCPPFLAGS) -c -o $@ $< +SUFFIXES=.qc .qfo .r +.r.qfo: + $(QFCC) $(QCFLAGS) $(QCPPFLAGS) -p $(STRIP) -c -o $@ $< +.r.o: + $(QFCC) $(QCFLAGS) $(QCPPFLAGS) -p $(STRIP) -c -o $@ $< libscheme_a_SOURCES=\ SchemeObject.r Cons.r Number.r SchemeString.r Symbol.r Lexer.r Parser.r \ @@ -60,9 +60,9 @@ scheme_data=\ main.dat$(GZ) scheme_src=\ - main.qc defs.qc + main.r defs.r -scheme_obj=$(addsuffix .o,$(basename $(scheme_src))) +scheme_obj=$(scheme_src:.qc=.o) main.dat$(GZ): $(scheme_obj) $(QFCC_DEP) ../lib/libcsqc.a ../lib/libr.a libscheme.a $(QFCC) $(QCFLAGS) -p $(STRIP) -o main.dat $(scheme_obj) libscheme.a ../lib/libcsqc.a ../lib/libr.a diff --git a/ruamoko/scheme/defs.qc b/ruamoko/scheme/defs.r similarity index 100% rename from ruamoko/scheme/defs.qc rename to ruamoko/scheme/defs.r diff --git a/ruamoko/scheme/main.qc b/ruamoko/scheme/main.r similarity index 100% rename from ruamoko/scheme/main.qc rename to ruamoko/scheme/main.r From 64881d2eca1687e7b5965008bad384e6fb5dbfb8 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 26 Jul 2011 11:29:41 +0900 Subject: [PATCH 019/334] Finish the docs for netchan. Also clean out some unnecessary declarations. --- include/netchan.h | 84 +++++++++++++++++++++++++++++++++++++++------ libs/net/net_chan.c | 42 ++++++++--------------- 2 files changed, 88 insertions(+), 38 deletions(-) diff --git a/include/netchan.h b/include/netchan.h index 5fa7e97c5..3ed79c4a6 100644 --- a/include/netchan.h +++ b/include/netchan.h @@ -41,8 +41,8 @@ \ingroup network */ //{ -#define MAX_MSGLEN 1450 // max length of a reliable message -#define MAX_DATAGRAM 1450 // max length of unreliable message +#define MAX_MSGLEN 1450 ///< max length of a reliable message +#define MAX_DATAGRAM 1450 ///< max length of unreliable message #define PORT_ANY -1 @@ -54,19 +54,17 @@ typedef struct byte ip[4]; #endif unsigned short port; - unsigned short family; // used to be pad, before IPV6 + unsigned short family; } netadr_t; +extern int net_socket; extern netadr_t net_local_adr; extern netadr_t net_loopback_adr; extern netadr_t net_from; // address of who sent the packet extern struct msg_s *net_message; -extern struct cvar_s *hostname; extern struct cvar_s *qport; -extern int net_socket; - int Net_Log_Init (const char **sound_precache); void Net_LogPrintf (const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); void Log_Incoming_Packet (const byte *p, int len, int has_sequence); @@ -78,7 +76,6 @@ void Analyze_Server_Packet (const byte * data, int len, int has_sequence); extern struct cvar_s *net_packetlog; extern qboolean is_server; -qboolean ServerPaused (void); //@} /** \defgroup qw-udp QuakeWorld udp support. @@ -194,7 +191,8 @@ qboolean NET_StringToAdr (const char *s, netadr_t *a); after the retransmit has been acknowledged and the reliable still failed to get there. - If the sequence number is -1, the packet should be handled without a + If the sequence number and reliable payload bits are all 1 (32bit -1), + the packet is an out-of-band packet and should be handled without a netcon. The reliable message can be added to at any time by doing @@ -292,30 +290,96 @@ typedef struct netchan_s { /** Disable packet choking. */ -extern int net_nochoke; // don't choke packets +extern int net_nochoke; /** Disable packet sending. Used by clients in demo playback mode. */ -extern int net_blocksend; // don't send packets (used by client for demos) +extern int net_blocksend; /** Pointer to variable holding the current time in seconds. */ extern double *net_realtime; +/** Initialize the netchan system. + + Currently only sets the qport cvar default to a random value. +*/ void Netchan_Init (void); + +/** Initialize the netchan cvars. +*/ void Netchan_Init_Cvars (void); + +/** Try to send an unreliable packet to a connection. + + Handles transmission or retransmission of the reliable packet. + + 0 length will still generate a packet and deal with the reliable messages. + + \param chan The netchan representing the connection. + \param length The size of the unreliable packet. + \param data The data of the unreliable packet. +*/ void Netchan_Transmit (netchan_t *chan, int length, byte *data); + +/** Send an out-of-band packet. + + \param adr The address to which the data will be sent. + \param length The length of the data to be sent. + \param data The data to be sent. +*/ void Netchan_OutOfBand (netadr_t adr, int length, byte *data); +/** Send a formatted string as an out-of-band packet. + + \param adr The address to which the data will be sent. + \param format The printf style format string. +*/ void Netchan_OutOfBandPrint (netadr_t adr, const char *format, ...) __attribute__ ((format (printf,2,3))); + +/** Process a packet for the specifiied connection. + + Called when the current net_message is from remote_address. + Modifies net_message so that it points to the packet payload. + + \param chan The netchan representing the connection. +*/ qboolean Netchan_Process (netchan_t *chan); + +/** Initialize a new connection. + + \param chan The netchan representing the connection. + \param adr The address of the remote end of the connection. + \param qport The qport associated with the connection. + \param flags Control of the sending/reading of the qport on this + connection. +*/ void Netchan_Setup (netchan_t *chan, netadr_t adr, int qport, ncqport_e flags); +/** Check if a packet can be sent to the connection. + + \param chan The netchan representing the connection. + \return True if the connection isn't chocked. +*/ qboolean Netchan_CanPacket (netchan_t *chan); + +/** Check if a reliable packet can be sent to the connection. + + \param chan The netchan representing the connection. + \return True if there is no outstanding reliable packet and the + connection isn't chocked. +*/ qboolean Netchan_CanReliable (netchan_t *chan); +/** Send a packet. + + Very raw. Just calls NET_SendPacket(). + \param length The length of the data to be sent. + \param data The data to be sent. + \param to The address to which the data will be sent. +*/ void Netchan_SendPacket (int length, const void *data, netadr_t to); //@} diff --git a/libs/net/net_chan.c b/libs/net/net_chan.c index c50651913..e6a19b583 100644 --- a/libs/net/net_chan.c +++ b/libs/net/net_chan.c @@ -187,14 +187,6 @@ Netchan_CanReliable (netchan_t *chan) return Netchan_CanPacket (chan); } -/* - Netchan_Transmit - - tries to send an unreliable message to a connection, and handles the - transmition / retransmition of the reliable messages. - - 0 length will still generate a packet and deal with the reliable messages. -*/ void Netchan_Transmit (netchan_t *chan, int length, byte *data) { @@ -239,20 +231,20 @@ Netchan_Transmit (netchan_t *chan, int length, byte *data) MSG_WriteLong (&send, w1); MSG_WriteLong (&send, w2); - // send the qport if we are a client + /// Send the qport if appropriate (we are a client). if (chan->flags & NC_QPORT_SEND) MSG_WriteShort (&send, chan->qport); - // copy the reliable message to the packet first + /// First copy the reliable message to the packet. if (send_reliable) { SZ_Write (&send, chan->reliable_buf, chan->reliable_length); chan->last_reliable_sequence = chan->outgoing_sequence; } - // add the unreliable part if space is available + /// Then add the unreliable part if space is available. if (send.maxsize - send.cursize >= length) SZ_Write (&send, data, length); - // send the datagram + /// Send the datagram if not blocked (in demo playback mode) i = chan->outgoing_sequence & (MAX_LATENT - 1); chan->outgoing_size[i] = send.cursize; chan->outgoing_time[i] = *net_realtime; @@ -276,12 +268,6 @@ Netchan_Transmit (netchan_t *chan, int length, byte *data) chan->outgoing_sequence - chan->incoming_sequence); } -/* - Netchan_Process - - called when the current net_message is from remote_address - modifies net_message so that it points to the packet payload -*/ qboolean Netchan_Process (netchan_t *chan) { @@ -291,12 +277,12 @@ Netchan_Process (netchan_t *chan) if (!NET_CompareAdr (net_from, chan->remote_address)) return false; - // get sequence numbers + /// Get the sequence numbers. MSG_BeginReading (net_message); sequence = MSG_ReadLong (net_message); sequence_ack = MSG_ReadLong (net_message); - // read the qport if we are a server, but drop it + /// Read the qport if appropriate (we are a server), but ignore it. if (chan->flags & NC_QPORT_READ) MSG_ReadShort (net_message); @@ -337,7 +323,7 @@ Netchan_Process (netchan_t *chan) } #endif - // discard stale or duplicated packets + /// Discard stale or duplicated packets. if (sequence < (unsigned int) chan->incoming_sequence + 1) { if (showdrop->int_val) Sys_Printf ("%s:Out of order packet %i at %i\n", @@ -346,7 +332,7 @@ Netchan_Process (netchan_t *chan) return false; } - // dropped packets don't keep the message from being used + /// Dropped packets don't keep the message from being used. chan->net_drop = sequence - (chan->incoming_sequence + 1); if (chan->net_drop > 0) { chan->drop_count += 1; @@ -357,21 +343,21 @@ Netchan_Process (netchan_t *chan) sequence - (chan->incoming_sequence + 1), sequence); } - // if the current outgoing reliable message has been acknowledged - // clear the buffer to make way for the next + /// If the current outgoing reliable message has been acknowledged, + /// clear the buffer to make way for the next. if (reliable_ack == (unsigned int) chan->reliable_sequence) chan->reliable_length = 0; // it has been received - // if this message contains a reliable message, bump - // incoming_reliable_sequence + /// If this message contains a reliable message, bump + /// incoming_reliable_sequence chan->incoming_sequence = sequence; chan->incoming_acknowledged = sequence_ack; chan->incoming_reliable_acknowledged = reliable_ack; if (reliable_message) chan->incoming_reliable_sequence ^= 1; - // the message can now be read from the current message pointer - // update statistics counters + // The message can now be read from the current message pointer. + /// Update statistics counters. chan->frame_latency = chan->frame_latency * OLD_AVG + (chan->outgoing_sequence - sequence_ack) * (1.0 - OLD_AVG); chan->frame_rate = chan->frame_rate * OLD_AVG From ca817fafc20112115d45eee3a714bb704b43f164 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 26 Jul 2011 11:34:17 +0900 Subject: [PATCH 020/334] Fix a typo. --- include/QF/draw.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/QF/draw.h b/include/QF/draw.h index 7d90d32e3..f86c77063 100644 --- a/include/QF/draw.h +++ b/include/QF/draw.h @@ -29,7 +29,7 @@ #ifndef _DRAW_H #define _DRAW_H -/** \defgroup video Video Syb-sytem */ +/** \defgroup video Video Sub-sytem */ /** \defgroup video_renderer Renderer Sub-system \ingroup video From 1d5747710189f259a83aa0d257eaefae500a8a7f Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 26 Jul 2011 14:15:41 +0900 Subject: [PATCH 021/334] Document the "public" functions of NQ's networking code. --- include/net_dgrm.h | 6 + include/net_loop.h | 7 + include/net_udp.h | 7 + include/net_vcr.h | 7 + include/net_wins.h | 7 + include/netmain.h | 341 +++++++++++++++++++++++++---------------- libs/net/net_main.c | 90 ++--------- libs/net/nm/net_bsd.c | 2 +- libs/net/nm/net_dgrm.c | 2 +- libs/net/nm/net_loop.c | 2 +- libs/net/nm/net_udp.c | 2 +- libs/net/nm/net_vcr.c | 2 +- libs/net/nm/net_win.c | 2 +- libs/net/nm/net_wins.c | 2 +- 14 files changed, 264 insertions(+), 215 deletions(-) diff --git a/include/net_dgrm.h b/include/net_dgrm.h index e2e1252b1..ac9b4b89b 100644 --- a/include/net_dgrm.h +++ b/include/net_dgrm.h @@ -27,6 +27,10 @@ */ +/** \defgroup nq-dgrm NetQuake Datagram network driver. + \ingroup nq-nd +*/ +//@{ int Datagram_Init (void); void Datagram_Listen (qboolean state); @@ -40,3 +44,5 @@ qboolean Datagram_CanSendMessage (qsocket_t *sock); qboolean Datagram_CanSendUnreliableMessage (qsocket_t *sock); void Datagram_Close (qsocket_t *sock); void Datagram_Shutdown (void); + +//@} diff --git a/include/net_loop.h b/include/net_loop.h index 78ec02e0e..e6671ccc5 100644 --- a/include/net_loop.h +++ b/include/net_loop.h @@ -32,6 +32,11 @@ #include "QF/qtypes.h" #include "netmain.h" +/** \defgroup nq-loop NetQuake loopback network driver. + \ingroup nq-nd +*/ +//@{ + int Loop_Init (void); void Loop_Listen (qboolean state); void Loop_SearchForHosts (qboolean xmit); @@ -45,4 +50,6 @@ qboolean Loop_CanSendUnreliableMessage (qsocket_t *sock); void Loop_Close (qsocket_t *sock); void Loop_Shutdown (void); +//@} + #endif//__net_loop_h diff --git a/include/net_udp.h b/include/net_udp.h index f2de5a2f8..26fd600d9 100644 --- a/include/net_udp.h +++ b/include/net_udp.h @@ -31,6 +31,11 @@ #include "QF/qtypes.h" +/** \defgroup nq-udp NetQuake UDP lan driver. + \ingroup nq-ld +*/ +//@{ + int UDP_Init (void); void UDP_Shutdown (void); void UDP_Listen (qboolean state); @@ -50,4 +55,6 @@ int UDP_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2); int UDP_GetSocketPort (struct qsockaddr *addr); int UDP_SetSocketPort (struct qsockaddr *addr, int port); +//@} + #endif // __net_udp_h diff --git a/include/net_vcr.h b/include/net_vcr.h index 8d69d2eb2..0c6409b17 100644 --- a/include/net_vcr.h +++ b/include/net_vcr.h @@ -27,6 +27,11 @@ */ +/** \defgroup nq-vcr NetQuake VCR network driver. + \ingroup nq-nd +*/ +//@{ + #define VCR_OP_CONNECT 1 #define VCR_OP_GETMESSAGE 2 #define VCR_OP_SENDMESSAGE 3 @@ -43,3 +48,5 @@ int VCR_SendMessage (qsocket_t *sock, sizebuf_t *data); qboolean VCR_CanSendMessage (qsocket_t *sock); void VCR_Close (qsocket_t *sock); void VCR_Shutdown (void); + +//@} diff --git a/include/net_wins.h b/include/net_wins.h index 4738cdaf1..66d60ca35 100644 --- a/include/net_wins.h +++ b/include/net_wins.h @@ -33,6 +33,11 @@ #include "QF/qtypes.h" +/** \defgroup nq-wins NetQuake Winsock lan driver. + \ingroup nq-ld +*/ +//@{ + extern int winsock_initialized; extern WSADATA winsockdata; @@ -57,4 +62,6 @@ int WINS_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2); int WINS_GetSocketPort (struct qsockaddr *addr); int WINS_SetSocketPort (struct qsockaddr *addr, int port); +//@} + #endif//__net_wins_h diff --git a/include/netmain.h b/include/netmain.h index 5622aebfd..565026119 100644 --- a/include/netmain.h +++ b/include/netmain.h @@ -32,6 +32,11 @@ #include "QF/quakeio.h" #include "QF/sizebuf.h" +/** \defgroup nq-net NetQuake network support. + \ingroup network +*/ +//@{ + struct qsockaddr { short qsa_family; @@ -165,8 +170,204 @@ extern qsocket_t *net_activeSockets; extern qsocket_t *net_freeSockets; extern int net_numsockets; -typedef struct -{ +#define MAX_NET_DRIVERS 8 + +extern int DEFAULTnet_hostport; +extern int net_hostport; + +extern int net_driverlevel; +extern char playername[]; +extern int playercolor; + +extern int messagesSent; +extern int messagesReceived; +extern int unreliableMessagesSent; +extern int unreliableMessagesReceived; + +/** Create and initialize a new qsocket. + + Called by drivers when a new communications endpoint is required. + The sequence and buffer fields will be filled in properly. + + \return The qsocket representing the connection. +*/ +qsocket_t *NET_NewQSocket (void); + +/** Destroy a qsocket. + + \param sock The qsocket representing the connection. +*/ +void NET_FreeQSocket(qsocket_t *sock); + +/** Cache the system time for the network sub-system. +*/ +double SetNetTime(void); + + +#define HOSTCACHESIZE 8 + +typedef struct { + char name[16]; + char map[16]; + char cname[32]; + int users; + int maxusers; + int driver; + int ldriver; + struct qsockaddr addr; +} hostcache_t; + +extern int hostCacheCount; +extern hostcache_t hostcache[HOSTCACHESIZE]; + +extern double net_time; +extern struct msg_s *net_message; +extern int net_activeconnections; + +/** Initialize the networking sub-system. +*/ +void NET_Init (void); + +/** Shutdown the networking sub-system. +*/ +void NET_Shutdown (void); + +/** Check for new connections. + + \return Pointer to the qsocket for the new connection if there + is one, otherwise null. +*/ +struct qsocket_s *NET_CheckNewConnections (void); + +/** Connect to a host. + + \param host The name of the host to which will be connected. + \return Pointer to the qsocket representing the connection, or + null if unable to connect. +*/ +struct qsocket_s *NET_Connect (const char *host); + +/** Check if a message can be sent to the connection. + + \param sock The qsocket representing the connection. + \return True if the message can be sent. +*/ +qboolean NET_CanSendMessage (qsocket_t *sock); + +/** Read a single message from the connection into net_message. + + If there is a complete message, return it in net_message. + + \param sock The qsocket representing the connection. + \return 0 if no data is waiting. + \return 1 if a message was received. + \return -1 if the connection died. +*/ +int NET_GetMessage (struct qsocket_s *sock); + +/** Send a single reliable message to the connection. + + Try to send a complete length+message unit over the reliable stream. + + \param sock The qsocket representing the connection. + \param data The message to send. + \return 0 if the message connot be delivered reliably, but the + connection is still considered valid + \return 1 if the message was sent properly + \return -1 if the connection died +*/ +int NET_SendMessage (struct qsocket_s *sock, sizebuf_t *data); + +/** Send a single unreliable message to the connection. + + \param sock The qsocket representing the connection. + \param data The message to send. + \return 1 if the message was sent properly + \return -1 if the connection died +*/ +int NET_SendUnreliableMessage (struct qsocket_s *sock, sizebuf_t *data); + +/** Send a reliable message to all attached clients. + + \param data The message to send. + \param blocktime The blocking timeout in seconds. + \return The number of clients to which the message could not be + sent before the timeout. +*/ +int NET_SendToAll(sizebuf_t *data, double blocktime); + +/** Close a connection. + + If a dead connection is returned by a get or send function, this function + should be called when it is convenient. + + Server calls when a client is kicked off for a game related misbehavior + like an illegal protocal conversation. Client calls when disconnecting + from a server. + + A netcon_t number will not be reused until this function is called for it + + \param sock The qsocket representing the connection. +*/ +void NET_Close (struct qsocket_s *sock); + +/** Run any current poll procedures. +*/ +void NET_Poll(void); + + +typedef struct _PollProcedure { + struct _PollProcedure *next; + double nextTime; + void (*procedure)(void *); + void *arg; +} PollProcedure; + +/** Schedule a poll procedure to run. + + The poll procedure will be called by NET_Poll() no earlier than + "now"+timeOffset. + + \param pp The poll procedure to shedule. + \param timeOffset The time offset from "now" at which the procedure + will be run. +*/ +void SchedulePollProcedure(PollProcedure *pp, double timeOffset); + +extern qboolean serialAvailable; +extern qboolean ipxAvailable; +extern qboolean tcpipAvailable; +extern char my_ipx_address[NET_NAMELEN]; +extern char my_tcpip_address[NET_NAMELEN]; +extern void (*GetComPortConfig) (int portNumber, int *port, int *irq, int *baud, qboolean *useModem); +extern void (*SetComPortConfig) (int portNumber, int port, int irq, int baud, qboolean useModem); +extern void (*GetModemConfig) (int portNumber, char *dialType, char *clear, char *init, char *hangup); +extern void (*SetModemConfig) (int portNumber, const char *dialType, const char *clear, const char *init, const char *hangup); + +extern qboolean slistInProgress; +extern qboolean slistSilent; +extern qboolean slistLocal; + +extern struct cvar_s *config_com_port; +extern struct cvar_s *config_com_irq; +extern struct cvar_s *config_com_baud; +extern struct cvar_s *config_com_modem; +extern struct cvar_s *config_modem_dialtype; +extern struct cvar_s *config_modem_clear; +extern struct cvar_s *config_modem_init; +extern struct cvar_s *config_modem_hangup; +extern struct cvar_s *hostname; + +extern QFile *vcrFile; + +//@} + +/** \defgroup nq-ld NetQuake lan drivers. + \ingroup nq-net +*/ +//@{ + +typedef struct { const char *name; qboolean initialized; int controlSock; @@ -190,12 +391,17 @@ typedef struct int (*SetSocketPort) (struct qsockaddr *addr, int port); } net_landriver_t; -#define MAX_NET_DRIVERS 8 extern int net_numlandrivers; extern net_landriver_t net_landrivers[MAX_NET_DRIVERS]; -typedef struct -{ +//@} + +/** \defgroup nq-nd NetQuake network drivers. + \ingroup nq-net +*/ +//@{ + +typedef struct { const char *name; qboolean initialized; int (*Init) (void); @@ -216,129 +422,6 @@ typedef struct extern int net_numdrivers; extern net_driver_t net_drivers[MAX_NET_DRIVERS]; -extern int DEFAULTnet_hostport; -extern int net_hostport; - -extern int net_driverlevel; -extern char playername[]; -extern int playercolor; - -extern int messagesSent; -extern int messagesReceived; -extern int unreliableMessagesSent; -extern int unreliableMessagesReceived; - -qsocket_t *NET_NewQSocket (void); -void NET_FreeQSocket(qsocket_t *); -double SetNetTime(void); - - -#define HOSTCACHESIZE 8 - -typedef struct -{ - char name[16]; - char map[16]; - char cname[32]; - int users; - int maxusers; - int driver; - int ldriver; - struct qsockaddr addr; -} hostcache_t; - -extern int hostCacheCount; -extern hostcache_t hostcache[HOSTCACHESIZE]; - -//============================================================================ -// -// public network functions -// -//============================================================================ - -extern double net_time; -extern struct msg_s *net_message; -extern int net_activeconnections; - -void NET_Init (void); -void NET_Shutdown (void); - -struct qsocket_s *NET_CheckNewConnections (void); -// returns a new connection number if there is one pending, else -1 - -struct qsocket_s *NET_Connect (const char *host); -// called by client to connect to a host. Returns -1 if not able to - -qboolean NET_CanSendMessage (qsocket_t *sock); -// Returns true or false if the given qsocket can currently accept a -// message to be transmitted. - -int NET_GetMessage (struct qsocket_s *sock); -// returns data in net_message sizebuf -// returns 0 if no data is waiting -// returns 1 if a message was received -// returns 2 if an unreliable message was received -// returns -1 if the connection died - -int NET_SendMessage (struct qsocket_s *sock, sizebuf_t *data); -int NET_SendUnreliableMessage (struct qsocket_s *sock, sizebuf_t *data); -// returns 0 if the message connot be delivered reliably, but the connection -// is still considered valid -// returns 1 if the message was sent properly -// returns -1 if the connection died - -int NET_SendToAll(sizebuf_t *data, double blocktime); -// This is a reliable *blocking* send to all attached clients. - - -void NET_Close (struct qsocket_s *sock); -// if a dead connection is returned by a get or send function, this function -// should be called when it is convenient - -// Server calls when a client is kicked off for a game related misbehavior -// like an illegal protocal conversation. Client calls when disconnecting -// from a server. -// A netcon_t number will not be reused until this function is called for it - -void NET_Poll(void); - - -typedef struct _PollProcedure -{ - struct _PollProcedure *next; - double nextTime; - void (*procedure)(void *); - void *arg; -} PollProcedure; - -void SchedulePollProcedure(PollProcedure *pp, double timeOffset); - -extern qboolean serialAvailable; -extern qboolean ipxAvailable; -extern qboolean tcpipAvailable; -extern char my_ipx_address[NET_NAMELEN]; -extern char my_tcpip_address[NET_NAMELEN]; -extern void (*GetComPortConfig) (int portNumber, int *port, int *irq, int *baud, qboolean *useModem); -extern void (*SetComPortConfig) (int portNumber, int port, int irq, int baud, qboolean useModem); -extern void (*GetModemConfig) (int portNumber, char *dialType, char *clear, char *init, char *hangup); -extern void (*SetModemConfig) (int portNumber, const char *dialType, const char *clear, const char *init, const char *hangup); - -extern qboolean slistInProgress; -extern qboolean slistSilent; -extern qboolean slistLocal; - -void NET_Slist_f (void); - -extern struct cvar_s *config_com_port; -extern struct cvar_s *config_com_irq; -extern struct cvar_s *config_com_baud; -extern struct cvar_s *config_com_modem; -extern struct cvar_s *config_modem_dialtype; -extern struct cvar_s *config_modem_clear; -extern struct cvar_s *config_modem_init; -extern struct cvar_s *config_modem_hangup; -extern struct cvar_s *hostname; - -extern QFile *vcrFile; +//@} #endif // __net_h diff --git a/libs/net/net_main.c b/libs/net/net_main.c index 4e585a19d..165a83d2d 100644 --- a/libs/net/net_main.c +++ b/libs/net/net_main.c @@ -133,15 +133,7 @@ SetNetTime (void) } -/* -=================== -NET_NewQSocket - -Called by drivers when a new communications endpoint is required -The sequence and buffer fields will be filled in properly -=================== -*/ -qsocket_t * +qsocket_t * NET_NewQSocket (void) { qsocket_t *sock; @@ -182,7 +174,7 @@ NET_NewQSocket (void) void -NET_FreeQSocket (qsocket_t * sock) +NET_FreeQSocket (qsocket_t *sock) { qsocket_t *s; @@ -327,7 +319,7 @@ PrintSlistTrailer (void) } -void +static void NET_Slist_f (void) { if (slistInProgress) @@ -393,16 +385,10 @@ Slist_Poll (void *unused) } -/* -=================== -NET_Connect -=================== -*/ - int hostCacheCount = 0; hostcache_t hostcache[HOSTCACHESIZE]; -qsocket_t * +qsocket_t * NET_Connect (const char *host) { qsocket_t *ret; @@ -471,19 +457,13 @@ NET_Connect (const char *host) } -/* -=================== -NET_CheckNewConnections -=================== -*/ - struct { double time; int op; intptr_t session; } vcrConnect; -qsocket_t * +qsocket_t * NET_CheckNewConnections (void) { qsocket_t *ret; @@ -519,13 +499,8 @@ NET_CheckNewConnections (void) return NULL; } -/* -=================== -NET_Close -=================== -*/ void -NET_Close (qsocket_t * sock) +NET_Close (qsocket_t *sock) { if (!sock) return; @@ -542,18 +517,6 @@ NET_Close (qsocket_t * sock) } -/* -================= -NET_GetMessage - -If there is a complete message, return it in net_message - -returns 0 if no data is waiting -returns 1 if a message was received -returns -1 if connection is invalid -================= -*/ - struct { double time; int op; @@ -564,7 +527,7 @@ struct { int -NET_GetMessage (qsocket_t * sock) +NET_GetMessage (qsocket_t *sock) { int ret; @@ -622,17 +585,6 @@ NET_GetMessage (qsocket_t * sock) } -/* -================== -NET_SendMessage - -Try to send a complete length+message unit over the reliable stream. -returns 0 if the message cannot be delivered reliably, but the connection - is still considered valid -returns 1 if the message was sent properly -returns -1 if the connection died -================== -*/ struct { double time; int op; @@ -641,7 +593,7 @@ struct { } vcrSendMessage; int -NET_SendMessage (qsocket_t * sock, sizebuf_t *data) +NET_SendMessage (qsocket_t *sock, sizebuf_t *data) { int r; @@ -671,7 +623,7 @@ NET_SendMessage (qsocket_t * sock, sizebuf_t *data) int -NET_SendUnreliableMessage (qsocket_t * sock, sizebuf_t *data) +NET_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data) { int r; @@ -700,16 +652,8 @@ NET_SendUnreliableMessage (qsocket_t * sock, sizebuf_t *data) } -/* -================== -NET_CanSendMessage - -Returns true or false if the given qsocket can currently accept a -message to be transmitted. -================== -*/ qboolean -NET_CanSendMessage (qsocket_t * sock) +NET_CanSendMessage (qsocket_t *sock) { int r; @@ -797,12 +741,6 @@ NET_SendToAll (sizebuf_t *data, double blocktime) //============================================================================= -/* -==================== -NET_Init -==================== -*/ - void NET_Init (void) { @@ -893,12 +831,6 @@ NET_Init (void) Sys_MaskPrintf (SYS_DEV, "TCP/IP address %s\n", my_tcpip_address); } -/* -==================== -NET_Shutdown -==================== -*/ - void NET_Shutdown (void) { @@ -964,7 +896,7 @@ NET_Poll (void) void -SchedulePollProcedure (PollProcedure * proc, double timeOffset) +SchedulePollProcedure (PollProcedure *proc, double timeOffset) { PollProcedure *pp, *prev; diff --git a/libs/net/nm/net_bsd.c b/libs/net/nm/net_bsd.c index ade4a96bc..a0ea534de 100644 --- a/libs/net/nm/net_bsd.c +++ b/libs/net/nm/net_bsd.c @@ -1,7 +1,7 @@ /* net_bsd.c - @description@ + BSD socket based network and lan driver structs. Copyright (C) 1996-1997 Id Software, Inc. diff --git a/libs/net/nm/net_dgrm.c b/libs/net/nm/net_dgrm.c index d2914890c..4c90029da 100644 --- a/libs/net/nm/net_dgrm.c +++ b/libs/net/nm/net_dgrm.c @@ -1,7 +1,7 @@ /* net_dgrm.c - @description@ + Datagram network driver. Copyright (C) 1996-1997 Id Software, Inc. diff --git a/libs/net/nm/net_loop.c b/libs/net/nm/net_loop.c index c75391de6..1799cd763 100644 --- a/libs/net/nm/net_loop.c +++ b/libs/net/nm/net_loop.c @@ -1,7 +1,7 @@ /* net_loop.c - @description@ + Loopback network driver. Copyright (C) 1996-1997 Id Software, Inc. diff --git a/libs/net/nm/net_udp.c b/libs/net/nm/net_udp.c index 56c77e906..55298e07a 100644 --- a/libs/net/nm/net_udp.c +++ b/libs/net/nm/net_udp.c @@ -1,7 +1,7 @@ /* net_udp.c - @description@ + UDP lan driver. Copyright (C) 1996-1997 Id Software, Inc. diff --git a/libs/net/nm/net_vcr.c b/libs/net/nm/net_vcr.c index 08ef11fdb..a2245139f 100644 --- a/libs/net/nm/net_vcr.c +++ b/libs/net/nm/net_vcr.c @@ -1,7 +1,7 @@ /* net_vcr.c - @description@ + VCR network driver. Copyright (C) 1996-1997 Id Software, Inc. diff --git a/libs/net/nm/net_win.c b/libs/net/nm/net_win.c index b1994eae4..cd24c108d 100644 --- a/libs/net/nm/net_win.c +++ b/libs/net/nm/net_win.c @@ -1,7 +1,7 @@ /* net_win.c - @description@ + Winsock based network and lan driver structs. Copyright (C) 1996-1997 Id Software, Inc. diff --git a/libs/net/nm/net_wins.c b/libs/net/nm/net_wins.c index 673cf9c38..c81737081 100644 --- a/libs/net/nm/net_wins.c +++ b/libs/net/nm/net_wins.c @@ -2,7 +2,7 @@ /* net_wins.c - @description@ + Winsock lan driver. Copyright (C) 1996-1997 Id Software, Inc. From 7d07b314084553e5e7ad49840464bf3c0a485680 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 26 Jul 2011 20:58:19 +0900 Subject: [PATCH 022/334] Document the connection protocol defines. Well, really re-use the existing documentation, but make doxygen do something with it. I'm not fully satisfied with the result, but it will do for now, and getting more information on what the messages really mean will help. --- include/netmain.h | 134 +++++++++++++++++++++++++--------------------- 1 file changed, 73 insertions(+), 61 deletions(-) diff --git a/include/netmain.h b/include/netmain.h index 565026119..1da713970 100644 --- a/include/netmain.h +++ b/include/netmain.h @@ -37,8 +37,7 @@ */ //@{ -struct qsockaddr -{ +struct qsockaddr { short qsa_family; unsigned char qsa_data[14]; }; @@ -62,77 +61,90 @@ struct qsockaddr #define NET_PROTOCOL_VERSION 3 -// This is the network info/connection protocol. It is used to find Quake -// servers, get info about them, and connect to them. Once connected, the -// Quake game protocol (documented elsewhere) is used. -// -// -// General notes: -// game_name is currently always "QUAKE", but is there so this same protocol -// can be used for future games as well -// -// CCREQ_CONNECT -// string game_name "QUAKE" -// byte net_protocol_version NET_PROTOCOL_VERSION -// -// CCREQ_SERVER_INFO -// string game_name "QUAKE" -// byte net_protocol_version NET_PROTOCOL_VERSION -// -// CCREQ_PLAYER_INFO -// byte player_number -// -// CCREQ_RULE_INFO -// string rule -// -// -// -// CCREP_ACCEPT -// long port -// -// CCREP_REJECT -// string reason -// -// CCREP_SERVER_INFO -// string server_address -// string host_name -// string level_name -// byte current_players -// byte max_players -// byte protocol_version NET_PROTOCOL_VERSION -// -// CCREP_PLAYER_INFO -// byte player_number -// string name -// long colors -// long frags -// long connect_time -// string address -// -// CCREP_RULE_INFO -// string rule -// string value +/** \name Connection Protocol -// note: -// There are two address forms used above. The short form is just a -// port number. The address that goes along with the port is defined as -// "whatever address you receive this reponse from". This lets us use -// the host OS to solve the problem of multiple host addresses (possibly -// with no routing between them); the host will use the right address -// when we reply to the inbound connection request. The long from is -// a full address and port in a string. It is used for returning the -// address of a server that is not running locally. + This is the network info/connection protocol. It is used to find Quake + servers, get info about them, and connect to them. Once connected, the + Quake game protocol (documented elsewhere) is used. + General notes: + + \note There are two address forms used. The short form is just a + port number. The address that goes along with the port is defined as + "whatever address you receive this reponse from". This lets us use + the host OS to solve the problem of multiple host addresses (possibly + with no routing between them); the host will use the right address + when we reply to the inbound connection request. The long from is + a full address and port in a string. It is used for returning the + address of a server that is not running locally. +*/ +///@{ + +/** Connect Request: + \arg \b string \c game_name \em "QUAKE" + \arg \b byte \c net_protocol_version \em NET_PROTOCOL_VERSION + + \note \c game_name is currently always "QUAKE", but is there so this + same protocol can be used for future games as well +*/ #define CCREQ_CONNECT 0x01 + +/** Connect Request: + \arg \b string \c game_name \em "QUAKE" + \arg \b byte \c net_protocol_version \em NET_PROTOCOL_VERSION + + \note \c game_name is currently always "QUAKE", but is there so this + same protocol can be used for future games as well +*/ #define CCREQ_SERVER_INFO 0x02 + +/** Connect Request: + \arg \b byte \c player_number +*/ #define CCREQ_PLAYER_INFO 0x03 + +/** Connect Request: + \arg \b string \c rule +*/ #define CCREQ_RULE_INFO 0x04 + +/** Connect Reply: + \arg \b long \c port +*/ #define CCREP_ACCEPT 0x81 + +/** Connect Reply: + \arg \b string \c reason +*/ #define CCREP_REJECT 0x82 + +/** Connect Reply: + \arg \b string \c server_address + \arg \b string \c host_name + \arg \b string \c level_name + \arg \b byte \c current_players + \arg \b byte \c max_players + \arg \b byte \c protocol_version \em NET_PROTOCOL_VERSION +*/ #define CCREP_SERVER_INFO 0x83 + +/** Connect Reply: + \arg \b byte \c player_number + \arg \b string \c name + \arg \b long \c colors + \arg \b long \c frags + \arg \b long \c connect_time + \arg \b string \c address +*/ #define CCREP_PLAYER_INFO 0x84 + +/** Connect Reply: + \arg \b string \c rule + \arg \b string \c value +*/ #define CCREP_RULE_INFO 0x85 +///@} typedef struct qsocket_s { From 1e3f32107097b40cbf80482679f938101b26d7b3 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 29 Jul 2011 09:04:09 +0900 Subject: [PATCH 023/334] Do some doc work on progs. --- include/QF/progs.h | 131 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 124 insertions(+), 7 deletions(-) diff --git a/include/QF/progs.h b/include/QF/progs.h index 7affaaf2a..764bfd05f 100644 --- a/include/QF/progs.h +++ b/include/QF/progs.h @@ -1157,8 +1157,7 @@ string_t PR_SetTempString(progs_t *pr, const char *s); \param a C string \param b C string \return string index of the progs string that represents the - concatenation - of strings a and b + concatenation of strings a and b */ string_t PR_CatStrings (progs_t *pr, const char *a, const char *b); @@ -1266,14 +1265,75 @@ void PR_Sprintf (progs_t *pr, struct dstring_s *result, const char *name, */ //@{ +/** Initialize the resource management fields. + + \param pr The VM of which the resource fields will be initialized. +*/ void PR_Resources_Init (progs_t *pr); + +/** Clear all resources before loading a new progs. + + Calls the clear() callback of all registered resources. + + \param pr The VM of which the resources will be cleared. +*/ void PR_Resources_Clear (progs_t *pr); + +/** Register a resource with a VM. + + \param pr The VM to which the resource will be associated. + \param name The name of the resource. Used for retrieving the + resource. + \param data The resource data. + callback. + \param clear Callback for performing any necessary cleanup. Called + by PR_Resources_Clear(). The parameters are the current + VM (\p pr) and \p data. + \note The name should be unique to the VM, but no checking is + done. If the name is not unique, the previous registered + resource will break. The name of the sub-system + registering the resource is a suitable name, and will + probably be unique. +*/ void PR_Resources_Register (progs_t *pr, const char *name, void *data, void (*clear)(progs_t *, void *)); + +/** Retrieve a resource registered with the VM. + + \param pr The VM from which the resource will be retrieved. + \param name The name of the resource. + \return The resource, or NULL if \p name does not match any + resource registered with the VM. +*/ void *PR_Resources_Find (progs_t *pr, const char *name); +/** \name Resource Map support + + These macros can be used to create functions for mapping C resources + to QuakeC integer handles. + + Valid handles are always negative. + + \note \p map is the resource map itself, not a pointer to the + resource map. +*/ +//@{ + +/** Type delcaration for the resource map. + + \param type The type of the resource. The size must be at least + as large as \c sizeof(type *). +*/ #define PR_RESMAP(type) struct { type *_free; type **_map; unsigned _size; } +/** Allocate a new resource from the resource map. + + \param type The type of the resource. Must match the \c type parameter + used for PR_RESMAP. + \param map The resource map. + \return A pointer to the new resource, or null if no more could + be allocated. +*/ #define PR_RESNEW(type,map) \ type *t; \ \ @@ -1297,11 +1357,27 @@ void *PR_Resources_Find (progs_t *pr, const char *name); memset (t, 0, sizeof (type)); \ return t +/** Free a resource returning it to the resource map. + + \param type The type of the resource. Must match the \c type parameter + used for PR_RESMAP. + \param map The resource map. + \param t Pointer to the resource to be freed. +*/ #define PR_RESFREE(type,map,t) \ memset (t, 0, sizeof (type)); \ *(type **) t = map._free; \ map._free = t +/** Free all resources in the resource map. + + Any memory allocated to the resource must be freed before freeing the + resource. + + \param type The type of the resource. Must match the \c type parameter + used for PR_RESMAP. + \param map The resource map. +*/ #define PR_RESRESET(type,map) \ unsigned i, j; \ if (!map._size) \ @@ -1315,6 +1391,13 @@ void *PR_Resources_Find (progs_t *pr, const char *name); } \ map._free = map._map[0]; +/** Retrieve a resource from the resource map using a handle. + + \param map The resource map. + \param col The handle. + \return A pointer to the resource, or NULL if the handle is + invalid. +*/ #define PR_RESGET(map,col) \ unsigned row = ~col / 1024; \ col = ~col % 1024; \ @@ -1322,6 +1405,12 @@ void *PR_Resources_Find (progs_t *pr, const char *name); return 0; \ return &map._map[row][col] +/** Convert a resource pointer to a handle. + + \param map The resource map. + \param ptr The resource pointer. + \return The handle or 0 if the pointer is invalid. +*/ #define PR_RESINDEX(map,ptr) \ unsigned i; \ for (i = 0; i < map._size; i++) { \ @@ -1330,6 +1419,7 @@ void *PR_Resources_Find (progs_t *pr, const char *name); return ~(i * 1024 + d); \ } \ return 0 +//@} //@} @@ -1401,9 +1491,9 @@ extern const char *pr_gametype; typedef struct strref_s strref_t; typedef struct { - pr_int_t s; - bfunction_t *f; - strref_t *tstr; + pr_int_t s; ///< Return statement. + bfunction_t *f; ///< Calling function. + strref_t *tstr; ///< Linked list of temporary strings. } prstack_t; struct obj_list_s; @@ -1438,15 +1528,23 @@ struct progs_s { struct memzone_s *zone; int zone_size; + /// \name builtin functions + //@{ struct hashtab_s *builtin_hash; struct hashtab_s *builtin_num_hash; unsigned bi_next; unsigned (*bi_map) (progs_t *pr, unsigned binum); + //@} + /// \name symbol management + //@{ struct hashtab_s *function_hash; struct hashtab_s *global_hash; struct hashtab_s *field_hash; + //@} + /// \name load hooks + //@{ int num_load_funcs; int max_load_funcs; pr_load_func_t **load_funcs; @@ -1457,7 +1555,10 @@ struct progs_s { int max_load_finish_funcs; pr_load_func_t **load_finish_funcs; //@} + //@} + /// \name string management + //@{ struct dstring_mem_s *ds_mem; strref_t *free_string_refs; strref_t *static_strings; @@ -1468,7 +1569,10 @@ struct progs_s { struct hashtab_s *strref_hash; int num_strings; strref_t *pr_xtstr; + //@} + /// \name memory map + //@{ dfunction_t *pr_functions; bfunction_t *function_table; char *pr_strings; @@ -1478,7 +1582,10 @@ struct progs_s { dstatement_t *pr_statements; pr_type_t *pr_globals; int globals_size; + //@} + /// \name parameter block + //@{ pr_type_t *pr_return; pr_type_t *pr_params[MAX_PARMS]; pr_type_t *pr_real_params[MAX_PARMS]; @@ -1486,11 +1593,14 @@ struct progs_s { pr_type_t *pr_saved_params; int pr_saved_argc; int pr_param_size; ///< covers both params and return + //@} int pr_edict_size; ///< in bytes int pr_edictareasize; ///< for bounds checking, starts at 0 func_t edict_parse; + /// \name execution state + //@{ int pr_argc; qboolean pr_trace; @@ -1503,11 +1613,15 @@ struct progs_s { int localstack[LOCALSTACK_SIZE]; int localstack_used; + //@} + /// \name resources + //@{ pr_resource_t *resources; struct hashtab_s *resource_hash; + //@} - /// obj info + /// \name obj info //@{ int selector_index; int selector_index_max; @@ -1523,7 +1637,7 @@ struct progs_s { struct obj_list_s *class_tree_list; //@} - /// debug info + /// \name debug info //@{ const char *debugfile; struct pr_debug_header_s *debug; @@ -1536,6 +1650,8 @@ struct progs_s { pr_type_t wp_val; //@} + /// \name globals and fields needed by the VM + //@{ struct { float *time; ///< required for OP_STATE pr_int_t *self; ///< required for OP_STATE @@ -1546,6 +1662,7 @@ struct progs_s { pr_int_t think; ///< required for OP_STATE pr_int_t this; ///< optional for entity<->object linking } fields; + //@} }; /** \addtogroup progs_data_access From 07d5b114bcfa01be397f35af67a0b4665fb0832c Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 29 Jul 2011 10:11:14 +0900 Subject: [PATCH 024/334] Clean out some dead code and variables. We haven't had serial or ipx support for a long time. --- include/QF/skin.h | 5 ++-- include/netmain.h | 17 ------------- libs/net/net_main.c | 58 -------------------------------------------- nq/source/host_cmd.c | 2 -- 4 files changed, 3 insertions(+), 79 deletions(-) diff --git a/include/QF/skin.h b/include/QF/skin.h index 9d0cf65d3..0c8174366 100644 --- a/include/QF/skin.h +++ b/include/QF/skin.h @@ -38,8 +38,7 @@ #define RSSHOT_WIDTH 320 #define RSSHOT_HEIGHT 200 -typedef struct skin_s -{ +typedef struct skin_s { char name[MAX_SKIN_LENGTH]; qboolean failedload; // the name isn't a valid skin union { @@ -56,6 +55,8 @@ extern skin_t skin_cache[MAX_CACHED_SKINS]; extern int skin_textures; extern int skin_fb_textures; +extern int playercolor; + struct tex_s; struct tex_s *Skin_Cache (skin_t *skin); struct player_info_s; diff --git a/include/netmain.h b/include/netmain.h index 1da713970..b14ee48e9 100644 --- a/include/netmain.h +++ b/include/netmain.h @@ -188,8 +188,6 @@ extern int DEFAULTnet_hostport; extern int net_hostport; extern int net_driverlevel; -extern char playername[]; -extern int playercolor; extern int messagesSent; extern int messagesReceived; @@ -346,28 +344,13 @@ typedef struct _PollProcedure { */ void SchedulePollProcedure(PollProcedure *pp, double timeOffset); -extern qboolean serialAvailable; -extern qboolean ipxAvailable; extern qboolean tcpipAvailable; -extern char my_ipx_address[NET_NAMELEN]; extern char my_tcpip_address[NET_NAMELEN]; -extern void (*GetComPortConfig) (int portNumber, int *port, int *irq, int *baud, qboolean *useModem); -extern void (*SetComPortConfig) (int portNumber, int port, int irq, int baud, qboolean useModem); -extern void (*GetModemConfig) (int portNumber, char *dialType, char *clear, char *init, char *hangup); -extern void (*SetModemConfig) (int portNumber, const char *dialType, const char *clear, const char *init, const char *hangup); extern qboolean slistInProgress; extern qboolean slistSilent; extern qboolean slistLocal; -extern struct cvar_s *config_com_port; -extern struct cvar_s *config_com_irq; -extern struct cvar_s *config_com_baud; -extern struct cvar_s *config_com_modem; -extern struct cvar_s *config_modem_dialtype; -extern struct cvar_s *config_modem_clear; -extern struct cvar_s *config_modem_init; -extern struct cvar_s *config_modem_hangup; extern struct cvar_s *hostname; extern QFile *vcrFile; diff --git a/libs/net/net_main.c b/libs/net/net_main.c index 165a83d2d..8f7e4c337 100644 --- a/libs/net/net_main.c +++ b/libs/net/net_main.c @@ -57,25 +57,13 @@ qsocket_t *net_activeSockets = NULL; qsocket_t *net_freeSockets = NULL; int net_numsockets = 0; -qboolean serialAvailable = false; -qboolean ipxAvailable = false; qboolean tcpipAvailable = false; int net_hostport; int DEFAULTnet_hostport = 26000; -char my_ipx_address[NET_NAMELEN]; char my_tcpip_address[NET_NAMELEN]; -void (*GetComPortConfig) (int portNumber, int *port, int *irq, int *baud, - qboolean *useModem); -void (*SetComPortConfig) (int portNumber, int port, int irq, int baud, - qboolean useModem); -void (*GetModemConfig) (int portNumber, char *dialType, char *clear, - char *init, char *hangup); -void (*SetModemConfig) (int portNumber, const char *dialType, const char *clear, - const char *init, const char *hangup); - static qboolean listening = false; qboolean slistInProgress = false; @@ -103,16 +91,6 @@ int unreliableMessagesReceived = 0; cvar_t *net_messagetimeout; cvar_t *hostname; -qboolean configRestored = false; -cvar_t *config_com_port; -cvar_t *config_com_irq; -cvar_t *config_com_baud; -cvar_t *config_com_modem; -cvar_t *config_modem_dialtype; -cvar_t *config_modem_clear; -cvar_t *config_modem_init; -cvar_t *config_modem_hangup; - QFile *vcrFile; qboolean recording = false; @@ -791,22 +769,6 @@ NET_Init (void) net_messagetimeout = Cvar_Get ("net_messagetimeout", "300", CVAR_NONE, NULL, "None"); hostname = Cvar_Get ("hostname", "UNNAMED", CVAR_NONE, NULL, "None"); - config_com_port = - Cvar_Get ("_config_com_port", "0x3f8", CVAR_ARCHIVE, NULL, "None"); - config_com_irq = Cvar_Get ("_config_com_irq", "4", CVAR_ARCHIVE, NULL, - "None"); - config_com_baud = - Cvar_Get ("_config_com_baud", "57600", CVAR_ARCHIVE, NULL, "None"); - config_com_modem = - Cvar_Get ("_config_com_modem", "1", CVAR_ARCHIVE, NULL, "None"); - config_modem_dialtype = - Cvar_Get ("_config_modem_dialtype", "T", CVAR_ARCHIVE, NULL, "None"); - config_modem_clear = - Cvar_Get ("_config_modem_clear", "ATZ", CVAR_ARCHIVE, NULL, "None"); - config_modem_init = - Cvar_Get ("_config_modem_init", "", CVAR_ARCHIVE, NULL, "None"); - config_modem_hangup = - Cvar_Get ("_config_modem_hangup", "AT H", CVAR_ARCHIVE, NULL, "None"); Cmd_AddCommand ("slist", NET_Slist_f, "No Description"); Cmd_AddCommand ("listen", NET_Listen_f, "No Description"); @@ -825,8 +787,6 @@ NET_Init (void) net_drivers[net_driverlevel].Listen (true); } - if (*my_ipx_address) - Sys_MaskPrintf (SYS_DEV, "IPX address %s\n", my_ipx_address); if (*my_tcpip_address) Sys_MaskPrintf (SYS_DEV, "TCP/IP address %s\n", my_tcpip_address); } @@ -865,24 +825,6 @@ void NET_Poll (void) { PollProcedure *pp; - qboolean useModem; - - if (!configRestored) { - if (serialAvailable) { - if (config_com_modem->int_val) - useModem = true; - else - useModem = false; - SetComPortConfig (0, config_com_port->int_val, - config_com_irq->int_val, config_com_baud->int_val, - useModem); - SetModemConfig (0, config_modem_dialtype->string, - config_modem_clear->string, - config_modem_init->string, - config_modem_hangup->string); - } - configRestored = true; - } SetNetTime (); diff --git a/nq/source/host_cmd.c b/nq/source/host_cmd.c index 348868740..52b2ce17c 100644 --- a/nq/source/host_cmd.c +++ b/nq/source/host_cmd.c @@ -100,8 +100,6 @@ Host_Status_f (void) print ("version: %4.2f\n", PACKAGE_VERSION); if (tcpipAvailable) print ("tcp/ip: %s\n", my_tcpip_address); - if (ipxAvailable) - print ("ipx: %s\n", my_ipx_address); print ("map: %s\n", sv.name); print ("players: %i active (%i max)\n\n", net_activeconnections, svs.maxclients); From b529bae0487f7c9314e8e3dda313a5f16c72e1ab Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 29 Jul 2011 12:41:46 +0900 Subject: [PATCH 025/334] Some more netmain documentation. I think I now understand enough to be able to start merging the low-level networking code. --- include/netmain.h | 65 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 18 deletions(-) diff --git a/include/netmain.h b/include/netmain.h index b14ee48e9..ce4acb073 100644 --- a/include/netmain.h +++ b/include/netmain.h @@ -49,7 +49,9 @@ struct qsockaddr { #define NET_HEADERSIZE (2 * sizeof(unsigned int)) #define NET_DATAGRAMSIZE (MAX_DATAGRAM + NET_HEADERSIZE) -// NetHeader flags +/** \name NetHeader flags +*/ +//@{ #define NETFLAG_LENGTH_MASK 0x0000ffff #define NETFLAG_DATA 0x00010000 #define NETFLAG_ACK 0x00020000 @@ -57,6 +59,7 @@ struct qsockaddr { #define NETFLAG_EOM 0x00080000 #define NETFLAG_UNRELIABLE 0x00100000 #define NETFLAG_CTL 0x80000000 +//@} #define NET_PROTOCOL_VERSION 3 @@ -78,7 +81,7 @@ struct qsockaddr { a full address and port in a string. It is used for returning the address of a server that is not running locally. */ -///@{ +//@{ /** Connect Request: \arg \b string \c game_name \em "QUAKE" @@ -144,43 +147,63 @@ struct qsockaddr { \arg \b string \c value */ #define CCREP_RULE_INFO 0x85 -///@} +//@} -typedef struct qsocket_s -{ +typedef struct qsocket_s { struct qsocket_s *next; - double connecttime; - double lastMessageTime; - double lastSendTime; + /// \name socket timing + //@{ + double connecttime; ///< Time client connected. + double lastMessageTime; ///< Time last message was received. + double lastSendTime; ///< Time last message was sent. + //@} - qboolean disconnected; - qboolean canSend; + /// \name socket status + //@{ + qboolean disconnected; ///< Socket is not in use. + qboolean canSend; ///< Socket can send a message. qboolean sendNext; + //@} - int driver; - int landriver; - int socket; - void *driverdata; + /// \name socket drivers + //@{ + int driver; ///< Net driver used by this socket. + int landriver; ///< Lan driver used by this socket. + int socket; ///< Lan driver socket handle. + void *driverdata; ///< Net driver private data. + //@} + /// \name message transmission + //@{ unsigned int ackSequence; unsigned int sendSequence; unsigned int unreliableSendSequence; int sendMessageLength; - byte sendMessage [NET_MAXMESSAGE]; + byte sendMessage[NET_MAXMESSAGE]; + //@} + /// \name message reception + //@{ unsigned int receiveSequence; unsigned int unreliableReceiveSequence; int receiveMessageLength; - byte receiveMessage [NET_MAXMESSAGE]; + byte receiveMessage[NET_MAXMESSAGE]; + //@} + /// \name socket address + //@{ struct qsockaddr addr; - char address[NET_NAMELEN]; - + char address[NET_NAMELEN]; ///< Human readable form. + //@} } qsocket_t; +/** \name socket management +*/ +//@{ extern qsocket_t *net_activeSockets; extern qsocket_t *net_freeSockets; extern int net_numsockets; +//@} #define MAX_NET_DRIVERS 8 @@ -189,10 +212,14 @@ extern int net_hostport; extern int net_driverlevel; +/** \name message statistics +*/ +//@{ extern int messagesSent; extern int messagesReceived; extern int unreliableMessagesSent; extern int unreliableMessagesReceived; +//@} /** Create and initialize a new qsocket. @@ -210,6 +237,8 @@ qsocket_t *NET_NewQSocket (void); void NET_FreeQSocket(qsocket_t *sock); /** Cache the system time for the network sub-system. + + \return The current time. */ double SetNetTime(void); From d6dc09d9f91675515f8eef6b17398beaeff2b811 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 29 Jul 2011 13:36:50 +0900 Subject: [PATCH 026/334] Re-enable the buglist. --- doc/quakeforge.dox.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/quakeforge.dox.in b/doc/quakeforge.dox.in index ad34a66cc..50a884194 100644 --- a/doc/quakeforge.dox.in +++ b/doc/quakeforge.dox.in @@ -454,7 +454,7 @@ GENERATE_TESTLIST = NO # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. -GENERATE_BUGLIST = NO +GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting From 50341d09724bdcea1d40afd8fae39a58d91b91d1 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 29 Jul 2011 13:51:58 +0900 Subject: [PATCH 027/334] Whitespace. --- libs/net/nm/net_udp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libs/net/nm/net_udp.c b/libs/net/nm/net_udp.c index 55298e07a..d0e578c49 100644 --- a/libs/net/nm/net_udp.c +++ b/libs/net/nm/net_udp.c @@ -365,7 +365,7 @@ UDP_CheckNewConnections (void) } int -UDP_Read (int socket, byte * buf, int len, struct qsockaddr *addr) +UDP_Read (int socket, byte *buf, int len, struct qsockaddr *addr) { socklen_t addrlen = sizeof (struct qsockaddr); int ret; @@ -391,7 +391,7 @@ UDP_MakeSocketBroadcastCapable (int socket) } int -UDP_Broadcast (int socket, byte * buf, int len) +UDP_Broadcast (int socket, byte *buf, int len) { int ret; @@ -409,7 +409,7 @@ UDP_Broadcast (int socket, byte * buf, int len) } int -UDP_Write (int socket, byte * buf, int len, struct qsockaddr *addr) +UDP_Write (int socket, byte *buf, int len, struct qsockaddr *addr) { int ret; From bc62988524abf2991d0871abe8547d05b986dcbb Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 29 Jul 2011 13:52:42 +0900 Subject: [PATCH 028/334] Document the NQ udp driver code. --- include/net_udp.h | 175 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 159 insertions(+), 16 deletions(-) diff --git a/include/net_udp.h b/include/net_udp.h index 26fd600d9..30f7d6cdb 100644 --- a/include/net_udp.h +++ b/include/net_udp.h @@ -1,7 +1,7 @@ /* net_udp.h - @description@ + NetQuake UDP lan driver. Copyright (C) 1996-1997 Id Software, Inc. @@ -36,24 +36,167 @@ */ //@{ -int UDP_Init (void); +/** Initialize the UDP network interface. + + Opens a single control socket. + + \return The control socket or -1 on failure. +*/ + +int UDP_Init (void); + +/** Shutdown the UDP network interface. +*/ void UDP_Shutdown (void); + +/** Open or close the accept socket. + + Sets net_acceptsocket to the socket number or -1. + + \param state True to open the socket, false to close it. +*/ void UDP_Listen (qboolean state); -int UDP_OpenSocket (int port); -int UDP_CloseSocket (int socket); -int UDP_Connect (int socket, struct qsockaddr *addr); -int UDP_CheckNewConnections (void); -int UDP_Read (int socket, byte *buf, int len, struct qsockaddr *addr); -int UDP_Write (int socket, byte *buf, int len, struct qsockaddr *addr); -int UDP_Broadcast (int socket, byte *buf, int len); + +/** Open a single socket on the specified port. + + If \p port is 0, then use the operating system default. + + \param port The port on which to open the socket. + \return The socket number or -1 on failure. +*/ +int UDP_OpenSocket (int port); + +/** Close a socket. + + \param socket The socket to close. + \return 0 for success, -1 for failure. +*/ +int UDP_CloseSocket (int socket); + +/** Does very little. + + \param socket The socket on which to do very little. + \param addr The address to which very little will be done. + \return 0 +*/ +int UDP_Connect (int socket, struct qsockaddr *addr); + +/** Check for incoming packets on the accept socket. + + Checks if any packets are available on net_acceptsocket. +*/ +int UDP_CheckNewConnections (void); + +/** Read a packet from the specified socket. + + \param socket The socket from which the packet will be read. + \param buf The buffer into which the packet will be read. + \param len The maximum number of bytes to read. + \param[out] addr The address from which the packet originated. + \return The number of bytes read or -1 on error. +*/ +int UDP_Read (int socket, byte *buf, int len, struct qsockaddr *addr); + +/** Send a packet via the specified socket to the specified address. + + \param socket The socket via which the packet will be sent. + \param buf The packet data to be sent. + \param len The number of bytes in the packet. + \param addr The addres to which the packet will be sent. + \return The number of bytes sent or -1 on error. +*/ +int UDP_Write (int socket, byte *buf, int len, struct qsockaddr *addr); + +/** Broadcast a packet via the specified socket. + + \warning It is a fatal error to use more than one socket for + broadcasting. + + \param socket The socket via which the packet will be broadcast. + \param buf The packet data to be sent. + \param len The number of bytes in the packet. + \return The number of bytes sent or -1 on error. +*/ +int UDP_Broadcast (int socket, byte *buf, int len); + +/** Convert an address to a string. + + Include the port number in the string. + + \warning The return value is a pointer to a static buffer. The returned + string must be saved if mixing calls with different addresses. + + \param addr The address to convert. + \return The address in human readable form. +*/ const char *UDP_AddrToString (struct qsockaddr *addr); -int UDP_StringToAddr (const char *string, struct qsockaddr *addr); -int UDP_GetSocketAddr (int socket, struct qsockaddr *addr); -int UDP_GetNameFromAddr (struct qsockaddr *addr, char *name); -int UDP_GetAddrFromName (const char *name, struct qsockaddr *addr); -int UDP_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2); -int UDP_GetSocketPort (struct qsockaddr *addr); -int UDP_SetSocketPort (struct qsockaddr *addr, int port); + +/** Convert a human readable address to a quake address. + + Parses a.b.c.d:p style addresses. + + \param[in] string The human readable address to be converted. + \param[out] addr The resulting address of the conversion. + \return 0 +*/ +int UDP_StringToAddr (const char *string, struct qsockaddr *addr); + +/** Retrieve the address to which the socket is bound. + + \param socket The socket for which the address will be retrieved. + \param[out] addr The address to which the socket is bound. + \return 0 +*/ +int UDP_GetSocketAddr (int socket, struct qsockaddr *addr); + +/** Convert an address to a hostname. + + \param[in] addr The address to covert. + \param[out] name Output buffer for the hostname. + + \bug No checking is done on the size of the buffer, and uses strcpy. +*/ +int UDP_GetNameFromAddr (struct qsockaddr *addr, char *name); + +/** Convert a human readable address to a quake address. + + Accepts both host names (full or partial) and numeric form. + + The port address can be specified when using a numeric address. + + Numeric addresses can be partial: unspecified portions are filled out + using the network address of the socket. + + \param name The human readable address to be converted. + \param addr The resulting address of the conversion. + \return 0 if the conversion is successful, otherwise -1. +*/ +int UDP_GetAddrFromName (const char *name, struct qsockaddr *addr); + +/** Compare two network addresses. + + Compare the port number too. + + \param addr1 The first address to compare. + \param addr2 The second address to compare. + \return True of the addresses match, otherwise false. +*/ +int UDP_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2); + +/** Get the port number from the socket address. + + \param addr The socket address from which to retrieve the port number. + \return The port number. +*/ +int UDP_GetSocketPort (struct qsockaddr *addr); + +/** Set the port number of the socket address. + + \param addr The socket address which to will have its port number set. + \param port The port number to which the socket address will be set. + \return 0 +*/ +int UDP_SetSocketPort (struct qsockaddr *addr, int port); //@} From 77dcd07b371ad689ae121fbe3a66ad8cf3159c6e Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 29 Jul 2011 14:30:54 +0900 Subject: [PATCH 029/334] Remove a dead function. --- include/net_udp.h | 10 ---------- include/net_wins.h | 1 - include/netmain.h | 1 - libs/net/nm/net_bsd.c | 1 - libs/net/nm/net_udp.c | 14 -------------- libs/net/nm/net_win.c | 1 - libs/net/nm/net_wins.c | 17 ----------------- 7 files changed, 45 deletions(-) diff --git a/include/net_udp.h b/include/net_udp.h index 30f7d6cdb..e7cd8cc7d 100644 --- a/include/net_udp.h +++ b/include/net_udp.h @@ -131,16 +131,6 @@ int UDP_Broadcast (int socket, byte *buf, int len); */ const char *UDP_AddrToString (struct qsockaddr *addr); -/** Convert a human readable address to a quake address. - - Parses a.b.c.d:p style addresses. - - \param[in] string The human readable address to be converted. - \param[out] addr The resulting address of the conversion. - \return 0 -*/ -int UDP_StringToAddr (const char *string, struct qsockaddr *addr); - /** Retrieve the address to which the socket is bound. \param socket The socket for which the address will be retrieved. diff --git a/include/net_wins.h b/include/net_wins.h index 66d60ca35..eccfef0dd 100644 --- a/include/net_wins.h +++ b/include/net_wins.h @@ -54,7 +54,6 @@ int WINS_Read (int socket, byte *buf, int len, struct qsockaddr *addr); int WINS_Write (int socket, byte *buf, int len, struct qsockaddr *addr); int WINS_Broadcast (int socket, byte *buf, int len); const char *WINS_AddrToString (struct qsockaddr *addr); -int WINS_StringToAddr (const char *string, struct qsockaddr *addr); int WINS_GetSocketAddr (int socket, struct qsockaddr *addr); int WINS_GetNameFromAddr (struct qsockaddr *addr, char *name); int WINS_GetAddrFromName (const char *name, struct qsockaddr *addr); diff --git a/include/netmain.h b/include/netmain.h index ce4acb073..c40c87340 100644 --- a/include/netmain.h +++ b/include/netmain.h @@ -406,7 +406,6 @@ typedef struct { int (*Write) (int socket, byte *buf, int len, struct qsockaddr *addr); int (*Broadcast) (int socket, byte *buf, int len); const char * (*AddrToString) (struct qsockaddr *addr); - int (*StringToAddr) (const char *string, struct qsockaddr *addr); int (*GetSocketAddr) (int socket, struct qsockaddr *addr); int (*GetNameFromAddr) (struct qsockaddr *addr, char *name); int (*GetAddrFromName) (const char *name, struct qsockaddr *addr); diff --git a/libs/net/nm/net_bsd.c b/libs/net/nm/net_bsd.c index a0ea534de..a8c49299f 100644 --- a/libs/net/nm/net_bsd.c +++ b/libs/net/nm/net_bsd.c @@ -89,7 +89,6 @@ net_landriver_t net_landrivers[MAX_NET_DRIVERS] = { UDP_Write, UDP_Broadcast, UDP_AddrToString, - UDP_StringToAddr, UDP_GetSocketAddr, UDP_GetNameFromAddr, UDP_GetAddrFromName, diff --git a/libs/net/nm/net_udp.c b/libs/net/nm/net_udp.c index d0e578c49..5a494356f 100644 --- a/libs/net/nm/net_udp.c +++ b/libs/net/nm/net_udp.c @@ -436,20 +436,6 @@ UDP_AddrToString (struct qsockaddr *addr) return buffer->str; } -int -UDP_StringToAddr (const char *string, struct qsockaddr *addr) -{ - int ha1, ha2, ha3, ha4, hp, ipaddr; - - sscanf (string, "%d.%d.%d.%d:%d", &ha1, &ha2, &ha3, &ha4, &hp); - ipaddr = (ha1 << 24) | (ha2 << 16) | (ha3 << 8) | ha4; - - addr->qsa_family = AF_INET; - ((struct sockaddr_in *) addr)->sin_addr.s_addr = htonl (ipaddr); - ((struct sockaddr_in *) addr)->sin_port = htons (hp); - return 0; -} - int UDP_GetSocketAddr (int socket, struct qsockaddr *addr) { diff --git a/libs/net/nm/net_win.c b/libs/net/nm/net_win.c index cd24c108d..b8a492daf 100644 --- a/libs/net/nm/net_win.c +++ b/libs/net/nm/net_win.c @@ -89,7 +89,6 @@ net_landriver_t net_landrivers[MAX_NET_DRIVERS] = { WINS_Write, WINS_Broadcast, WINS_AddrToString, - WINS_StringToAddr, WINS_GetSocketAddr, WINS_GetNameFromAddr, WINS_GetAddrFromName, diff --git a/libs/net/nm/net_wins.c b/libs/net/nm/net_wins.c index c81737081..deb31f80b 100644 --- a/libs/net/nm/net_wins.c +++ b/libs/net/nm/net_wins.c @@ -502,23 +502,6 @@ WINS_AddrToString (struct qsockaddr *addr) //============================================================================= -int -WINS_StringToAddr (const char *string, struct qsockaddr *addr) -{ - int ha1, ha2, ha3, ha4, hp; - int ipaddr; - - sscanf (string, "%d.%d.%d.%d:%d", &ha1, &ha2, &ha3, &ha4, &hp); - ipaddr = (ha1 << 24) | (ha2 << 16) | (ha3 << 8) | ha4; - - addr->qsa_family = AF_INET; - ((struct sockaddr_in *) addr)->sin_addr.s_addr = htonl (ipaddr); - ((struct sockaddr_in *) addr)->sin_port = htons ((unsigned short) hp); - return 0; -} - -//============================================================================= - int WINS_GetSocketAddr (int socket, struct qsockaddr *addr) { From a5272fac174d69743795bdb2762b7e11b7ced599 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 29 Jul 2011 16:32:35 +0900 Subject: [PATCH 030/334] Make the lack of libsamplerate a non-fatal error. Requiring libsamplerate when not building clients is rather silly. When building clients, disable sound if libsamplerate can't be found. --- config.d/sound.m4 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/config.d/sound.m4 b/config.d/sound.m4 index d1bc0057f..ec4850c3d 100644 --- a/config.d/sound.m4 +++ b/config.d/sound.m4 @@ -113,7 +113,9 @@ fi AC_SUBST(SAMPLERATE_LIBS) dnl AM_CONDITIONAL(HAVE_SAMPLERATE, test "$HAVE_SAMPLERATE" = "yes") if test "x$HAVE_SAMPLERATE" = "xno"; then - AC_MSG_ERROR(libsamplerate is required but was not found) + AC_MSG_WARN([libsamplerate is required but was not found.] + [Sound will be disabled.]) + enable_sound=no fi SOUND_TYPES="$SOUND_TYPES DISK" From 056d6a08ff2f319d7c919bd04e9ecf754f290131 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 29 Jul 2011 16:51:52 +0900 Subject: [PATCH 031/334] Do not define HAVE_ZLIB when it is unavailable. Oops :P --- config.d/compression.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.d/compression.m4 b/config.d/compression.m4 index 7d624a18c..3b7484a2b 100644 --- a/config.d/compression.m4 +++ b/config.d/compression.m4 @@ -61,12 +61,12 @@ if test "x$enable_zlib" != "xno"; then AC_CHECK_HEADER(zlib.h, HAVE_ZLIB=yes, HAVE_ZLIB=no) if test "x$HAVE_ZLIB" = "xyes"; then Z_LIBS="-lz" + AC_DEFINE(HAVE_ZLIB, 1, [Define if you have zlib]) fi fi fi fi AC_SUBST(Z_LIBS) -AC_DEFINE(HAVE_ZLIB, 1, [Define if you have zlib]) AM_CONDITIONAL(HAVE_ZLIB, test "$HAVE_ZLIB" = "yes") AC_ARG_ENABLE(png, From bf58ad9d8059c3c94f0e13f943b747f68e0d2289 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 29 Jul 2011 17:21:33 +0900 Subject: [PATCH 032/334] And silence a "set but not used" warning. --- libs/util/quakeio.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libs/util/quakeio.c b/libs/util/quakeio.c index 642ad3656..a3f3ae5ae 100644 --- a/libs/util/quakeio.c +++ b/libs/util/quakeio.c @@ -217,7 +217,9 @@ Qdopen (int fd, const char *mode) { QFile *file; char *m, *p; +#ifdef HAVE_ZLIB int zip = 0; +#endif int len = strlen (mode); m = alloca (len + 1); @@ -226,7 +228,9 @@ Qdopen (int fd, const char *mode) #endif for (p = m; *mode && p - m < len; mode++) { if (*mode == 'z') { +#ifdef HAVE_ZLIB zip = 1; +#endif continue; } *p++ = *mode; From c6e0e094d898a053d9896535e604225dd63062e7 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 30 Jul 2011 15:01:16 +0900 Subject: [PATCH 033/334] Fix an unterminated array. That was sneaky. It took building qfcc on an arm to trigger that bug. --- tools/qfcc/source/class.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/qfcc/source/class.c b/tools/qfcc/source/class.c index e7c9589b8..664cfae3a 100644 --- a/tools/qfcc/source/class.c +++ b/tools/qfcc/source/class.c @@ -160,6 +160,7 @@ static struct_def_t class_ivars[] = { {"sibling_class", &type_pointer}, {"protocols", &type_pointer}, {"gc_object_type", &type_pointer}, + {0, 0} }; static struct_def_t protocol_ivars[] = { From 28610c08e374257f4d4454646acb8522333a8fce Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 30 Jul 2011 15:03:19 +0900 Subject: [PATCH 034/334] Do not try to build testsound when not building sound libs. --- config.d/build_control.m4 | 3 +++ libs/audio/test/Makefile.am | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/config.d/build_control.m4 b/config.d/build_control.m4 index 52e6c1d86..86eea3d44 100644 --- a/config.d/build_control.m4 +++ b/config.d/build_control.m4 @@ -298,6 +298,7 @@ SND_OUTPUT_DEFAULT="" if test -n "$CL_TARGETS"; then CD_TARGETS="libQFcd.la" SND_TARGETS="libQFsound.la" + AUDIO_TARGETS="testsound" JOY_TARGETS="libQFjs.la" if test "`echo $SOUND_TYPES | grep ALSA`"; then SND_PLUGIN_TARGETS="$SND_PLUGIN_TARGETS snd_output_alsa.la" @@ -364,6 +365,7 @@ else SND_PLUGIN_TARGETS="" SND_REND_TARGETS="" SND_TARGETS="" + AUDIO_TARGETS="" unset SOUND_TYPES fi AC_DEFINE_UNQUOTED(SND_OUTPUT_DEFAULT, "$SND_OUTPUT_DEFAULT", [Define this to the default sound output driver.]) @@ -510,6 +512,7 @@ AC_SUBST(SND_REND_STATIC) AC_SUBST(SND_REND_STATIC_LIBS) AC_SUBST(SND_REND_TARGETS) AC_SUBST(SND_TARGETS) +AC_SUBST(AUDIO_TARGETS) AC_SUBST(VID_MODEL_TARGETS) AC_SUBST(VID_REND_TARGETS) AC_SUBST(VID_REND_NOINST_TARGETS) diff --git a/libs/audio/test/Makefile.am b/libs/audio/test/Makefile.am index 91d45a2f8..532aef98f 100644 --- a/libs/audio/test/Makefile.am +++ b/libs/audio/test/Makefile.am @@ -2,7 +2,9 @@ AUTOMAKE_OPTIONS= foreign INCLUDES= -I$(top_srcdir)/include -noinst_PROGRAMS= testsound +noinst_PROGRAMS= @AUDIO_TARGETS@ + +EXTRA_PROGRAMS= testsound testsound_SOURCES= testsound.c testsound_LDADD= $(top_builddir)/libs/audio/libQFsound.la $(top_builddir)/libs/util/libQFutil.la From 8e140bc97e9846c7fb68758fe8a9300ea5f1dc43 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 30 Jul 2011 17:44:03 +0900 Subject: [PATCH 035/334] Use SYS_NET instead of SYS_DEV for networking debug prints. --- libs/net/net_main.c | 2 +- libs/net/nm/net_dgrm.c | 12 ++++++------ libs/net/nm/net_udp.c | 2 +- libs/net/nm/net_wins.c | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/libs/net/net_main.c b/libs/net/net_main.c index 8f7e4c337..b55c74287 100644 --- a/libs/net/net_main.c +++ b/libs/net/net_main.c @@ -788,7 +788,7 @@ NET_Init (void) } if (*my_tcpip_address) - Sys_MaskPrintf (SYS_DEV, "TCP/IP address %s\n", my_tcpip_address); + Sys_MaskPrintf (SYS_NET, "TCP/IP address %s\n", my_tcpip_address); } void diff --git a/libs/net/nm/net_dgrm.c b/libs/net/nm/net_dgrm.c index 4c90029da..09bf5ce49 100644 --- a/libs/net/nm/net_dgrm.c +++ b/libs/net/nm/net_dgrm.c @@ -309,7 +309,7 @@ Datagram_GetMessage (qsocket_t * sock) while (1) { length = - sfunc.Read (sock->socket, (byte *) & packetBuffer, NET_DATAGRAMSIZE, + sfunc.Read (sock->socket, (byte *) &packetBuffer, NET_DATAGRAMSIZE, &readaddr); // if ((rand() & 255) > 220) @@ -344,14 +344,14 @@ Datagram_GetMessage (qsocket_t * sock) if (flags & NETFLAG_UNRELIABLE) { if (sequence < sock->unreliableReceiveSequence) { - Sys_MaskPrintf (SYS_DEV, "Got a stale datagram\n"); + Sys_MaskPrintf (SYS_NET, "Got a stale datagram\n"); ret = 0; break; } if (sequence != sock->unreliableReceiveSequence) { count = sequence - sock->unreliableReceiveSequence; droppedDatagrams += count; - Sys_MaskPrintf (SYS_DEV, "Dropped %u datagram(s)\n", count); + Sys_MaskPrintf (SYS_NET, "Dropped %u datagram(s)\n", count); } sock->unreliableReceiveSequence = sequence + 1; @@ -366,15 +366,15 @@ Datagram_GetMessage (qsocket_t * sock) if (flags & NETFLAG_ACK) { if (sequence != (sock->sendSequence - 1)) { - Sys_MaskPrintf (SYS_DEV, "Stale ACK received\n"); + Sys_MaskPrintf (SYS_NET, "Stale ACK received\n"); continue; } if (sequence == sock->ackSequence) { sock->ackSequence++; if (sock->ackSequence != sock->sendSequence) - Sys_MaskPrintf (SYS_DEV, "ack sequencing error\n"); + Sys_MaskPrintf (SYS_NET, "ack sequencing error\n"); } else { - Sys_MaskPrintf (SYS_DEV, "Duplicate ACK received\n"); + Sys_MaskPrintf (SYS_NET, "Duplicate ACK received\n"); continue; } sock->sendMessageLength -= MAX_DATAGRAM; diff --git a/libs/net/nm/net_udp.c b/libs/net/nm/net_udp.c index 5a494356f..8a291a538 100644 --- a/libs/net/nm/net_udp.c +++ b/libs/net/nm/net_udp.c @@ -141,7 +141,7 @@ get_address (int sock) if (ioctl (sock, SIOCGIFADDR, &ifr[i]) == -1) continue; in_addr = (struct sockaddr_in *)&ifr[i].ifr_addr; - Sys_MaskPrintf (SYS_DEV, "%s: %s\n", ifr[i].ifr_name, + Sys_MaskPrintf (SYS_NET, "%s: %s\n", ifr[i].ifr_name, inet_ntoa (in_addr->sin_addr)); addr = *(unsigned *)&in_addr->sin_addr; if (addr != htonl (0x7f000001)) { diff --git a/libs/net/nm/net_wins.c b/libs/net/nm/net_wins.c index deb31f80b..9b7e1ce3e 100644 --- a/libs/net/nm/net_wins.c +++ b/libs/net/nm/net_wins.c @@ -202,7 +202,7 @@ WINS_Init (void) // determine my name if (pgethostname (buff, MAXHOSTNAMELEN) == SOCKET_ERROR) { - Sys_MaskPrintf (SYS_DEV, "Winsock TCP/IP Initialization failed.\n"); + Sys_MaskPrintf (SYS_NET, "Winsock TCP/IP Initialization failed.\n"); if (--winsock_initialized == 0) pWSACleanup (); return -1; From 6f413c0aec69458cd6b710ae017f58de784af095 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 2 Aug 2011 11:24:51 +0900 Subject: [PATCH 036/334] Fix testsound building in mingw. I had forgotten about $(EXEEXT) :P --- config.d/build_control.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.d/build_control.m4 b/config.d/build_control.m4 index 86eea3d44..8f4953a95 100644 --- a/config.d/build_control.m4 +++ b/config.d/build_control.m4 @@ -298,7 +298,7 @@ SND_OUTPUT_DEFAULT="" if test -n "$CL_TARGETS"; then CD_TARGETS="libQFcd.la" SND_TARGETS="libQFsound.la" - AUDIO_TARGETS="testsound" + AUDIO_TARGETS="testsound\$(EXEEXT)" JOY_TARGETS="libQFjs.la" if test "`echo $SOUND_TYPES | grep ALSA`"; then SND_PLUGIN_TARGETS="$SND_PLUGIN_TARGETS snd_output_alsa.la" From e89532cb9fcb651ac8d1f1da4402ae35c5720050 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 2 Aug 2011 11:29:20 +0900 Subject: [PATCH 037/334] Fix a couple of missed view.h->clview.h changes. --- libs/video/renderer/sw32/screen.c | 2 +- libs/video/renderer/sw32/sw32_rmain.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/video/renderer/sw32/screen.c b/libs/video/renderer/sw32/screen.c index 313ce52fb..f197f6c6a 100644 --- a/libs/video/renderer/sw32/screen.c +++ b/libs/video/renderer/sw32/screen.c @@ -57,7 +57,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "r_local.h" #include "r_screen.h" #include "sbar.h" -#include "view.h" +#include "clview.h" static void SCR_ApplyBlend (void) // Used to be V_UpdatePalette diff --git a/libs/video/renderer/sw32/sw32_rmain.c b/libs/video/renderer/sw32/sw32_rmain.c index 3983d3b56..e78d64c59 100644 --- a/libs/video/renderer/sw32/sw32_rmain.c +++ b/libs/video/renderer/sw32/sw32_rmain.c @@ -53,7 +53,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "r_cvar.h" #include "r_dynamic.h" #include "r_local.h" -#include "view.h" +#include "clview.h" //define PASSAGES From e5876752f30fb2dc4cb66276d7c57d4ebae3f0da Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 2 Aug 2011 15:22:33 +0900 Subject: [PATCH 038/334] Document the datagram net driver interface. --- include/net_dgrm.h | 81 ++++++++++++++++++++++++++++++++++++++++++ include/net_udp.h | 6 +++- libs/net/nm/net_dgrm.c | 22 +++++++----- 3 files changed, 99 insertions(+), 10 deletions(-) diff --git a/include/net_dgrm.h b/include/net_dgrm.h index ac9b4b89b..84cfcee37 100644 --- a/include/net_dgrm.h +++ b/include/net_dgrm.h @@ -32,17 +32,98 @@ */ //@{ +/** Initialize the Datagram net driver. + + Also initializes the underlying lan drivers. + + \return 0 if successful, otherwise -1. +*/ int Datagram_Init (void); + +/** Control the listen status of the underlying lan drivers. + + \param state True to enable, false to disable. +*/ void Datagram_Listen (qboolean state); + +/** Search for hosts (servers) on the local network. + + If \p xmit is true, broadcast a CCREQ_SERVER_INFO packet via all + underlying lan drivers using their control ports. + + Check for any CCREP_SERVER_INFO responses. Ignore all other packets. + + \param xmit True to send the broadcast, falst to only listen. +*/ void Datagram_SearchForHosts (qboolean xmit); + +/** Connect to the specified host. + + \param host The host to which the connection will be made. + \return A pointer to the socket representing the connection, or + null if unsuccessful. +*/ qsocket_t *Datagram_Connect (const char *host); + +/** Check for a new incoming connection. + + \return A pointer to the socekt representing the new connection, + or null if none found. +*/ qsocket_t *Datagram_CheckNewConnections (void); + +/** Check for and process an incoming packet on the socket. + + \param sock The socket to check. + \return -1 if there is an error + \return 0 if the packet is stale + \return 1 if the packet is reliable + \return 2 if the packet is unreliable +*/ int Datagram_GetMessage (qsocket_t *sock); + +/** Send a reliable packet to the socket. + + \param sock The socket to which the packet will be sent. + \param data The packet to be sent. + \return -1 If there is an error + \return 1 if everything is ok. +*/ int Datagram_SendMessage (qsocket_t *sock, sizebuf_t *data); + +/** Send an unreliable packet to the socket. + + \param sock The socket to which the packet will be sent. + \param data The packet to be sent. + \return -1 If there is an error + \return 1 if everything is ok. +*/ int Datagram_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data); + +/** Check if a reliable message can be sent to the socket. + + \param sock The socket to check. + \return True if the packet can be sent. +*/ qboolean Datagram_CanSendMessage (qsocket_t *sock); + +/** Check if an unreliable message can be sent to the socket. + + Always true. + + \param sock The socket to check. + \return True if the packet can be sent. +*/ qboolean Datagram_CanSendUnreliableMessage (qsocket_t *sock); + +/** Close the socket. + + \param sock The socket to close. +*/ void Datagram_Close (qsocket_t *sock); + +/** Shutdown the Datagram net driver. +*/ void Datagram_Shutdown (void); //@} diff --git a/include/net_udp.h b/include/net_udp.h index e7cd8cc7d..79690f3cd 100644 --- a/include/net_udp.h +++ b/include/net_udp.h @@ -52,6 +52,7 @@ void UDP_Shutdown (void); /** Open or close the accept socket. Sets net_acceptsocket to the socket number or -1. + The accept socket is stored in net_hostport. \param state True to open the socket, false to close it. */ @@ -169,7 +170,10 @@ int UDP_GetAddrFromName (const char *name, struct qsockaddr *addr); \param addr1 The first address to compare. \param addr2 The second address to compare. - \return True of the addresses match, otherwise false. + \return -1 if the family or address are different. + \return 1 if the family and address are the same, but the port + is different. + \return 0 if everything is the same. */ int UDP_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2); diff --git a/libs/net/nm/net_dgrm.c b/libs/net/nm/net_dgrm.c index 09bf5ce49..29e77ecf8 100644 --- a/libs/net/nm/net_dgrm.c +++ b/libs/net/nm/net_dgrm.c @@ -157,7 +157,7 @@ NET_Ban_f (void) int -Datagram_SendMessage (qsocket_t * sock, sizebuf_t *data) +Datagram_SendMessage (qsocket_t *sock, sizebuf_t *data) { unsigned int packetLen; unsigned int dataLen; @@ -193,7 +193,7 @@ Datagram_SendMessage (qsocket_t * sock, sizebuf_t *data) static int -SendMessageNext (qsocket_t * sock) +SendMessageNext (qsocket_t *sock) { unsigned int packetLen; unsigned int dataLen; @@ -225,7 +225,7 @@ SendMessageNext (qsocket_t * sock) static int -ReSendMessage (qsocket_t * sock) +ReSendMessage (qsocket_t *sock) { unsigned int packetLen; unsigned int dataLen; @@ -257,7 +257,7 @@ ReSendMessage (qsocket_t * sock) qboolean -Datagram_CanSendMessage (qsocket_t * sock) +Datagram_CanSendMessage (qsocket_t *sock) { if (sock->sendNext) SendMessageNext (sock); @@ -267,14 +267,14 @@ Datagram_CanSendMessage (qsocket_t * sock) qboolean -Datagram_CanSendUnreliableMessage (qsocket_t * sock) +Datagram_CanSendUnreliableMessage (qsocket_t *sock) { return true; } int -Datagram_SendUnreliableMessage (qsocket_t * sock, sizebuf_t *data) +Datagram_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data) { int packetLen; @@ -294,7 +294,7 @@ Datagram_SendUnreliableMessage (qsocket_t * sock, sizebuf_t *data) int -Datagram_GetMessage (qsocket_t * sock) +Datagram_GetMessage (qsocket_t *sock) { unsigned int length; unsigned int flags; @@ -303,6 +303,8 @@ Datagram_GetMessage (qsocket_t * sock) unsigned int sequence; unsigned int count; + /// If there is an outstanding reliable packet and more than 1 second has + /// passed, resend the packet. if (!sock->canSend) if ((net_time - sock->lastSendTime) > 1.0) ReSendMessage (sock); @@ -357,6 +359,7 @@ Datagram_GetMessage (qsocket_t * sock) length -= NET_HEADERSIZE; + /// Copy unreliable data to net_message SZ_Clear (net_message->message); SZ_Write (net_message->message, packetBuffer.data, length); @@ -414,6 +417,7 @@ Datagram_GetMessage (qsocket_t * sock) break; } + /// Append reliable data to sock->receiveMessage. memcpy (sock->receiveMessage + sock->receiveMessageLength, packetBuffer.data, length); sock->receiveMessageLength += length; @@ -429,7 +433,7 @@ Datagram_GetMessage (qsocket_t * sock) static void -PrintStats (qsocket_t * s) +PrintStats (qsocket_t *s) { Sys_Printf ("canSend = %4u \n", s->canSend); Sys_Printf ("sendSeq = %4u ", s->sendSequence); @@ -790,7 +794,7 @@ Datagram_Shutdown (void) void -Datagram_Close (qsocket_t * sock) +Datagram_Close (qsocket_t *sock) { sfunc.CloseSocket (sock->socket); } From 76f894a29f6220d36250594258a1e212a77620db Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 2 Aug 2011 15:22:57 +0900 Subject: [PATCH 039/334] Add some debug prints for nq networking. --- libs/net/nm/net_dgrm.c | 2 ++ libs/net/nm/net_udp.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/libs/net/nm/net_dgrm.c b/libs/net/nm/net_dgrm.c index 29e77ecf8..100c3b2f5 100644 --- a/libs/net/nm/net_dgrm.c +++ b/libs/net/nm/net_dgrm.c @@ -1269,6 +1269,8 @@ _Datagram_Connect (const char *host) if (ret > 0) { // is it from the right place? if (sfunc.AddrCompare (&readaddr, &sendaddr) != 0) { + Sys_MaskPrintf (SYS_NET, "%s ", sfunc.AddrToString (&readaddr)); + Sys_MaskPrintf (SYS_NET, "%s\n", sfunc.AddrToString (&sendaddr)); ret = 0; continue; } diff --git a/libs/net/nm/net_udp.c b/libs/net/nm/net_udp.c index 8a291a538..795092339 100644 --- a/libs/net/nm/net_udp.c +++ b/libs/net/nm/net_udp.c @@ -373,6 +373,7 @@ UDP_Read (int socket, byte *buf, int len, struct qsockaddr *addr) ret = recvfrom (socket, buf, len, 0, (struct sockaddr *) addr, &addrlen); if (ret == -1 && (errno == EWOULDBLOCK || errno == ECONNREFUSED)) return 0; + Sys_MaskPrintf (SYS_NET, "got %d bytes from %s\n", ret, UDP_AddrToString (addr)); return ret; } @@ -417,6 +418,7 @@ UDP_Write (int socket, byte *buf, int len, struct qsockaddr *addr) sizeof (struct qsockaddr)); if (ret == -1 && errno == EWOULDBLOCK) return 0; + Sys_MaskPrintf (SYS_NET, "sent %d bytes to %s\n", ret, UDP_AddrToString (addr)); return ret; } From eba66b1ddea00aa0f4a646ec1641b1ec29e40019 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 2 Aug 2011 17:32:36 +0900 Subject: [PATCH 040/334] Doc tweaks and some whitespace. --- include/netmain.h | 3 ++- libs/net/nm/net_dgrm.c | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/include/netmain.h b/include/netmain.h index c40c87340..57d989a4a 100644 --- a/include/netmain.h +++ b/include/netmain.h @@ -113,7 +113,8 @@ struct qsockaddr { /** Connect Reply: - \arg \b long \c port + \arg \b long \c port The port which the client is to use for further + communication. */ #define CCREP_ACCEPT 0x81 diff --git a/libs/net/nm/net_dgrm.c b/libs/net/nm/net_dgrm.c index 100c3b2f5..0226adff6 100644 --- a/libs/net/nm/net_dgrm.c +++ b/libs/net/nm/net_dgrm.c @@ -1269,8 +1269,10 @@ _Datagram_Connect (const char *host) if (ret > 0) { // is it from the right place? if (sfunc.AddrCompare (&readaddr, &sendaddr) != 0) { - Sys_MaskPrintf (SYS_NET, "%s ", sfunc.AddrToString (&readaddr)); - Sys_MaskPrintf (SYS_NET, "%s\n", sfunc.AddrToString (&sendaddr)); + Sys_MaskPrintf (SYS_NET, "%s ", + sfunc.AddrToString (&readaddr)); + Sys_MaskPrintf (SYS_NET, "%s\n", + sfunc.AddrToString (&sendaddr)); ret = 0; continue; } From 3898f5fd5c3273e61f27722559a6290b07b78a95 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 4 Aug 2011 20:21:52 +0900 Subject: [PATCH 041/334] Debian build fixes from sergio. --- debian/changelog | 6 ++++++ debian/quakeforge-common.install | 1 - debian/quakeforge-common.postinst | 1 - debian/quakeforge-dev.install | 2 -- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/debian/changelog b/debian/changelog index 7649dacf0..93ec5a9f4 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +quakeforge (0.6.0~git20110804-0) frozen unstable; urgency=low + + * Small debian bugfixes and GIT snapshot + + -- sergio Thu, 04 Aug 2011 03:24:32 +0400 + quakeforge (0.6.0~git20101223-1) frozen unstable; urgency=low * The "No, really" release. diff --git a/debian/quakeforge-common.install b/debian/quakeforge-common.install index b9d04288f..25ea083fa 100644 --- a/debian/quakeforge-common.install +++ b/debian/quakeforge-common.install @@ -3,7 +3,6 @@ usr/lib/libQFcd.so.* usr/lib/libQFconsole.so.* usr/lib/libQFruamoko.so.* usr/lib/libQFgamecode.so.* -usr/lib/libQFgamecode_builtins.so.* usr/lib/libQFgib.so.* usr/lib/libQFimage.so.* usr/lib/libQFjs.so.* diff --git a/debian/quakeforge-common.postinst b/debian/quakeforge-common.postinst index 6b9a30f55..a043e26a2 100644 --- a/debian/quakeforge-common.postinst +++ b/debian/quakeforge-common.postinst @@ -1,7 +1,6 @@ #!/bin/sh -e update-alternatives --install /usr/lib/quakeforge/plugins/snd_output_default.so quakeforge-audio-default /usr/lib/quakeforge/plugins/snd_output_disk.so 10 -update-alternatives --install /usr/lib/quakeforge/plugins/snd_output_default.so quakeforge-audio-default /usr/lib/quakeforge/plugins/snd_output_oss.so 20 #DEBHELPER# exit 0 diff --git a/debian/quakeforge-dev.install b/debian/quakeforge-dev.install index b816de68e..fe2d441e2 100644 --- a/debian/quakeforge-dev.install +++ b/debian/quakeforge-dev.install @@ -6,8 +6,6 @@ usr/lib/libQFruamoko.*a usr/lib/libQFruamoko.so usr/lib/libQFgamecode.*a usr/lib/libQFgamecode.so -usr/lib/libQFgamecode_builtins.*a -usr/lib/libQFgamecode_builtins.so usr/lib/libQFgib.a usr/lib/libQFgib.so usr/lib/libQFimage.*a From 6f0ab844ead892259232d3d773a3e3507c30adef Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 2 Aug 2011 17:36:38 +0900 Subject: [PATCH 042/334] Some more nq networking debug prints. --- libs/net/net_main.c | 2 ++ libs/net/nm/net_dgrm.c | 5 +++++ nq/source/host.c | 1 + 3 files changed, 8 insertions(+) diff --git a/libs/net/net_main.c b/libs/net/net_main.c index b55c74287..dcb82cfea 100644 --- a/libs/net/net_main.c +++ b/libs/net/net_main.c @@ -491,6 +491,7 @@ NET_Close (qsocket_t *sock) // call the driver_Close function sfunc.Close (sock); + Sys_MaskPrintf (SYS_NET, "closing socket\n"); NET_FreeQSocket (sock); } @@ -524,6 +525,7 @@ NET_GetMessage (qsocket_t *sock) // see if this connection has timed out if (ret == 0 && sock->driver) { if (net_time - sock->lastMessageTime > net_messagetimeout->value) { + Sys_MaskPrintf (SYS_NET, "socket timed out\n"); NET_Close (sock); return -1; } diff --git a/libs/net/nm/net_dgrm.c b/libs/net/nm/net_dgrm.c index 0226adff6..732fa7c90 100644 --- a/libs/net/nm/net_dgrm.c +++ b/libs/net/nm/net_dgrm.c @@ -1025,6 +1025,8 @@ _Datagram_CheckNewConnections (void) } // it's somebody coming back in from a crash/disconnect // so close the old qsocket and let their retry get them back in + Sys_MaskPrintf (SYS_NET, "closing stale socket %d %g\n", ret, + net_time - s->connecttime); NET_Close (s); return NULL; } @@ -1050,11 +1052,13 @@ _Datagram_CheckNewConnections (void) // allocate a network socket newsock = dfunc.OpenSocket (0); if (newsock == -1) { + Sys_MaskPrintf (SYS_NET, "failed to open socket"); NET_FreeQSocket (sock); return NULL; } // connect to the client if (dfunc.Connect (newsock, &clientaddr) == -1) { + Sys_MaskPrintf (SYS_NET, "failed to connect client"); dfunc.CloseSocket (newsock); NET_FreeQSocket (sock); return NULL; @@ -1361,6 +1365,7 @@ _Datagram_Connect (const char *host) ErrorReturn: // FIXME: MENUCODE - do something with reason + Sys_MaskPrintf (SYS_NET, "FIXME: MENUCODE - do something with reason\n"); NET_FreeQSocket (sock); ErrorReturn2: dfunc.CloseSocket (newsock); diff --git a/nq/source/host.c b/nq/source/host.c index a7efdcc63..d33e4d95e 100644 --- a/nq/source/host.c +++ b/nq/source/host.c @@ -432,6 +432,7 @@ SV_DropClient (qboolean crash) Sys_Printf ("Client %s removed\n", host_client->name); } // break the net connection + Sys_MaskPrintf (SYS_NET, "dropping client\n"); NET_Close (host_client->netconnection); host_client->netconnection = NULL; From 6716b2e8abcbfd4bf527f0104093b20a8b1c4478 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 6 Aug 2011 17:21:54 +0900 Subject: [PATCH 043/334] Add some disabled test code for interface access. As part of the work on getting nq to work on multi-homed nodes, I used the existing recvmsg code in qw-master to check how things work. I figured it might be worth keeping. --- qw/source/master.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/qw/source/master.c b/qw/source/master.c index be8823d1a..62e1da445 100644 --- a/qw/source/master.c +++ b/qw/source/master.c @@ -346,6 +346,22 @@ QW_Master (struct sockaddr_in *addr) perror ("qf_recvmsg failed\n"); continue; } +#if 0 + { + /* Dump the destination information (ie, our iface/address) of + * the packet. Mostly so I know how this stuff works. + */ + struct cmsghdr *cmsg; + + for (cmsg = CMSG_FIRSTHDR (&msghdr); cmsg; + cmsg = CMSG_NXTHDR (&msghdr, cmsg)) { + struct in_pktinfo *d; + d = (struct in_pktinfo *) CMSG_DATA (cmsg); + printf ("iface %d %s %s\n", d->ipi_ifindex, + inet_ntoa(d->ipi_spec_dst), inet_ntoa (d->ipi_addr)); + } + } +#endif #if 0 ma_log ("Got %d bytes: 0x%x from %s\n", size, buf[0], inet_ntoa (recvaddr.sin_addr)); From 30885665022842d9633dc8937270c6da7fb60cb0 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 6 Aug 2011 18:57:53 +0900 Subject: [PATCH 044/334] Replace get_address() with get_iface_list(). --- libs/net/nm/net_udp.c | 69 +++++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 28 deletions(-) diff --git a/libs/net/nm/net_udp.c b/libs/net/nm/net_udp.c index 795092339..a8fa71b09 100644 --- a/libs/net/nm/net_udp.c +++ b/libs/net/nm/net_udp.c @@ -118,39 +118,50 @@ static unsigned myAddr; #include "net_udp.h" +static int num_ifaces; +uint32_t *ifaces; +uint32_t *default_iface; + static int -get_address (int sock) +get_iface_list (int sock) { - struct ifconf ifc; - struct ifreq *ifr; - char buf[8192]; - int i, n; - struct sockaddr_in *in_addr; - unsigned addr; + int ret; + int buflen; + struct ifconf ifconf; - ifc.ifc_len = sizeof (buf); - ifc.ifc_buf = buf; - - if (ioctl (sock, SIOCGIFCONF, &ifc) == -1) - return 0; - - ifr = ifc.ifc_req; - n = ifc.ifc_len / sizeof (struct ifreq); - - for (i = 0; i < n; i++) { - if (ioctl (sock, SIOCGIFADDR, &ifr[i]) == -1) - continue; - in_addr = (struct sockaddr_in *)&ifr[i].ifr_addr; - Sys_MaskPrintf (SYS_NET, "%s: %s\n", ifr[i].ifr_name, - inet_ntoa (in_addr->sin_addr)); - addr = *(unsigned *)&in_addr->sin_addr; - if (addr != htonl (0x7f000001)) { - myAddr = addr; + buflen = sizeof (*ifconf.ifc_req) * 4; + ifconf.ifc_req = 0; + do { + buflen *= 2; + ifconf.ifc_len = buflen; + ifconf.ifc_req = realloc (ifconf.ifc_req, ifconf.ifc_len); + if ((ret = ioctl (sock, SIOCGIFCONF, &ifconf)) < 0) { + Sys_MaskPrintf (SYS_NET, "ioctl: %s", strerror (errno)); break; } - } + } while (ifconf.ifc_len == buflen); - return 1; + if (ret >= 0) { + int i; + num_ifaces = ifconf.ifc_len / sizeof (*ifconf.ifc_req); + ifaces = malloc (num_ifaces * sizeof (int32_t)); + Sys_MaskPrintf (SYS_NET, "Interfaces (count = %d)\n", num_ifaces); + for (i = 0; i < num_ifaces; i++) { + struct sockaddr_in *sa; + + sa = (struct sockaddr_in *) &ifconf.ifc_req[i].ifr_ifru.ifru_addr; + Sys_MaskPrintf (SYS_NET, " %-10s %s\n", + ifconf.ifc_req[i].ifr_name, + inet_ntoa (sa->sin_addr)); + memcpy (&ifaces[i], &sa->sin_addr, sizeof (uint32_t)); + if (!default_iface && ifaces[i] != htonl (0x7f000001)) + default_iface = &ifaces[i]; + } + } + if (default_iface) + myAddr = *default_iface; + free (ifconf.ifc_req); + return ret; } int @@ -188,7 +199,7 @@ UDP_Init (void) if ((net_controlsocket = UDP_OpenSocket (0)) == -1) Sys_Error ("UDP_Init: Unable to open control socket"); - get_address (net_controlsocket); + get_iface_list (net_controlsocket); { struct sockaddr_in t; @@ -359,6 +370,8 @@ UDP_CheckNewConnections (void) if (available) return net_acceptsocket; // quietly absorb empty packets + // there is no way to tell between an empty packet and no packets, but + // as non-blocking io is used, this is not a problem. recvfrom (net_acceptsocket, buff, 0, 0, (struct sockaddr *) &from, &fromlen); return -1; From ae9404cc2714a47056a772a7f4c790291f3feb93 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 6 Aug 2011 20:30:56 +0900 Subject: [PATCH 045/334] Obtain the interface on which the packet arrived. Once I sort out just how to get the information to the right place, this should fix a lot of the problems with nq on multi-homed nodes. --- libs/net/nm/net_udp.c | 59 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 3 deletions(-) diff --git a/libs/net/nm/net_udp.c b/libs/net/nm/net_udp.c index a8fa71b09..2172a5a52 100644 --- a/libs/net/nm/net_udp.c +++ b/libs/net/nm/net_udp.c @@ -121,6 +121,7 @@ static unsigned myAddr; static int num_ifaces; uint32_t *ifaces; uint32_t *default_iface; +uint32_t *last_iface; static int get_iface_list (int sock) @@ -257,7 +258,10 @@ UDP_OpenSocket (int port) #define ioctl ioctlsocket unsigned long _true = true; #else - int _true = true; + int _true = true; +#endif +#ifdef HAVE_IN_PKTINFO + int ip_pktinfo = 1; #endif if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) @@ -265,6 +269,13 @@ UDP_OpenSocket (int port) if (ioctl (newsocket, FIONBIO, &_true) == -1) goto ErrorReturn; +#ifdef HAVE_IN_PKTINFO + if (setsockopt (newsocket, SOL_IP, IP_PKTINFO, &ip_pktinfo, + sizeof (ip_pktinfo)) == -1) { + close (newsocket); + return -1; + } +#endif address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; @@ -372,6 +383,7 @@ UDP_CheckNewConnections (void) // quietly absorb empty packets // there is no way to tell between an empty packet and no packets, but // as non-blocking io is used, this is not a problem. + // we don't care about the interface on which the packet arrived recvfrom (net_acceptsocket, buff, 0, 0, (struct sockaddr *) &from, &fromlen); return -1; @@ -380,13 +392,54 @@ UDP_CheckNewConnections (void) int UDP_Read (int socket, byte *buf, int len, struct qsockaddr *addr) { - socklen_t addrlen = sizeof (struct qsockaddr); int ret; +#ifdef HAVE_IN_PKTINFO + char ancillary[CMSG_SPACE (sizeof (struct in_pktinfo))]; + struct msghdr msghdr = { + addr, + sizeof (*addr), + 0, 0, + ancillary, + sizeof (ancillary), + 0 + }; + struct iovec iovec = {buf, len}; + struct cmsghdr *cmsg; + struct in_pktinfo *info = 0; + + msghdr.msg_iov = &iovec; + msghdr.msg_iovlen = 1; + ret = recvmsg (socket, &msghdr, 0); + if (ret == -1 && (errno == EWOULDBLOCK || errno == ECONNREFUSED)) + return 0; + for (cmsg = CMSG_FIRSTHDR (&msghdr); cmsg; + cmsg = CMSG_NXTHDR (&msghdr, cmsg)) { + Sys_MaskPrintf (SYS_NET, "%d\n", cmsg->cmsg_type); + if (cmsg->cmsg_type == IP_PKTINFO) { + info = (struct in_pktinfo *) CMSG_DATA (cmsg); + break; + } + } + last_iface = 0; + if (info) { + /* Our iterface list is 0 based, but the pktinfo interface index is 1 + * based. + */ + last_iface = &ifaces[info->ipi_ifindex - 1]; + } + Sys_MaskPrintf (SYS_NET, "got %d bytes from %s on iface %d (%s)\n", ret, + UDP_AddrToString (addr), info ? info->ipi_ifindex - 1 : -1, + last_iface ? inet_ntoa (info->ipi_addr) : "?"); +#else + socklen_t addrlen = sizeof (struct qsockaddr); ret = recvfrom (socket, buf, len, 0, (struct sockaddr *) addr, &addrlen); if (ret == -1 && (errno == EWOULDBLOCK || errno == ECONNREFUSED)) return 0; - Sys_MaskPrintf (SYS_NET, "got %d bytes from %s\n", ret, UDP_AddrToString (addr)); + Sys_MaskPrintf (SYS_NET, "got %d bytes from %s\n", ret, + UDP_AddrToString (addr)); + last_iface = default_iface; +#endif return ret; } From 805256ff657ca568f3e62d67f131798d603e0a1c Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 6 Aug 2011 21:47:57 +0900 Subject: [PATCH 046/334] Use the last used interface address for the socket address. This allows the correct address to be put in the server info packet allowing nq to work on multi-homed hosts. More testing needs to be done to ensure nothing is broken, or better yet, a rewrite of the networking code to properly associate the information with the packets. --- libs/net/nm/net_udp.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libs/net/nm/net_udp.c b/libs/net/nm/net_udp.c index 2172a5a52..1b9f5a7b8 100644 --- a/libs/net/nm/net_udp.c +++ b/libs/net/nm/net_udp.c @@ -514,8 +514,11 @@ UDP_GetSocketAddr (int socket, struct qsockaddr *addr) getsockname (socket, (struct sockaddr *) addr, &addrlen); a = ((struct sockaddr_in *) addr)->sin_addr.s_addr; - if (a == 0 || a == inet_addr ("127.0.0.1")) - ((struct sockaddr_in *) addr)->sin_addr.s_addr = myAddr; + if (a == 0 || a == inet_addr ("127.0.0.1")) { + ((struct sockaddr_in *) addr)->sin_addr.s_addr = *default_iface; + if (last_iface) + ((struct sockaddr_in *) addr)->sin_addr.s_addr = *last_iface; + } return 0; } From ff857a9c7145db06306106a2a45f0c3e2a192fe3 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 11 Aug 2011 14:22:27 +0900 Subject: [PATCH 047/334] Permit control of single character tokens. --- include/QF/script.h | 4 ++++ libs/util/script.c | 2 ++ 2 files changed, 6 insertions(+) diff --git a/include/QF/script.h b/include/QF/script.h index ce8194eab..bc11b0e2a 100644 --- a/include/QF/script.h +++ b/include/QF/script.h @@ -45,6 +45,10 @@ typedef struct script_s { void (*error)(struct script_s *script, const char *msg); /// if set, multi line quoted tokens will be treated as errors int no_quote_lines; + /// if set, characters in this string will always be lexed as single + /// character tokens. If not set, defaults to "{}()':". Set to "" + /// (empty string) to disable. Not set by default. + const char *single; } script_t; /** Return a new script_t object. diff --git a/libs/util/script.c b/libs/util/script.c index 6f8a65f57..f78f427a1 100644 --- a/libs/util/script.c +++ b/libs/util/script.c @@ -159,6 +159,8 @@ Script_GetToken (script_t *script, qboolean crossline) } else { const char *single = "{}()':"; + if (script->single) + single = script->single; token_p = script->p; if (strchr (single, *script->p)) { script->p++; From 5d52810b9cbac1bdeb6accb1580bcf6affd09666 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 11 Aug 2011 14:23:25 +0900 Subject: [PATCH 048/334] Disable single character tokens when parsing old save games. --- nq/source/host_cmd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/nq/source/host_cmd.c b/nq/source/host_cmd.c index 52b2ce17c..15c518702 100644 --- a/nq/source/host_cmd.c +++ b/nq/source/host_cmd.c @@ -639,6 +639,7 @@ Host_Loadgame_f (void) Qclose (f); script = Script_New (); + script->single = ""; // disable {}()': lexing Script_Start (script, name->str, script_data); Script_GetToken (script, 1); From e42c5a4272fe30f173c5087e02ce8efbe919cebf Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 11 Aug 2011 14:58:13 +0900 Subject: [PATCH 049/334] More tests and fix vector/quaternion global dumps. --- tools/qfcc/source/dump_globals.c | 4 ++-- tools/qfcc/test/cast2.r | 9 +++++++++ tools/qfcc/test/class-end.r | 23 +++++++++++++++++++++++ tools/qfcc/test/const.r | 2 ++ tools/qfcc/test/field-alias.r | 11 +++++++++++ tools/qfcc/test/self-this.r | 6 ++++++ tools/qfcc/test/value.r | 7 +++++++ tools/qfcc/test/vector2.r | 13 +++++++++++++ 8 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 tools/qfcc/test/cast2.r create mode 100644 tools/qfcc/test/class-end.r create mode 100644 tools/qfcc/test/const.r create mode 100644 tools/qfcc/test/field-alias.r create mode 100644 tools/qfcc/test/self-this.r create mode 100644 tools/qfcc/test/vector2.r diff --git a/tools/qfcc/source/dump_globals.c b/tools/qfcc/source/dump_globals.c index d2c4702a6..c42ab10d7 100644 --- a/tools/qfcc/source/dump_globals.c +++ b/tools/qfcc/source/dump_globals.c @@ -89,7 +89,7 @@ dump_def (progs_t *pr, ddef_t *def, int indent) comment = va (" %g", G_FLOAT (pr, offset)); break; case ev_vector: - comment = va (" '%g %g %g", + comment = va (" '%g %g %g'", G_VECTOR (pr, offset)[0], G_VECTOR (pr, offset)[1], G_VECTOR (pr, offset)[2]); @@ -118,7 +118,7 @@ dump_def (progs_t *pr, ddef_t *def, int indent) comment = va (" %x", G_INT (pr, offset)); break; case ev_quat: - comment = va (" '%g %g %g %g", + comment = va (" '%g %g %g %g'", G_QUAT (pr, offset)[0], G_QUAT (pr, offset)[1], G_QUAT (pr, offset)[2], diff --git a/tools/qfcc/test/cast2.r b/tools/qfcc/test/cast2.r new file mode 100644 index 000000000..0427a4221 --- /dev/null +++ b/tools/qfcc/test/cast2.r @@ -0,0 +1,9 @@ +void foo (vector x) +{ + entity *ep; + int d; + + //d = (int) x.y; + //ep = (entity *) d; + ep = (entity *) (int) x.y; +} diff --git a/tools/qfcc/test/class-end.r b/tools/qfcc/test/class-end.r new file mode 100644 index 000000000..02dfc1017 --- /dev/null +++ b/tools/qfcc/test/class-end.r @@ -0,0 +1,23 @@ +@interface foo +-init; +@end + +@implementation foo +-init +{ + return self; +} + +@protocol baz +-blah; +@end + +@interface bar +-init; +@end + +@implementation bar +-init +{ + return self; +} diff --git a/tools/qfcc/test/const.r b/tools/qfcc/test/const.r new file mode 100644 index 000000000..961b83d43 --- /dev/null +++ b/tools/qfcc/test/const.r @@ -0,0 +1,2 @@ +int x = 3; +float y = 4; diff --git a/tools/qfcc/test/field-alias.r b/tools/qfcc/test/field-alias.r new file mode 100644 index 000000000..a333f2ba2 --- /dev/null +++ b/tools/qfcc/test/field-alias.r @@ -0,0 +1,11 @@ +.int blah; +.void () think; +.SEL thinkMethod = think; + +void foo (entity e) +{ + *(SEL *)&e.think = @selector(foo:); + e.thinkMethod = @selector(foo:); +} +void __obj_exec_class (obj_module_t *msg) = #0; + diff --git a/tools/qfcc/test/self-this.r b/tools/qfcc/test/self-this.r new file mode 100644 index 000000000..12860140f --- /dev/null +++ b/tools/qfcc/test/self-this.r @@ -0,0 +1,6 @@ +.int a; + +void f(void) +{ + @self.@this = nil; +} diff --git a/tools/qfcc/test/value.r b/tools/qfcc/test/value.r index 816b3ff51..96b357d50 100644 --- a/tools/qfcc/test/value.r +++ b/tools/qfcc/test/value.r @@ -1,9 +1,16 @@ float VAL1 = 4; float VAL2 = 6; +vector VMIN = '-16 -16 -24'; +vector VMAX = '16 16 32'; +vector v; void send (float to, ...) = #0; void do_something () { + vector a; + + a = VMIN; + a = VMAX; send (VAL1, VAL2); } diff --git a/tools/qfcc/test/vector2.r b/tools/qfcc/test/vector2.r new file mode 100644 index 000000000..4b9aa031a --- /dev/null +++ b/tools/qfcc/test/vector2.r @@ -0,0 +1,13 @@ +vector a; +entity e; +.vector v; + +float foo (void) +{ + a.z += 3; + a_z += 3; + e.v = a; + e.v.y = 2; + e.v_y = 2; + return e.v.z; +} From d3c2afc5d7ae0e02f7399a2ea15df4218559c6c7 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 11 Aug 2011 15:36:51 +0900 Subject: [PATCH 050/334] Handle old global vector compontents. In the original save gave format, global vectors were saved as individual components rather than as a single vector, using the _x/_y/_z tags on the vector name. However, recent qfcc completely dumped vector components as separate defs, so old save games would have trouble loading with progs built with a recent qfcc. Thus, do the component translation if necessary. --- libs/gamecode/engine/pr_parse.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/libs/gamecode/engine/pr_parse.c b/libs/gamecode/engine/pr_parse.c index 64037fcb6..d7c4d39c2 100644 --- a/libs/gamecode/engine/pr_parse.c +++ b/libs/gamecode/engine/pr_parse.c @@ -342,6 +342,7 @@ ED_ConvertToPlist (progs_t *pr, script_t *script) VISIBLE void ED_InitGlobals (progs_t *pr, plitem_t *globals) { + ddef_t vector_def; ddef_t *global; plitem_t *keys; int count; @@ -354,6 +355,28 @@ ED_InitGlobals (progs_t *pr, plitem_t *globals) global_name = PL_String (PL_ObjectAtIndex (keys, count)); value = PL_String (PL_ObjectForKey (globals, global_name)); global = PR_FindGlobal (pr, global_name); + //FIXME should this be here? + //This is a hardcoded fix for a design mistake in the original qcc + //(saving global vector components rather than the whole vector). + if (!global) { + int len = strlen (global_name); + const char *tag = global_name + len - 2; + if (len > 2 && tag[0] == '_' && strchr ("xyz", tag[1])) { + char *vector_name = strdup (global_name); + vector_name[len - 2] = 0; + global = PR_FindGlobal (pr, vector_name); + if (global) { + if ((global->type & ~DEF_SAVEGLOBAL) == ev_vector) { + vector_def = *global; + vector_def.ofs += tag[1] - 'x'; + vector_def.type = ev_float; + global = &vector_def; + } else { + global = 0; + } + } + } + } if (!global) { Sys_Printf ("'%s' is not a global\n", global_name); continue; From 290ac30efc7a8dc5daa163ed3e7a8bc0d50e615c Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 11 Aug 2011 16:08:20 +0900 Subject: [PATCH 051/334] Fix x11 gamma control. Seems we lost a header include at one stage. --- libs/video/targets/context_x11.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libs/video/targets/context_x11.c b/libs/video/targets/context_x11.c index ffc409cbd..a7bae5570 100644 --- a/libs/video/targets/context_x11.c +++ b/libs/video/targets/context_x11.c @@ -61,6 +61,11 @@ static __attribute__ ((used)) const char rcsid[] = #ifdef HAVE_VIDMODE # include +# ifdef DGA_OLD_HEADERS +# include +# else +# include +# endif #endif #include "QF/cmd.h" From 5feb0454ca22f1414e9acba5b150f638b4fb252a Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 11 Aug 2011 17:20:33 +0900 Subject: [PATCH 052/334] Add and use SYS_SND for both sound and cd debug prints. --- include/QF/sys.h | 1 + libs/audio/cd_linux.c | 26 +++++++++++++------------- libs/audio/cd_sdl.c | 10 +++++----- libs/audio/cd_sgi.c | 16 ++++++++-------- libs/audio/cd_win.c | 30 +++++++++++++++--------------- libs/audio/cd_xmms.c | 2 +- libs/audio/targets/snd_win.c | 2 +- 7 files changed, 44 insertions(+), 43 deletions(-) diff --git a/include/QF/sys.h b/include/QF/sys.h index 5b6d6389d..e4663c9cb 100644 --- a/include/QF/sys.h +++ b/include/QF/sys.h @@ -86,6 +86,7 @@ void Sys_MaskPrintf (int mask, const char *fmt, ...) __attribute__((format(print #define SYS_NET (1|64) #define SYS_RUA_OBJ (1|128) #define SYS_RUA_MSG (1|256) +#define SYS_SND (1|512) int Sys_CheckInput (int idle, int net_socket); const char *Sys_ConsoleInput (void); diff --git a/libs/audio/cd_linux.c b/libs/audio/cd_linux.c index aeae950fd..c6904d2c8 100644 --- a/libs/audio/cd_linux.c +++ b/libs/audio/cd_linux.c @@ -89,7 +89,7 @@ I_CDAudio_CloseDoor (void) return; // no cd init'd if (ioctl (cdfile, CDROMCLOSETRAY) == -1) - Sys_MaskPrintf (SYS_DEV, "CDAudio: ioctl cdromclosetray failed\n"); + Sys_MaskPrintf (SYS_SND, "CDAudio: ioctl cdromclosetray failed\n"); } static void @@ -99,7 +99,7 @@ I_CDAudio_Eject (void) return; // no cd init'd if (ioctl (cdfile, CDROMEJECT) == -1) - Sys_MaskPrintf (SYS_DEV, "CDAudio: ioctl cdromeject failed\n"); + Sys_MaskPrintf (SYS_SND, "CDAudio: ioctl cdromeject failed\n"); } static int @@ -110,12 +110,12 @@ I_CDAudio_GetAudioDiskInfo (void) cdValid = false; if (ioctl (cdfile, CDROMREADTOCHDR, &tochdr) == -1) { - Sys_MaskPrintf (SYS_DEV, "CDAudio: ioctl cdromreadtochdr failed\n"); + Sys_MaskPrintf (SYS_SND, "CDAudio: ioctl cdromreadtochdr failed\n"); return -1; } if (tochdr.cdth_trk0 < 1) { - Sys_MaskPrintf (SYS_DEV, "CDAudio: no music tracks\n"); + Sys_MaskPrintf (SYS_SND, "CDAudio: no music tracks\n"); return -1; } @@ -135,7 +135,7 @@ I_CDAudio_Pause (void) return; if (ioctl (cdfile, CDROMPAUSE) == -1) - Sys_MaskPrintf (SYS_DEV, "CDAudio: ioctl cdrompause failed\n"); + Sys_MaskPrintf (SYS_SND, "CDAudio: ioctl cdrompause failed\n"); wasPlaying = playing; playing = false; @@ -151,7 +151,7 @@ I_CDAudio_Stop (void) return; if (ioctl (cdfile, CDROMSTOP) == -1) - Sys_MaskPrintf (SYS_DEV, "CDAudio: ioctl cdromstop failed (%d)\n", + Sys_MaskPrintf (SYS_SND, "CDAudio: ioctl cdromstop failed (%d)\n", errno); wasPlaying = false; @@ -189,7 +189,7 @@ I_CDAudio_Play (int track, qboolean looping) entry0.cdte_track = track; entry0.cdte_format = CDROM_MSF; if (ioctl (cdfile, CDROMREADTOCENTRY, &entry0) == -1) { - Sys_MaskPrintf (SYS_DEV, "CDAudio: ioctl cdromreadtocentry failed\n"); + Sys_MaskPrintf (SYS_SND, "CDAudio: ioctl cdromreadtocentry failed\n"); return; } entry1.cdte_track = track + 1; @@ -198,7 +198,7 @@ I_CDAudio_Play (int track, qboolean looping) entry1.cdte_track = CDROM_LEADOUT; } if (ioctl (cdfile, CDROMREADTOCENTRY, &entry1) == -1) { - Sys_MaskPrintf (SYS_DEV, "CDAudio: ioctl cdromreadtocentry failed\n"); + Sys_MaskPrintf (SYS_SND, "CDAudio: ioctl cdromreadtocentry failed\n"); return; } if (entry0.cdte_ctrl == CDROM_DATA_TRACK) { @@ -220,14 +220,14 @@ I_CDAudio_Play (int track, qboolean looping) msf.cdmsf_sec1 = entry1.cdte_addr.msf.second; msf.cdmsf_frame1 = entry1.cdte_addr.msf.frame; - Sys_MaskPrintf (SYS_DEV, "%2d:%02d:%02d %2d:%02d:%02d\n", + Sys_MaskPrintf (SYS_SND, "%2d:%02d:%02d %2d:%02d:%02d\n", msf.cdmsf_min0, msf.cdmsf_sec0, msf.cdmsf_frame0, msf.cdmsf_min1, msf.cdmsf_sec1, msf.cdmsf_frame1); if (ioctl (cdfile, CDROMPLAYMSF, &msf) == -1) { - Sys_MaskPrintf (SYS_DEV, + Sys_MaskPrintf (SYS_SND, "CDAudio: ioctl cdromplaytrkind failed (%s)\n", strerror (errno)); return; @@ -254,7 +254,7 @@ I_CDAudio_Resume (void) return; if (ioctl (cdfile, CDROMRESUME) == -1) - Sys_MaskPrintf (SYS_DEV, "CDAudio: ioctl cdromresume failed\n"); + Sys_MaskPrintf (SYS_SND, "CDAudio: ioctl cdromresume failed\n"); playing = true; } @@ -399,7 +399,7 @@ I_CDAudio_Update (void) lastchk = time (NULL) + 2; // two seconds between chks subchnl.cdsc_format = CDROM_MSF; if (ioctl (cdfile, CDROMSUBCHNL, &subchnl) == -1) { - Sys_MaskPrintf (SYS_DEV, "CDAudio: ioctl cdromsubchnl failed\n"); + Sys_MaskPrintf (SYS_SND, "CDAudio: ioctl cdromsubchnl failed\n"); playing = false; return; } @@ -424,7 +424,7 @@ Mus_CDChange (cvar_t *mus_cdaudio) cdfile = open (mus_cdaudio->string, O_RDONLY | O_NONBLOCK); if (cdfile == -1) { - Sys_MaskPrintf (SYS_DEV, + Sys_MaskPrintf (SYS_SND, "Mus_CDInit: open device \"%s\" failed (error %i)\n", mus_cdaudio->string, errno); return; diff --git a/libs/audio/cd_sdl.c b/libs/audio/cd_sdl.c index e24e0cc3a..cd420d944 100644 --- a/libs/audio/cd_sdl.c +++ b/libs/audio/cd_sdl.c @@ -75,7 +75,7 @@ I_CDAudio_Eject (void) return; if (SDL_CDEject (cd_id)) - Sys_MaskPrintf (SYS_DEV, "Unable to eject CD-ROM tray.\n"); + Sys_MaskPrintf (SYS_SND, "Unable to eject CD-ROM tray.\n"); } static void @@ -87,7 +87,7 @@ I_CDAudio_Pause (void) return; if (SDL_CDPause (cd_id)) - Sys_MaskPrintf (SYS_DEV, "CDAudio_Pause: Failed to pause track.\n"); + Sys_MaskPrintf (SYS_SND, "CDAudio_Pause: Failed to pause track.\n"); } static void @@ -102,7 +102,7 @@ I_CDAudio_Stop (void) return; if (SDL_CDStop (cd_id)) - Sys_MaskPrintf (SYS_DEV, "CDAudio_Stop: Failed to stop track.\n"); + Sys_MaskPrintf (SYS_SND, "CDAudio_Stop: Failed to stop track.\n"); } static void @@ -135,7 +135,7 @@ I_CDAudio_Play (int track, qboolean looping) if (SDL_CDPlay (cd_id, cd_id->track[track].offset, cd_id->track[track].length)) { - Sys_MaskPrintf (SYS_DEV, "CDAudio_Play: Unable to play track: %d\n", + Sys_MaskPrintf (SYS_SND, "CDAudio_Play: Unable to play track: %d\n", track + 1); return; } @@ -151,7 +151,7 @@ I_CDAudio_Resume (void) return; if (SDL_CDResume (cd_id)) - Sys_MaskPrintf (SYS_DEV, "CDAudio_Resume: Failed tp resume track.\n"); + Sys_MaskPrintf (SYS_SND, "CDAudio_Resume: Failed tp resume track.\n"); } static void diff --git a/libs/audio/cd_sgi.c b/libs/audio/cd_sgi.c index 9209dd563..ae88bc207 100644 --- a/libs/audio/cd_sgi.c +++ b/libs/audio/cd_sgi.c @@ -73,7 +73,7 @@ I_SGI_Eject (void) return; // no cd init'd if (CDeject (cdp) == 0) - Sys_MaskPrintf (SYS_DEV, "I_SGI_Eject: CDeject failed\n"); + Sys_MaskPrintf (SYS_SND, "I_SGI_Eject: CDeject failed\n"); } static int @@ -85,7 +85,7 @@ I_SGI_GetState (void) return -1; // no cd init'd if (CDgetstatus (cdp, &cds) == 0) { - Sys_MaskPrintf (SYS_DEV, "CDAudio_GetStatus: CDgetstatus failed\n"); + Sys_MaskPrintf (SYS_SND, "CDAudio_GetStatus: CDgetstatus failed\n"); return -1; } @@ -101,7 +101,7 @@ I_SGI_MaxTrack (void) return -1; // no cd init'd if (CDgetstatus (cdp, &cds) == 0) { - Sys_MaskPrintf (SYS_DEV, "I_SGI_MaxTrack: CDgetstatus failed\n"); + Sys_MaskPrintf (SYS_SND, "I_SGI_MaxTrack: CDgetstatus failed\n"); return -1; } @@ -115,7 +115,7 @@ I_SGI_Pause (void) return; if (CDtogglepause (cdp) == 0) - Sys_MaskPrintf (SYS_DEV, "CDAudio_PAUSE: CDtogglepause failed (%d)\n", errno); + Sys_MaskPrintf (SYS_SND, "CDAudio_PAUSE: CDtogglepause failed (%d)\n", errno); } void @@ -133,7 +133,7 @@ I_SGI_Play (int track, qboolean looping) } if (maxtrack < 0) { - Sys_MaskPrintf (SYS_DEV, + Sys_MaskPrintf (SYS_SND, "CDAudio_Play: Error getting maximum track number\n"); return; } @@ -173,7 +173,7 @@ I_SGI_Play (int track, qboolean looping) } if (CDplaytrack (cdp, track, cdvolume == 0.0 ? 0 : 1) == 0) { - Sys_MaskPrintf (SYS_DEV, "CDAudio_Play: CDplay failed (%d)\n", errno); + Sys_MaskPrintf (SYS_SND, "CDAudio_Play: CDplay failed (%d)\n", errno); return; } @@ -188,7 +188,7 @@ I_SGI_Resume (void) return; if (CDtogglepause (cdp) == 0) - Sys_MaskPrintf (SYS_DEV, "CDAudio_Resume: CDtogglepause failed (%d)\n", + Sys_MaskPrintf (SYS_SND, "CDAudio_Resume: CDtogglepause failed (%d)\n", errno); } @@ -211,7 +211,7 @@ I_SGI_Stop (void) return; if (CDstop (cdp) == 0) - Sys_MaskPrintf (SYS_DEV, "I_SGI_Stop: CDStop failed (%d)\n", errno); + Sys_MaskPrintf (SYS_SND, "I_SGI_Stop: CDStop failed (%d)\n", errno); } void diff --git a/libs/audio/cd_win.c b/libs/audio/cd_win.c index c1bfd0a36..b222d8b91 100644 --- a/libs/audio/cd_win.c +++ b/libs/audio/cd_win.c @@ -77,7 +77,7 @@ I_CDAudio_CloseDoor (void) dwReturn = mciSendCommand (wDeviceID, MCI_SET, MCI_SET_DOOR_CLOSED, (DWORD_PTR) NULL); if (dwReturn) { - Sys_MaskPrintf (SYS_DEV, "MCI_SET_DOOR_CLOSED failed (%li)\n", + Sys_MaskPrintf (SYS_SND, "MCI_SET_DOOR_CLOSED failed (%li)\n", dwReturn); } } @@ -90,7 +90,7 @@ I_CDAudio_Eject (void) dwReturn = mciSendCommand (wDeviceID, MCI_SET, MCI_SET_DOOR_OPEN, (DWORD_PTR) NULL); if (dwReturn) { - Sys_MaskPrintf (SYS_DEV, "MCI_SET_DOOR_OPEN failed (%li)\n", dwReturn); + Sys_MaskPrintf (SYS_SND, "MCI_SET_DOOR_OPEN failed (%li)\n", dwReturn); } } @@ -107,12 +107,12 @@ I_CDAudio_GetAudioDiskInfo (void) mciSendCommand (wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_WAIT, (DWORD_PTR) (LPVOID) & mciStatusParms); if (dwReturn) { - Sys_MaskPrintf (SYS_DEV, + Sys_MaskPrintf (SYS_SND, "CDAudio: drive ready test - get status failed\n"); return -1; } if (!mciStatusParms.dwReturn) { - Sys_MaskPrintf (SYS_DEV, "CDAudio: drive not ready\n"); + Sys_MaskPrintf (SYS_SND, "CDAudio: drive not ready\n"); return -1; } @@ -121,11 +121,11 @@ I_CDAudio_GetAudioDiskInfo (void) mciSendCommand (wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_WAIT, (DWORD_PTR) (LPVOID) & mciStatusParms); if (dwReturn) { - Sys_MaskPrintf (SYS_DEV, "CDAudio: get tracks - status failed\n"); + Sys_MaskPrintf (SYS_SND, "CDAudio: get tracks - status failed\n"); return -1; } if (mciStatusParms.dwReturn < 1) { - Sys_MaskPrintf (SYS_DEV, "CDAudio: no music tracks\n"); + Sys_MaskPrintf (SYS_SND, "CDAudio: no music tracks\n"); return -1; } @@ -156,13 +156,13 @@ static I_CDAudio_MessageHandler (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPa break; case MCI_NOTIFY_FAILURE: - Sys_MaskPrintf (SYS_DEV, "MCI_NOTIFY_FAILURE\n"); + Sys_MaskPrintf (SYS_SND, "MCI_NOTIFY_FAILURE\n"); I_CDAudio_Stop (); cdValid = false; break; default: - Sys_MaskPrintf (SYS_DEV, "Unexpected MM_MCINOTIFY type (%i)\n", + Sys_MaskPrintf (SYS_SND, "Unexpected MM_MCINOTIFY type (%i)\n", wParam); return 1; } @@ -187,7 +187,7 @@ I_CDAudio_Pause (void) mciSendCommand (wDeviceID, MCI_PAUSE, 0, (DWORD_PTR) (LPVOID) & mciGenericParms); if (dwReturn) { - Sys_MaskPrintf (SYS_DEV, "MCI_PAUSE failed (%li)", dwReturn); + Sys_MaskPrintf (SYS_SND, "MCI_PAUSE failed (%li)", dwReturn); } wasPlaying = playing; @@ -228,7 +228,7 @@ I_CDAudio_Play (int track, qboolean looping) MCI_STATUS_ITEM | MCI_TRACK | MCI_WAIT, (DWORD_PTR) (LPVOID) & mciStatusParms); if (dwReturn) { - Sys_MaskPrintf (SYS_DEV, "MCI_STATUS failed (%li)\n", dwReturn); + Sys_MaskPrintf (SYS_SND, "MCI_STATUS failed (%li)\n", dwReturn); return; } if (mciStatusParms.dwReturn != MCI_CDA_TRACK_AUDIO) { @@ -243,7 +243,7 @@ I_CDAudio_Play (int track, qboolean looping) MCI_STATUS_ITEM | MCI_TRACK | MCI_WAIT, (DWORD_PTR) (LPVOID) & mciStatusParms); if (dwReturn) { - Sys_MaskPrintf (SYS_DEV, "MCI_STATUS failed (%li)\n", dwReturn); + Sys_MaskPrintf (SYS_SND, "MCI_STATUS failed (%li)\n", dwReturn); return; } @@ -260,7 +260,7 @@ I_CDAudio_Play (int track, qboolean looping) mciSendCommand (wDeviceID, MCI_PLAY, MCI_NOTIFY | MCI_FROM | MCI_TO, (DWORD_PTR) (LPVOID) & mciPlayParms); if (dwReturn) { - Sys_MaskPrintf (SYS_DEV, "CDAudio: MCI_PLAY failed (%li)\n", dwReturn); + Sys_MaskPrintf (SYS_SND, "CDAudio: MCI_PLAY failed (%li)\n", dwReturn); return; } @@ -292,7 +292,7 @@ I_CDAudio_Resume (void) mciSendCommand (wDeviceID, MCI_PLAY, MCI_TO | MCI_NOTIFY, (DWORD_PTR) (LPVOID) & mciPlayParms); if (dwReturn) { - Sys_MaskPrintf (SYS_DEV, "CDAudio: MCI_PLAY failed (%li)\n", dwReturn); + Sys_MaskPrintf (SYS_SND, "CDAudio: MCI_PLAY failed (%li)\n", dwReturn); return; } playing = true; @@ -305,7 +305,7 @@ I_CDAudio_Shutdown (void) return; I_CDAudio_Stop (); if (mciSendCommand (wDeviceID, MCI_CLOSE, MCI_WAIT, (DWORD_PTR) NULL)) - Sys_MaskPrintf (SYS_DEV, "CDAudio_Shutdown: MCI_CLOSE failed\n"); + Sys_MaskPrintf (SYS_SND, "CDAudio_Shutdown: MCI_CLOSE failed\n"); } static void @@ -320,7 +320,7 @@ I_CDAudio_Stop (void) dwReturn = mciSendCommand (wDeviceID, MCI_STOP, 0, (DWORD_PTR) NULL); if (dwReturn) { - Sys_MaskPrintf (SYS_DEV, "MCI_STOP failed (%li)", dwReturn); + Sys_MaskPrintf (SYS_SND, "MCI_STOP failed (%li)", dwReturn); } wasPlaying = false; diff --git a/libs/audio/cd_xmms.c b/libs/audio/cd_xmms.c index c9ed2126f..774ba5962 100644 --- a/libs/audio/cd_xmms.c +++ b/libs/audio/cd_xmms.c @@ -152,7 +152,7 @@ I_XMMS_Running (void) break; case -1: // ICH! // inform user - Sys_MaskPrintf (SYS_DEV, "XMMSAudio: error, can't fork!?\n"); + Sys_MaskPrintf (SYS_SND, "XMMSAudio: error, can't fork!?\n"); break; default: // Parent // don't need now :/ diff --git a/libs/audio/targets/snd_win.c b/libs/audio/targets/snd_win.c index 80d5beb04..df46dcab5 100644 --- a/libs/audio/targets/snd_win.c +++ b/libs/audio/targets/snd_win.c @@ -316,7 +316,7 @@ SNDDMA_Submit (void) // find which sound blocks have completed while (1) { if (snd_completed == snd_sent) { - Sys_MaskPrintf (SYS_DEV, "Sound overrun\n"); + Sys_MaskPrintf (SYS_SND, "Sound overrun\n"); break; } From c1a60551ae1ab55d9d7d3c14b901865860203a27 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 11 Aug 2011 17:22:14 +0900 Subject: [PATCH 053/334] Clean up default rate setting and add explicit support for 48kHz. --- libs/audio/targets/snd_alsa.c | 44 +++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/libs/audio/targets/snd_alsa.c b/libs/audio/targets/snd_alsa.c index 8c778a40a..81e337365 100644 --- a/libs/audio/targets/snd_alsa.c +++ b/libs/audio/targets/snd_alsa.c @@ -237,32 +237,36 @@ SNDDMA_Init (void) switch (rate) { case 0: - rate = 44100; - err = qfsnd_pcm_hw_params_set_rate_near (pcm, hw, &rate, 0); - if (0 <= err) { - frag_size = 32 * bps; - } else { - rate = 22050; - err = qfsnd_pcm_hw_params_set_rate_near (pcm, hw, &rate, 0); - if (0 <= err) { - frag_size = 16 * bps; - } else { - rate = 11025; - err = qfsnd_pcm_hw_params_set_rate_near (pcm, hw, &rate, - 0); + { + int rates[] = { + 48000, + 44100, + 22050, + 11025, + 0 + }; + int i; + + for (i = 0; rates[i]; i++) { + rate = rates[i]; + Sys_MaskPrintf (SYS_SND, "ALSA: trying %dHz\n", rate); + err = qfsnd_pcm_hw_params_set_rate_near (pcm, hw, + &rate, 0); if (0 <= err) { - frag_size = 8 * bps; - } else { - Sys_Printf ("ALSA: no usable rates. %s\n", - qfsnd_strerror (err)); - goto error; + frag_size = 8 * bps * (rate / 11025); + break; } } - } - break; + if (!rates[i]) { + Sys_Printf ("ALSA: no usable rates. %s\n", + qfsnd_strerror (err)); + goto error; + } + } break; case 11025: case 22050: case 44100: + case 48000: default: err = qfsnd_pcm_hw_params_set_rate_near (pcm, hw, &rate, 0); if (0 > err) { From 4cec4b9f96caf0b2bb5c3e39e8cd1767b34156ff Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 11 Aug 2011 18:32:39 +0900 Subject: [PATCH 054/334] Rewrite the interface detection code. Turns out SIOCGIFCONF is rather painful to get working cross-platform. This should work better, and can be used even with ipv6 :) --- config.d/header_files.m4 | 8 ++-- config.d/networking.m4 | 13 ++++++ libs/net/nm/net_udp.c | 87 +++++++++++++++++++++++----------------- 3 files changed, 67 insertions(+), 41 deletions(-) diff --git a/config.d/header_files.m4 b/config.d/header_files.m4 index a9cd4da1f..2f8bd6861 100644 --- a/config.d/header_files.m4 +++ b/config.d/header_files.m4 @@ -10,10 +10,10 @@ AC_CHECK_HEADERS( alloca.h arpa/inet.h asm/io.h assert.h conio.h \ ctype.h ddraw.h dinput.h direct.h dirent.h dlfcn.h dmedia/audio.h \ dmedia/cdaudio.h dpmi.h dsound.h errno.h execinfo.h fcntl.h io.h \ - libc.h limits.h linux/cdrom.h linux/joystick.h linux/soundcard.h \ - machine/soundcard.h malloc.h math.h mgraph.h _mingw.h netdb.h \ - netinet/in.h process.h pthread.h pwd.h rpc/types.h setjmp.h signal.h \ - stdarg.h stdio.h stdlib.h string.h strings.h sys/asoundlib.h \ + ifaddrs.h libc.h limits.h linux/cdrom.h linux/joystick.h \ + linux/soundcard.h machine/soundcard.h malloc.h math.h mgraph.h _mingw.h \ + netdb.h netinet/in.h process.h pthread.h pwd.h rpc/types.h setjmp.h \ + signal.h stdarg.h stdio.h stdlib.h string.h strings.h sys/asoundlib.h \ sys/audioio.h sys/filio.h sys/ioctl.h sys/io.h sys/ipc.h sys/mman.h \ sys/param.h sys/poll.h sys/shm.h sys/signal.h sys/socket.h \ sys/soundcard.h sys/stat.h sys/time.h sys/types.h sys/uio.h termios.h \ diff --git a/config.d/networking.m4 b/config.d/networking.m4 index 1ed5a9d52..815bce859 100644 --- a/config.d/networking.m4 +++ b/config.d/networking.m4 @@ -79,3 +79,16 @@ connect (0, NULL, 42); LIBS="$SAVELIBS" fi AC_SUBST(NET_LIBS) + +AC_MSG_CHECKING([for getifaddrs]) +SAVELIBS="$LIBS" +LIBS="$LIBS $NET_LIBS" +AC_TRY_LINK([], + [ +getifaddrs (0); + ], + AC_DEFINE(HAVE_GETIFADDRS, 1, [Define this if you have getifaddrs()]) + AC_MSG_RESULT(yes), + AC_MSG_RESULT(no) +) +LIBS="$SAVELIBS" diff --git a/libs/net/nm/net_udp.c b/libs/net/nm/net_udp.c index 1b9f5a7b8..d705ac04e 100644 --- a/libs/net/nm/net_udp.c +++ b/libs/net/nm/net_udp.c @@ -52,6 +52,9 @@ static __attribute__ ((used)) const char rcsid[] = #ifdef HAVE_NETDB_H # include #endif +#ifdef HAVE_IFADDRS_H +# include +#endif #ifdef HAVE_SYS_PARAM_H # include #endif @@ -114,7 +117,7 @@ static int net_controlsocket; static int net_broadcastsocket = 0; static struct qsockaddr broadcastaddr; -static unsigned myAddr; +static uint32_t myAddr; #include "net_udp.h" @@ -126,43 +129,53 @@ uint32_t *last_iface; static int get_iface_list (int sock) { - int ret; - int buflen; - struct ifconf ifconf; +#ifdef HAVE_GETIFADDRS + struct ifaddrs *ifa_head; + struct ifaddrs *ifa; + struct ifreq ifreq; - buflen = sizeof (*ifconf.ifc_req) * 4; - ifconf.ifc_req = 0; - do { - buflen *= 2; - ifconf.ifc_len = buflen; - ifconf.ifc_req = realloc (ifconf.ifc_req, ifconf.ifc_len); - if ((ret = ioctl (sock, SIOCGIFCONF, &ifconf)) < 0) { - Sys_MaskPrintf (SYS_NET, "ioctl: %s", strerror (errno)); - break; - } - } while (ifconf.ifc_len == buflen); - - if (ret >= 0) { - int i; - num_ifaces = ifconf.ifc_len / sizeof (*ifconf.ifc_req); - ifaces = malloc (num_ifaces * sizeof (int32_t)); - Sys_MaskPrintf (SYS_NET, "Interfaces (count = %d)\n", num_ifaces); - for (i = 0; i < num_ifaces; i++) { - struct sockaddr_in *sa; - - sa = (struct sockaddr_in *) &ifconf.ifc_req[i].ifr_ifru.ifru_addr; - Sys_MaskPrintf (SYS_NET, " %-10s %s\n", - ifconf.ifc_req[i].ifr_name, - inet_ntoa (sa->sin_addr)); - memcpy (&ifaces[i], &sa->sin_addr, sizeof (uint32_t)); - if (!default_iface && ifaces[i] != htonl (0x7f000001)) - default_iface = &ifaces[i]; - } + if (getifaddrs (&ifa_head) < 0) + goto no_ifaddrs; + for (ifa = ifa_head; ifa; ifa = ifa->ifa_next) { + if (!ifa->ifa_flags & IFF_UP) + continue; + if (!ifa->ifa_addr || ifa->ifa_addr->sa_family != AF_INET) + continue; + strncpy (ifreq.ifr_name, ifa->ifa_name, IFNAMSIZ); + ifreq.ifr_name[IFNAMSIZ - 1] = 0; + ioctl (sock, SIOCGIFINDEX, (char*) &ifreq); + if (ifreq.ifr_ifindex > num_ifaces) + num_ifaces = ifreq.ifr_ifindex; } - if (default_iface) - myAddr = *default_iface; - free (ifconf.ifc_req); - return ret; + ifaces = malloc (num_ifaces * sizeof (uint32_t)); + Sys_MaskPrintf (SYS_NET, "%d interfaces\n", num_ifaces); + for (ifa = ifa_head; ifa; ifa = ifa->ifa_next) { + int index; + struct sockaddr_in *sa; + + if (!ifa->ifa_flags & IFF_UP) + continue; + if (!ifa->ifa_addr || ifa->ifa_addr->sa_family != AF_INET) + continue; + strncpy (ifreq.ifr_name, ifa->ifa_name, IFNAMSIZ); + ifreq.ifr_name[IFNAMSIZ - 1] = 0; + ioctl (sock, SIOCGIFINDEX, (char*) &ifreq); + index = ifreq.ifr_ifindex - 1; + sa = (struct sockaddr_in *) ifa->ifa_addr; + memcpy (&ifaces[index], &sa->sin_addr, sizeof (uint32_t)); + Sys_MaskPrintf (SYS_NET, " %-10s %s\n", ifa->ifa_name, + inet_ntoa (sa->sin_addr)); + if (!default_iface && ifaces[index] != htonl (0x7f000001)) + default_iface = &ifaces[index]; + } + freeifaddrs (ifa_head); + return 0; +#endif +no_ifaddrs: + ifaces = &myAddr; + default_iface = &ifaces[0]; + num_ifaces = 1; + return 0; } int @@ -187,7 +200,7 @@ UDP_Init (void) gethostname (buff, MAXHOSTNAMELEN); local = gethostbyname (buff); if (local) - myAddr = *(int *) local->h_addr_list[0]; + myAddr = *(uint32_t *) local->h_addr_list[0]; else myAddr = 0; From 53049e33ebccc50aba4337a6bbe07da667395d07 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 16 Aug 2011 10:03:43 +0900 Subject: [PATCH 055/334] Make the interface code more portable. It turns out SIOCGIFINDEX isn't (readily?) available in BSD, but if_nametoindex() is defined by posix, so use that instead. --- libs/net/nm/net_udp.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/libs/net/nm/net_udp.c b/libs/net/nm/net_udp.c index d705ac04e..19525a963 100644 --- a/libs/net/nm/net_udp.c +++ b/libs/net/nm/net_udp.c @@ -132,7 +132,7 @@ get_iface_list (int sock) #ifdef HAVE_GETIFADDRS struct ifaddrs *ifa_head; struct ifaddrs *ifa; - struct ifreq ifreq; + int index; if (getifaddrs (&ifa_head) < 0) goto no_ifaddrs; @@ -141,26 +141,20 @@ get_iface_list (int sock) continue; if (!ifa->ifa_addr || ifa->ifa_addr->sa_family != AF_INET) continue; - strncpy (ifreq.ifr_name, ifa->ifa_name, IFNAMSIZ); - ifreq.ifr_name[IFNAMSIZ - 1] = 0; - ioctl (sock, SIOCGIFINDEX, (char*) &ifreq); - if (ifreq.ifr_ifindex > num_ifaces) - num_ifaces = ifreq.ifr_ifindex; + index = if_nametoindex (ifa->ifa_name); + if (index > num_ifaces) + num_ifaces = index; } ifaces = malloc (num_ifaces * sizeof (uint32_t)); Sys_MaskPrintf (SYS_NET, "%d interfaces\n", num_ifaces); for (ifa = ifa_head; ifa; ifa = ifa->ifa_next) { - int index; struct sockaddr_in *sa; if (!ifa->ifa_flags & IFF_UP) continue; if (!ifa->ifa_addr || ifa->ifa_addr->sa_family != AF_INET) continue; - strncpy (ifreq.ifr_name, ifa->ifa_name, IFNAMSIZ); - ifreq.ifr_name[IFNAMSIZ - 1] = 0; - ioctl (sock, SIOCGIFINDEX, (char*) &ifreq); - index = ifreq.ifr_ifindex - 1; + index = if_nametoindex (ifa->ifa_name) - 1; sa = (struct sockaddr_in *) ifa->ifa_addr; memcpy (&ifaces[index], &sa->sin_addr, sizeof (uint32_t)); Sys_MaskPrintf (SYS_NET, " %-10s %s\n", ifa->ifa_name, From bb065bd2335290ffb1177b45bf3397e2d1102e5b Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 16 Aug 2011 12:10:05 +0900 Subject: [PATCH 056/334] Be a little leniant with vector param stores. qcc always used vector stores to load values into the function parameters, but if the location of the value is too close to the end of the global data block (the vector spans the end of the block), it would trigger the bounds check code. Thus, allow such instructions without a murmer, so long as it actually is a parameter write. --- libs/gamecode/engine/pr_opcode.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/libs/gamecode/engine/pr_opcode.c b/libs/gamecode/engine/pr_opcode.c index 18aed9b11..9901347e5 100644 --- a/libs/gamecode/engine/pr_opcode.c +++ b/libs/gamecode/engine/pr_opcode.c @@ -1092,6 +1092,22 @@ check_branch (progs_t *pr, dstatement_t *st, opcode_t *op, short offset) (long)(st - pr->pr_statements), op->opname); } +static int +is_vector_parameter_store (progs_t *pr, dstatement_t *st, + unsigned short operand) +{ + int i; + + if (st->op != OP_STORE_V) + return 0; + if (operand != st->a) + return 0; + for (i = 0; i < MAX_PARMS; i++) + if (st->b == pr->pr_params[i] - pr->pr_globals) + return 1; + return 0; +} + #define ISDENORM(x) ((x) && !((x) & 0x7f800000)) static inline void @@ -1113,8 +1129,11 @@ check_global (progs_t *pr, dstatement_t *st, opcode_t *op, etype_t type, default: if (operand + (unsigned) pr_type_size[type] > pr->progs->numglobals) { - msg = "out of bounds global index"; - goto error; + if (operand >= pr->progs->numglobals + || !is_vector_parameter_store (pr, st, operand)) { + msg = "out of bounds global index"; + goto error; + } } if (type != ev_float || !check_denorm) break; From f7b52e0e15bcd3196477a292bba004b2fa3f009a Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 16 Aug 2011 14:17:17 +0900 Subject: [PATCH 057/334] Convert and link INSTALL into our doxygen docs. --- INSTALL | 116 ++++++++++++++++++++++++++---------------- doc/Makefile.am | 12 +++-- doc/quakeforge.dox.in | 1 + doc/quakeforge.txt | 1 + 4 files changed, 82 insertions(+), 48 deletions(-) diff --git a/INSTALL b/INSTALL index d047ccb7f..7e4c4be88 100644 --- a/INSTALL +++ b/INSTALL @@ -1,72 +1,98 @@ -This is our new development tree (we're back to "quakeforge"), where we're again in the process of merging Quake and QuakeWorld ... but this time, it's much better. :), and will eventually provide the 0.6 versions of QuakeForge. +//This file is formatted for processing with doxygen. +//unfortunatly, have to wrap the docs in a C comment for doxygen +/** +\page build-install Building and Installing QuakeForge -While almost always in working order, it's under heavy development so be prepared to encounter some issues (Wear your hard hat!). Please check the docs. +This is our new development tree (we're back to "quakeforge"), where we're +again in the process of merging Quake and QuakeWorld ... but this time, +it's much better. :), and will eventually provide the 0.6 versions of +QuakeForge. -UNIX users: because of the diversity of machines QuakeForge runs on, we do not provide UNIX binaries. You need to compile QuakeForge yourself, however QuakeForge is very easy to compile once you have the following packages installed: +While almost always in working order, it's under heavy development so be +prepared to encounter some issues (Wear your hard hat!). Please check the +docs. - * GNU autoconf 2.50 or later - * GNU automake 1.6 or later - * GNU libtool 1.4 or later - * GNU bison - * GNU flex - * GNU make (BSD make doesn't like some constructs used) - * C compiler and preprocessor (gcc and cpp recommended) - * libsamplerate +\note UNIX users: because of the diversity of machines on which QuakeForge +runs , we do not provide UNIX binaries. You need to compile QuakeForge +yourself, however QuakeForge is very easy to compile once you have the +necessary packages installed. + +\section req-pack Required Packages +The following packages are required to build QuakeForge: +\li GNU autoconf 2.50 or later +\li GNU automake 1.6 or later +\li GNU libtool 1.4 or later +\li GNU bison +\li GNU flex +\li GNU make (BSD make doesn't like some constructs used) +\li C compiler and preprocessor (gcc and cpp recommended) +\li libsamplerate + +\section rec-pack Recommended Packages The following are recommended: - * git (highly recommended for staying up to date with current changes) - * zlib devel (highly recommended for compressed file and download support) - * Ogg Vorbis libs (for compressed sound effects support) - * X11 devel (for X11-based clients: software and OpenGL) - * glide and mesa or other GL compatible lib - * svgalib (for console-based clients: software and 3dfx) +\li git (highly recommended for staying up to date with current changes) +\li zlib devel (highly recommended for compressed file and download support) +\li curl (for http download support (\ref qw_download_spec)) +\li Ogg Vorbis libs (for compressed sound effects support) +\li X11 devel (for X11-based clients: software and OpenGL) +\li glide and mesa or other GL compatible lib +\li svgalib (for console-based clients: software and 3dfx) -Relevant packages (debian): - * build-essential - * autoconf - * automake - * libtool - * flex - * bison - * git +\section package-names Relevant Package Names +The following is the list of relevant package names in debian. +\li build-essential +\li autoconf +\li automake +\li libtool +\li flex +\li bison +\li git - * libasound2-dev - * libjack-dev +\li libasound2-dev +\li libjack-dev - * libsamplerate0-dev +\li libsamplerate0-dev - * libflac-dev - * libogg-dev - * libvorbis-dev - * libpng12-dev - * zlib1g-dev +\li libflac-dev +\li libogg-dev +\li libvorbis-dev +\li libpng12-dev +\li zlib1g-dev - * libcurl4-openssl-dev (or libcurl4-gnutls-dev) - * libncurses5-dev - - * libsdl1.2-dev - * libsvga1-dev - * libxxf86dga-dev - * libxxf86vm-dev +\li libcurl4-openssl-dev (or libcurl4-gnutls-dev) +\li libncurses5-dev +\li libsdl1.2-dev +\li libsvga1-dev +\li libxxf86dga-dev +\li libxxf86vm-dev +\section building-and-installing Build and Install Procedure Basic process to build and install QuakeForge: +\verbatim ./bootstrap ./configure make install +\endverbatim -You may want to check `./configure --help` and select options. +You may want to check ./configure --help and select options. To build and install only the quakeworld server: +\verbatim ./bootstrap ./configure --without-clients --without-tools --with-servers=qw make install +\endverbatim To build documentation (doxygen, graphviz and mscgen are required), in an already configured source tree: +\verbatim cd doc make doc +\endverbatim -Then either point your webbrowser to doxygen/html/index.html, or copy/move -doxygen/html to a webserver and point your browser to that. The -documentation is currently grossly inadequate, but hopefully it is of some -help. +Then either point your webbrowser to doxygen/html/index.html, or +copy/move doxygen/html to a webserver and point your browser +to that. The documentation is currently grossly inadequate, but hopefully +it is of some help. +*/ diff --git a/doc/Makefile.am b/doc/Makefile.am index a976c72ec..e0e71f25d 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -1,12 +1,18 @@ AUTOMAKE_OPTIONS= foreign SUBDIRS= man + +TXT_DOCS=\ + bind.txt connect.txt cshifts.txt dirconf.txt faq.txt \ + filesystem.txt mapformat.txt qtv.txt quakeforge.txt qw-cap-spec.txt \ + qw-download-spec.txt surround-sound.txt timestamps.txt + EXTRA_DIST= qf.ico \ \ - skybox.fig template.c template.h timestamps.txt \ + skybox.fig template.c template.h \ quakeforge.dox.in \ \ - faq.txt quakeforge.txt \ + ${TXT_DOCS} \ \ config/glspeed-v1.cfg config/glspeed-v3.cfg config/swspeed.cfg \ \ @@ -33,5 +39,5 @@ progs/vm-mem.eps: progs/vm-mem.fig qtv/qwtv.png: qtv/qwtv.fig qtv/qwtv.eps: qtv/qwtv.fig -doc: quakeforge.dox progs/vm-mem.png progs/vm-mem.eps qtv/qwtv.png qtv/qwtv.eps +doc: quakeforge.dox progs/vm-mem.png progs/vm-mem.eps qtv/qwtv.png qtv/qwtv.eps ${TXT_DOCS} doxygen quakeforge.dox diff --git a/doc/quakeforge.dox.in b/doc/quakeforge.dox.in index 50a884194..01ed89503 100644 --- a/doc/quakeforge.dox.in +++ b/doc/quakeforge.dox.in @@ -588,6 +588,7 @@ INPUT += @TOPSRC@/qtv INPUT += @TOPSRC@/qw INPUT += @TOPSRC@/tools INPUT += @TOPSRC@/doc/bind.txt +INPUT += @TOPSRC@/INSTALL INPUT += @TOPSRC@/doc/connect.txt INPUT += @TOPSRC@/doc/cshifts.txt INPUT += @TOPSRC@/doc/dirconf.txt diff --git a/doc/quakeforge.txt b/doc/quakeforge.txt index f75e84f46..7744230e4 100644 --- a/doc/quakeforge.txt +++ b/doc/quakeforge.txt @@ -8,6 +8,7 @@ Quake and QuakeWorld game engine. Our purpose? To improve the state of the game by improving the engine and making it accessable to the largest number of players we can. +\li \subpage build-install \li \subpage faq \li \subpage key_binding \li \subpage cshift_cvars From cf2845a387e0954753bd64735a0cd56ebf07cc49 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 20 Aug 2011 13:13:43 +0900 Subject: [PATCH 058/334] Ensure Sys_Error can not form an infinite loop. I don't remember what propted this change, but it seems like a good idea anyway, so get it into the repository and clean out my stash :) --- libs/util/sys.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libs/util/sys.c b/libs/util/sys.c index 636de0528..00179f44d 100644 --- a/libs/util/sys.c +++ b/libs/util/sys.c @@ -430,6 +430,14 @@ Sys_Error (const char *error, ...) #ifdef VA_LIST_IS_ARRAY va_list tmp_args; #endif + static int in_sys_error = 0; + + if (in_sys_error) { + const char *msg = "\nSys_Error: recursive error condition\n"; + write (2, msg, strlen (msg)); + abort (); + } + in_sys_error = 1; va_start (args, error); #ifdef VA_LIST_IS_ARRAY From 605d60167dbae658e1f0ad2cc5ab4f66548daaa5 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 20 Aug 2011 13:35:51 +0900 Subject: [PATCH 059/334] Rename the doxygen formatted text files. So I don't have to keep duplicating file names all over the place, I've decided to use the "dox" extension on text files that are formatted for doxygen processing. This way, doxygen can search for them using wildcards, and unformated text files won't cause any headaches. --- config.d/ac_config_files.m4 | 2 +- doc/Makefile.am | 16 ++++++++-------- doc/{bind.txt => bind.dox} | 0 doc/{connect.txt => connect.dox} | 0 doc/{cshifts.txt => cshifts.dox} | 0 doc/{dirconf.txt => dirconf.dox} | 0 doc/{faq.txt => faq.dox} | 0 doc/{filesystem.txt => filesystem.dox} | 0 doc/{mapformat.txt => mapformat.dox} | 0 doc/{qtv.txt => qtv.dox} | 0 doc/{quakeforge.txt => quakeforge.dox} | 0 ...{quakeforge.dox.in => quakeforge.dox.conf.in} | 16 ++-------------- doc/{qw-cap-spec.txt => qw-cap-spec.dox} | 0 ...qw-download-spec.txt => qw-download-spec.dox} | 0 doc/{surround-sound.txt => surround-sound.dox} | 0 doc/{timestamps.txt => timestamps.dox} | 0 16 files changed, 11 insertions(+), 23 deletions(-) rename doc/{bind.txt => bind.dox} (100%) rename doc/{connect.txt => connect.dox} (100%) rename doc/{cshifts.txt => cshifts.dox} (100%) rename doc/{dirconf.txt => dirconf.dox} (100%) rename doc/{faq.txt => faq.dox} (100%) rename doc/{filesystem.txt => filesystem.dox} (100%) rename doc/{mapformat.txt => mapformat.dox} (100%) rename doc/{qtv.txt => qtv.dox} (100%) rename doc/{quakeforge.txt => quakeforge.dox} (100%) rename doc/{quakeforge.dox.in => quakeforge.dox.conf.in} (98%) rename doc/{qw-cap-spec.txt => qw-cap-spec.dox} (100%) rename doc/{qw-download-spec.txt => qw-download-spec.dox} (100%) rename doc/{surround-sound.txt => surround-sound.dox} (100%) rename doc/{timestamps.txt => timestamps.dox} (100%) diff --git a/config.d/ac_config_files.m4 b/config.d/ac_config_files.m4 index 960aa4f64..7ce3af258 100644 --- a/config.d/ac_config_files.m4 +++ b/config.d/ac_config_files.m4 @@ -89,7 +89,7 @@ pkg-config/quakeforge.pc doc/Makefile - doc/quakeforge.dox + doc/quakeforge.dox.conf doc/man/Makefile debian/Makefile diff --git a/doc/Makefile.am b/doc/Makefile.am index e0e71f25d..1c9009a66 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -2,17 +2,17 @@ AUTOMAKE_OPTIONS= foreign SUBDIRS= man -TXT_DOCS=\ - bind.txt connect.txt cshifts.txt dirconf.txt faq.txt \ - filesystem.txt mapformat.txt qtv.txt quakeforge.txt qw-cap-spec.txt \ - qw-download-spec.txt surround-sound.txt timestamps.txt +DOX=\ + bind.dox connect.dox cshifts.dox dirconf.dox faq.dox \ + filesystem.dox mapformat.dox qtv.dox quakeforge.dox qw-cap-spec.dox \ + qw-download-spec.dox surround-sound.dox timestamps.dox EXTRA_DIST= qf.ico \ \ skybox.fig template.c template.h \ - quakeforge.dox.in \ + quakeforge.dox.conf.in \ \ - ${TXT_DOCS} \ + ${DOX} \ \ config/glspeed-v1.cfg config/glspeed-v3.cfg config/swspeed.cfg \ \ @@ -39,5 +39,5 @@ progs/vm-mem.eps: progs/vm-mem.fig qtv/qwtv.png: qtv/qwtv.fig qtv/qwtv.eps: qtv/qwtv.fig -doc: quakeforge.dox progs/vm-mem.png progs/vm-mem.eps qtv/qwtv.png qtv/qwtv.eps ${TXT_DOCS} - doxygen quakeforge.dox +doc: quakeforge.dox.conf progs/vm-mem.png progs/vm-mem.eps qtv/qwtv.png qtv/qwtv.eps ${DOX} + doxygen quakeforge.dox.conf diff --git a/doc/bind.txt b/doc/bind.dox similarity index 100% rename from doc/bind.txt rename to doc/bind.dox diff --git a/doc/connect.txt b/doc/connect.dox similarity index 100% rename from doc/connect.txt rename to doc/connect.dox diff --git a/doc/cshifts.txt b/doc/cshifts.dox similarity index 100% rename from doc/cshifts.txt rename to doc/cshifts.dox diff --git a/doc/dirconf.txt b/doc/dirconf.dox similarity index 100% rename from doc/dirconf.txt rename to doc/dirconf.dox diff --git a/doc/faq.txt b/doc/faq.dox similarity index 100% rename from doc/faq.txt rename to doc/faq.dox diff --git a/doc/filesystem.txt b/doc/filesystem.dox similarity index 100% rename from doc/filesystem.txt rename to doc/filesystem.dox diff --git a/doc/mapformat.txt b/doc/mapformat.dox similarity index 100% rename from doc/mapformat.txt rename to doc/mapformat.dox diff --git a/doc/qtv.txt b/doc/qtv.dox similarity index 100% rename from doc/qtv.txt rename to doc/qtv.dox diff --git a/doc/quakeforge.txt b/doc/quakeforge.dox similarity index 100% rename from doc/quakeforge.txt rename to doc/quakeforge.dox diff --git a/doc/quakeforge.dox.in b/doc/quakeforge.dox.conf.in similarity index 98% rename from doc/quakeforge.dox.in rename to doc/quakeforge.dox.conf.in index 01ed89503..37efc18fc 100644 --- a/doc/quakeforge.dox.in +++ b/doc/quakeforge.dox.conf.in @@ -587,20 +587,8 @@ INPUT += @TOPSRC@/nq INPUT += @TOPSRC@/qtv INPUT += @TOPSRC@/qw INPUT += @TOPSRC@/tools -INPUT += @TOPSRC@/doc/bind.txt +INPUT += @TOPSRC@/doc/ INPUT += @TOPSRC@/INSTALL -INPUT += @TOPSRC@/doc/connect.txt -INPUT += @TOPSRC@/doc/cshifts.txt -INPUT += @TOPSRC@/doc/dirconf.txt -INPUT += @TOPSRC@/doc/faq.txt -INPUT += @TOPSRC@/doc/filesystem.txt -INPUT += @TOPSRC@/doc/mapformat.txt -INPUT += @TOPSRC@/doc/qtv.txt -INPUT += @TOPSRC@/doc/quakeforge.txt -INPUT += @TOPSRC@/doc/qw-cap-spec.txt -INPUT += @TOPSRC@/doc/qw-download-spec.txt -INPUT += @TOPSRC@/doc/surround-sound.txt -INPUT += @TOPSRC@/doc/timestamps.txt # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is @@ -617,7 +605,7 @@ INPUT_ENCODING = UTF-8 # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 -FILE_PATTERNS = *.c *.h +FILE_PATTERNS = *.c *.h *.dox # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. diff --git a/doc/qw-cap-spec.txt b/doc/qw-cap-spec.dox similarity index 100% rename from doc/qw-cap-spec.txt rename to doc/qw-cap-spec.dox diff --git a/doc/qw-download-spec.txt b/doc/qw-download-spec.dox similarity index 100% rename from doc/qw-download-spec.txt rename to doc/qw-download-spec.dox diff --git a/doc/surround-sound.txt b/doc/surround-sound.dox similarity index 100% rename from doc/surround-sound.txt rename to doc/surround-sound.dox diff --git a/doc/timestamps.txt b/doc/timestamps.dox similarity index 100% rename from doc/timestamps.txt rename to doc/timestamps.dox From 14c23879b1b99d7757789ec47aad97c95baefde4 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 20 Aug 2011 16:11:24 +0900 Subject: [PATCH 060/334] Add a shortcut for QuakeForge. I got tired of typing QuakeForge all the time, and to ensure consistency, made it so \QF or @QF will expand to QuakeForge in the generated docs. --- doc/quakeforge.dox.conf.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/quakeforge.dox.conf.in b/doc/quakeforge.dox.conf.in index 37efc18fc..067381054 100644 --- a/doc/quakeforge.dox.conf.in +++ b/doc/quakeforge.dox.conf.in @@ -179,7 +179,7 @@ TAB_SIZE = 4 # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. -ALIASES = +ALIASES = QF=QuakeForge # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. From a759a5a376ba9688cc23cef62b3bb9160964e8b2 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 20 Aug 2011 16:26:51 +0900 Subject: [PATCH 061/334] Make the property-list documentation useful for users. --- doc/Makefile.am | 4 +- doc/property-lists.dox | 90 ++++++++++++++++++++++++++++++++++++++++++ include/QF/qfplist.h | 47 +++++----------------- 3 files changed, 101 insertions(+), 40 deletions(-) create mode 100644 doc/property-lists.dox diff --git a/doc/Makefile.am b/doc/Makefile.am index 1c9009a66..6d83fb2f0 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -4,8 +4,8 @@ SUBDIRS= man DOX=\ bind.dox connect.dox cshifts.dox dirconf.dox faq.dox \ - filesystem.dox mapformat.dox qtv.dox quakeforge.dox qw-cap-spec.dox \ - qw-download-spec.dox surround-sound.dox timestamps.dox + filesystem.dox mapformat.dox property-lists.dox qtv.dox quakeforge.dox \ + qw-cap-spec.dox qw-download-spec.dox surround-sound.dox timestamps.dox EXTRA_DIST= qf.ico \ \ diff --git a/doc/property-lists.dox b/doc/property-lists.dox new file mode 100644 index 000000000..fcdeef9f6 --- /dev/null +++ b/doc/property-lists.dox @@ -0,0 +1,90 @@ +//unfortunatly, have to wrap the docs in a C comment for doxygen +/** +\page property-lists Property Lists + +\QF's property lists are based on those used in OpenStep. + +\QF uses property lists for a wide variety of purposes. This includes saved +game data, directory configuration and play-lists. + +Property lists are text files that describe a single value. However, that +value can be one of the following types: +
+
Dictionaries
Lists of values that are each accociated + with a key
+
Arrays
Lists of indexed values
+
Strings
Simple text strings.
+
Binary data
Random binary data
+
+Dictionary and Array values allow for arbitrarily complex data to be +represented by a property list. + +In addition, property lists also support comments, both single-line and +multi-line. Single-line comments start with \c // and continue to the end +of the line. Multi-line comments begine with +/* and +end with */, and may span multiple lines, or be +contained entirely within a single line, possibly with non-comment text +following the comment. + +\section pl-dictionaries Dictionaries. +A dictionary is a list of values, each associated with a key. The order of +key/value pairs in a dictionary is not preserved. + +\code +{ + key1 = value1; + key2 = value2; + // ... +} +\endcode + +A dictionary may be empty or have any number of +key = value pairs separated by \c ;. The final \c ; +before the closing \c } is optional. + +The key must be a string, but the value may be of any type, including +dictionary or array. + +\section Arrays +An array is an ordered list of values. The order of the values in an array +is preserved. + +\code +( + value1, + value2, + // ... +) +\endcode + +An array may be empty or have any number of values. Each value may be of +any type, including dictionary or array. + +\section pl-strings Strings +\QF's property lists support three types of strings: unquoted, quoted and +"long". + +An unquoted string may contain most printable characters. This includes the +digits \c 0 to \c 9, the letters \c a to \c z and \c A to \c Z, and the +symbols \c !, \c #, \c $, \c %, \c &, \c *, \c +, \c -, \c ., \c /, \c :, +\c ?, \c @, \c |, \c ~, \c _ and \c ^. +\verbatim +0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ +abcdefghijklmnopqrstuvwxyz!#$%&*+-./:?@|~_^ +\endverbatim + +Quoted strings may contain whitespace, C escape sequences, and any +printable character. The quote character is \c \". + +Long strings use tripple quotes (\c \"\"\") instead of \c \" as the quote +character. This allows the use of unquoted \c \" characters in the string. +And yes, these long strings were inspired by Python's long strings. + +\section pl-binary Binary Data + +Binary data is hex-encoded and contained within angle brackets (\c \< \c +\>). There must be an even number of hex-digits. That is, while \c \ +is value, \c \ is not. +*/ diff --git a/include/QF/qfplist.h b/include/QF/qfplist.h index fae266b22..f040c77f3 100644 --- a/include/QF/qfplist.h +++ b/include/QF/qfplist.h @@ -36,46 +36,17 @@ #include "QF/qtypes.h" -/** - There are four types of data that can be stored in a property list: +/** The type of the property list item. -
-
QFDictionary
A list of values, each associated with a - key (a C string).
-
QFArray
A list of indexed values
-
QFString
A string.
-
QFBinary
Random binary data.
-
- - In textual form, a dictionary looks like: - \code - { - key = value; - } - \endcode - An array looks like: - \code - ( - value1, - value2 - ) - \endcode - An unquoted string may contain only alphanumeric characters and/or the - underscore character, _. Quoted strings may contain - whitespace, C escape sequences, and so on. The quote character is - \". Optionally, Python style long strings - (\"\"\"...\"\"\") may be used, allowing for unquoted - " quotes in the string. - - - QFBinary data is hex-encoded and contained within angle brackets, \c \< - \c \>. The length of the encoded data must be an even number, so while - \c \ is valid, \c \ isn't. - - Property lists may contain C-style or BCPL-style comments. + For further details, see \ref property-lists. */ -typedef enum {QFDictionary, QFArray, QFBinary, QFString} pltype_t; +typedef enum { + QFDictionary, ///< The property list item represents a dictionary. + QFArray, ///< The property list item represents an array. + QFBinary, ///< The property list item represents arbitrary binary + ///< data. + QFString ///< The property list item represents a C string. +} pltype_t; /** Generic property list item. From 1402feafd231b9c164cf45543992d809e06c291e Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 20 Aug 2011 16:30:43 +0900 Subject: [PATCH 062/334] Kill some magic numbers and clean up some whitespace. --- libs/util/qfplist.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libs/util/qfplist.c b/libs/util/qfplist.c index 7e0587cbb..3b9768fd1 100644 --- a/libs/util/qfplist.c +++ b/libs/util/qfplist.c @@ -69,7 +69,7 @@ struct plarray_s { int numvals; ///< Number of items in array int maxvals; ///< Number of items that can be stored ///< before a realloc is necesary. - struct plitem_s **values; ///< Array data + struct plitem_s **values; ///< Array data }; typedef struct plarray_s plarray_t; @@ -93,8 +93,9 @@ typedef struct pldata_s { // Unparsed property list string // Ugly defines for fast checking and conversion from char to number #define inrange(ch,min,max) ((ch) >= (min) && (ch) <= (max)) #define char2num(ch) \ -inrange((ch), '0', '9') ? ((ch) - 0x30) \ -: (inrange((ch), 'a', 'f') ? ((ch) - 0x57) : ((ch) - 0x37)) + (inrange((ch), '0', '9') ? ((ch) - '0') \ + : 10 + (inrange((ch), 'a', 'f') ? ((ch) - 'a') \ + : ((ch) - 'A'))) static byte quotable_bitmap[32]; static inline int @@ -554,7 +555,7 @@ PL_ParseQuotedString (pldata_t *pl) shrink++; } else if (c == '"' && (!long_string || (pl->ptr[pl->pos + 1] == '"' - && pl->ptr[pl->pos + 2] == '"'))) { + && pl->ptr[pl->pos + 2] == '"'))) { break; } } From 6268bd2965a6810d4d0a4bb92b00059d6db3d84d Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 20 Aug 2011 19:23:31 +0900 Subject: [PATCH 063/334] Tweak the property list docs a little. --- doc/Makefile.am | 2 +- doc/{property-lists.dox => property-list.dox} | 4 ++-- include/QF/qfplist.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) rename doc/{property-lists.dox => property-list.dox} (96%) diff --git a/doc/Makefile.am b/doc/Makefile.am index 6d83fb2f0..395621e84 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -4,7 +4,7 @@ SUBDIRS= man DOX=\ bind.dox connect.dox cshifts.dox dirconf.dox faq.dox \ - filesystem.dox mapformat.dox property-lists.dox qtv.dox quakeforge.dox \ + filesystem.dox mapformat.dox property-list.dox qtv.dox quakeforge.dox \ qw-cap-spec.dox qw-download-spec.dox surround-sound.dox timestamps.dox EXTRA_DIST= qf.ico \ diff --git a/doc/property-lists.dox b/doc/property-list.dox similarity index 96% rename from doc/property-lists.dox rename to doc/property-list.dox index fcdeef9f6..bc4338c00 100644 --- a/doc/property-lists.dox +++ b/doc/property-list.dox @@ -1,13 +1,13 @@ //unfortunatly, have to wrap the docs in a C comment for doxygen /** -\page property-lists Property Lists +\page property-list Property List \QF's property lists are based on those used in OpenStep. \QF uses property lists for a wide variety of purposes. This includes saved game data, directory configuration and play-lists. -Property lists are text files that describe a single value. However, that +A property list is a text file that describes a single value. However, that value can be one of the following types:
Dictionaries
Lists of values that are each accociated diff --git a/include/QF/qfplist.h b/include/QF/qfplist.h index f040c77f3..a7e0fbb53 100644 --- a/include/QF/qfplist.h +++ b/include/QF/qfplist.h @@ -38,7 +38,7 @@ /** The type of the property list item. - For further details, see \ref property-lists. + For further details, see \ref property-list. */ typedef enum { QFDictionary, ///< The property list item represents a dictionary. From 46f9c9b1056fce0282e0d78f080c0ec137866313 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 20 Aug 2011 19:24:14 +0900 Subject: [PATCH 064/334] Document QF's tracklists. --- doc/faq.dox | 22 ++++++++++++++++++++++ doc/tracklist.cfg | 20 ++++++++++---------- doc/tracklist.dox | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 10 deletions(-) create mode 100644 doc/tracklist.dox diff --git a/doc/faq.dox b/doc/faq.dox index bb04925b1..e909bba7e 100644 --- a/doc/faq.dox +++ b/doc/faq.dox @@ -5,6 +5,7 @@ \li \ref gfx_wad \li \ref pak0_pak \li \ref git_compile_error +\li \ref no_music \section gfx_wad What does "W_LoadWadFile: unable to load gfx.wad" mean? The most common cause of this error is QuakeForge is unable to find @@ -32,4 +33,25 @@ configure is being created autotools sources m4 files... If the files do not exist, you get the errors you have seen. Try installing packages which contain the libraries that caused the syntax error, including the -dev versions, then recreate configure using bootstrap and try again. + +\section no_music Why doesn't \QF play the background music even though I have the CD in the drive? +By default, \QF no longer uses the CD drive to play music. Instead, \QF now +looks for a \ref tracklist to map Quake's cd tracks to sound files. If you +wish to continue using the CD instead, you may set the \c cd_plugin cvar to +the value appropriate for your system: +
+
file
The default CD plugin. Uses sound files + for the BGM.
+
linux
Use this plugin on a Linux system.
+
sdl
This plugin can be used on most + systems.
+ +
win
Use this plugin on Windows + systems.
+
xmms
The predecessor to the \c file plugin. + Not always available, and expects xmms + to be available (but not necessarily + running) on the system. Useful if you + absolutely must have MP3 support.
+
*/ diff --git a/doc/tracklist.cfg b/doc/tracklist.cfg index 9f143f0c1..5b473299f 100644 --- a/doc/tracklist.cfg +++ b/doc/tracklist.cfg @@ -1,14 +1,14 @@ // sample track list { - 2 = "music/02.ogg"; - 3 = "music/03.ogg"; - 4 = "music/04.ogg"; - 5 = "music/05.ogg"; - 6 = "music/06.ogg"; - 7 = "music/07.ogg"; - 8 = "music/08.ogg"; - 9 = "music/09.ogg"; - 10 = "music/10.ogg"; - 11 = "music/11.ogg"; + 2 = "music/track02.cdda.ogg"; + 3 = "music/track03.cdda.ogg"; + 4 = "music/track04.cdda.ogg"; + 5 = "music/track05.cdda.ogg"; + 6 = "music/track06.cdda.ogg"; + 7 = "music/track07.cdda.ogg"; + 8 = "music/track08.cdda.ogg"; + 9 = "music/track09.cdda.ogg"; + 10 = "music/track10.cdda.ogg"; + 11 = "music/track11.cdda.ogg"; } diff --git a/doc/tracklist.dox b/doc/tracklist.dox new file mode 100644 index 000000000..fd61c9454 --- /dev/null +++ b/doc/tracklist.dox @@ -0,0 +1,46 @@ +//unfortunately, have to wrap the docs in a C comment for doxygen +/** +\page tracklist Tracklist config file + +As \QF supports playing arbitrarily sized audio files, it seemed rather +obvious that \QF should be able to use them as BGM in place of the CD +drive. However, requiring specific names and locations for the files seemed +overly onerous. Thus \QF looks for \c traclist.cfg in the root of the game +directory (eg. \c id1, same place as \c pak0.pak, \c config.cfg, etc). + +Using the following \c tracklist.cfg: +\verbinclude tracklist.cfg + +and the following commands in the \c id1 directory: +\verbatim +mkdir music +cd music +cdparanoia -B 2- +oggenc *.wav +rm *.wav +cd .. +pak -vcf quake1-music.pak tracklist.cfg `find music -type f print` +rm -rf music tracklist.cfg +\endverbatim + +a convenient pak file can be made of the Quake CD audio. Of course, the +last two commands are optional if you prefer to have the files loose in the +filesystem. + +\section tl-format Tracklist format +The tracklist config file is a \ref property-list consistinf of a +dictionary mapping the track numbers to the file to be played when that +track is requested. The keys of the dictionary are the track number (the +Quake CD has only tracks 2 to 11 as audio tracks) as a property list +string, and the values are the file to play, also as a property list +string. + +However, if the value is an array of strings, that track will +become a playlist, and each file specified in the array will be played in +order, looping back to the first file in the list. + +The files may be .wav, .ogg (Ogg Vorbis), +.mid or .midi (MIDI), or .flac +files. MP3 is not supported, and is not likely to ever be +supported. +*/ From f49a41b4b216a1fada7d93017cf9e3817276d982 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 20 Aug 2011 19:31:01 +0900 Subject: [PATCH 065/334] Comment on our lack of mp3 support. --- doc/faq.dox | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/faq.dox b/doc/faq.dox index e909bba7e..161b395a5 100644 --- a/doc/faq.dox +++ b/doc/faq.dox @@ -6,6 +6,7 @@ \li \ref pak0_pak \li \ref git_compile_error \li \ref no_music +\li \ref no_mp3 \section gfx_wad What does "W_LoadWadFile: unable to load gfx.wad" mean? The most common cause of this error is QuakeForge is unable to find @@ -54,4 +55,9 @@ the value appropriate for your system: running) on the system. Useful if you absolutely must have MP3 support.
+ +\section no_mp3 Why doesn't \QF support MP3s? +Because they are not free. MP3 support is a patent minefield, and we really +don't want to wind up with lawyers at ten paces, especially since we'd be +unarmed with no armor, and they have rocket launchers and quad-dammage. */ From 373f136fe691796f36320a87c9e7f21627e948b5 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 20 Aug 2011 19:39:47 +0900 Subject: [PATCH 066/334] Fix a typo. --- doc/tracklist.dox | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tracklist.dox b/doc/tracklist.dox index fd61c9454..343cc2229 100644 --- a/doc/tracklist.dox +++ b/doc/tracklist.dox @@ -28,7 +28,7 @@ last two commands are optional if you prefer to have the files loose in the filesystem. \section tl-format Tracklist format -The tracklist config file is a \ref property-list consistinf of a +The tracklist config file is a \ref property-list consisting of a dictionary mapping the track numbers to the file to be played when that track is requested. The keys of the dictionary are the track number (the Quake CD has only tracks 2 to 11 as audio tracks) as a property list From d14eff6c769c9b0febdcd9d3107bfa09b3627fca Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 20 Aug 2011 19:55:54 +0900 Subject: [PATCH 067/334] Run the docs through aspell. --- doc/dirconf.dox | 2 +- doc/faq.dox | 8 ++++---- doc/filesystem.dox | 2 +- doc/property-list.dox | 6 +++--- doc/quakeforge.dox | 4 ++-- doc/tracklist.dox | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/doc/dirconf.dox b/doc/dirconf.dox index 08ee4d7d4..6886937a7 100644 --- a/doc/dirconf.dox +++ b/doc/dirconf.dox @@ -1,4 +1,4 @@ -//unfortunatly, have to wrap the docs in a C comment for doxygen +//unfortunately, have to wrap the docs in a C comment for doxygen /** \page dirconf Directory Configuration diff --git a/doc/faq.dox b/doc/faq.dox index 161b395a5..4a16182f1 100644 --- a/doc/faq.dox +++ b/doc/faq.dox @@ -1,4 +1,4 @@ -//unfortunatly, have to wrap the docs in a C comment for doxygen +//unfortunately, have to wrap the docs in a C comment for doxygen /** \page faq Frequently Asked Questions @@ -25,11 +25,11 @@ While QuakeForge itself (and the Quake source code in general) is Free Software, the game itself is not free. You need to either purchase it from id Software or you can use OpenQuartz, a -project developing GPL compatable game data for Quake. +project developing GPL compatible game data for Quake. \section git_compile_error Checking out git and running ./bootstrap creates a configure that syntax errors when I run it! What's wrong? Unlike downloading and compiling a release, when you checkout from git, you -must have all the dependencies of quakeforge already installed as when +must have all the dependencies of QuakeForge already installed as when configure is being created autotools sources m4 files... If the files do not exist, you get the errors you have seen. Try installing packages which contain the libraries that caused the syntax error, including the -dev versions, then @@ -59,5 +59,5 @@ the value appropriate for your system: \section no_mp3 Why doesn't \QF support MP3s? Because they are not free. MP3 support is a patent minefield, and we really don't want to wind up with lawyers at ten paces, especially since we'd be -unarmed with no armor, and they have rocket launchers and quad-dammage. +unarmed with no armor, and they have rocket launchers and quad-damage. */ diff --git a/doc/filesystem.dox b/doc/filesystem.dox index bfe230be8..699e7064a 100644 --- a/doc/filesystem.dox +++ b/doc/filesystem.dox @@ -47,6 +47,6 @@ same as Quake (an \c id1 directory tree, plus other mod directories), but with the addition of a \c QF directory which holds QuakeForge specific data (such as the menus). The structure of the data trees and, more importantly, the relationship between the mod directories can be configured with the -directory configurtion file (see \ref dirconf). +directory configuration file (see \ref dirconf). */ diff --git a/doc/property-list.dox b/doc/property-list.dox index bc4338c00..e2c680fb2 100644 --- a/doc/property-list.dox +++ b/doc/property-list.dox @@ -1,4 +1,4 @@ -//unfortunatly, have to wrap the docs in a C comment for doxygen +//unfortunately, have to wrap the docs in a C comment for doxygen /** \page property-list Property List @@ -21,7 +21,7 @@ represented by a property list. In addition, property lists also support comments, both single-line and multi-line. Single-line comments start with \c // and continue to the end -of the line. Multi-line comments begine with +of the line. Multi-line comments begin with /* and end with */, and may span multiple lines, or be contained entirely within a single line, possibly with non-comment text @@ -77,7 +77,7 @@ abcdefghijklmnopqrstuvwxyz!#$%&*+-./:?@|~_^ Quoted strings may contain whitespace, C escape sequences, and any printable character. The quote character is \c \". -Long strings use tripple quotes (\c \"\"\") instead of \c \" as the quote +Long strings use triple quotes (\c \"\"\") instead of \c \" as the quote character. This allows the use of unquoted \c \" characters in the string. And yes, these long strings were inspired by Python's long strings. diff --git a/doc/quakeforge.dox b/doc/quakeforge.dox index 7744230e4..547871bd5 100644 --- a/doc/quakeforge.dox +++ b/doc/quakeforge.dox @@ -1,11 +1,11 @@ -//unfortunatly, have to wrap the docs in a C comment for doxygen +//unfortunately, have to wrap the docs in a C comment for doxygen /** \mainpage QuakeForge QuakeForge is a 3D graphics game engine based on id Software's legendary Quake and QuakeWorld game engine. Our purpose? To improve the state of the -game by improving the engine and making it accessable to the largest number +game by improving the engine and making it accessible to the largest number of players we can. \li \subpage build-install diff --git a/doc/tracklist.dox b/doc/tracklist.dox index 343cc2229..c298a88f0 100644 --- a/doc/tracklist.dox +++ b/doc/tracklist.dox @@ -5,7 +5,7 @@ As \QF supports playing arbitrarily sized audio files, it seemed rather obvious that \QF should be able to use them as BGM in place of the CD drive. However, requiring specific names and locations for the files seemed -overly onerous. Thus \QF looks for \c traclist.cfg in the root of the game +overly onerous. Thus \QF looks for \c tracklist.cfg in the root of the game directory (eg. \c id1, same place as \c pak0.pak, \c config.cfg, etc). Using the following \c tracklist.cfg: From 8b23e0e7f0c2943a3cade6dd972feabab48e97c7 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 20 Aug 2011 20:26:41 +0900 Subject: [PATCH 068/334] Fix yet another typo :P --- doc/quakeforge.dox | 2 +- doc/timestamps.dox | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/quakeforge.dox b/doc/quakeforge.dox index 547871bd5..f5d354f62 100644 --- a/doc/quakeforge.dox +++ b/doc/quakeforge.dox @@ -16,6 +16,6 @@ of players we can. \li \subpage dirconf \li \subpage qw_cap_spec \li \subpage qw_download_spec -\li \subpage server_timestampes +\li \subpage server_timestamps \li \subpage qtv_overview */ diff --git a/doc/timestamps.dox b/doc/timestamps.dox index 61af5b449..d024d7e41 100644 --- a/doc/timestamps.dox +++ b/doc/timestamps.dox @@ -1,6 +1,6 @@ //unfortunately, have to wrap the docs in a C comment for doxygen /** -\page server_timestampes Server Log Timestamps +\page server_timestamps Server Log Timestamps To enable time-stamped messages in the server, set the Cvar sv_timestamps to a value other than 0. When enabled, the string Cvar sv_timefmt is used to format From efce040d489ac67b12a6820154ba687ea9eae8e1 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 16 Oct 2010 12:39:56 +0900 Subject: [PATCH 069/334] Document the fields qflight uses to control lighting. --- tools/qflight/source/properties.txt | 37 +++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 tools/qflight/source/properties.txt diff --git a/tools/qflight/source/properties.txt b/tools/qflight/source/properties.txt new file mode 100644 index 000000000..85bbb86cb --- /dev/null +++ b/tools/qflight/source/properties.txt @@ -0,0 +1,37 @@ +light/_light * + halflife: "r g b i", r/g/b 0-255, i is id "light" + rgb: "r g b" + id: "intensity" +style * + light style: 0-254 +angle * + spotlight cone angle in degrees. defaults to 20 +wait + light "falloff". defaults to 1.0 +_lightradius + size of light. interacts with falloff for distance clipping (?) + defaults to 0 +color/_color + "r g b", r/g/b 0-1.0 +_attenuation + attenuation style: + linear id style. level falls off linearly from "light" at 0 to + 0 at distance "light". + radius similar to linear, but the cutoff distance is at "radius" + inverse 1/r attenuation + realistic 1/(r*r) (inverse-square) attenuation + none no attenuation, level is always "light" + havoc like realistic, but with a cutoff. +_radius + the range of the light. +_noise + noise intensity (?) +_noisetype + noise type: + random + smooth + perlin +_persistence + noise parameter +_resolution + noise parameter From 2d8b011bc8c6843d3bb55d4767e59b7129e8df73 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 16 Oct 2010 12:40:49 +0900 Subject: [PATCH 070/334] Support negative lights. --- tools/qflight/source/ltface.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tools/qflight/source/ltface.c b/tools/qflight/source/ltface.c index 6e75c42fc..b3d0cfbc6 100644 --- a/tools/qflight/source/ltface.c +++ b/tools/qflight/source/ltface.c @@ -340,16 +340,20 @@ SingleLightFace (entity_t *light, lightinfo_t *l) switch (light->attenuation) { case LIGHT_LINEAR: - add = light->light - dist; + add = fabs (light->light) - dist; break; case LIGHT_RADIUS: - add = light->light * (light->radius - dist) / light->radius; + add = fabs (light->light) * (light->radius - dist); + add /= light->radius; break; case LIGHT_INVERSE: - add = light->light / dist; + add = fabs (light->light) / dist; break; case LIGHT_REALISTIC: - add = light->light / (dist * dist); + add = fabs (light->light) / (dist * dist); + break; + case LIGHT_NO_ATTEN: + add = fabs (light->light); break; case LIGHT_LH: add = 1 / (dist * dist * lightfalloff + LIGHTDISTBIAS); From 73a280f86ac1c9c252f8d537c3841ff21ed0ee3a Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 16 Oct 2010 12:41:27 +0900 Subject: [PATCH 071/334] Handle all light types in the switch. Even though nothing is down for those types. --- tools/qflight/source/entities.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/qflight/source/entities.c b/tools/qflight/source/entities.c index 6b49fa511..f1c5803bf 100644 --- a/tools/qflight/source/entities.c +++ b/tools/qflight/source/entities.c @@ -312,6 +312,10 @@ LoadEntities (void) entity->radius = cutoff_range; } break; + case LIGHT_NO_ATTEN: + break; + case LIGHT_LH: + break; } } From 70d42cc83895e65da3a0c85c38d235e109f584ce Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 16 Oct 2010 12:42:27 +0900 Subject: [PATCH 072/334] Allow light entities to specify a named light property. --- tools/qflight/source/properties.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tools/qflight/source/properties.c b/tools/qflight/source/properties.c index 2b76469a9..0851613e9 100644 --- a/tools/qflight/source/properties.c +++ b/tools/qflight/source/properties.c @@ -175,6 +175,13 @@ set_properties (entity_t *ent, plitem_t *dict) const char *str; if (properties) { + prop = PL_ObjectForKey (properties, ent->classname); + if ((p = get_item ("_light_name", dict, 0)) + && (str = PL_String (p))) + prop = PL_ObjectForKey (properties, str); + if (!prop) + prop = PL_ObjectForKey (properties, ent->classname); + prop = PL_ObjectForKey (properties, ent->classname); if (!prop) prop = PL_ObjectForKey (properties, "default"); From ce070000549db111987b966b47c9d3a570cc8d4f Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 22 Aug 2011 10:30:35 +0900 Subject: [PATCH 073/334] Make the address comparison a little more informative. Still hunting the openbsd connection issues. It seems the address comparision isn't working. --- include/net_udp.h | 4 +++- libs/net/nm/net_dgrm.c | 2 ++ libs/net/nm/net_udp.c | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/include/net_udp.h b/include/net_udp.h index 79690f3cd..b85d69000 100644 --- a/include/net_udp.h +++ b/include/net_udp.h @@ -170,7 +170,9 @@ int UDP_GetAddrFromName (const char *name, struct qsockaddr *addr); \param addr1 The first address to compare. \param addr2 The second address to compare. - \return -1 if the family or address are different. + \return -2 if the family is different. + \return -1 if the family is the same, but the address is + different. \return 1 if the family and address are the same, but the port is different. \return 0 if everything is the same. diff --git a/libs/net/nm/net_dgrm.c b/libs/net/nm/net_dgrm.c index 732fa7c90..a4f482893 100644 --- a/libs/net/nm/net_dgrm.c +++ b/libs/net/nm/net_dgrm.c @@ -1273,6 +1273,8 @@ _Datagram_Connect (const char *host) if (ret > 0) { // is it from the right place? if (sfunc.AddrCompare (&readaddr, &sendaddr) != 0) { + Sys_MaskPrintf (SYS_NET, "%2d ", + sfunc.AddrCompare (&readaddr, &sendaddr)); Sys_MaskPrintf (SYS_NET, "%s ", sfunc.AddrToString (&readaddr)); Sys_MaskPrintf (SYS_NET, "%s\n", diff --git a/libs/net/nm/net_udp.c b/libs/net/nm/net_udp.c index 19525a963..8166b33b5 100644 --- a/libs/net/nm/net_udp.c +++ b/libs/net/nm/net_udp.c @@ -573,7 +573,7 @@ int UDP_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2) { if (addr1->qsa_family != addr2->qsa_family) - return -1; + return -2; if (((struct sockaddr_in *) addr1)->sin_addr.s_addr != ((struct sockaddr_in *) addr2)->sin_addr.s_addr) From 87ad73f146466399b64ae11ecaffdc161dec62bc Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 22 Aug 2011 18:34:52 +0900 Subject: [PATCH 074/334] Add even more info to the address comparison failure. It turns out the family check is failing. Why? --- libs/net/nm/net_dgrm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/net/nm/net_dgrm.c b/libs/net/nm/net_dgrm.c index a4f482893..ac0e87c03 100644 --- a/libs/net/nm/net_dgrm.c +++ b/libs/net/nm/net_dgrm.c @@ -1275,9 +1275,9 @@ _Datagram_Connect (const char *host) if (sfunc.AddrCompare (&readaddr, &sendaddr) != 0) { Sys_MaskPrintf (SYS_NET, "%2d ", sfunc.AddrCompare (&readaddr, &sendaddr)); - Sys_MaskPrintf (SYS_NET, "%s ", + Sys_MaskPrintf (SYS_NET, "%d %s ", readaddr.qsa_family, sfunc.AddrToString (&readaddr)); - Sys_MaskPrintf (SYS_NET, "%s\n", + Sys_MaskPrintf (SYS_NET, "%d %s\n", sendaddr.qsa_family, sfunc.AddrToString (&sendaddr)); ret = 0; continue; From a56f6b2e37e75d6e0843f4b88e099f6578c1deca Mon Sep 17 00:00:00 2001 From: Jeff Teunissen Date: Tue, 23 Aug 2011 01:31:03 -0400 Subject: [PATCH 075/334] Docs: switch to SVG for the .fig files, add borders around imgs Self-explanatory, really. --- .gitignore | 2 ++ doc/Makefile.am | 10 +++++++--- doc/doxygen.css | 2 ++ doc/qtv.dox | 2 +- doc/qtv/qwtv.fig | 2 +- include/QF/progs.h | 2 +- qtv/include/qtv.h | 2 +- 7 files changed, 15 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 39e0f7515..0ef4e1e9c 100644 --- a/.gitignore +++ b/.gitignore @@ -74,8 +74,10 @@ core /doc/man /doc/progs/vm-mem.eps /doc/progs/vm-mem.png +/doc/progs/vm-mem.svg /doc/qtv/qwtv.eps /doc/qtv/qwtv.png +/doc/qtv/qwtv.svg /doc/quakeforge.dox /doc/texinfo /doc/stamp-* diff --git a/doc/Makefile.am b/doc/Makefile.am index 395621e84..a031ecbe6 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -31,13 +31,17 @@ SUFFIXES=.eps .fig .png @mkdir -p `dirname $@` fig2dev -L ps $< $@ +.fig.svg: + @mkdir -p `dirname $@` + fig2dev -L svg $< $@ + clean-local: -rm -fr doxygen -progs/vm-mem.png: progs/vm-mem.fig +progs/vm-mem.svg: progs/vm-mem.fig progs/vm-mem.eps: progs/vm-mem.fig -qtv/qwtv.png: qtv/qwtv.fig +qtv/qwtv.svg: qtv/qwtv.fig qtv/qwtv.eps: qtv/qwtv.fig -doc: quakeforge.dox.conf progs/vm-mem.png progs/vm-mem.eps qtv/qwtv.png qtv/qwtv.eps ${DOX} +doc: quakeforge.dox.conf progs/vm-mem.svg progs/vm-mem.eps qtv/qwtv.svg qtv/qwtv.eps ${DOX} doxygen quakeforge.dox.conf diff --git a/doc/doxygen.css b/doc/doxygen.css index 3f471a8b8..cab3828e2 100644 --- a/doc/doxygen.css +++ b/doc/doxygen.css @@ -884,6 +884,8 @@ dl.bug .image { text-align: center; + background: white; + border: 2px solid #737b9c; } .dotgraph diff --git a/doc/qtv.dox b/doc/qtv.dox index 496dd7c1c..9fedff083 100644 --- a/doc/qtv.dox +++ b/doc/qtv.dox @@ -2,7 +2,7 @@ /** \page qtv_overview QF QTV overview/status. OVERVIEW: -\image html qwtv.png +\image html qwtv.svg \image latex qwtv.eps "" The server is "reserved" for playing clients. Any spectators would be diff --git a/doc/qtv/qwtv.fig b/doc/qtv/qwtv.fig index af11a6ba4..56ee4a05a 100644 --- a/doc/qtv/qwtv.fig +++ b/doc/qtv/qwtv.fig @@ -358,7 +358,7 @@ Single 3 1 1.00 60.00 120.00 10575 2850 10200 1800 4 0 0 50 -1 0 12 0.0000 4 105 555 2475 4155 server\001 -4 0 0 50 -1 0 12 0.0000 4 195 975 2475 3900 quakeword\001 +4 0 0 50 -1 0 12 0.0000 4 195 975 2475 3900 quakeworld\001 4 0 0 50 -1 0 12 0.0000 4 165 435 6075 3900 qwtv\001 4 0 0 50 -1 0 12 0.0000 4 150 495 6075 4155 proxy\001 4 0 0 45 -1 0 16 0.0000 4 255 1485 1500 6000 Player clients\001 diff --git a/include/QF/progs.h b/include/QF/progs.h index 764bfd05f..c11a941d6 100644 --- a/include/QF/progs.h +++ b/include/QF/progs.h @@ -30,7 +30,7 @@ #define __QF_progs_h /** \defgroup progs QuakeC Virtual Machine (VM) - \image html vm-mem.png + \image html vm-mem.svg \image latex vm-mem.eps "VM memory map" */ diff --git a/qtv/include/qtv.h b/qtv/include/qtv.h index fb1d5204b..452147840 100644 --- a/qtv/include/qtv.h +++ b/qtv/include/qtv.h @@ -33,7 +33,7 @@ #define __qtv_h /** \defgroup qtv QuakeForge QTV Proxy - \image html qwtv.png + \image html qwtv.svg \image latex qwtv.eps "" \ref qtv_overview */ From d2fa1e2479646304253c3f1764cfde40531fd27f Mon Sep 17 00:00:00 2001 From: Jeff Teunissen Date: Tue, 23 Aug 2011 01:33:00 -0400 Subject: [PATCH 076/334] QW IPv6: lose a pointless assign We already assign a->family earlier, no need to do it again. --- libs/net/nc/net_udp6.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libs/net/nc/net_udp6.c b/libs/net/nc/net_udp6.c index 8b261db2e..5c432fbf8 100644 --- a/libs/net/nc/net_udp6.c +++ b/libs/net/nc/net_udp6.c @@ -185,7 +185,6 @@ SockadrToNetadr (AF_address_t *s, netadr_t *a) } case AF_INET6: { memcpy (a->ip, &(s->s6.sin6_addr), sizeof (s->s6.sin6_addr)); - a->family = AF_INET6; a->port = s->s6.sin6_port; break; } From 1cc2b1b1787d71b1009684fda6810870b5f9f602 Mon Sep 17 00:00:00 2001 From: Jeff Teunissen Date: Tue, 23 Aug 2011 01:33:51 -0400 Subject: [PATCH 077/334] whitespace --- libs/net/nc/net_udp6.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libs/net/nc/net_udp6.c b/libs/net/nc/net_udp6.c index 5c432fbf8..6407cce77 100644 --- a/libs/net/nc/net_udp6.c +++ b/libs/net/nc/net_udp6.c @@ -207,6 +207,7 @@ NET_AdrIsLoopback (netadr_t a) return false; } */ + qboolean NET_CompareBaseAdr (netadr_t a, netadr_t b) { @@ -237,7 +238,7 @@ NET_AdrToString (netadr_t a) string returned from NET_BaseAdrToString() */ memset (&ss, 0, sizeof (ss)); - NetadrToSockadr(&a,&ss); + NetadrToSockadr (&a, &ss); // Convert any "mapped" addresses back to v4 if (a.family == AF_INET6 && IN6_IS_ADDR_V4MAPPED (&(ss.s6.sin6_addr))) { @@ -272,7 +273,7 @@ NET_BaseAdrToString (netadr_t a) AF_address_t ss; memset (&ss, 0, sizeof (ss)); - NetadrToSockadr(&a,&ss); + NetadrToSockadr (&a, &ss); // Convert any "mapped" addresses back to v4 if (a.family == AF_INET6 && IN6_IS_ADDR_V4MAPPED (&(ss.s6.sin6_addr))) { From 6fb6b0c4e470137363b4a8f696dda62f995b7128 Mon Sep 17 00:00:00 2001 From: Jeff Teunissen Date: Tue, 23 Aug 2011 02:18:11 -0400 Subject: [PATCH 078/334] ignore the renamed doxy conf Is there a reason it's not just called Doxyfile / Doxyfile.in ? --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 0ef4e1e9c..7de7a36b9 100644 --- a/.gitignore +++ b/.gitignore @@ -78,7 +78,7 @@ core /doc/qtv/qwtv.eps /doc/qtv/qwtv.png /doc/qtv/qwtv.svg -/doc/quakeforge.dox +/doc/quakeforge.dox.conf /doc/texinfo /doc/stamp-* /doc/aclocal.m4 From 0d5bebabe235f900c7b2049432b43ce9c4c6439b Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 24 Aug 2011 09:14:02 +0900 Subject: [PATCH 079/334] Replace qsockaddr with AF_address_t. It seems qsockaddr's assumptions aren't necessarily portable, as OpenBSD seems to be doing weird things with qsa_family. Even if that's not the case, this is cleaner. --- include/net_udp.h | 20 +++++----- include/netmain.h | 48 +++++++++++++++--------- libs/net/nm/net_dgrm.c | 38 +++++++++---------- libs/net/nm/net_udp.c | 83 +++++++++++++++++++----------------------- nq/source/sys_sdl.c | 4 +- nq/source/sys_unix.c | 4 +- nq/source/sys_unixd.c | 4 +- nq/source/sys_win.c | 4 +- nq/source/sys_wind.c | 4 +- 9 files changed, 107 insertions(+), 102 deletions(-) diff --git a/include/net_udp.h b/include/net_udp.h index b85d69000..0931f38bb 100644 --- a/include/net_udp.h +++ b/include/net_udp.h @@ -80,7 +80,7 @@ int UDP_CloseSocket (int socket); \param addr The address to which very little will be done. \return 0 */ -int UDP_Connect (int socket, struct qsockaddr *addr); +int UDP_Connect (int socket, AF_address_t *addr); /** Check for incoming packets on the accept socket. @@ -96,7 +96,7 @@ int UDP_CheckNewConnections (void); \param[out] addr The address from which the packet originated. \return The number of bytes read or -1 on error. */ -int UDP_Read (int socket, byte *buf, int len, struct qsockaddr *addr); +int UDP_Read (int socket, byte *buf, int len, AF_address_t *addr); /** Send a packet via the specified socket to the specified address. @@ -106,7 +106,7 @@ int UDP_Read (int socket, byte *buf, int len, struct qsockaddr *addr); \param addr The addres to which the packet will be sent. \return The number of bytes sent or -1 on error. */ -int UDP_Write (int socket, byte *buf, int len, struct qsockaddr *addr); +int UDP_Write (int socket, byte *buf, int len, AF_address_t *addr); /** Broadcast a packet via the specified socket. @@ -130,7 +130,7 @@ int UDP_Broadcast (int socket, byte *buf, int len); \param addr The address to convert. \return The address in human readable form. */ -const char *UDP_AddrToString (struct qsockaddr *addr); +const char *UDP_AddrToString (AF_address_t *addr); /** Retrieve the address to which the socket is bound. @@ -138,7 +138,7 @@ const char *UDP_AddrToString (struct qsockaddr *addr); \param[out] addr The address to which the socket is bound. \return 0 */ -int UDP_GetSocketAddr (int socket, struct qsockaddr *addr); +int UDP_GetSocketAddr (int socket, AF_address_t *addr); /** Convert an address to a hostname. @@ -147,7 +147,7 @@ int UDP_GetSocketAddr (int socket, struct qsockaddr *addr); \bug No checking is done on the size of the buffer, and uses strcpy. */ -int UDP_GetNameFromAddr (struct qsockaddr *addr, char *name); +int UDP_GetNameFromAddr (AF_address_t *addr, char *name); /** Convert a human readable address to a quake address. @@ -162,7 +162,7 @@ int UDP_GetNameFromAddr (struct qsockaddr *addr, char *name); \param addr The resulting address of the conversion. \return 0 if the conversion is successful, otherwise -1. */ -int UDP_GetAddrFromName (const char *name, struct qsockaddr *addr); +int UDP_GetAddrFromName (const char *name, AF_address_t *addr); /** Compare two network addresses. @@ -177,14 +177,14 @@ int UDP_GetAddrFromName (const char *name, struct qsockaddr *addr); is different. \return 0 if everything is the same. */ -int UDP_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2); +int UDP_AddrCompare (AF_address_t *addr1, AF_address_t *addr2); /** Get the port number from the socket address. \param addr The socket address from which to retrieve the port number. \return The port number. */ -int UDP_GetSocketPort (struct qsockaddr *addr); +int UDP_GetSocketPort (AF_address_t *addr); /** Set the port number of the socket address. @@ -192,7 +192,7 @@ int UDP_GetSocketPort (struct qsockaddr *addr); \param port The port number to which the socket address will be set. \return 0 */ -int UDP_SetSocketPort (struct qsockaddr *addr, int port); +int UDP_SetSocketPort (AF_address_t *addr, int port); //@} diff --git a/include/netmain.h b/include/netmain.h index 57d989a4a..7c0df05b9 100644 --- a/include/netmain.h +++ b/include/netmain.h @@ -29,6 +29,15 @@ #ifndef __net_h #define __net_h +#ifdef HAVE_SYS_SOCKET_H +# include +#endif +#ifdef HAVE_NETINET_IN_H +# define model_t sun_model_t +# include +# undef model_t +#endif + #include "QF/quakeio.h" #include "QF/sizebuf.h" @@ -37,11 +46,14 @@ */ //@{ -struct qsockaddr { - short qsa_family; - unsigned char qsa_data[14]; -}; - +typedef union address { + struct sockaddr_storage ss; + struct sockaddr sa; + struct sockaddr_in s4; +#ifdef HAVE_IPV6 + struct sockaddr_in6 s6; +#endif +} AF_address_t; #define NET_NAMELEN 64 @@ -193,8 +205,8 @@ typedef struct qsocket_s { /// \name socket address //@{ - struct qsockaddr addr; - char address[NET_NAMELEN]; ///< Human readable form. + AF_address_t addr; + char address[NET_NAMELEN]; ///< Human readable form. //@} } qsocket_t; @@ -254,7 +266,7 @@ typedef struct { int maxusers; int driver; int ldriver; - struct qsockaddr addr; + AF_address_t addr; } hostcache_t; extern int hostCacheCount; @@ -401,18 +413,18 @@ typedef struct { void (*Listen) (qboolean state); int (*OpenSocket) (int port); int (*CloseSocket) (int socket); - int (*Connect) (int socket, struct qsockaddr *addr); + int (*Connect) (int socket, AF_address_t *addr); int (*CheckNewConnections) (void); - int (*Read) (int socket, byte *buf, int len, struct qsockaddr *addr); - int (*Write) (int socket, byte *buf, int len, struct qsockaddr *addr); + int (*Read) (int socket, byte *buf, int len, AF_address_t *addr); + int (*Write) (int socket, byte *buf, int len, AF_address_t *addr); int (*Broadcast) (int socket, byte *buf, int len); - const char * (*AddrToString) (struct qsockaddr *addr); - int (*GetSocketAddr) (int socket, struct qsockaddr *addr); - int (*GetNameFromAddr) (struct qsockaddr *addr, char *name); - int (*GetAddrFromName) (const char *name, struct qsockaddr *addr); - int (*AddrCompare) (struct qsockaddr *addr1, struct qsockaddr *addr2); - int (*GetSocketPort) (struct qsockaddr *addr); - int (*SetSocketPort) (struct qsockaddr *addr, int port); + const char * (*AddrToString) (AF_address_t *addr); + int (*GetSocketAddr) (int socket, AF_address_t *addr); + int (*GetNameFromAddr) (AF_address_t *addr, char *name); + int (*GetAddrFromName) (const char *name, AF_address_t *addr); + int (*AddrCompare) (AF_address_t *addr1, AF_address_t *addr2); + int (*GetSocketPort) (AF_address_t *addr); + int (*SetSocketPort) (AF_address_t *addr, int port); } net_landriver_t; extern int net_numlandrivers; diff --git a/libs/net/nm/net_dgrm.c b/libs/net/nm/net_dgrm.c index ac0e87c03..8897febd3 100644 --- a/libs/net/nm/net_dgrm.c +++ b/libs/net/nm/net_dgrm.c @@ -299,7 +299,7 @@ Datagram_GetMessage (qsocket_t *sock) unsigned int length; unsigned int flags; int ret = 0; - struct qsockaddr readaddr; + AF_address_t readaddr; unsigned int sequence; unsigned int count; @@ -491,7 +491,7 @@ PollProcedure testPollProcedure = { NULL, 0.0, Test_Poll }; static void Test_Poll (void *unused) { - struct qsockaddr clientaddr; + AF_address_t clientaddr; int control; int len; char name[32]; //FIXME: overflow @@ -552,7 +552,7 @@ Test_f (void) const char *host; int n; int max = MAX_SCOREBOARD; - struct qsockaddr sendaddr; + AF_address_t sendaddr; if (testInProgress) return; @@ -568,7 +568,7 @@ Test_f (void) max = hostcache[n].maxusers; memcpy (&sendaddr, &hostcache[n].addr, - sizeof (struct qsockaddr)); + sizeof (AF_address_t)); break; } if (n < hostCacheCount) @@ -623,7 +623,7 @@ PollProcedure test2PollProcedure = { NULL, 0.0, Test2_Poll }; static void Test2_Poll (void *unused) { - struct qsockaddr clientaddr; + AF_address_t clientaddr; int control; int len; char name[256]; //FIXME: overflow @@ -689,7 +689,7 @@ Test2_f (void) { const char *host; int n; - struct qsockaddr sendaddr; + AF_address_t sendaddr; if (test2InProgress) return; @@ -704,7 +704,7 @@ Test2_f (void) net_landriverlevel = hostcache[n].ldriver; memcpy (&sendaddr, &hostcache[n].addr, - sizeof (struct qsockaddr)); + sizeof (AF_address_t)); break; } if (n < hostCacheCount) @@ -814,8 +814,8 @@ Datagram_Listen (qboolean state) static qsocket_t * _Datagram_CheckNewConnections (void) { - struct qsockaddr clientaddr; - struct qsockaddr newaddr; + AF_address_t clientaddr; + AF_address_t newaddr; int newsock; int acceptsock; qsocket_t *sock; @@ -977,10 +977,10 @@ _Datagram_CheckNewConnections (void) } #ifdef BAN_TEST // check for a ban - if (clientaddr.qsa_family == AF_INET) { + if (clientaddr.sa.sa_family == AF_INET) { unsigned testAddr; - testAddr = ((struct sockaddr_in *) &clientaddr)->sin_addr.s_addr; + testAddr = clientaddr.s4.sin_addr.s_addr; if ((testAddr & banMask) == banAddr) { SZ_Clear (net_message->message); // save space for the header, filled in later @@ -1108,8 +1108,8 @@ _Datagram_SearchForHosts (qboolean xmit) int ret; int n; int i; - struct qsockaddr readaddr; - struct qsockaddr myaddr; + AF_address_t readaddr; + AF_address_t myaddr; int control; dfunc.GetSocketAddr (dfunc.controlSock, &myaddr); @@ -1180,7 +1180,7 @@ _Datagram_SearchForHosts (qboolean xmit) strcpy (hostcache[n].name, "*"); strcat (hostcache[n].name, hostcache[n].cname); } - memcpy (&hostcache[n].addr, &readaddr, sizeof (struct qsockaddr)); + memcpy (&hostcache[n].addr, &readaddr, sizeof (AF_address_t)); hostcache[n].driver = net_driverlevel; hostcache[n].ldriver = net_landriverlevel; @@ -1219,8 +1219,8 @@ Datagram_SearchForHosts (qboolean xmit) static qsocket_t * _Datagram_Connect (const char *host) { - struct qsockaddr sendaddr; - struct qsockaddr readaddr; + AF_address_t sendaddr; + AF_address_t readaddr; qsocket_t *sock; int newsock; int ret; @@ -1275,9 +1275,9 @@ _Datagram_Connect (const char *host) if (sfunc.AddrCompare (&readaddr, &sendaddr) != 0) { Sys_MaskPrintf (SYS_NET, "%2d ", sfunc.AddrCompare (&readaddr, &sendaddr)); - Sys_MaskPrintf (SYS_NET, "%d %s ", readaddr.qsa_family, + Sys_MaskPrintf (SYS_NET, "%d %s ", readaddr.sa.sa_family, sfunc.AddrToString (&readaddr)); - Sys_MaskPrintf (SYS_NET, "%d %s\n", sendaddr.qsa_family, + Sys_MaskPrintf (SYS_NET, "%d %s\n", sendaddr.sa.sa_family, sfunc.AddrToString (&sendaddr)); ret = 0; continue; @@ -1338,7 +1338,7 @@ _Datagram_Connect (const char *host) } if (ret == CCREP_ACCEPT) { - memcpy (&sock->addr, &sendaddr, sizeof (struct qsockaddr)); + memcpy (&sock->addr, &sendaddr, sizeof (AF_address_t)); dfunc.SetSocketPort (&sock->addr, MSG_ReadLong (net_message)); } else { diff --git a/libs/net/nm/net_udp.c b/libs/net/nm/net_udp.c index 8166b33b5..ae57dd393 100644 --- a/libs/net/nm/net_udp.c +++ b/libs/net/nm/net_udp.c @@ -91,6 +91,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "compat.h" #include "netmain.h" +#include "net_udp.h" #ifdef _WIN32 # undef EWOULDBLOCK @@ -115,12 +116,10 @@ static int net_acceptsocket = -1; // socket for fielding new // connections static int net_controlsocket; static int net_broadcastsocket = 0; -static struct qsockaddr broadcastaddr; +static AF_address_t broadcastaddr; static uint32_t myAddr; -#include "net_udp.h" - static int num_ifaces; uint32_t *ifaces; uint32_t *default_iface; @@ -177,7 +176,7 @@ UDP_Init (void) { struct hostent *local; char buff[MAXHOSTNAMELEN]; - struct qsockaddr addr; + AF_address_t addr; char *colon; #ifdef _WIN32 WSADATA winsockdata; @@ -318,7 +317,7 @@ UDP_CloseSocket (int socket) the local network components to fill in the rest */ static int -PartialIPAddress (const char *in, struct qsockaddr *hostaddr) +PartialIPAddress (const char *in, AF_address_t *hostaddr) { char *buff; char *b; @@ -353,11 +352,9 @@ PartialIPAddress (const char *in, struct qsockaddr *hostaddr) else port = net_hostport; - hostaddr->qsa_family = AF_INET; - ((struct sockaddr_in *) hostaddr)->sin_port = htons ((short) port); - - ((struct sockaddr_in *) hostaddr)->sin_addr.s_addr = - (myAddr & htonl (mask)) | htonl (addr); + hostaddr->sa.sa_family = AF_INET; + hostaddr->s4.sin_port = htons ((short) port); + hostaddr->s4.sin_addr.s_addr = (myAddr & htonl (mask)) | htonl (addr); free (buff); return 0; @@ -367,7 +364,7 @@ error: } int -UDP_Connect (int socket, struct qsockaddr *addr) +UDP_Connect (int socket, AF_address_t *addr) { return 0; } @@ -376,8 +373,8 @@ int UDP_CheckNewConnections (void) { unsigned long available; - struct sockaddr_in from; - socklen_t fromlen; + AF_address_t from; + socklen_t fromlen = sizeof (from); char buff[1]; if (net_acceptsocket == -1) @@ -397,7 +394,7 @@ UDP_CheckNewConnections (void) } int -UDP_Read (int socket, byte *buf, int len, struct qsockaddr *addr) +UDP_Read (int socket, byte *buf, int len, AF_address_t *addr) { int ret; #ifdef HAVE_IN_PKTINFO @@ -438,7 +435,7 @@ UDP_Read (int socket, byte *buf, int len, struct qsockaddr *addr) UDP_AddrToString (addr), info ? info->ipi_ifindex - 1 : -1, last_iface ? inet_ntoa (info->ipi_addr) : "?"); #else - socklen_t addrlen = sizeof (struct qsockaddr); + socklen_t addrlen = sizeof (AF_address_t); ret = recvfrom (socket, buf, len, 0, (struct sockaddr *) addr, &addrlen); if (ret == -1 && (errno == EWOULDBLOCK || errno == ECONNREFUSED)) @@ -483,12 +480,12 @@ UDP_Broadcast (int socket, byte *buf, int len) } int -UDP_Write (int socket, byte *buf, int len, struct qsockaddr *addr) +UDP_Write (int socket, byte *buf, int len, AF_address_t *addr) { int ret; ret = sendto (socket, buf, len, 0, (struct sockaddr *) addr, - sizeof (struct qsockaddr)); + sizeof (AF_address_t)); if (ret == -1 && errno == EWOULDBLOCK) return 0; Sys_MaskPrintf (SYS_NET, "sent %d bytes to %s\n", ret, UDP_AddrToString (addr)); @@ -496,7 +493,7 @@ UDP_Write (int socket, byte *buf, int len, struct qsockaddr *addr) } const char * -UDP_AddrToString (struct qsockaddr *addr) +UDP_AddrToString (AF_address_t *addr) { static dstring_t *buffer; int haddr; @@ -504,40 +501,39 @@ UDP_AddrToString (struct qsockaddr *addr) if (!buffer) buffer = dstring_new (); - haddr = ntohl (((struct sockaddr_in *) addr)->sin_addr.s_addr); + haddr = ntohl (addr->s4.sin_addr.s_addr); dsprintf (buffer, "%d.%d.%d.%d:%d", (haddr >> 24) & 0xff, (haddr >> 16) & 0xff, (haddr >> 8) & 0xff, haddr & 0xff, - ntohs (((struct sockaddr_in *) addr)->sin_port)); + ntohs (addr->s4.sin_port)); return buffer->str; } int -UDP_GetSocketAddr (int socket, struct qsockaddr *addr) +UDP_GetSocketAddr (int socket, AF_address_t *addr) { unsigned int a; - socklen_t addrlen = sizeof (struct qsockaddr); + socklen_t addrlen = sizeof (AF_address_t); - memset (addr, 0, sizeof (struct qsockaddr)); + memset (addr, 0, sizeof (AF_address_t)); getsockname (socket, (struct sockaddr *) addr, &addrlen); - a = ((struct sockaddr_in *) addr)->sin_addr.s_addr; + a = addr->s4.sin_addr.s_addr; if (a == 0 || a == inet_addr ("127.0.0.1")) { - ((struct sockaddr_in *) addr)->sin_addr.s_addr = *default_iface; + addr->s4.sin_addr.s_addr = *default_iface; if (last_iface) - ((struct sockaddr_in *) addr)->sin_addr.s_addr = *last_iface; + addr->s4.sin_addr.s_addr = *last_iface; } return 0; } int -UDP_GetNameFromAddr (struct qsockaddr *addr, char *name) +UDP_GetNameFromAddr (AF_address_t *addr, char *name) { struct hostent *hostentry; - hostentry = - gethostbyaddr ((char *) &((struct sockaddr_in *) addr)->sin_addr, - sizeof (struct in_addr), AF_INET); + hostentry = gethostbyaddr ((char *) &addr->s4.sin_addr, + sizeof (struct in_addr), AF_INET); if (hostentry) { strncpy (name, (char *) hostentry->h_name, NET_NAMELEN - 1); @@ -549,7 +545,7 @@ UDP_GetNameFromAddr (struct qsockaddr *addr, char *name) } int -UDP_GetAddrFromName (const char *name, struct qsockaddr *addr) +UDP_GetAddrFromName (const char *name, AF_address_t *addr) { struct hostent *hostentry; @@ -560,41 +556,38 @@ UDP_GetAddrFromName (const char *name, struct qsockaddr *addr) if (!hostentry) return -1; - addr->qsa_family = AF_INET; - ((struct sockaddr_in *) addr)->sin_port = htons (net_hostport); + addr->sa.sa_family = AF_INET; + addr->s4.sin_port = htons (net_hostport); - ((struct sockaddr_in *) addr)->sin_addr.s_addr = - *(int *) hostentry->h_addr_list[0]; + addr->s4.sin_addr.s_addr = *(uint32_t *) hostentry->h_addr_list[0]; return 0; } int -UDP_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2) +UDP_AddrCompare (AF_address_t *addr1, AF_address_t *addr2) { - if (addr1->qsa_family != addr2->qsa_family) + if (addr1->sa.sa_family != addr2->sa.sa_family) return -2; - if (((struct sockaddr_in *) addr1)->sin_addr.s_addr != - ((struct sockaddr_in *) addr2)->sin_addr.s_addr) + if (addr1->s4.sin_addr.s_addr != addr2->s4.sin_addr.s_addr) return -1; - if (((struct sockaddr_in *) addr1)->sin_port != - ((struct sockaddr_in *) addr2)->sin_port) + if (addr1->s4.sin_port != addr2->s4.sin_port) return 1; return 0; } int -UDP_GetSocketPort (struct qsockaddr *addr) +UDP_GetSocketPort (AF_address_t *addr) { - return ntohs (((struct sockaddr_in *) addr)->sin_port); + return ntohs (addr->s4.sin_port); } int -UDP_SetSocketPort (struct qsockaddr *addr, int port) +UDP_SetSocketPort (AF_address_t *addr, int port) { - ((struct sockaddr_in *) addr)->sin_port = htons (port); + addr->s4.sin_port = htons (port); return 0; } diff --git a/nq/source/sys_sdl.c b/nq/source/sys_sdl.c index e6543b3ee..fe9c38cab 100644 --- a/nq/source/sys_sdl.c +++ b/nq/source/sys_sdl.c @@ -100,7 +100,7 @@ startup (void) } static void -shutdown (void) +shutdown_f (void) { #ifndef _WIN32 fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~O_NONBLOCK); @@ -131,7 +131,7 @@ SDL_main (int c, char **v) #endif Sys_RegisterShutdown (Host_Shutdown); - Sys_RegisterShutdown (shutdown); + Sys_RegisterShutdown (shutdown_f); Host_Init (); diff --git a/nq/source/sys_unix.c b/nq/source/sys_unix.c index 5ed1bfbd0..895c6aba1 100644 --- a/nq/source/sys_unix.c +++ b/nq/source/sys_unix.c @@ -62,7 +62,7 @@ static __attribute__ ((used)) const char rcsid[] = qboolean isDedicated = false; static void -shutdown (void) +shutdown_f (void) { // change stdin to blocking fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~O_NONBLOCK); @@ -85,7 +85,7 @@ main (int c, const char *v[]) fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) | O_NONBLOCK); Sys_RegisterShutdown (Host_Shutdown); - Sys_RegisterShutdown (shutdown); + Sys_RegisterShutdown (shutdown_f); Host_Init (); diff --git a/nq/source/sys_unixd.c b/nq/source/sys_unixd.c index 62f8f8357..9a19e326a 100644 --- a/nq/source/sys_unixd.c +++ b/nq/source/sys_unixd.c @@ -60,7 +60,7 @@ qboolean isDedicated = true; int nostdout = 0; static void -shutdown (void) +shutdown_f (void) { fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~O_NONBLOCK); fflush (stdout); @@ -95,7 +95,7 @@ main (int argc, const char **argv) fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) | O_NONBLOCK); Sys_RegisterShutdown (Host_Shutdown); - Sys_RegisterShutdown (shutdown); + Sys_RegisterShutdown (shutdown_f); Host_Init (); diff --git a/nq/source/sys_win.c b/nq/source/sys_win.c index 0ae97bbf6..d9660d6c1 100644 --- a/nq/source/sys_win.c +++ b/nq/source/sys_win.c @@ -112,7 +112,7 @@ startup (void) } static void -shutdown (void) +shutdown_f (void) { if (tevent) CloseHandle (tevent); @@ -214,7 +214,7 @@ WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, Host_Init (); Sys_RegisterShutdown (Host_Shutdown); - Sys_RegisterShutdown (shutdown); + Sys_RegisterShutdown (shutdown_f); oldtime = Sys_DoubleTime (); diff --git a/nq/source/sys_wind.c b/nq/source/sys_wind.c index ea8c53780..c85ee0076 100644 --- a/nq/source/sys_wind.c +++ b/nq/source/sys_wind.c @@ -48,7 +48,7 @@ static __attribute__ ((used)) const char rcsid[] = qboolean isDedicated = true; static void -shutdown (void) +shutdown_f (void) { } @@ -84,7 +84,7 @@ main (int argc, const char **argv) host_parms.argv = com_argv; Sys_RegisterShutdown (Host_Shutdown); - Sys_RegisterShutdown (shutdown); + Sys_RegisterShutdown (shutdown_f); Host_Init (); From f75b0a611be5c8ba235e7fb9bf8471bc22c03f05 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 25 Aug 2011 22:35:20 +0900 Subject: [PATCH 080/334] Some compile fixes for OpenBSD --- include/netmain.h | 1 + libs/audio/renderer/Makefile.am | 2 +- libs/audio/renderer/snd_mem.c | 2 +- libs/audio/targets/snd_sun.c | 20 +++++++++++++------- libs/console/server.c | 2 +- libs/gamecode/engine/pr_parse.c | 2 +- libs/gib/regex.c | 2 +- libs/ruamoko/rua_obj.c | 2 +- libs/ruamoko/rua_string.c | 2 +- libs/util/qfplist.c | 2 +- libs/util/quakefs.c | 2 +- libs/util/quakeio.c | 2 +- libs/video/renderer/gl/gl_sky_clip.c | 2 +- libs/video/targets/old_keys.c | 2 +- qw/source/cl_main.c | 2 +- qw/source/sv_pr_cpqw.c | 2 +- tools/qfbsp/source/qfbsp.c | 2 +- tools/qfbsp/source/winding.c | 2 +- tools/qflight/source/vis.c | 2 +- 19 files changed, 31 insertions(+), 24 deletions(-) diff --git a/include/netmain.h b/include/netmain.h index 7c0df05b9..a6699f86d 100644 --- a/include/netmain.h +++ b/include/netmain.h @@ -29,6 +29,7 @@ #ifndef __net_h #define __net_h +#include #ifdef HAVE_SYS_SOCKET_H # include #endif diff --git a/libs/audio/renderer/Makefile.am b/libs/audio/renderer/Makefile.am index abc37e600..f28f99b66 100644 --- a/libs/audio/renderer/Makefile.am +++ b/libs/audio/renderer/Makefile.am @@ -1,6 +1,6 @@ AUTOMAKE_OPTIONS= foreign -AM_CFLAGS= @PREFER_PIC@ @VORBIS_CFLAGS@ @OGG_CFLAGS@ +AM_CFLAGS= @PREFER_PIC@ @VORBIS_CFLAGS@ @OGG_CFLAGS@ @SAMPLERATE_CFLAGS@ INCLUDES= -I$(top_srcdir)/include plugin_ldflags= @plugin_ldflags@ -avoid-version -module -rpath $(plugindir) plugin_libadd= @plugin_libadd@ diff --git a/libs/audio/renderer/snd_mem.c b/libs/audio/renderer/snd_mem.c index 6452657a4..5463dbb17 100644 --- a/libs/audio/renderer/snd_mem.c +++ b/libs/audio/renderer/snd_mem.c @@ -38,7 +38,7 @@ static __attribute__ ((used)) const char rcsid[] = # include #endif -#ifdef HAVE_MALLOC_H +#if defined(_WIN32) && defined(HAVE_MALLOC_H) #include #endif diff --git a/libs/audio/targets/snd_sun.c b/libs/audio/targets/snd_sun.c index 493f37cb0..8400487ad 100644 --- a/libs/audio/targets/snd_sun.c +++ b/libs/audio/targets/snd_sun.c @@ -36,6 +36,12 @@ static __attribute__ ((used)) const char rcsid[] = #ifdef HAVE_UNISTD_H # include #endif +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif #include #include @@ -59,7 +65,7 @@ static int audio_fd; static int snd_inited; static int snd_blocked = 0; -static int wbufp; +static unsigned int wbufp; static audio_info_t info; #define BUFFER_SIZE 8192 @@ -141,8 +147,8 @@ SNDDMA_Init (void) sn.channels = 2; } - sn.samples = sizeof (dma_buffer) / (sn.samplebits / 8); - sn.samplepos = 0; + sn.frames = sizeof (dma_buffer) / (sn.samplebits / 8); + sn.framepos = 0; sn.submission_chunk = 1; sn.buffer = (unsigned char *) dma_buffer; @@ -165,9 +171,9 @@ SNDDMA_GetDMAPos (void) return (0); } - return ((info.play.samples * sn.channels) % sn.samples); + return ((info.play.samples * sn.channels) % sn.frames); } - +#if 0 static int SNDDMA_GetSamples (void) { @@ -184,7 +190,7 @@ SNDDMA_GetSamples (void) return info.play.samples; } - +#endif static void SNDDMA_Shutdown (void) { @@ -219,7 +225,7 @@ SNDDMA_Submit (void) if (!bytes) return; - if (bytes > sizeof (writebuf)) { + if (bytes > (int) sizeof (writebuf)) { bytes = sizeof (writebuf); stop = wbufp + bytes / bsize; } diff --git a/libs/console/server.c b/libs/console/server.c index 3e124b788..8d5ceda0d 100644 --- a/libs/console/server.c +++ b/libs/console/server.c @@ -46,7 +46,7 @@ static __attribute__ ((used)) const char rcsid[] = #ifdef HAVE_UNISTD_H # include #endif -#ifdef HAVE_MALLOC_H +#if defined(_WIN32) && defined(HAVE_MALLOC_H) # include #endif diff --git a/libs/gamecode/engine/pr_parse.c b/libs/gamecode/engine/pr_parse.c index d7c4d39c2..9c6fddd31 100644 --- a/libs/gamecode/engine/pr_parse.c +++ b/libs/gamecode/engine/pr_parse.c @@ -40,7 +40,7 @@ static __attribute__ ((used)) const char rcsid[] = #include #include -#ifdef HAVE_MALLOC_H +#if defined(_WIN32) && defined(HAVE_MALLOC_H) #include #endif diff --git a/libs/gib/regex.c b/libs/gib/regex.c index 83962ca77..5e3b2e8b4 100644 --- a/libs/gib/regex.c +++ b/libs/gib/regex.c @@ -66,7 +66,7 @@ #ifdef STDC_HEADERS #include -#ifdef HAVE_MALLOC_H +#if defined(_WIN32) && defined(HAVE_MALLOC_H) #include #endif diff --git a/libs/ruamoko/rua_obj.c b/libs/ruamoko/rua_obj.c index 273cb4cfc..fc81e4bb8 100644 --- a/libs/ruamoko/rua_obj.c +++ b/libs/ruamoko/rua_obj.c @@ -41,7 +41,7 @@ static __attribute__ ((used)) const char rcsid[] = # include #endif -#ifdef HAVE_MALLOC_H +#if defined(_WIN32) && defined(HAVE_MALLOC_H) #include #endif diff --git a/libs/ruamoko/rua_string.c b/libs/ruamoko/rua_string.c index 5c1f2129d..f2b160fd5 100644 --- a/libs/ruamoko/rua_string.c +++ b/libs/ruamoko/rua_string.c @@ -42,7 +42,7 @@ static __attribute__ ((used)) const char rcsid[] = #endif #include -#ifdef HAVE_MALLOC_H +#if defined(_WIN32) && defined(HAVE_MALLOC_H) #include #endif diff --git a/libs/util/qfplist.c b/libs/util/qfplist.c index 3b9768fd1..ef13b7f61 100644 --- a/libs/util/qfplist.c +++ b/libs/util/qfplist.c @@ -35,7 +35,7 @@ static __attribute__ ((used)) const char rcsid[] = #include #include -#ifdef HAVE_MALLOC_H +#if defined(_WIN32) && defined(HAVE_MALLOC_H) #include #endif diff --git a/libs/util/quakefs.c b/libs/util/quakefs.c index 45cc6ea4e..43fd0e30b 100644 --- a/libs/util/quakefs.c +++ b/libs/util/quakefs.c @@ -44,7 +44,7 @@ static __attribute__ ((used)) const char rcsid[] = # include #endif -#ifdef HAVE_MALLOC_H +#if defined(_WIN32) && defined(HAVE_MALLOC_H) #include #endif diff --git a/libs/util/quakeio.c b/libs/util/quakeio.c index a3f3ae5ae..fa1cc3ff2 100644 --- a/libs/util/quakeio.c +++ b/libs/util/quakeio.c @@ -49,7 +49,7 @@ static __attribute__ ((used)) const char rcsid[] = #include #include -#ifdef HAVE_MALLOC_H +#if defined(_WIN32) && defined(HAVE_MALLOC_H) #include #endif diff --git a/libs/video/renderer/gl/gl_sky_clip.c b/libs/video/renderer/gl/gl_sky_clip.c index 836754f61..ede8c3bdf 100644 --- a/libs/video/renderer/gl/gl_sky_clip.c +++ b/libs/video/renderer/gl/gl_sky_clip.c @@ -42,7 +42,7 @@ static __attribute__ ((used)) const char rcsid[] = # include #endif -#ifdef HAVE_MALLOC_H +#if defined(_WIN32) && defined(HAVE_MALLOC_H) #include #endif diff --git a/libs/video/targets/old_keys.c b/libs/video/targets/old_keys.c index d6a4f1496..91ec1719a 100644 --- a/libs/video/targets/old_keys.c +++ b/libs/video/targets/old_keys.c @@ -44,7 +44,7 @@ static __attribute__ ((used)) const char rcsid[] = # include #endif -#ifdef HAVE_MALLOC_H +#if defined(_WIN32) && defined(HAVE_MALLOC_H) #include #endif diff --git a/qw/source/cl_main.c b/qw/source/cl_main.c index 7527126be..ca0f31989 100644 --- a/qw/source/cl_main.c +++ b/qw/source/cl_main.c @@ -56,7 +56,7 @@ static __attribute__ ((used)) const char rcsid[] = # include #endif -#ifdef HAVE_MALLOC_H +#if defined(_WIN32) && defined(HAVE_MALLOC_H) #include #endif diff --git a/qw/source/sv_pr_cpqw.c b/qw/source/sv_pr_cpqw.c index 7862ba4a7..ef5acefac 100644 --- a/qw/source/sv_pr_cpqw.c +++ b/qw/source/sv_pr_cpqw.c @@ -30,7 +30,7 @@ const char rcsid[] = "$Id: $"; #ifdef HAVE_STRINGS_H # include #endif -#ifdef HAVE_MALLOC_H +#if defined(_WIN32) && defined(HAVE_MALLOC_H) # include #endif #include diff --git a/tools/qfbsp/source/qfbsp.c b/tools/qfbsp/source/qfbsp.c index de44605f8..db55b44c2 100644 --- a/tools/qfbsp/source/qfbsp.c +++ b/tools/qfbsp/source/qfbsp.c @@ -37,7 +37,7 @@ static __attribute__ ((used)) const char rcsid[] = #ifdef HAVE_STRINGS_H # include #endif -#ifdef HAVE_MALLOC_H +#if defined(_WIN32) && defined(HAVE_MALLOC_H) #include #endif #include diff --git a/tools/qfbsp/source/winding.c b/tools/qfbsp/source/winding.c index b087e69cb..1ec35c96b 100644 --- a/tools/qfbsp/source/winding.c +++ b/tools/qfbsp/source/winding.c @@ -30,7 +30,7 @@ static __attribute__ ((used)) const char rcsid[] = #ifdef HAVE_STRINGS_H # include #endif -#ifdef HAVE_MALLOC_H +#if defined(_WIN32) && defined(HAVE_MALLOC_H) #include #endif #include diff --git a/tools/qflight/source/vis.c b/tools/qflight/source/vis.c index e34894633..97b217ad4 100644 --- a/tools/qflight/source/vis.c +++ b/tools/qflight/source/vis.c @@ -41,7 +41,7 @@ static __attribute__ ((used)) const char rcsid[] = #ifdef HAVE_STRINGS_H # include #endif -#ifdef HAVE_MALLOC_H +#if defined(_WIN32) && defined(HAVE_MALLOC_H) # include #endif From 7e5d654f3d4420d970d0462d08e5c52b6451a529 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 25 Aug 2011 23:04:02 +0900 Subject: [PATCH 081/334] Fix the accidental nukage of PNG_LIBS. Kind of silly setting PNG_LIBS to -lpng after going to the effort of using pkg-config now, isn't it :P --- config.d/compression.m4 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/config.d/compression.m4 b/config.d/compression.m4 index 3b7484a2b..b13574f64 100644 --- a/config.d/compression.m4 +++ b/config.d/compression.m4 @@ -80,12 +80,11 @@ if test "x$enable_png" != "xno"; then else AC_CHECK_LIB(png, png_set_read_fn, HAVE_PNG=yes, HAVE_PNG=no, [$LIBS]) if test "x$HAVE_PNG" = "xyes"; then - AC_CHECK_HEADER(png.h, HAVE_PNG=yes, HAVE_PNG=no) + AC_CHECK_HEADER(png.h, HAVE_PNG=yes PNG_LIBS="-lpng", HAVE_PNG=no) fi fi fi AC_SUBST(PNG_LIBS) if test "x$HAVE_PNG" = "xyes"; then - PNG_LIBS="-lpng" AC_DEFINE(HAVE_PNG, 1, [Define if you have libpng]) fi From f0b0a0f34fd4c5af9dd78fb01b17af5cb6e5252f Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 26 Aug 2011 10:43:41 +0300 Subject: [PATCH 082/334] Fix curl related building on OpenBSD. We weren't using the specified CPP flags :P. --- qw/source/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qw/source/Makefile.am b/qw/source/Makefile.am index f6c61aa23..e46e41a15 100644 --- a/qw/source/Makefile.am +++ b/qw/source/Makefile.am @@ -30,7 +30,7 @@ AUTOMAKE_OPTIONS= foreign # Stuff that is common to both client and server -INCLUDES= -I$(top_srcdir)/include -I$(top_srcdir)/qw/include +INCLUDES= -I$(top_srcdir)/include -I$(top_srcdir)/qw/include @LIBCURL_CPPFLAGS@ SDL_LIBS = @SDL_LIBS@ bin_PROGRAMS= @QW_TARGETS@ From 265ff06e8de1969783f0d4178e2eab9c0c1c683f Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 26 Aug 2011 11:14:51 +0300 Subject: [PATCH 083/334] Work around OpenBSD's overzealousness. Requiring exactly the right size (ie, no bigger) for the address buffer is going a little too far. --- include/netmain.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/netmain.h b/include/netmain.h index a6699f86d..a933313c1 100644 --- a/include/netmain.h +++ b/include/netmain.h @@ -47,12 +47,13 @@ */ //@{ +//FIXME our code is not yet ready for anything but ipv4 addresses typedef union address { - struct sockaddr_storage ss; +// struct sockaddr_storage ss; struct sockaddr sa; struct sockaddr_in s4; #ifdef HAVE_IPV6 - struct sockaddr_in6 s6; +// struct sockaddr_in6 s6; #endif } AF_address_t; From bfcdc5ed1706e3efbac7a0b7b7a2d5e79090cd3f Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 31 Aug 2011 18:07:41 +0900 Subject: [PATCH 084/334] Fix qw networking on OpenBSD. OpenBSD is very picky about the address size, but does provide sa_len and friends to make life easier. Use them as appropriate :) --- libs/net/nc/net_udp6.c | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/libs/net/nc/net_udp6.c b/libs/net/nc/net_udp6.c index 6407cce77..922c4b32e 100644 --- a/libs/net/nc/net_udp6.c +++ b/libs/net/nc/net_udp6.c @@ -140,6 +140,25 @@ typedef union address { struct sockaddr_in6 s6; } AF_address_t; +#undef SA_LEN +#undef SS_LEN + +#ifdef HAVE_SA_LEN +#define SA_LEN(sa) (sa)->sa_len +#else +#define SA_LEN(sa) (((sa)->sa_family == AF_INET6) \ + ? sizeof(struct sockaddr_in6) \ + : sizeof(struct sockaddr_in)) +#endif + +#ifdef HAVE_SS_LEN +#define SS_LEN(ss) (ss)->ss_len +#else +#define SS_LEN(ss) (((ss)->ss_family == AF_INET6) \ + ? sizeof(struct sockaddr_in6) \ + : sizeof(struct sockaddr_in)) +#endif + static void NetadrToSockadr (netadr_t *a, AF_address_t *s) @@ -249,13 +268,8 @@ NET_AdrToString (netadr_t a) memcpy (&(ss.s4.sin_addr), &ss.s6.sin6_addr.s6_addr[12], sizeof (ss.s4.sin_addr)); } -#ifdef HAVE_SS_LEN - if (getnameinfo (&ss.sa, ss.ss.ss_len, base, sizeof (base), + if (getnameinfo (&ss.sa, SS_LEN(&ss.ss), base, sizeof (base), NULL, 0, NI_NUMERICHOST)) strcpy (base, ""); -#else - if (getnameinfo (&ss.sa, sizeof (ss.ss), base, sizeof (base), - NULL, 0, NI_NUMERICHOST)) strcpy (base, ""); -#endif if (ss.ss.ss_family == AF_INET6) { sprintf (s, "[%s]:%d", base, ntohs (a.port)); @@ -281,16 +295,12 @@ NET_BaseAdrToString (netadr_t a) ss.ss.ss_len = sizeof (ss.s4); #endif ss.ss.ss_family = AF_INET; - memcpy (&(ss.s4.sin_addr), &ss.s6.sin6_addr.s6_addr[12], sizeof (ss.s4.sin_addr)); + memcpy (&(ss.s4.sin_addr), &ss.s6.sin6_addr.s6_addr[12], + sizeof (ss.s4.sin_addr)); } -#ifdef HAVE_SS_LEN - if (getnameinfo (&ss.sa, ss.ss.ss_len, s, sizeof (s), + if (getnameinfo (&ss.sa, SS_LEN(&ss.ss), s, sizeof (s), NULL, 0, NI_NUMERICHOST)) strcpy (s, ""); -#else - if (getnameinfo (&ss.sa, sizeof (ss.ss), s, sizeof (s), - NULL, 0, NI_NUMERICHOST)) strcpy (s, ""); -#endif return s; } @@ -427,7 +437,7 @@ NET_SendPacket (int length, const void *data, netadr_t to) NetadrToSockadr (&to, &addr); - ret = sendto (net_socket, data, length, 0, &addr.sa, sizeof (addr)); + ret = sendto (net_socket, data, length, 0, &addr.sa, SA_LEN (&addr.sa)); if (ret == -1) { #ifdef _WIN32 int err = WSAGetLastError (); From 29a52a8cc8f24f5153b7490e99fb68b1882b9ddb Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 31 Aug 2011 18:32:47 +0900 Subject: [PATCH 085/334] FIx it for IPv4, too. Oops, I forgot about that :P --- libs/net/nc/net_udp.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/libs/net/nc/net_udp.c b/libs/net/nc/net_udp.c index 88ecac68f..45d484762 100644 --- a/libs/net/nc/net_udp.c +++ b/libs/net/nc/net_udp.c @@ -128,6 +128,25 @@ typedef union address { struct sockaddr_in s4; } AF_address_t; +#undef SA_LEN +#undef SS_LEN + +#ifdef HAVE_SA_LEN +#define SA_LEN(sa) (sa)->sa_len +#else +#define SA_LEN(sa) (((sa)->sa_family == AF_INET6) \ + ? sizeof(struct sockaddr_in6) \ + : sizeof(struct sockaddr_in)) +#endif + +#ifdef HAVE_SS_LEN +#define SS_LEN(ss) (ss)->ss_len +#else +#define SS_LEN(ss) (((ss)->ss_family == AF_INET6) \ + ? sizeof(struct sockaddr_in6) \ + : sizeof(struct sockaddr_in)) +#endif + static void NetadrToSockadr (netadr_t *a, AF_address_t *s) @@ -299,7 +318,7 @@ NET_SendPacket (int length, const void *data, netadr_t to) NetadrToSockadr (&to, &addr); - ret = sendto (net_socket, data, length, 0, &addr.sa, sizeof (addr)); + ret = sendto (net_socket, data, length, 0, &addr.sa, SA_LEN (&addr.sa)); if (ret == -1) { #ifdef _WIN32 int err = WSAGetLastError (); @@ -350,7 +369,7 @@ UDP_OpenSocket (int port) address.s4.sin_port = 0; else address.s4.sin_port = htons ((short) port); - if (bind (newsocket, (void *) &address, sizeof (address)) == -1) + if (bind (newsocket, &address.sa, SA_LEN (&address.sa)) == -1) Sys_Error ("UDP_OpenSocket: bind: %s", strerror (errno)); return newsocket; From 80b2b82092005667c4d6c2b0c63d8c2266b6d307 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 3 Sep 2011 13:04:47 +0900 Subject: [PATCH 086/334] Add a cvar to control the address family. OpenBSD doesn't allow mixed binding of ipv4 and ipv6, but being able to use ipv6 enabled qf with ipv4 addresses would be nice... --- libs/net/nc/net_udp6.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/libs/net/nc/net_udp6.c b/libs/net/nc/net_udp6.c index 922c4b32e..b34b7d051 100644 --- a/libs/net/nc/net_udp6.c +++ b/libs/net/nc/net_udp6.c @@ -117,6 +117,8 @@ static __attribute__ ((used)) const char rcsid[] = # endif #endif +static cvar_t *net_family; + netadr_t net_from; netadr_t net_local_adr; netadr_t net_loopback_adr; @@ -329,7 +331,13 @@ NET_StringToAdr (const char *s, netadr_t *a) memset (&hints, 0, sizeof (hints)); hints.ai_socktype = SOCK_DGRAM; - hints.ai_family = PF_UNSPEC; + if (strchr (net_family->string, '6')) { + hints.ai_family = AF_INET6; + } else if (strchr (net_family->string, '4')) { + hints.ai_family = AF_INET; + } else { + hints.ai_family = AF_UNSPEC; + } dstring_copystr (copy, s); addrs = space = copy->str; @@ -568,6 +576,9 @@ NET_Init (int port) if (r) Sys_Error ("Winsock initialization failed."); #endif /* _WIN32 */ + net_family = Cvar_Get ("net_family", "unspecified", CVAR_ROM, 0, + "Set the address family to ipv4, ipv6 or" + " unspecified"); // open the single socket to be used for all communications net_socket = UDP_OpenSocket (port); From 5ee01879ec2dda14e48bf16ac64b3479a5fde9b9 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 3 Sep 2011 16:28:00 +0900 Subject: [PATCH 087/334] Missed a spot for net_family. --- libs/net/nc/net_udp6.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libs/net/nc/net_udp6.c b/libs/net/nc/net_udp6.c index b34b7d051..6112c2a31 100644 --- a/libs/net/nc/net_udp6.c +++ b/libs/net/nc/net_udp6.c @@ -493,7 +493,13 @@ UDP_OpenSocket (int port) address.sin6_family = AF_INET6; memset (&hints, 0, sizeof (hints)); - hints.ai_family = PF_UNSPEC; + if (strchr (net_family->string, '6')) { + hints.ai_family = AF_INET6; + } else if (strchr (net_family->string, '4')) { + hints.ai_family = AF_INET; + } else { + hints.ai_family = AF_UNSPEC; + } hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; hints.ai_flags = AI_PASSIVE; From e50f0e18ba1b37d7166f7481419646b43d89dede Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 4 Sep 2011 09:00:42 +0900 Subject: [PATCH 088/334] Make netmain use netadr_t, same as netchan. Having sockaddr and friends in a header file was bad news for portability (especially windows). --- include/net_udp.h | 20 +++--- include/netchan.h | 4 +- include/netmain.h | 54 ++++++-------- libs/net/nm/net_dgrm.c | 38 +++++----- libs/net/nm/net_udp.c | 159 +++++++++++++++++++++++++++-------------- 5 files changed, 160 insertions(+), 115 deletions(-) diff --git a/include/net_udp.h b/include/net_udp.h index 0931f38bb..6df3683f5 100644 --- a/include/net_udp.h +++ b/include/net_udp.h @@ -80,7 +80,7 @@ int UDP_CloseSocket (int socket); \param addr The address to which very little will be done. \return 0 */ -int UDP_Connect (int socket, AF_address_t *addr); +int UDP_Connect (int socket, netadr_t *addr); /** Check for incoming packets on the accept socket. @@ -96,7 +96,7 @@ int UDP_CheckNewConnections (void); \param[out] addr The address from which the packet originated. \return The number of bytes read or -1 on error. */ -int UDP_Read (int socket, byte *buf, int len, AF_address_t *addr); +int UDP_Read (int socket, byte *buf, int len, netadr_t *addr); /** Send a packet via the specified socket to the specified address. @@ -106,7 +106,7 @@ int UDP_Read (int socket, byte *buf, int len, AF_address_t *addr); \param addr The addres to which the packet will be sent. \return The number of bytes sent or -1 on error. */ -int UDP_Write (int socket, byte *buf, int len, AF_address_t *addr); +int UDP_Write (int socket, byte *buf, int len, netadr_t *addr); /** Broadcast a packet via the specified socket. @@ -130,7 +130,7 @@ int UDP_Broadcast (int socket, byte *buf, int len); \param addr The address to convert. \return The address in human readable form. */ -const char *UDP_AddrToString (AF_address_t *addr); +const char *UDP_AddrToString (netadr_t *addr); /** Retrieve the address to which the socket is bound. @@ -138,7 +138,7 @@ const char *UDP_AddrToString (AF_address_t *addr); \param[out] addr The address to which the socket is bound. \return 0 */ -int UDP_GetSocketAddr (int socket, AF_address_t *addr); +int UDP_GetSocketAddr (int socket, netadr_t *addr); /** Convert an address to a hostname. @@ -147,7 +147,7 @@ int UDP_GetSocketAddr (int socket, AF_address_t *addr); \bug No checking is done on the size of the buffer, and uses strcpy. */ -int UDP_GetNameFromAddr (AF_address_t *addr, char *name); +int UDP_GetNameFromAddr (netadr_t *addr, char *name); /** Convert a human readable address to a quake address. @@ -162,7 +162,7 @@ int UDP_GetNameFromAddr (AF_address_t *addr, char *name); \param addr The resulting address of the conversion. \return 0 if the conversion is successful, otherwise -1. */ -int UDP_GetAddrFromName (const char *name, AF_address_t *addr); +int UDP_GetAddrFromName (const char *name, netadr_t *addr); /** Compare two network addresses. @@ -177,14 +177,14 @@ int UDP_GetAddrFromName (const char *name, AF_address_t *addr); is different. \return 0 if everything is the same. */ -int UDP_AddrCompare (AF_address_t *addr1, AF_address_t *addr2); +int UDP_AddrCompare (netadr_t *addr1, netadr_t *addr2); /** Get the port number from the socket address. \param addr The socket address from which to retrieve the port number. \return The port number. */ -int UDP_GetSocketPort (AF_address_t *addr); +int UDP_GetSocketPort (netadr_t *addr); /** Set the port number of the socket address. @@ -192,7 +192,7 @@ int UDP_GetSocketPort (AF_address_t *addr); \param port The port number to which the socket address will be set. \return 0 */ -int UDP_SetSocketPort (AF_address_t *addr, int port); +int UDP_SetSocketPort (netadr_t *addr, int port); //@} diff --git a/include/netchan.h b/include/netchan.h index 3ed79c4a6..52b591ee5 100644 --- a/include/netchan.h +++ b/include/netchan.h @@ -49,9 +49,9 @@ typedef struct { #ifdef HAVE_IPV6 - byte ip[16]; + byte ip[16]; #else - byte ip[4]; + byte ip[4]; #endif unsigned short port; unsigned short family; diff --git a/include/netmain.h b/include/netmain.h index a933313c1..a9ce337de 100644 --- a/include/netmain.h +++ b/include/netmain.h @@ -29,16 +29,6 @@ #ifndef __net_h #define __net_h -#include -#ifdef HAVE_SYS_SOCKET_H -# include -#endif -#ifdef HAVE_NETINET_IN_H -# define model_t sun_model_t -# include -# undef model_t -#endif - #include "QF/quakeio.h" #include "QF/sizebuf.h" @@ -47,15 +37,17 @@ */ //@{ -//FIXME our code is not yet ready for anything but ipv4 addresses -typedef union address { -// struct sockaddr_storage ss; - struct sockaddr sa; - struct sockaddr_in s4; -#ifdef HAVE_IPV6 -// struct sockaddr_in6 s6; -#endif -} AF_address_t; +typedef struct +{ +//FIXME not yet ready for ipv6 +//#ifdef HAVE_IPV6 +// byte ip[16]; +//#else + byte ip[4]; +//#endif + unsigned short port; + unsigned short family; +} netadr_t; #define NET_NAMELEN 64 @@ -207,7 +199,7 @@ typedef struct qsocket_s { /// \name socket address //@{ - AF_address_t addr; + netadr_t addr; char address[NET_NAMELEN]; ///< Human readable form. //@} } qsocket_t; @@ -268,7 +260,7 @@ typedef struct { int maxusers; int driver; int ldriver; - AF_address_t addr; + netadr_t addr; } hostcache_t; extern int hostCacheCount; @@ -415,18 +407,18 @@ typedef struct { void (*Listen) (qboolean state); int (*OpenSocket) (int port); int (*CloseSocket) (int socket); - int (*Connect) (int socket, AF_address_t *addr); + int (*Connect) (int socket, netadr_t *addr); int (*CheckNewConnections) (void); - int (*Read) (int socket, byte *buf, int len, AF_address_t *addr); - int (*Write) (int socket, byte *buf, int len, AF_address_t *addr); + int (*Read) (int socket, byte *buf, int len, netadr_t *addr); + int (*Write) (int socket, byte *buf, int len, netadr_t *addr); int (*Broadcast) (int socket, byte *buf, int len); - const char * (*AddrToString) (AF_address_t *addr); - int (*GetSocketAddr) (int socket, AF_address_t *addr); - int (*GetNameFromAddr) (AF_address_t *addr, char *name); - int (*GetAddrFromName) (const char *name, AF_address_t *addr); - int (*AddrCompare) (AF_address_t *addr1, AF_address_t *addr2); - int (*GetSocketPort) (AF_address_t *addr); - int (*SetSocketPort) (AF_address_t *addr, int port); + const char * (*AddrToString) (netadr_t *addr); + int (*GetSocketAddr) (int socket, netadr_t *addr); + int (*GetNameFromAddr) (netadr_t *addr, char *name); + int (*GetAddrFromName) (const char *name, netadr_t *addr); + int (*AddrCompare) (netadr_t *addr1, netadr_t *addr2); + int (*GetSocketPort) (netadr_t *addr); + int (*SetSocketPort) (netadr_t *addr, int port); } net_landriver_t; extern int net_numlandrivers; diff --git a/libs/net/nm/net_dgrm.c b/libs/net/nm/net_dgrm.c index 8897febd3..d3d9b6f4b 100644 --- a/libs/net/nm/net_dgrm.c +++ b/libs/net/nm/net_dgrm.c @@ -299,7 +299,7 @@ Datagram_GetMessage (qsocket_t *sock) unsigned int length; unsigned int flags; int ret = 0; - AF_address_t readaddr; + netadr_t readaddr; unsigned int sequence; unsigned int count; @@ -491,7 +491,7 @@ PollProcedure testPollProcedure = { NULL, 0.0, Test_Poll }; static void Test_Poll (void *unused) { - AF_address_t clientaddr; + netadr_t clientaddr; int control; int len; char name[32]; //FIXME: overflow @@ -552,7 +552,7 @@ Test_f (void) const char *host; int n; int max = MAX_SCOREBOARD; - AF_address_t sendaddr; + netadr_t sendaddr; if (testInProgress) return; @@ -568,7 +568,7 @@ Test_f (void) max = hostcache[n].maxusers; memcpy (&sendaddr, &hostcache[n].addr, - sizeof (AF_address_t)); + sizeof (netadr_t)); break; } if (n < hostCacheCount) @@ -623,7 +623,7 @@ PollProcedure test2PollProcedure = { NULL, 0.0, Test2_Poll }; static void Test2_Poll (void *unused) { - AF_address_t clientaddr; + netadr_t clientaddr; int control; int len; char name[256]; //FIXME: overflow @@ -689,7 +689,7 @@ Test2_f (void) { const char *host; int n; - AF_address_t sendaddr; + netadr_t sendaddr; if (test2InProgress) return; @@ -704,7 +704,7 @@ Test2_f (void) net_landriverlevel = hostcache[n].ldriver; memcpy (&sendaddr, &hostcache[n].addr, - sizeof (AF_address_t)); + sizeof (netadr_t)); break; } if (n < hostCacheCount) @@ -814,8 +814,8 @@ Datagram_Listen (qboolean state) static qsocket_t * _Datagram_CheckNewConnections (void) { - AF_address_t clientaddr; - AF_address_t newaddr; + netadr_t clientaddr; + netadr_t newaddr; int newsock; int acceptsock; qsocket_t *sock; @@ -977,10 +977,10 @@ _Datagram_CheckNewConnections (void) } #ifdef BAN_TEST // check for a ban - if (clientaddr.sa.sa_family == AF_INET) { + if (clientaddr.family == AF_INET) { unsigned testAddr; - testAddr = clientaddr.s4.sin_addr.s_addr; + memcpy (&testAddr, clientaddr.ip, 4); if ((testAddr & banMask) == banAddr) { SZ_Clear (net_message->message); // save space for the header, filled in later @@ -1108,8 +1108,8 @@ _Datagram_SearchForHosts (qboolean xmit) int ret; int n; int i; - AF_address_t readaddr; - AF_address_t myaddr; + netadr_t readaddr; + netadr_t myaddr; int control; dfunc.GetSocketAddr (dfunc.controlSock, &myaddr); @@ -1180,7 +1180,7 @@ _Datagram_SearchForHosts (qboolean xmit) strcpy (hostcache[n].name, "*"); strcat (hostcache[n].name, hostcache[n].cname); } - memcpy (&hostcache[n].addr, &readaddr, sizeof (AF_address_t)); + memcpy (&hostcache[n].addr, &readaddr, sizeof (netadr_t)); hostcache[n].driver = net_driverlevel; hostcache[n].ldriver = net_landriverlevel; @@ -1219,8 +1219,8 @@ Datagram_SearchForHosts (qboolean xmit) static qsocket_t * _Datagram_Connect (const char *host) { - AF_address_t sendaddr; - AF_address_t readaddr; + netadr_t sendaddr; + netadr_t readaddr; qsocket_t *sock; int newsock; int ret; @@ -1275,9 +1275,9 @@ _Datagram_Connect (const char *host) if (sfunc.AddrCompare (&readaddr, &sendaddr) != 0) { Sys_MaskPrintf (SYS_NET, "%2d ", sfunc.AddrCompare (&readaddr, &sendaddr)); - Sys_MaskPrintf (SYS_NET, "%d %s ", readaddr.sa.sa_family, + Sys_MaskPrintf (SYS_NET, "%d %s ", readaddr.family, sfunc.AddrToString (&readaddr)); - Sys_MaskPrintf (SYS_NET, "%d %s\n", sendaddr.sa.sa_family, + Sys_MaskPrintf (SYS_NET, "%d %s\n", sendaddr.family, sfunc.AddrToString (&sendaddr)); ret = 0; continue; @@ -1338,7 +1338,7 @@ _Datagram_Connect (const char *host) } if (ret == CCREP_ACCEPT) { - memcpy (&sock->addr, &sendaddr, sizeof (AF_address_t)); + memcpy (&sock->addr, &sendaddr, sizeof (netadr_t)); dfunc.SetSocketPort (&sock->addr, MSG_ReadLong (net_message)); } else { diff --git a/libs/net/nm/net_udp.c b/libs/net/nm/net_udp.c index ae57dd393..0885a5d47 100644 --- a/libs/net/nm/net_udp.c +++ b/libs/net/nm/net_udp.c @@ -112,11 +112,57 @@ static __attribute__ ((used)) const char rcsid[] = # endif #endif +#define ADDR_SIZE 4 + +typedef union address { + struct sockaddr_storage ss; + struct sockaddr sa; + struct sockaddr_in s4; +} AF_address_t; + +#undef SA_LEN +#undef SS_LEN + +#ifdef HAVE_SA_LEN +#define SA_LEN(sa) (sa)->sa_len +#else +#define SA_LEN(sa) (((sa)->sa_family == AF_INET6) \ + ? sizeof(struct sockaddr_in6) \ + : sizeof(struct sockaddr_in)) +#endif + +#ifdef HAVE_SS_LEN +#define SS_LEN(ss) (ss)->ss_len +#else +#define SS_LEN(ss) (((ss)->ss_family == AF_INET6) \ + ? sizeof(struct sockaddr_in6) \ + : sizeof(struct sockaddr_in)) +#endif + + +static void +NetadrToSockadr (netadr_t *a, AF_address_t *s) +{ + memset (s, 0, sizeof (*s)); + s->s4.sin_family = AF_INET; + + memcpy (&s->s4.sin_addr, &a->ip, ADDR_SIZE); + s->s4.sin_port = a->port; +} + +static void +SockadrToNetadr (AF_address_t *s, netadr_t *a) +{ + memcpy (&a->ip, &s->s4.sin_addr, ADDR_SIZE); + a->port = s->s4.sin_port; + a->family = s->s4.sin_family; +} + static int net_acceptsocket = -1; // socket for fielding new // connections static int net_controlsocket; static int net_broadcastsocket = 0; -static AF_address_t broadcastaddr; +static netadr_t broadcastaddr; static uint32_t myAddr; @@ -176,7 +222,7 @@ UDP_Init (void) { struct hostent *local; char buff[MAXHOSTNAMELEN]; - AF_address_t addr; + netadr_t addr; char *colon; #ifdef _WIN32 WSADATA winsockdata; @@ -209,12 +255,11 @@ UDP_Init (void) get_iface_list (net_controlsocket); { - struct sockaddr_in t; - memcpy (&t, &broadcastaddr, sizeof (t)); - t.sin_family = AF_INET; - t.sin_addr.s_addr = INADDR_BROADCAST; - t.sin_port = htons (net_hostport); - memcpy (&broadcastaddr, &t, sizeof (broadcastaddr)); + AF_address_t t; + t.s4.sin_family = AF_INET; + t.s4.sin_addr.s_addr = INADDR_BROADCAST; + t.s4.sin_port = htons (net_hostport); + SockadrToNetadr (&t, &broadcastaddr); } UDP_GetSocketAddr (net_controlsocket, &addr); @@ -317,7 +362,7 @@ UDP_CloseSocket (int socket) the local network components to fill in the rest */ static int -PartialIPAddress (const char *in, AF_address_t *hostaddr) +PartialIPAddress (const char *in, netadr_t *hostaddr) { char *buff; char *b; @@ -352,9 +397,13 @@ PartialIPAddress (const char *in, AF_address_t *hostaddr) else port = net_hostport; - hostaddr->sa.sa_family = AF_INET; - hostaddr->s4.sin_port = htons ((short) port); - hostaddr->s4.sin_addr.s_addr = (myAddr & htonl (mask)) | htonl (addr); + hostaddr->family = AF_INET; + hostaddr->port = htons ((short) port); + { + int32_t t = myAddr & htonl (mask); + t |= htonl (addr); + memcpy (hostaddr->ip, &t, ADDR_SIZE); + } free (buff); return 0; @@ -364,7 +413,7 @@ error: } int -UDP_Connect (int socket, AF_address_t *addr) +UDP_Connect (int socket, netadr_t *addr) { return 0; } @@ -388,20 +437,20 @@ UDP_CheckNewConnections (void) // there is no way to tell between an empty packet and no packets, but // as non-blocking io is used, this is not a problem. // we don't care about the interface on which the packet arrived - recvfrom (net_acceptsocket, buff, 0, 0, (struct sockaddr *) &from, - &fromlen); + recvfrom (net_acceptsocket, buff, 0, 0, &from.sa, &fromlen); return -1; } int -UDP_Read (int socket, byte *buf, int len, AF_address_t *addr) +UDP_Read (int socket, byte *buf, int len, netadr_t *from) { int ret; + AF_address_t addr; #ifdef HAVE_IN_PKTINFO char ancillary[CMSG_SPACE (sizeof (struct in_pktinfo))]; struct msghdr msghdr = { - addr, - sizeof (*addr), + &addr, + sizeof (addr), 0, 0, ancillary, sizeof (ancillary), @@ -411,6 +460,7 @@ UDP_Read (int socket, byte *buf, int len, AF_address_t *addr) struct cmsghdr *cmsg; struct in_pktinfo *info = 0; + memset (&addr, 0, sizeof (addr)); msghdr.msg_iov = &iovec; msghdr.msg_iovlen = 1; ret = recvmsg (socket, &msghdr, 0); @@ -431,17 +481,20 @@ UDP_Read (int socket, byte *buf, int len, AF_address_t *addr) */ last_iface = &ifaces[info->ipi_ifindex - 1]; } + SockadrToNetadr (&addr, from); Sys_MaskPrintf (SYS_NET, "got %d bytes from %s on iface %d (%s)\n", ret, - UDP_AddrToString (addr), info ? info->ipi_ifindex - 1 : -1, + UDP_AddrToString (from), info ? info->ipi_ifindex - 1 : -1, last_iface ? inet_ntoa (info->ipi_addr) : "?"); #else socklen_t addrlen = sizeof (AF_address_t); - ret = recvfrom (socket, buf, len, 0, (struct sockaddr *) addr, &addrlen); + memset (&addr, 0, sizeof (addr)); + ret = recvfrom (socket, buf, len, 0, &addr, &addrlen); if (ret == -1 && (errno == EWOULDBLOCK || errno == ECONNREFUSED)) return 0; + SockadrToNetadr (&addr, from); Sys_MaskPrintf (SYS_NET, "got %d bytes from %s\n", ret, - UDP_AddrToString (addr)); + UDP_AddrToString (from)); last_iface = default_iface; #endif return ret; @@ -480,60 +533,61 @@ UDP_Broadcast (int socket, byte *buf, int len) } int -UDP_Write (int socket, byte *buf, int len, AF_address_t *addr) +UDP_Write (int socket, byte *buf, int len, netadr_t *to) { int ret; + AF_address_t addr; - ret = sendto (socket, buf, len, 0, (struct sockaddr *) addr, - sizeof (AF_address_t)); + NetadrToSockadr (to, &addr); + ret = sendto (socket, buf, len, 0, &addr.sa, SA_LEN (&addr.sa)); if (ret == -1 && errno == EWOULDBLOCK) return 0; - Sys_MaskPrintf (SYS_NET, "sent %d bytes to %s\n", ret, UDP_AddrToString (addr)); + Sys_MaskPrintf (SYS_NET, "sent %d bytes to %s\n", ret, + UDP_AddrToString (to)); return ret; } const char * -UDP_AddrToString (AF_address_t *addr) +UDP_AddrToString (netadr_t *addr) { static dstring_t *buffer; - int haddr; if (!buffer) buffer = dstring_new (); - haddr = ntohl (addr->s4.sin_addr.s_addr); - dsprintf (buffer, "%d.%d.%d.%d:%d", (haddr >> 24) & 0xff, - (haddr >> 16) & 0xff, (haddr >> 8) & 0xff, haddr & 0xff, - ntohs (addr->s4.sin_port)); + dsprintf (buffer, "%d.%d.%d.%d:%d", addr->ip[0], + addr->ip[1], addr->ip[2], addr->ip[3], + ntohs (addr->port)); return buffer->str; } int -UDP_GetSocketAddr (int socket, AF_address_t *addr) +UDP_GetSocketAddr (int socket, netadr_t *na) { unsigned int a; socklen_t addrlen = sizeof (AF_address_t); + AF_address_t addr; - memset (addr, 0, sizeof (AF_address_t)); + memset (&addr, 0, sizeof (AF_address_t)); - getsockname (socket, (struct sockaddr *) addr, &addrlen); - a = addr->s4.sin_addr.s_addr; + getsockname (socket, &addr.sa, &addrlen); + SockadrToNetadr (&addr, na); + memcpy (&a, na->ip, ADDR_SIZE); if (a == 0 || a == inet_addr ("127.0.0.1")) { - addr->s4.sin_addr.s_addr = *default_iface; + memcpy (na->ip, default_iface, ADDR_SIZE); if (last_iface) - addr->s4.sin_addr.s_addr = *last_iface; + memcpy (na->ip, last_iface, ADDR_SIZE); } return 0; } int -UDP_GetNameFromAddr (AF_address_t *addr, char *name) +UDP_GetNameFromAddr (netadr_t *addr, char *name) { struct hostent *hostentry; - hostentry = gethostbyaddr ((char *) &addr->s4.sin_addr, - sizeof (struct in_addr), AF_INET); + hostentry = gethostbyaddr (&addr->ip, ADDR_SIZE, AF_INET); if (hostentry) { strncpy (name, (char *) hostentry->h_name, NET_NAMELEN - 1); @@ -545,7 +599,7 @@ UDP_GetNameFromAddr (AF_address_t *addr, char *name) } int -UDP_GetAddrFromName (const char *name, AF_address_t *addr) +UDP_GetAddrFromName (const char *name, netadr_t *addr) { struct hostent *hostentry; @@ -556,38 +610,37 @@ UDP_GetAddrFromName (const char *name, AF_address_t *addr) if (!hostentry) return -1; - addr->sa.sa_family = AF_INET; - addr->s4.sin_port = htons (net_hostport); - - addr->s4.sin_addr.s_addr = *(uint32_t *) hostentry->h_addr_list[0]; + addr->family = AF_INET; + addr->port = htons (net_hostport); + memcpy (addr->ip, hostentry->h_addr_list[0], ADDR_SIZE); return 0; } int -UDP_AddrCompare (AF_address_t *addr1, AF_address_t *addr2) +UDP_AddrCompare (netadr_t *addr1, netadr_t *addr2) { - if (addr1->sa.sa_family != addr2->sa.sa_family) + if (addr1->family != addr2->family) return -2; - if (addr1->s4.sin_addr.s_addr != addr2->s4.sin_addr.s_addr) + if (memcmp (addr1->ip, addr2->ip, ADDR_SIZE)) return -1; - if (addr1->s4.sin_port != addr2->s4.sin_port) + if (addr1->port != addr2->port) return 1; return 0; } int -UDP_GetSocketPort (AF_address_t *addr) +UDP_GetSocketPort (netadr_t *addr) { - return ntohs (addr->s4.sin_port); + return ntohs (addr->port); } int -UDP_SetSocketPort (AF_address_t *addr, int port) +UDP_SetSocketPort (netadr_t *addr, int port) { - addr->s4.sin_port = htons (port); + addr->port = htons (port); return 0; } From 5c9ab2832f769890c952f77913a1709f2b499f80 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 4 Sep 2011 09:48:16 +0900 Subject: [PATCH 089/334] Fix win32 cross-building. No idea if the code actually works :( --- include/net_wins.h | 22 +++--- libs/net/nc/net_udp.c | 8 +- libs/net/nm/net_udp.c | 8 +- libs/net/nm/net_wins.c | 171 ++++++++++++++++++++++++++--------------- 4 files changed, 121 insertions(+), 88 deletions(-) diff --git a/include/net_wins.h b/include/net_wins.h index eccfef0dd..330a9340a 100644 --- a/include/net_wins.h +++ b/include/net_wins.h @@ -41,25 +41,23 @@ extern int winsock_initialized; extern WSADATA winsockdata; -struct qsockaddr; - int WINS_Init (void); void WINS_Shutdown (void); void WINS_Listen (qboolean state); int WINS_OpenSocket (int port); int WINS_CloseSocket (int socket); -int WINS_Connect (int socket, struct qsockaddr *addr); +int WINS_Connect (int socket, netadr_t *addr); int WINS_CheckNewConnections (void); -int WINS_Read (int socket, byte *buf, int len, struct qsockaddr *addr); -int WINS_Write (int socket, byte *buf, int len, struct qsockaddr *addr); +int WINS_Read (int socket, byte *buf, int len, netadr_t *addr); +int WINS_Write (int socket, byte *buf, int len, netadr_t *addr); int WINS_Broadcast (int socket, byte *buf, int len); -const char *WINS_AddrToString (struct qsockaddr *addr); -int WINS_GetSocketAddr (int socket, struct qsockaddr *addr); -int WINS_GetNameFromAddr (struct qsockaddr *addr, char *name); -int WINS_GetAddrFromName (const char *name, struct qsockaddr *addr); -int WINS_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2); -int WINS_GetSocketPort (struct qsockaddr *addr); -int WINS_SetSocketPort (struct qsockaddr *addr, int port); +const char *WINS_AddrToString (netadr_t *addr); +int WINS_GetSocketAddr (int socket, netadr_t *addr); +int WINS_GetNameFromAddr (netadr_t *addr, char *name); +int WINS_GetAddrFromName (const char *name, netadr_t *addr); +int WINS_AddrCompare (netadr_t *addr1, netadr_t *addr2); +int WINS_GetSocketPort (netadr_t *addr); +int WINS_SetSocketPort (netadr_t *addr, int port); //@} diff --git a/libs/net/nc/net_udp.c b/libs/net/nc/net_udp.c index 45d484762..10b7c049a 100644 --- a/libs/net/nc/net_udp.c +++ b/libs/net/nc/net_udp.c @@ -134,17 +134,13 @@ typedef union address { #ifdef HAVE_SA_LEN #define SA_LEN(sa) (sa)->sa_len #else -#define SA_LEN(sa) (((sa)->sa_family == AF_INET6) \ - ? sizeof(struct sockaddr_in6) \ - : sizeof(struct sockaddr_in)) +#define SA_LEN(sa) (sizeof(struct sockaddr_in)) #endif #ifdef HAVE_SS_LEN #define SS_LEN(ss) (ss)->ss_len #else -#define SS_LEN(ss) (((ss)->ss_family == AF_INET6) \ - ? sizeof(struct sockaddr_in6) \ - : sizeof(struct sockaddr_in)) +#define SS_LEN(ss) (sizeof(struct sockaddr_in)) #endif diff --git a/libs/net/nm/net_udp.c b/libs/net/nm/net_udp.c index 0885a5d47..ec62320a0 100644 --- a/libs/net/nm/net_udp.c +++ b/libs/net/nm/net_udp.c @@ -126,17 +126,13 @@ typedef union address { #ifdef HAVE_SA_LEN #define SA_LEN(sa) (sa)->sa_len #else -#define SA_LEN(sa) (((sa)->sa_family == AF_INET6) \ - ? sizeof(struct sockaddr_in6) \ - : sizeof(struct sockaddr_in)) +#define SA_LEN(sa) (sizeof(struct sockaddr_in)) #endif #ifdef HAVE_SS_LEN #define SS_LEN(ss) (ss)->ss_len #else -#define SS_LEN(ss) (((ss)->ss_family == AF_INET6) \ - ? sizeof(struct sockaddr_in6) \ - : sizeof(struct sockaddr_in)) +#define SS_LEN(ss) (sizeof(struct sockaddr_in)) #endif diff --git a/libs/net/nm/net_wins.c b/libs/net/nm/net_wins.c index 9b7e1ce3e..079718ab2 100644 --- a/libs/net/nm/net_wins.c +++ b/libs/net/nm/net_wins.c @@ -35,12 +35,36 @@ static __attribute__ ((used)) const char rcsid[] = #include "winquake.h" #include "QF/cvar.h" +#include "QF/dstring.h" #include "QF/qargs.h" #include "QF/sys.h" #include "compat.h" #include "netmain.h" +#define ADDR_SIZE 4 + +typedef union address { + struct sockaddr_storage ss; + struct sockaddr sa; + struct sockaddr_in s4; +} AF_address_t; + +#undef SA_LEN +#undef SS_LEN + +#ifdef HAVE_SA_LEN +#define SA_LEN(sa) (sa)->sa_len +#else +#define SA_LEN(sa) (sizeof(struct sockaddr_in)) +#endif + +#ifdef HAVE_SS_LEN +#define SS_LEN(ss) (ss)->ss_len +#else +#define SS_LEN(ss) (sizeof(struct sockaddr_in)) +#endif + #define MAXHOSTNAMELEN 256 static int net_acceptsocket = -1; // socket for fielding new @@ -48,7 +72,7 @@ static int net_acceptsocket = -1; // socket for fielding new // connections static int net_controlsocket; static int net_broadcastsocket = 0; -static struct qsockaddr broadcastaddr; +static netadr_t broadcastaddr; static unsigned long myAddr; @@ -85,6 +109,25 @@ WSADATA winsockdata; //============================================================================= +static void +NetadrToSockadr (netadr_t *a, AF_address_t *s) +{ + memset (s, 0, sizeof (*s)); + s->s4.sin_family = AF_INET; + + memcpy (&s->s4.sin_addr, &a->ip, ADDR_SIZE); + s->s4.sin_port = a->port; +} + +static void +SockadrToNetadr (AF_address_t *s, netadr_t *a) +{ + memcpy (&a->ip, &s->s4.sin_addr, ADDR_SIZE); + a->port = s->s4.sin_port; + a->family = s->s4.sin_family; +} + + static double blocktime; static BOOL PASCAL FAR @@ -246,9 +289,13 @@ WINS_Init (void) return -1; } - ((struct sockaddr_in *) &broadcastaddr)->sin_family = AF_INET; - ((struct sockaddr_in *) &broadcastaddr)->sin_addr.s_addr = INADDR_BROADCAST; - ((struct sockaddr_in *) &broadcastaddr)->sin_port = htons ((unsigned short) net_hostport); + { + AF_address_t t; + t.s4.sin_family = AF_INET; + t.s4.sin_addr.s_addr = INADDR_BROADCAST; + t.s4.sin_port = htons (net_hostport); + SockadrToNetadr (&t, &broadcastaddr); + } Sys_Printf ("Winsock TCP/IP Initialized\n"); tcpipAvailable = true; @@ -294,7 +341,8 @@ int WINS_OpenSocket (int port) { int newsocket; - struct sockaddr_in address; + AF_address_t address; + netadr_t na; u_long _true = 1; if ((newsocket = psocket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) @@ -303,14 +351,14 @@ WINS_OpenSocket (int port) if (pioctlsocket (newsocket, FIONBIO, &_true) == -1) goto ErrorReturn; - address.sin_family = AF_INET; - address.sin_addr.s_addr = myAddr; - address.sin_port = htons ((unsigned short) port); - if (bind (newsocket, (void *) &address, sizeof (address)) == 0) + address.s4.sin_family = AF_INET; + address.s4.sin_addr.s_addr = myAddr; + address.s4.sin_port = htons ((unsigned short) port); + if (bind (newsocket, &address.sa, SA_LEN (&address)) == 0) return newsocket; - Sys_Error ("Unable to bind to %s", - WINS_AddrToString ((struct qsockaddr *) &address)); + SockadrToNetadr (&address, &na); + Sys_Error ("Unable to bind to %s", WINS_AddrToString (&na)); ErrorReturn: pclosesocket (newsocket); return -1; @@ -337,7 +385,7 @@ the local network components to fill in the rest ============ */ static int -PartialIPAddress (const char *in, struct qsockaddr *hostaddr) +PartialIPAddress (const char *in, netadr_t *hostaddr) { char buff[256]; char *b; @@ -377,18 +425,19 @@ PartialIPAddress (const char *in, struct qsockaddr *hostaddr) else port = net_hostport; - hostaddr->qsa_family = AF_INET; - ((struct sockaddr_in *) hostaddr)->sin_port = htons ((short) port); - - ((struct sockaddr_in *) hostaddr)->sin_addr.s_addr = - (myAddr & htonl (mask)) | htonl (addr); - + hostaddr->family = AF_INET; + hostaddr->port = htons ((short) port); + { + int32_t t = myAddr & htonl (mask); + t |= htonl (addr); + memcpy (hostaddr->ip, &t, ADDR_SIZE); + } return 0; } //============================================================================= int -WINS_Connect (int socket, struct qsockaddr *addr) +WINS_Connect (int socket, netadr_t *addr) { return 0; } @@ -403,8 +452,8 @@ WINS_CheckNewConnections (void) if (net_acceptsocket == -1) return -1; - if (precvfrom (net_acceptsocket, buf, sizeof (buf), MSG_PEEK, NULL, NULL) >= - 0) { + if (precvfrom (net_acceptsocket, buf, sizeof (buf), + MSG_PEEK, NULL, NULL) >= 0) { return net_acceptsocket; } return -1; @@ -413,13 +462,14 @@ WINS_CheckNewConnections (void) //============================================================================= int -WINS_Read (int socket, byte *buf, int len, struct qsockaddr *addr) +WINS_Read (int socket, byte *buf, int len, netadr_t *from) { - int addrlen = sizeof (struct qsockaddr); + int addrlen = sizeof (AF_address_t); int ret; + AF_address_t addr; - ret = precvfrom (socket, (char *) buf, len, 0, (struct sockaddr *) addr, - &addrlen); + ret = precvfrom (socket, (char *) buf, len, 0, &addr.sa, &addrlen); + SockadrToNetadr (&addr, from); if (ret == -1) { int err = pWSAGetLastError (); @@ -470,14 +520,13 @@ WINS_Broadcast (int socket, byte * buf, int len) //============================================================================= int -WINS_Write (int socket, byte *buf, int len, struct qsockaddr *addr) +WINS_Write (int socket, byte *buf, int len, netadr_t *to) { int ret; + AF_address_t addr; - ret = - - psendto (socket, (char *) buf, len, 0, (struct sockaddr *) addr, - sizeof (struct qsockaddr)); + NetadrToSockadr (to, &addr); + ret = psendto (socket, (char *) buf, len, 0, &addr.sa, SA_LEN (&addr)); if (ret == -1) if (pWSAGetLastError () == WSAEWOULDBLOCK) return 0; @@ -488,32 +537,32 @@ WINS_Write (int socket, byte *buf, int len, struct qsockaddr *addr) //============================================================================= const char * -WINS_AddrToString (struct qsockaddr *addr) +WINS_AddrToString (netadr_t *addr) { - static char buffer[22]; - int haddr; + static dstring_t *buffer; - haddr = ntohl (((struct sockaddr_in *) addr)->sin_addr.s_addr); - snprintf (buffer, sizeof (buffer), "%d.%d.%d.%d:%d", (haddr >> 24) & 0xff, - (haddr >> 16) & 0xff, (haddr >> 8) & 0xff, haddr & 0xff, - ntohs (((struct sockaddr_in *) addr)->sin_port)); - return buffer; + dsprintf (buffer, "%d.%d.%d.%d:%d", addr->ip[0], + addr->ip[1], addr->ip[2], addr->ip[3], + ntohs (addr->port)); + return buffer->str; } //============================================================================= int -WINS_GetSocketAddr (int socket, struct qsockaddr *addr) +WINS_GetSocketAddr (int socket, netadr_t *addr) { - int addrlen = sizeof (struct qsockaddr); + int addrlen = sizeof (AF_address_t); + AF_address_t ta; unsigned int a; - memset (addr, 0, sizeof (struct qsockaddr)); + memset (&ta, 0, sizeof (AF_address_t)); - pgetsockname (socket, (struct sockaddr *) addr, &addrlen); - a = ((struct sockaddr_in *) addr)->sin_addr.s_addr; + pgetsockname (socket, &ta.sa, &addrlen); + SockadrToNetadr (&ta, addr); + memcpy (&a, addr->ip, ADDR_SIZE); if (a == 0 || a == inet_addr ("127.0.0.1")) - ((struct sockaddr_in *) addr)->sin_addr.s_addr = myAddr; + memcpy (addr->ip, &myAddr, ADDR_SIZE); return 0; } @@ -521,13 +570,11 @@ WINS_GetSocketAddr (int socket, struct qsockaddr *addr) //============================================================================= int -WINS_GetNameFromAddr (struct qsockaddr *addr, char *name) +WINS_GetNameFromAddr (netadr_t *addr, char *name) { struct hostent *hostentry; - hostentry = - pgethostbyaddr ((char *) &((struct sockaddr_in *) addr)->sin_addr, - sizeof (struct in_addr), AF_INET); + hostentry = pgethostbyaddr ((char *) addr->ip, ADDR_SIZE, AF_INET); if (hostentry) { strncpy (name, (char *) hostentry->h_name, NET_NAMELEN - 1); @@ -541,7 +588,7 @@ WINS_GetNameFromAddr (struct qsockaddr *addr, char *name) //============================================================================= int -WINS_GetAddrFromName (const char *name, struct qsockaddr *addr) +WINS_GetAddrFromName (const char *name, netadr_t *addr) { struct hostent *hostentry; @@ -552,11 +599,9 @@ WINS_GetAddrFromName (const char *name, struct qsockaddr *addr) if (!hostentry) return -1; - addr->qsa_family = AF_INET; - ((struct sockaddr_in *) addr)->sin_port = htons ((unsigned short) net_hostport); - - ((struct sockaddr_in *) addr)->sin_addr.s_addr = - *(int *) hostentry->h_addr_list[0]; + addr->family = AF_INET; + addr->port = htons ((unsigned short) net_hostport); + memcpy (addr->ip, hostentry->h_addr_list[0], ADDR_SIZE); return 0; } @@ -564,17 +609,15 @@ WINS_GetAddrFromName (const char *name, struct qsockaddr *addr) //============================================================================= int -WINS_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2) +WINS_AddrCompare (netadr_t *addr1, netadr_t *addr2) { - if (addr1->qsa_family != addr2->qsa_family) + if (addr1->family != addr2->family) return -1; - if (((struct sockaddr_in *) addr1)->sin_addr.s_addr != - ((struct sockaddr_in *) addr2)->sin_addr.s_addr) + if (memcmp (addr1->ip, addr2->ip, ADDR_SIZE)) return -1; - if (((struct sockaddr_in *) addr1)->sin_port != - ((struct sockaddr_in *) addr2)->sin_port) + if (addr1->port != addr2->port) return 1; return 0; @@ -583,16 +626,16 @@ WINS_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2) //============================================================================= int -WINS_GetSocketPort (struct qsockaddr *addr) +WINS_GetSocketPort (netadr_t *addr) { - return ntohs (((struct sockaddr_in *) addr)->sin_port); + return ntohs (addr->port); } int -WINS_SetSocketPort (struct qsockaddr *addr, int port) +WINS_SetSocketPort (netadr_t *addr, int port) { - ((struct sockaddr_in *) addr)->sin_port = htons ((unsigned short) port); + addr->port = htons ((unsigned short) port); return 0; } From a59fee53466aee274cea1d39940685e0ec436115 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 18 Jun 2011 22:22:06 +0900 Subject: [PATCH 090/334] Add the QuatSet macro. Same as the VectorSet macro. --- include/QF/mathlib.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/QF/mathlib.h b/include/QF/mathlib.h index 7c8d3ac64..0164fe8bd 100644 --- a/include/QF/mathlib.h +++ b/include/QF/mathlib.h @@ -180,6 +180,13 @@ extern const vec_t * const quat_origin; #define QuatIsZero(a) (!(a)[0] && !(a)[1] && !(a)[2] && !(a)[3]) #define QuatZero(a) ((a)[3] = (a)[2] = (a)[1] = (a)[0] = 0); +#define QuatSet(a,b,c,d,e) \ + do { \ + (e)[0] = a; \ + (e)[1] = b; \ + (e)[2] = c; \ + (e)[3] = d; \ + } while (0) #define QuatBlend(v1,v2,b,v) \ do { \ From 88005f67105b00213aafc3ec47000181699a60a6 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 18 Jun 2011 22:22:47 +0900 Subject: [PATCH 091/334] Diff reduction. --- nq/include/client.h | 1 + nq/source/cl_tent.c | 23 ++++++-------- nq/source/cl_view.c | 73 ++++++++++++++++++++++----------------------- qw/source/cl_tent.c | 19 ++++-------- qw/source/cl_view.c | 48 ++++++++++++++--------------- 5 files changed, 74 insertions(+), 90 deletions(-) diff --git a/nq/include/client.h b/nq/include/client.h index 61e5cb67d..8f208fdc7 100644 --- a/nq/include/client.h +++ b/nq/include/client.h @@ -132,6 +132,7 @@ typedef struct struct qsocket_s *netcon; sizebuf_t message; // writing buffer to send to server + int sv_cshifts; } client_static_t; extern client_static_t cls; diff --git a/nq/source/cl_tent.c b/nq/source/cl_tent.c index ad7371b61..5fae66ae0 100644 --- a/nq/source/cl_tent.c +++ b/nq/source/cl_tent.c @@ -134,10 +134,9 @@ CL_Init_Entity (entity_t *ent) memset (ent, 0, sizeof (*ent)); ent->colormap = vid.colormap8; - ent->colormod[0] = ent->colormod[1] = ent->colormod[2] = - ent->colormod[3] = 1.0; + QuatSet (1.0, 1.0, 1.0, 1.0, ent->colormod); ent->scale = 1.0; - ent->lerpflags |= LERP_RESETMOVE|LERP_RESETANIM; + ent->lerpflags |= LERP_RESETMOVE | LERP_RESETANIM; } static tent_t * @@ -326,7 +325,8 @@ CL_ParseTEnt (void) tent_obj_t *to; explosion_t *ex; int colorStart, colorLength; - vec3_t col, pos; + quat_t col; + vec3_t pos; sfx_t *spike_sound[] = { cl_sfx_ric3, cl_sfx_ric3, cl_sfx_ric2, cl_sfx_ric1, }; @@ -389,10 +389,7 @@ CL_ParseTEnt (void) dl->radius = 350; dl->die = cl.time + 0.5; dl->decay = 300; - dl->color[0] = 1.0; - dl->color[1] = 0.5; - dl->color[2] = 0.25; - dl->color[3] = 0.7; + QuatSet (1.0, 0.5, 0.25, 0.7, dl->color); } // sound @@ -466,15 +463,14 @@ CL_ParseTEnt (void) dl->die = cl.time + 0.5; dl->decay = 300; colorStart = (colorStart + (rand () % colorLength)) * 3; - dl->color[0] = vid.palette[colorStart] * (1.0 / 255.0); - dl->color[1] = vid.palette[colorStart + 1] * (1.0 / 255.0); - dl->color[2] = vid.palette[colorStart + 2] * (1.0 / 255.0); + VectorScale (&vid.palette[colorStart], 1.0 / 255.0, dl->color); dl->color[3] = 0.7; break; case TE_EXPLOSION3: // Nehahra colored light explosion MSG_ReadCoordV (net_message, pos); MSG_ReadCoordV (net_message, col); // OUCH! + col[3] = 0.7; R_ParticleExplosion (pos); S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1); dl = R_AllocDlight (0); @@ -483,8 +479,7 @@ CL_ParseTEnt (void) dl->radius = 350; dl->die = cl.time + 0.5; dl->decay = 300; - VectorCopy (col, dl->color); - dl->color[3] = 0.7; + QuatCopy (col, dl->color); } break; @@ -494,7 +489,7 @@ CL_ParseTEnt (void) break; default: - Sys_Error ("CL_ParseTEnt: bad type"); + Sys_Error ("CL_ParseTEnt: bad type %d", type); } } diff --git a/nq/source/cl_view.c b/nq/source/cl_view.c index 786892ae9..5384998a5 100644 --- a/nq/source/cl_view.c +++ b/nq/source/cl_view.c @@ -67,6 +67,10 @@ cvar_t *cl_bobup; cvar_t *v_centermove; cvar_t *v_centerspeed; +cvar_t *v_kicktime; +cvar_t *v_kickroll; +cvar_t *v_kickpitch; + cvar_t *v_iyaw_cycle; cvar_t *v_iroll_cycle; cvar_t *v_ipitch_cycle; @@ -76,10 +80,6 @@ cvar_t *v_ipitch_level; cvar_t *v_idlescale; -cvar_t *v_kicktime; -cvar_t *v_kickroll; -cvar_t *v_kickpitch; - float v_dmg_time, v_dmg_roll, v_dmg_pitch; float v_blend[4]; @@ -122,9 +122,9 @@ void V_StartPitchDrift (void) { if (cl.laststop == cl.time) { - return; // something else is keeping it from - // drifting + return; // something else is keeping it from drifting } + if (cl.nodrift || !cl.pitchvel) { cl.pitchvel = v_centerspeed->value; cl.nodrift = false; @@ -221,9 +221,9 @@ V_ParseDamage (void) cl.faceanimtime = cl.time + 0.2; // but sbar face into pain frame - if (cl_cshift_damage->int_val) { -// || (atoi (Info_ValueForKey (cl.serverinfo, "cshifts")) & -// INFO_CSHIFT_DAMAGE)) { + if (cl_cshift_damage->int_val + || (cl.sv_cshifts & INFO_CSHIFT_DAMAGE)) { + cl.cshifts[CSHIFT_DAMAGE].percent += 3 * count; cl.cshifts[CSHIFT_DAMAGE].percent = bound (0, cl.cshifts[CSHIFT_DAMAGE].percent, 150); @@ -277,7 +277,8 @@ V_cshift_f (void) static void V_BonusFlash_f (void) { - if (!cl_cshift_bonus->int_val) + if (!cl_cshift_bonus->int_val + && !(cl.sv_cshifts & INFO_CSHIFT_BONUS)) return; cl.cshifts[CSHIFT_BONUS] = cshift_bonus; } @@ -290,14 +291,15 @@ V_BonusFlash_f (void) void V_SetContentsColor (int contents) { - if (!cl_cshift_contents->int_val) { + if (!cl_cshift_contents->int_val + && !(cl.sv_cshifts & INFO_CSHIFT_CONTENTS)) { cl.cshifts[CSHIFT_CONTENTS] = cshift_empty; return; } switch (contents) { case CONTENTS_EMPTY: - cl.cshifts[CSHIFT_CONTENTS] = cshift_empty; + cl.cshifts[CSHIFT_CONTENTS] = cshift_empty; break; case CONTENTS_LAVA: cl.cshifts[CSHIFT_CONTENTS] = cshift_lava; @@ -337,7 +339,7 @@ V_CalcPowerupCshift (void) cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 255; cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 0; cl.cshifts[CSHIFT_POWERUP].percent = 30; - } else if (cl.stats[STAT_ITEMS] & IT_SUIT) { + } else if (cl.stats[STAT_ITEMS] & IT_SUIT) { cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 0; cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 255; cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 0; @@ -399,9 +401,8 @@ V_PrepBlend (void) { int i, j; - if (cl_cshift_powerup->int_val) -// || (atoi (Info_ValueForKey (cl.serverinfo, "cshifts")) -// & INFO_CSHIFT_POWERUP)) + if (cl_cshift_powerup->int_val + || (cl.sv_cshifts & INFO_CSHIFT_POWERUP)) V_CalcPowerupCshift (); vid.cshift_changed = false; @@ -450,7 +451,7 @@ angledelta (float a) static void CalcGunAngle (void) { - float yaw, pitch, move; + float yaw, pitch, move; static float oldpitch = 0, oldyaw = 0; yaw = r_refdef.viewangles[YAW]; @@ -527,15 +528,12 @@ V_BoundOffsets (void) static void V_AddIdle (void) { - r_refdef.viewangles[ROLL] += - v_idlescale->value * sin (cl.time * v_iroll_cycle->value) * - v_iroll_level->value; - r_refdef.viewangles[PITCH] += - v_idlescale->value * sin (cl.time * v_ipitch_cycle->value) * - v_ipitch_level->value; - r_refdef.viewangles[YAW] += - v_idlescale->value * sin (cl.time * v_iyaw_cycle->value) * - v_iyaw_level->value; + r_refdef.viewangles[ROLL] += v_idlescale->value * + sin (cl.time * v_iroll_cycle->value) * v_iroll_level->value; + r_refdef.viewangles[PITCH] += v_idlescale->value * + sin (cl.time * v_ipitch_cycle->value) * v_ipitch_level->value; + r_refdef.viewangles[YAW] += v_idlescale->value * + sin (cl.time * v_iyaw_cycle->value) * v_iyaw_level->value; } /* @@ -612,7 +610,7 @@ V_CalcRefdef (void) r_refdef.vieworg[2] += cl.viewheight + bob; // never let it sit exactly on a node line, because a water plane can - // dissapear when viewed with the eye exactly on it. + // disappear when viewed with the eye exactly on it. // server protocol specifies to only 1/16 pixel, so add 1/32 in each axis r_refdef.vieworg[0] += 1.0 / 32; r_refdef.vieworg[1] += 1.0 / 32; @@ -648,8 +646,8 @@ V_CalcRefdef (void) for (i = 0; i < 3; i++) { view->origin[i] += forward[i] * bob * 0.4; -// view->origin[i] += right[i]*bob*0.4; -// view->origin[i] += up[i]*bob*0.8; +// view->origin[i] += right[i] * bob * 0.4; +// view->origin[i] += up[i] * bob * 0.8; } view->origin[2] += bob; @@ -727,23 +725,23 @@ V_RenderView (void) void V_Init (void) { - Cmd_AddCommand ("v_cshift", V_cshift_f, "This adjusts all of the colors " - "currently being displayed.\n" - "Used when you are underwater, hit, have the Ring of " - "Shadows, or Quad Damage. (v_cshift r g b intensity)"); Cmd_AddCommand ("bf", V_BonusFlash_f, "Background flash, used when you " "pick up an item"); Cmd_AddCommand ("centerview", V_StartPitchDrift, "Centers the player's " "view ahead after +lookup or +lookdown\n" "Will not work while mlook is active or freelook is 1."); + Cmd_AddCommand ("v_cshift", V_cshift_f, "This adjusts all of the colors " + "currently being displayed.\n" + "Used when you are underwater, hit, have the Ring of " + "Shadows, or Quad Damage. (v_cshift r g b intensity)"); } void V_Init_Cvars (void) { v_centermove = Cvar_Get ("v_centermove", "0.15", CVAR_NONE, NULL, - "How far the player must move forward before " - "the view re-centers"); + "How far the player must move forward before the " + "view re-centers"); v_centerspeed = Cvar_Get ("v_centerspeed", "500", CVAR_NONE, NULL, "How quickly you return to a center view after " "a lookup or lookdown"); @@ -780,8 +778,9 @@ V_Init_Cvars (void) cl_bobcycle = Cvar_Get ("cl_bobcycle", "0.6", CVAR_NONE, NULL, "How quickly your weapon moves up and down when " "walking"); - cl_bobup = Cvar_Get ("cl_bobup", "0.5", CVAR_NONE, NULL, "How long your " - "weapon stays up before cycling when walking"); + cl_bobup = Cvar_Get ("cl_bobup", "0.5", CVAR_NONE, NULL, + "How long your weapon stays up before cycling when " + "walking"); v_kicktime = Cvar_Get ("v_kicktime", "0.5", CVAR_NONE, NULL, "How long the kick from an attack lasts"); v_kickroll = Cvar_Get ("v_kickroll", "0.6", CVAR_NONE, NULL, diff --git a/qw/source/cl_tent.c b/qw/source/cl_tent.c index 72853c8bc..8f51ae6ad 100644 --- a/qw/source/cl_tent.c +++ b/qw/source/cl_tent.c @@ -140,8 +140,7 @@ CL_Init_Entity (entity_t *ent) memset (ent, 0, sizeof (*ent)); ent->colormap = vid.colormap8; - VectorSet (1.0, 1.0, 1.0, ent->colormod); - ent->colormod[3] = 1.0; + QuatSet (1.0, 1.0, 1.0, 1.0, ent->colormod); ent->scale = 1.0; ent->lerpflags |= LERP_RESETMOVE | LERP_RESETANIM; } @@ -396,10 +395,7 @@ CL_ParseTEnt (void) dl->radius = 350; dl->die = cl.time + 0.5; dl->decay = 300; - dl->color[0] = 0.86; - dl->color[1] = 0.31; - dl->color[2] = 0.24; - dl->color[3] = 0.7; + QuatSet (0.86, 0.31, 0.24, 0.7, dl->color); } // sound @@ -469,9 +465,7 @@ CL_ParseTEnt (void) dl->die = cl.time + 0.5; dl->decay = 300; colorStart = (colorStart + (rand () % colorLength)) * 3; - dl->color[0] = vid.palette[colorStart] * (1.0 / 255.0); - dl->color[1] = vid.palette[colorStart + 1] * (1.0 / 255.0); - dl->color[2] = vid.palette[colorStart + 2] * (1.0 / 255.0); + VectorScale (&vid.palette[colorStart], 1.0 / 255.0, dl->color); dl->color[3] = 0.7; break; @@ -497,10 +491,7 @@ CL_ParseTEnt (void) dl->radius = 150; dl->die = cl.time + 0.1; dl->decay = 200; - dl->color[0] = 0.25; - dl->color[1] = 0.40; - dl->color[2] = 0.65; - dl->color[3] = 1; + QuatSet (0.25, 0.40, 0.65, 1, dl->color); } R_LightningBloodEffect (pos); @@ -525,6 +516,8 @@ CL_UpdateBeams (void) // update lightning for (to = &cl_beams; *to; ) { b = &(*to)->to.beam; + if (!b->endtime) + continue; if (!b->model || b->endtime < cl.time) { tent_obj_t *_to; b->endtime = 0; diff --git a/qw/source/cl_view.c b/qw/source/cl_view.c index e8a9de14c..9fbde1eae 100644 --- a/qw/source/cl_view.c +++ b/qw/source/cl_view.c @@ -41,6 +41,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "QF/vid.h" #include "qw/bothdefs.h" +#include "cl_cam.h" #include "cl_main.h" #include "client.h" #include "compat.h" @@ -187,7 +188,7 @@ V_StopPitchDrift (void) static void V_DriftPitch (void) { - float delta, move; + float delta, move; if (view_message->onground == -1 || cls.demoplayback) { cl.driftmove = 0; @@ -246,8 +247,7 @@ V_ParseDamage (void) armor = MSG_ReadByte (net_message); blood = MSG_ReadByte (net_message); - for (i = 0; i < 3; i++) - from[i] = MSG_ReadCoord (net_message); + MSG_ReadCoordV (net_message, from); count = blood * 0.5 + armor * 0.5; if (count < 10) @@ -375,7 +375,7 @@ V_CalcPowerupCshift (void) cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 255; cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 0; cl.cshifts[CSHIFT_POWERUP].percent = 30; - } else if (cl.stats[STAT_ITEMS] & IT_SUIT) { + } else if (cl.stats[STAT_ITEMS] & IT_SUIT) { cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 0; cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 255; cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 0; @@ -399,12 +399,12 @@ V_CalcPowerupCshift (void) void V_CalcBlend (void) { - float a2, a3; - float r = 0, g = 0, b = 0, a = 0; - int i; + float a2, a3; + float r = 0, g = 0, b = 0, a = 0; + int i; for (i = 0; i < NUM_CSHIFTS; i++) { - a2 = cl.cshifts[i].percent * (1.0 / 255.0); + a2 = cl.cshifts[i].percent / 255.0; if (!a2) continue; @@ -426,16 +426,16 @@ V_CalcBlend (void) b *= a2; } - v_blend[0] = min (r, 255.0) * (1.0 / 255.0); - v_blend[1] = min (g, 255.0) * (1.0 / 255.0); - v_blend[2] = min (b, 255.0) * (1.0 / 255.0); + v_blend[0] = min (r, 255.0) / 255.0; + v_blend[1] = min (g, 255.0) / 255.0; + v_blend[2] = min (b, 255.0) / 255.0; v_blend[3] = bound (0.0, a, 1.0); } void V_PrepBlend (void) { - int i, j; + int i, j; if (cl_cshift_powerup->int_val || (cl.sv_cshifts & INFO_CSHIFT_POWERUP)) @@ -487,8 +487,8 @@ angledelta (float a) static void CalcGunAngle (void) { - float yaw, pitch, move; - static float oldpitch = 0, oldyaw = 0; + float yaw, pitch, move; + static float oldpitch = 0, oldyaw = 0; yaw = r_refdef.viewangles[YAW]; pitch = -r_refdef.viewangles[PITCH]; @@ -553,7 +553,7 @@ V_AddIdle (void) static void V_CalcViewRoll (void) { - float side; + float side; side = V_CalcRoll (cl.simangles, cl.simvel); r_refdef.viewangles[ROLL] += side; @@ -574,7 +574,7 @@ V_CalcIntermissionRefdef (void) entity_t *view; float old; - // view is the weapon model + // view is the weapon model (visible only from inside body) view = &cl.viewent; VectorCopy (cl.simorg, r_refdef.vieworg); @@ -588,18 +588,15 @@ V_CalcIntermissionRefdef (void) Cvar_SetValue (v_idlescale, old); } -#include "cl_cam.h" - - static void V_CalcRefdef (void) { entity_t *view; - float bob; + float bob; static float oldz = 0; - int i; - int zofs = 22; - vec3_t forward, right, up; + int i; + int zofs = 22; + vec3_t forward, right, up; if (cl.stdver) zofs = cl.stats[STAT_VIEWHEIGHT]; @@ -650,7 +647,7 @@ V_CalcRefdef (void) for (i = 0; i < 3; i++) { view->origin[i] += forward[i] * bob * 0.4; -// view->origin[i] += right[i] * bob *0.4; +// view->origin[i] += right[i] * bob * 0.4; // view->origin[i] += up[i] * bob * 0.8; } view->origin[2] += bob; @@ -733,14 +730,13 @@ V_RenderView (void) R_RenderView (); } - void V_Init (void) { Cmd_AddCommand ("bf", V_BonusFlash_f, "Background flash, used when you " "pick up an item"); Cmd_AddCommand ("centerview", V_StartPitchDrift, "Centers the player's " - "view ahead after +lookup or +lookdown \n" + "view ahead after +lookup or +lookdown\n" "Will not work while mlook is active or freelook is 1."); Cmd_AddCommand ("v_cshift", V_cshift_f, "This adjusts all of the colors " "currently being displayed.\n" From 245cfb0b6f12ffff88e6bf1b2149235b53329f5b Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 19 Jun 2011 09:49:39 +0900 Subject: [PATCH 092/334] Much diff reduction. In the process, found a bug where the yaw speed was not being limited as desired. --- nq/include/client.h | 26 +++- nq/source/cl_input.c | 52 ++++---- nq/source/cl_main.c | 3 +- qw/source/cl_input.c | 283 +++++++++++++++++++++---------------------- qw/source/cl_view.c | 2 +- 5 files changed, 197 insertions(+), 169 deletions(-) diff --git a/nq/include/client.h b/nq/include/client.h index 8f208fdc7..b850cc3d0 100644 --- a/nq/include/client.h +++ b/nq/include/client.h @@ -131,12 +131,28 @@ typedef struct int signon; // 0 to SIGNONS struct qsocket_s *netcon; sizebuf_t message; // writing buffer to send to server - - int sv_cshifts; } client_static_t; extern client_static_t cls; +#define FPD_NO_MACROS 0x0001 // Many clients ignore this, and it isn't used, but let's honor it +#define FPD_NO_TIMERS 0x0002 // We never allow timers anyway +#define FPD_NO_STRIGGER 0x0004 // Don't have soundtrigger yet, but this disables it +#define FPD_HIDE_PERCENTE 0x0020 // Ditto +#define FPD_HIDE_POINT 0x0080 // Can ignore if we do visibility checking for point +#define FPD_NO_TEAMSKIN 0x0100 // Disable skin force +#define FPD_NO_TEAMCOLOR 0x0200 // Disable color force +#define FPD_HIDE_ITEM 0x0400 // No idea what this does +#define FPD_LIMIT_PITCH 0x4000 // Limit pitchspeed +#define FPD_LIMIT_YAW 0x8000 // Limit yawspeed + +#define FPD_DEFAULT (FPD_HIDE_PERCENTE | FPD_NO_TEAMSKIN) + +// These limits prevent a usable RJ script, requiring > 0.1 sec of turning time. +#define FPD_MAXPITCH 1000 +#define FPD_MAXYAW 2000 + + /* the client_state_t structure is wiped completely at every server signon @@ -220,6 +236,10 @@ typedef struct scoreboard_t *scores; // [cl.maxclients] unsigned protocol; + + int sv_cshifts; + int chase; + int fpd; } client_state_t; @@ -309,7 +329,7 @@ void CL_NextDemo (void); // cl_input -void CL_InitInput (void); +void CL_Input_Init (void); void CL_SendCmd (void); void CL_SendMove (usercmd_t *cmd); diff --git a/nq/source/cl_input.c b/nq/source/cl_input.c index 98423eb5e..295d9d922 100644 --- a/nq/source/cl_input.c +++ b/nq/source/cl_input.c @@ -67,7 +67,6 @@ static __attribute__ ((used)) const char rcsid[] = state bit 2 is edge triggered on the down to up transition */ - kbutton_t in_left, in_right, in_forward, in_back; kbutton_t in_lookup, in_lookdown, in_moveleft, in_moveright; kbutton_t in_use, in_jump, in_attack; @@ -163,7 +162,7 @@ static void IN_MLookRelease (void) { KeyRelease (&in_mlook); - if (!(in_mlook.state & 1) && lookspring->int_val) + if (!freelook && lookspring->int_val) V_StartPitchDrift (); } @@ -419,37 +418,46 @@ cvar_t *cl_yawspeed; static void CL_AdjustAngles (void) { - float speed, up, down; + float down, up; + float pitchspeed, yawspeed; - if (in_speed.state & 1) - speed = host_frametime * cl_anglespeedkey->value; - else - speed = host_frametime; + pitchspeed = cl_pitchspeed->value; + yawspeed = cl_yawspeed->value; + + if (in_speed.state & 1) { + pitchspeed *= cl_anglespeedkey->value; + yawspeed *= cl_anglespeedkey->value; + } + + if ((cl.fpd & FPD_LIMIT_PITCH) && pitchspeed > FPD_MAXPITCH) + pitchspeed = FPD_MAXPITCH; + if ((cl.fpd & FPD_LIMIT_YAW) && yawspeed > FPD_MAXYAW) + yawspeed = FPD_MAXYAW; + + pitchspeed *= host_frametime; + yawspeed *= host_frametime; if (!(in_strafe.state & 1)) { - cl.viewangles[YAW] -= - speed * cl_yawspeed->value * CL_KeyState (&in_right); - cl.viewangles[YAW] += - speed * cl_yawspeed->value * CL_KeyState (&in_left); + cl.viewangles[YAW] -= yawspeed * CL_KeyState (&in_right); + cl.viewangles[YAW] += yawspeed * CL_KeyState (&in_left); cl.viewangles[YAW] = anglemod (cl.viewangles[YAW]); } if (in_klook.state & 1) { V_StopPitchDrift (); - cl.viewangles[PITCH] -= - speed * cl_pitchspeed->value * CL_KeyState (&in_forward); - cl.viewangles[PITCH] += - speed * cl_pitchspeed->value * CL_KeyState (&in_back); + cl.viewangles[PITCH] -= pitchspeed * CL_KeyState (&in_forward); + cl.viewangles[PITCH] += pitchspeed * CL_KeyState (&in_back); } up = CL_KeyState (&in_lookup); down = CL_KeyState (&in_lookdown); - cl.viewangles[PITCH] -= speed * cl_pitchspeed->value * up; - cl.viewangles[PITCH] += speed * cl_pitchspeed->value * down; + cl.viewangles[PITCH] -= pitchspeed * up; + cl.viewangles[PITCH] += pitchspeed * down; if (up || down) V_StopPitchDrift (); + // FIXME: Need to clean up view angle limits if (cl.viewangles[PITCH] > 80) cl.viewangles[PITCH] = 80; if (cl.viewangles[PITCH] < -70) @@ -459,7 +467,6 @@ CL_AdjustAngles (void) cl.viewangles[ROLL] = 50; if (cl.viewangles[ROLL] < -50) cl.viewangles[ROLL] = -50; - } /* @@ -509,9 +516,10 @@ CL_BaseMove (usercmd_t *cmd) IN_Move (); // adjust for chase camera angles - if (chase_active->int_val == 2 || chase_active->int_val == 3) { - vec3_t forward, right, up, f, r; - vec3_t dir = {0, 0, 0}; + if (cl.chase + && (chase_active->int_val == 2 || chase_active->int_val == 3)) { + vec3_t forward, right, up, f, r; + vec3_t dir = {0, 0, 0}; dir[1] = r_refdef.viewangles[1] - cl.viewangles[1]; AngleVectors (dir, forward, right, up); @@ -594,7 +602,7 @@ CL_SendMove (usercmd_t *cmd) } void -CL_InitInput (void) +CL_Input_Init (void) { Cmd_AddCommand ("+moveup", IN_UpPress, "When active the player is " "swimming up in a liquid"); diff --git a/nq/source/cl_main.c b/nq/source/cl_main.c index f0e0e1d61..7cfb88d62 100644 --- a/nq/source/cl_main.c +++ b/nq/source/cl_main.c @@ -156,6 +156,7 @@ CL_ClearState (void) // wipe the entire cl structure memset (&cl, 0, sizeof (cl)); + cl.chase = 1; r_force_fullscreen = 0; CL_Init_Entity (&cl.viewent); @@ -765,7 +766,7 @@ CL_Init (void) { SZ_Alloc (&cls.message, 1024); - CL_InitInput (); + CL_Input_Init (); CL_TEnts_Init (); CL_ClearState (); diff --git a/qw/source/cl_input.c b/qw/source/cl_input.c index 4b842d018..51aaf5d4f 100644 --- a/qw/source/cl_input.c +++ b/qw/source/cl_input.c @@ -89,10 +89,10 @@ int in_impulse; static void -KeyDown (kbutton_t *b) +KeyPress (kbutton_t *b) { - int k; const char *c; + int k; c = Cmd_Argv (1); if (c[0]) @@ -119,10 +119,10 @@ KeyDown (kbutton_t *b) } static void -KeyUp (kbutton_t *b) +KeyRelease (kbutton_t *b) { - int k; const char *c; + int k; c = Cmd_Argv (1); if (c[0]) @@ -153,209 +153,209 @@ KeyUp (kbutton_t *b) } static void -IN_KLookDown (void) +IN_KLookPress (void) { - KeyDown (&in_klook); + KeyPress (&in_klook); } static void -IN_KLookUp (void) +IN_KLookRelease (void) { - KeyUp (&in_klook); + KeyRelease (&in_klook); } static void -IN_MLookDown (void) +IN_MLookPress (void) { - KeyDown (&in_mlook); + KeyPress (&in_mlook); } static void -IN_MLookUp (void) +IN_MLookRelease (void) { - KeyUp (&in_mlook); + KeyRelease (&in_mlook); if (!freelook && lookspring->int_val) V_StartPitchDrift (); } static void -IN_UpDown (void) +IN_UpPress (void) { - KeyDown (&in_up); + KeyPress (&in_up); } static void -IN_UpUp (void) +IN_UpRelease (void) { - KeyUp (&in_up); + KeyRelease (&in_up); } static void -IN_DownDown (void) +IN_DownPress (void) { - KeyDown (&in_down); + KeyPress (&in_down); } static void -IN_DownUp (void) +IN_DownRelease (void) { - KeyUp (&in_down); + KeyRelease (&in_down); } static void -IN_LeftDown (void) +IN_LeftPress (void) { - KeyDown (&in_left); + KeyPress (&in_left); } static void -IN_LeftUp (void) +IN_LeftRelease (void) { - KeyUp (&in_left); + KeyRelease (&in_left); } static void -IN_RightDown (void) +IN_RightPress (void) { - KeyDown (&in_right); + KeyPress (&in_right); } static void -IN_RightUp (void) +IN_RightRelease (void) { - KeyUp (&in_right); + KeyRelease (&in_right); } static void -IN_ForwardDown (void) +IN_ForwardPress (void) { - KeyDown (&in_forward); + KeyPress (&in_forward); } static void -IN_ForwardUp (void) +IN_ForwardRelease (void) { - KeyUp (&in_forward); + KeyRelease (&in_forward); } static void -IN_BackDown (void) +IN_BackPress (void) { - KeyDown (&in_back); + KeyPress (&in_back); } static void -IN_BackUp (void) +IN_BackRelease (void) { - KeyUp (&in_back); + KeyRelease (&in_back); } static void -IN_LookupDown (void) +IN_LookupPress (void) { - KeyDown (&in_lookup); + KeyPress (&in_lookup); } static void -IN_LookupUp (void) +IN_LookupRelease (void) { - KeyUp (&in_lookup); + KeyRelease (&in_lookup); } static void -IN_LookdownDown (void) +IN_LookdownPress (void) { - KeyDown (&in_lookdown); + KeyPress (&in_lookdown); } static void -IN_LookdownUp (void) +IN_LookdownRelease (void) { - KeyUp (&in_lookdown); + KeyRelease (&in_lookdown); } static void -IN_MoveleftDown (void) +IN_MoveleftPress (void) { - KeyDown (&in_moveleft); + KeyPress (&in_moveleft); } static void -IN_MoveleftUp (void) +IN_MoveleftRelease (void) { - KeyUp (&in_moveleft); + KeyRelease (&in_moveleft); } static void -IN_MoverightDown (void) +IN_MoverightPress (void) { - KeyDown (&in_moveright); + KeyPress (&in_moveright); } static void -IN_MoverightUp (void) +IN_MoverightRelease (void) { - KeyUp (&in_moveright); + KeyRelease (&in_moveright); } static void -IN_SpeedDown (void) +IN_SpeedPress (void) { - KeyDown (&in_speed); + KeyPress (&in_speed); } static void -IN_SpeedUp (void) +IN_SpeedRelease (void) { - KeyUp (&in_speed); + KeyRelease (&in_speed); } static void -IN_StrafeDown (void) +IN_StrafePress (void) { - KeyDown (&in_strafe); + KeyPress (&in_strafe); } static void -IN_StrafeUp (void) +IN_StrafeRelease (void) { - KeyUp (&in_strafe); + KeyRelease (&in_strafe); } static void -IN_AttackDown (void) +IN_AttackPress (void) { - KeyDown (&in_attack); + KeyPress (&in_attack); } static void -IN_AttackUp (void) +IN_AttackRelease (void) { - KeyUp (&in_attack); + KeyRelease (&in_attack); } static void -IN_UseDown (void) +IN_UsePress (void) { - KeyDown (&in_use); + KeyPress (&in_use); } static void -IN_UseUp (void) +IN_UseRelease (void) { - KeyUp (&in_use); + KeyRelease (&in_use); } static void -IN_JumpDown (void) +IN_JumpPress (void) { - KeyDown (&in_jump); + KeyPress (&in_jump); } static void -IN_JumpUp (void) +IN_JumpRelease (void) { - KeyUp (&in_jump); + KeyRelease (&in_jump); } static void @@ -376,7 +376,7 @@ IN_Impulse (void) 0 if held then released, and 1.0 if held for the entire time */ -float // FIXME: float? for 4 states? Ugh! +float CL_KeyState (kbutton_t *key) { float val; @@ -417,8 +417,6 @@ CL_KeyState (kbutton_t *key) return val; } -//========================================================================== - cvar_t *cl_anglespeedkey; cvar_t *cl_backspeed; cvar_t *cl_forwardspeed; @@ -449,29 +447,28 @@ CL_AdjustAngles (void) if ((cl.fpd & FPD_LIMIT_PITCH) && pitchspeed > FPD_MAXPITCH) pitchspeed = FPD_MAXPITCH; - if ((cl.fpd & FPD_LIMIT_YAW) && pitchspeed > FPD_MAXYAW) - pitchspeed = FPD_MAXYAW; + if ((cl.fpd & FPD_LIMIT_YAW) && yawspeed > FPD_MAXYAW) + yawspeed = FPD_MAXYAW; + + pitchspeed *= host_frametime; + yawspeed *= host_frametime; if (!(in_strafe.state & 1)) { - cl.viewangles[YAW] -= - host_frametime * yawspeed * CL_KeyState (&in_right); - cl.viewangles[YAW] += - host_frametime * yawspeed * CL_KeyState (&in_left); + cl.viewangles[YAW] -= yawspeed * CL_KeyState (&in_right); + cl.viewangles[YAW] += yawspeed * CL_KeyState (&in_left); cl.viewangles[YAW] = anglemod (cl.viewangles[YAW]); } if (in_klook.state & 1) { V_StopPitchDrift (); - cl.viewangles[PITCH] -= - host_frametime * pitchspeed * CL_KeyState (&in_forward); - cl.viewangles[PITCH] += - host_frametime * pitchspeed * CL_KeyState (&in_back); + cl.viewangles[PITCH] -= pitchspeed * CL_KeyState (&in_forward); + cl.viewangles[PITCH] += pitchspeed * CL_KeyState (&in_back); } up = CL_KeyState (&in_lookup); down = CL_KeyState (&in_lookdown); - cl.viewangles[PITCH] -= host_frametime * pitchspeed * up; - cl.viewangles[PITCH] += host_frametime * pitchspeed * down; + cl.viewangles[PITCH] -= pitchspeed * up; + cl.viewangles[PITCH] += pitchspeed * down; if (up || down) V_StopPitchDrift (); @@ -533,19 +530,20 @@ CL_BaseMove (usercmd_t *cmd) IN_Move (); // adjust for chase camera angles - if (cl.chase - && (chase_active->int_val == 2 || chase_active->int_val == 3)) - { - vec3_t dir = {0,0,0}, forward, right, up, f, r; + if (cl.chase + && (chase_active->int_val == 2 || chase_active->int_val == 3)) { + vec3_t forward, right, up, f, r; + vec3_t dir = {0, 0, 0}; + dir[1] = r_refdef.viewangles[1] - cl.viewangles[1]; AngleVectors (dir, forward, right, up); VectorScale (forward, cmd->forwardmove, f); - VectorScale (right, cmd->sidemove, r); + VectorScale (right, cmd->sidemove, r); cmd->forwardmove = f[0] + r[0]; - cmd->sidemove = f[1] + r[1]; + cmd->sidemove = f[1] + r[1]; VectorScale (forward, viewdelta.position[2], f); - VectorScale (right, viewdelta.position[0], r); - viewdelta.position[2] = f[0] + r[0]; + VectorScale (right, viewdelta.position[0], r); + viewdelta.position[2] = f[0] + r[0]; viewdelta.position[0] = (f[1] + r[1]) * -1; } @@ -767,77 +765,78 @@ CL_SendCmd (void) void CL_Input_Init (void) { - Cmd_AddCommand ("+moveup", IN_UpDown, "When active the player is swimming " - "up in a liquid"); - Cmd_AddCommand ("-moveup", IN_UpUp, "When active the player is not " + Cmd_AddCommand ("+moveup", IN_UpPress, "When active the player is " "swimming up in a liquid"); - Cmd_AddCommand ("+movedown", IN_DownDown, "When active the player is " + Cmd_AddCommand ("-moveup", IN_UpRelease, "When active the player is not " + "swimming up in a liquid"); + Cmd_AddCommand ("+movedown", IN_DownPress, "When active the player is " "swimming down in a liquid"); - Cmd_AddCommand ("-movedown", IN_DownUp, "When active the player is not " - "swimming down in a liquid"); - Cmd_AddCommand ("+left", IN_LeftDown, "When active the player is turning " + Cmd_AddCommand ("-movedown", IN_DownRelease, "When active the player is " + "not swimming down in a liquid"); + Cmd_AddCommand ("+left", IN_LeftPress, "When active the player is turning " "left"); - Cmd_AddCommand ("-left", IN_LeftUp, "When active the player is not turning" - " left"); - Cmd_AddCommand ("+right", IN_RightDown, "When active the player is " + Cmd_AddCommand ("-left", IN_LeftRelease, "When active the player is not " + "turning left"); + Cmd_AddCommand ("+right", IN_RightPress, "When active the player is " "turning right"); - Cmd_AddCommand ("-right", IN_RightUp, "When active the player is not " + Cmd_AddCommand ("-right", IN_RightRelease, "When active the player is not " "turning right"); - Cmd_AddCommand ("+forward", IN_ForwardDown, "When active the player is " + Cmd_AddCommand ("+forward", IN_ForwardPress, "When active the player is " "moving forward"); - Cmd_AddCommand ("-forward", IN_ForwardUp, "When active the player is not " - "moving forward"); - Cmd_AddCommand ("+back", IN_BackDown, "When active the player is moving " + Cmd_AddCommand ("-forward", IN_ForwardRelease, "When active the player is " + "not moving forward"); + Cmd_AddCommand ("+back", IN_BackPress, "When active the player is moving " "backwards"); - Cmd_AddCommand ("-back", IN_BackUp, "When active the player is not " + Cmd_AddCommand ("-back", IN_BackRelease, "When active the player is not " "moving backwards"); - Cmd_AddCommand ("+lookup", IN_LookupDown, "When active the player's view " + Cmd_AddCommand ("+lookup", IN_LookupPress, "When active the player's view " "is looking up"); - Cmd_AddCommand ("-lookup", IN_LookupUp, "When active the player's view is " - "not looking up"); - Cmd_AddCommand ("+lookdown", IN_LookdownDown, "When active the player's " - "view is looking down"); - Cmd_AddCommand ("-lookdown", IN_LookdownUp, "When active the player's " + Cmd_AddCommand ("-lookup", IN_LookupRelease, "When active the player's " "view is not looking up"); - Cmd_AddCommand ("+strafe", IN_StrafeDown, "When active, +left and +right " + Cmd_AddCommand ("+lookdown", IN_LookdownPress, "When active the player's " + "view is looking down"); + Cmd_AddCommand ("-lookdown", IN_LookdownRelease, "When active the " + "player's view is not looking up"); + Cmd_AddCommand ("+strafe", IN_StrafePress, "When active, +left and +right " "function like +moveleft and +moveright"); - Cmd_AddCommand ("-strafe", IN_StrafeUp, "When active, +left and +right " - "stop functioning like +moveleft and +moveright"); - Cmd_AddCommand ("+moveleft", IN_MoveleftDown, "When active the player is " + Cmd_AddCommand ("-strafe", IN_StrafeRelease, "When active, +left and " + "+right stop functioning like +moveleft and +moveright"); + Cmd_AddCommand ("+moveleft", IN_MoveleftPress, "When active the player is " "strafing left"); - Cmd_AddCommand ("-moveleft", IN_MoveleftUp, "When active the player is " - "not strafing left"); - Cmd_AddCommand ("+moveright", IN_MoverightDown, "When active the player " + Cmd_AddCommand ("-moveleft", IN_MoveleftRelease, "When active the player " + "is not strafing left"); + Cmd_AddCommand ("+moveright", IN_MoverightPress, "When active the player " "is strafing right"); - Cmd_AddCommand ("-moveright", IN_MoverightUp, "When active the player is " - "not strafing right"); - Cmd_AddCommand ("+speed", IN_SpeedDown, "When active the player is " + Cmd_AddCommand ("-moveright", IN_MoverightRelease, "When active the " + "player is not strafing right"); + Cmd_AddCommand ("+speed", IN_SpeedPress, "When active the player is " "running"); - Cmd_AddCommand ("-speed", IN_SpeedUp, "When active the player is not " + Cmd_AddCommand ("-speed", IN_SpeedRelease, "When active the player is not " "running"); - Cmd_AddCommand ("+attack", IN_AttackDown, "When active player is " + Cmd_AddCommand ("+attack", IN_AttackPress, "When active player is " "firing/using current weapon"); - Cmd_AddCommand ("-attack", IN_AttackUp, "When active player is not " + Cmd_AddCommand ("-attack", IN_AttackRelease, "When active player is not " "firing/using current weapon"); - Cmd_AddCommand ("+use", IN_UseDown, "Non-functional. Left over command " + Cmd_AddCommand ("+use", IN_UsePress, "Non-functional. Left over command " "for opening doors and triggering switches"); - Cmd_AddCommand ("-use", IN_UseUp, "Non-functional. Left over command for " - "opening doors and triggering switches"); - Cmd_AddCommand ("+jump", IN_JumpDown, "When active the player is jumping"); - Cmd_AddCommand ("-jump", IN_JumpUp, "When active the player is not " + Cmd_AddCommand ("-use", IN_UseRelease, "Non-functional. Left over command " + "for opening doors and triggering switches"); + Cmd_AddCommand ("+jump", IN_JumpPress, "When active the player is " + "jumping"); + Cmd_AddCommand ("-jump", IN_JumpRelease, "When active the player is not " "jumping"); Cmd_AddCommand ("impulse", IN_Impulse, "Call a game function or QuakeC " "function."); - Cmd_AddCommand ("+klook", IN_KLookDown, "When active, +forward and +back " + Cmd_AddCommand ("+klook", IN_KLookPress, "When active, +forward and +back " "perform +lookup and +lookdown"); - Cmd_AddCommand ("-klook", IN_KLookUp, "When active, +forward and +back " - "don't perform +lookup and +lookdown"); - Cmd_AddCommand ("+mlook", IN_MLookDown, "When active moving the mouse or " + Cmd_AddCommand ("-klook", IN_KLookRelease, "When active, +forward and " + "+back don't perform +lookup and +lookdown"); + Cmd_AddCommand ("+mlook", IN_MLookPress, "When active moving the mouse or " "joystick forwards and backwards performs +lookup and " "+lookdown"); - Cmd_AddCommand ("-mlook", IN_MLookUp, "When active moving the mouse or " - "joystick forwards and backwards doesn't perform +lookup " - "and +lookdown"); + Cmd_AddCommand ("-mlook", IN_MLookRelease, "When active moving the mouse " + "or joystick forwards and backwards doesn't perform " + "+lookup and +lookdown"); } void diff --git a/qw/source/cl_view.c b/qw/source/cl_view.c index 9fbde1eae..3b023763c 100644 --- a/qw/source/cl_view.c +++ b/qw/source/cl_view.c @@ -242,7 +242,7 @@ void V_ParseDamage (void) { float count, side; - int armor, blood, i; + int armor, blood; vec3_t forward, from, right, up; armor = MSG_ReadByte (net_message); From 62f7d14ed2d6e3e377436eabff2df1b6e5263e9e Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 19 Jun 2011 19:04:49 +0900 Subject: [PATCH 093/334] White space cleanups. --- nq/source/cl_view.c | 18 +++++++++--------- qw/source/cl_view.c | 40 ++++++++++++++++++++-------------------- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/nq/source/cl_view.c b/nq/source/cl_view.c index 5384998a5..3c640ef59 100644 --- a/nq/source/cl_view.c +++ b/nq/source/cl_view.c @@ -84,11 +84,11 @@ float v_dmg_time, v_dmg_roll, v_dmg_pitch; float v_blend[4]; -cshift_t cshift_empty = { {130, 80, 50}, 0}; -cshift_t cshift_water = { {130, 80, 50}, 128}; -cshift_t cshift_slime = { {0, 25, 5}, 150}; -cshift_t cshift_lava = { {255, 80, 0}, 150}; -cshift_t cshift_bonus = { {215, 186, 60}, 50}; +cshift_t cshift_empty = { {130, 80, 50}, 0}; +cshift_t cshift_water = { {130, 80, 50}, 128}; +cshift_t cshift_slime = { {0, 25, 5}, 150}; +cshift_t cshift_lava = { {255, 80, 0}, 150}; +cshift_t cshift_bonus = { {215, 186, 60}, 50}; static float @@ -102,8 +102,8 @@ V_CalcBob (void) if (cycle < cl_bobup->value) cycle = M_PI * cycle / cl_bobup->value; else - cycle = M_PI + M_PI * (cycle - cl_bobup->value) / (1.0 - - cl_bobup->value); + cycle = M_PI + M_PI * (cycle - cl_bobup->value) / + (1.0 - cl_bobup->value); // bob is proportional to velocity in the xy plane // (don't count Z, or jumping messes it up) @@ -531,8 +531,8 @@ V_AddIdle (void) r_refdef.viewangles[ROLL] += v_idlescale->value * sin (cl.time * v_iroll_cycle->value) * v_iroll_level->value; r_refdef.viewangles[PITCH] += v_idlescale->value * - sin (cl.time * v_ipitch_cycle->value) * v_ipitch_level->value; - r_refdef.viewangles[YAW] += v_idlescale->value * + sin (cl.time * v_ipitch_cycle->value) * v_ipitch_level->value; + r_refdef.viewangles[YAW] += v_idlescale->value * sin (cl.time * v_iyaw_cycle->value) * v_iyaw_level->value; } diff --git a/qw/source/cl_view.c b/qw/source/cl_view.c index 3b023763c..45e565864 100644 --- a/qw/source/cl_view.c +++ b/qw/source/cl_view.c @@ -86,11 +86,11 @@ float v_blend[4]; frame_t *view_frame; player_state_t *view_message; -cshift_t cshift_empty = { {130, 80, 50}, 0}; -cshift_t cshift_water = { {130, 80, 50}, 128}; -cshift_t cshift_slime = { {0, 25, 5}, 150}; -cshift_t cshift_lava = { {255, 80, 0}, 150}; -cshift_t cshift_bonus = { {215, 186, 60}, 50}; +cshift_t cshift_empty = { {130, 80, 50}, 0}; +cshift_t cshift_water = { {130, 80, 50}, 128}; +cshift_t cshift_slime = { {0, 25, 5}, 150}; +cshift_t cshift_lava = { {255, 80, 0}, 150}; +cshift_t cshift_bonus = { {215, 186, 60}, 50}; @@ -118,9 +118,9 @@ V_CalcRoll (const vec3_t angles, const vec3_t velocity) static float V_CalcBob (void) { - static double bobtime; - float cycle; - static float bob; + static double bobtime; + float cycle; + static float bob; if (cl.spectator) return 0; @@ -135,7 +135,7 @@ V_CalcBob (void) if (cycle < cl_bobup->value) cycle = M_PI * cycle / cl_bobup->value; else - cycle = M_PI + M_PI * (cycle - cl_bobup->value) / + cycle = M_PI + M_PI * (cycle - cl_bobup->value) / (1.0 - cl_bobup->value); // bob is proportional to simulated velocity in the xy plane @@ -241,9 +241,9 @@ V_DriftPitch (void) void V_ParseDamage (void) { - float count, side; - int armor, blood; - vec3_t forward, from, right, up; + float count, side; + int armor, blood; + vec3_t from, forward, right, up; armor = MSG_ReadByte (net_message); blood = MSG_ReadByte (net_message); @@ -533,14 +533,14 @@ V_AddIdle (void) r_refdef.viewangles[ROLL] += v_idlescale->value * sin (cl.time * v_iroll_cycle->value) * v_iroll_level->value; r_refdef.viewangles[PITCH] += v_idlescale->value * - sin (cl.time * v_ipitch_cycle->value) * v_ipitch_level->value; - r_refdef.viewangles[YAW] += v_idlescale->value * + sin (cl.time * v_ipitch_cycle->value) * v_ipitch_level->value; + r_refdef.viewangles[YAW] += v_idlescale->value * sin (cl.time * v_iyaw_cycle->value) * v_iyaw_level->value; cl.viewent.angles[ROLL] -= v_idlescale->value * sin (cl.time * v_iroll_cycle->value) * v_iroll_level->value; - cl.viewent.angles[PITCH] -= v_idlescale->value * - sin (cl.time * v_ipitch_cycle->value) * v_ipitch_level->value; + cl.viewent.angles[PITCH] -= v_idlescale->value * + sin (cl.time * v_ipitch_cycle->value) * v_ipitch_level->value; cl.viewent.angles[YAW] -= v_idlescale->value * sin (cl.time * v_iyaw_cycle->value) * v_iyaw_level->value; } @@ -625,14 +625,14 @@ V_CalcRefdef (void) V_AddIdle (); if (view_message->pls.flags & PF_GIB) - r_refdef.vieworg[2] += 8; // gib view height + r_refdef.vieworg[2] += 8; // gib view height else if (view_message->pls.flags & PF_DEAD) - r_refdef.vieworg[2] -= 16; // corpse view height + r_refdef.vieworg[2] -= 16; // corpse view height else - r_refdef.vieworg[2] += zofs; // view height + r_refdef.vieworg[2] += zofs; // view height if (view_message->pls.flags & PF_DEAD) // PF_GIB will also set PF_DEAD - r_refdef.viewangles[ROLL] = 80; // dead view angle + r_refdef.viewangles[ROLL] = 80; // dead view angle // offsets AngleVectors (cl.simangles, forward, right, up); From 62b17d362980dcc45ce767f5fdb68111139dbbec Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 19 Jun 2011 20:02:00 +0900 Subject: [PATCH 094/334] Split out the entity linking code. This should smooth the merge process a little. --- nq/include/client.h | 3 +- nq/source/Makefile.am | 4 +- nq/source/cl_ents.c | 330 ++++++++++++++++++++++++++++++++++++++++++ nq/source/cl_main.c | 311 +-------------------------------------- qw/source/cl_parse.c | 11 +- 5 files changed, 341 insertions(+), 318 deletions(-) create mode 100644 nq/source/cl_ents.c diff --git a/nq/include/client.h b/nq/include/client.h index b850cc3d0..41bdf561c 100644 --- a/nq/include/client.h +++ b/nq/include/client.h @@ -373,11 +373,12 @@ void V_PrepBlend (void); // cl_tent void CL_TEnts_Init (void); -void CL_ClearEnts (void); void CL_ClearTEnts (void); void CL_Init_Entity (struct entity_s *ent); void CL_ParseTEnt (void); void CL_SignonReply (void); +void CL_RelinkEntities (void); +void CL_ClearEnts (void); extern kbutton_t in_left, in_right, in_forward, in_back; extern kbutton_t in_lookup, in_lookdown, in_moveleft, in_moveright; diff --git a/nq/source/Makefile.am b/nq/source/Makefile.am index 5a6ccd42a..daeb49dc3 100644 --- a/nq/source/Makefile.am +++ b/nq/source/Makefile.am @@ -75,8 +75,8 @@ server_LIBS= $(server_LIBFILES) $(common_LIBFILES) $(NET_LIBS) server_LIB_DEPS=$(server_LIBFILES) $(common_LIBFILES) libnq_client_a_SOURCES= \ - cl_cam.c cl_cmd.c cl_demo.c cl_input.c cl_main.c cl_screen.c \ - cl_parse.c cl_tent.c cl_view.c host_skin.c skin.c \ + cl_cam.c cl_cmd.c cl_demo.c cl_ents.c cl_input.c cl_main.c \ + cl_screen.c cl_parse.c cl_tent.c cl_view.c host_skin.c skin.c \ sbar.c libnq_server_a_SOURCES= \ diff --git a/nq/source/cl_ents.c b/nq/source/cl_ents.c new file mode 100644 index 000000000..fa4b2617b --- /dev/null +++ b/nq/source/cl_ents.c @@ -0,0 +1,330 @@ +/* + cl_main.c + + entity parsing and management + + Copyright (C) 1996-1997 Id Software, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + + Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA + +*/ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +static __attribute__ ((used)) const char rcsid[] = + "$Id$"; + +#include "QF/cbuf.h" +#include "QF/cmd.h" +#include "QF/console.h" +#include "QF/cvar.h" +#include "QF/input.h" +#include "QF/keys.h" +#include "QF/msg.h" +#include "QF/plugin.h" +#include "QF/qfplist.h" +#include "QF/render.h" +#include "QF/screen.h" +#include "QF/skin.h" +#include "QF/sys.h" +#include "QF/va.h" + +#include "chase.h" +#include "client.h" +#include "compat.h" +#include "host.h" +#include "host.h" +#include "r_cvar.h" +#include "r_dynamic.h" +#include "server.h" + +// FIXME: put these on hunk? +entity_t cl_entities[MAX_EDICTS]; +cl_entity_state_t cl_baselines[MAX_EDICTS]; + + +void +CL_ClearEnts (void) +{ + int i; + + // clear other arrays + memset (cl_entities, 0, sizeof (cl_entities)); + memset (cl_baselines, 0, sizeof (cl_baselines)); + memset (r_lightstyle, 0, sizeof (r_lightstyle)); + + for (i = 0; i < MAX_EDICTS; i++) { + cl_baselines[i].ent = &cl_entities[i]; + CL_Init_Entity (cl_entities + i); + } +} + +static void +CL_NewDlight (int key, vec3_t org, int effects) +{ + float radius; + float time = 0.1; + dlight_t *dl; + static quat_t normal = {0.4, 0.2, 0.05, 0.7}; + static quat_t red = {0.5, 0.05, 0.05, 0.7}; + static quat_t blue = {0.05, 0.05, 0.5, 0.7}; + static quat_t purple = {0.5, 0.05, 0.5, 0.7}; + + if (!(effects & (EF_BLUE | EF_RED | EF_BRIGHTLIGHT | EF_DIMLIGHT))) + return; + + dl = R_AllocDlight (key); + if (!dl) + return; + VectorCopy (org, dl->origin); + + radius = 200 + (rand () & 31); + if (effects & EF_BRIGHTLIGHT) { + radius += 200; + dl->origin[2] += 16; + } + if (effects & EF_DIMLIGHT) + if (effects & ~EF_DIMLIGHT) + radius -= 100; + dl->radius = radius; + dl->die = cl.time + time; + + switch (effects & (EF_BLUE | EF_RED)) { + case EF_RED | EF_BLUE: + QuatCopy (purple, dl->color); + break; + case EF_RED: + QuatCopy (red, dl->color); + break; + case EF_BLUE: + QuatCopy (blue, dl->color); + break; + default: + QuatCopy (normal, dl->color); + break; + } +} + +/* + CL_LerpPoint + + Determines the fraction between the last two messages that the objects + should be put at. +*/ +static float +CL_LerpPoint (void) +{ + float f, frac; + + f = cl.mtime[0] - cl.mtime[1]; + + if (!f || cl_nolerp->int_val || cls.timedemo || sv.active) { + cl.time = cl.mtime[0]; + return 1; + } + + if (f > 0.1) { // dropped packet, or start of demo + cl.mtime[1] = cl.mtime[0] - 0.1; + f = 0.1; + } + frac = (cl.time - cl.mtime[1]) / f; + + if (frac < 0) { + if (frac < -0.01) + cl.time = cl.mtime[1]; + frac = 0; + } else if (frac > 1) { + if (frac > 1.01) + cl.time = cl.mtime[0]; + frac = 1; + } + + return frac; +} + +void +CL_RelinkEntities (void) +{ + entity_t *ent; + cl_entity_state_t *state; + dlight_t *dl; + float bobjrotate, frac, f, d; + int i, j; + vec3_t delta; + + r_player_entity = &cl_entities[cl.viewentity]; + + // determine partial update time + frac = CL_LerpPoint (); + + // interpolate player info + for (i = 0; i < 3; i++) + cl.velocity[i] = cl.mvelocity[1][i] + + frac * (cl.mvelocity[0][i] - cl.mvelocity[1][i]); + + if (cls.demoplayback) { + // interpolate the angles + for (j = 0; j < 3; j++) { + d = cl.mviewangles[0][j] - cl.mviewangles[1][j]; + if (d > 180) + d -= 360; + else if (d < -180) + d += 360; + cl.viewangles[j] = cl.mviewangles[1][j] + frac * d; + } + } + + bobjrotate = anglemod (100 * cl.time); + + // start on the entity after the world + for (i = 1, state = cl_baselines + 1; i < cl.num_entities; i++, state++) { + ent = state->ent; + if (!ent->model) { // empty slot + if (ent->efrag) + R_RemoveEfrags (ent); // just became empty + continue; + } + // if the object wasn't included in the last packet, remove it + if (state->msgtime != cl.mtime[0]) { + ent->model = NULL; + //johnfitz -- next time this entity slot is reused, the lerp will + //need to be reset + ent->lerpflags |= LERP_RESETMOVE|LERP_RESETANIM; + if (ent->efrag) + R_RemoveEfrags (ent); // just became empty + continue; + } + + ent->colormod[3] = ENTALPHA_DECODE (state->alpha); + + VectorCopy (ent->origin, ent->old_origin); + + if (state->forcelink) { + // The entity was not updated in the last message so move to the + // final spot + VectorCopy (state->msg_origins[0], ent->origin); + VectorCopy (state->msg_angles[0], ent->angles); + if (i != cl.viewentity || chase_active->int_val) { + if (ent->efrag) + R_RemoveEfrags (ent); + R_AddEfrags (ent); + } + } else { + // If the delta is large, assume a teleport and don't lerp + f = frac; + VectorSubtract (state->msg_origins[0], + state->msg_origins[1], delta); + if (fabs (delta[0]) > 100 || fabs (delta[1] > 100) + || fabs (delta[2]) > 100) { + // assume a teleportation, not a motion + VectorCopy (state->msg_origins[0], ent->origin); + VectorCopy (state->msg_angles[0], ent->angles); + ent->lerpflags |= LERP_RESETMOVE; + } else { + // interpolate the origin and angles + // FIXME r_lerpmove.value && + if (ent->lerpflags & LERP_MOVESTEP) + f = 1; + VectorMultAdd (state->msg_origins[1], f, delta, ent->origin); + for (j = 0; j < 3; j++) { + d = state->msg_angles[0][j] - state->msg_angles[1][j]; + if (d > 180) + d -= 360; + else if (d < -180) + d += 360; + ent->angles[j] = state->msg_angles[1][j] + f * d; + } + } + if (i != cl.viewentity || chase_active->int_val) { + if (ent->efrag) { + if (!VectorCompare (ent->origin, ent->old_origin)) { + R_RemoveEfrags (ent); + R_AddEfrags (ent); + } + } else { + R_AddEfrags (ent); + } + } + } + + // rotate binary objects locally + if (ent->model->flags & EF_ROTATE) + ent->angles[1] = bobjrotate; + + if (state->effects & EF_BRIGHTFIELD) + R_EntityParticles (ent); + if (state->effects & EF_MUZZLEFLASH) { + vec3_t fv, rv, uv; + + dl = R_AllocDlight (i); + if (dl) { + AngleVectors (ent->angles, fv, rv, uv); + + VectorMultAdd (ent->origin, 18, fv, dl->origin); + dl->origin[2] += 16; + dl->radius = 200 + (rand () & 31); + dl->die = cl.time + 0.1; + dl->minlight = 32; + dl->color[0] = 0.2; + dl->color[1] = 0.1; + dl->color[2] = 0.05; + dl->color[3] = 0.7; + } +#if 0 //FIXME how much do we want this? + //johnfitz -- assume muzzle flash accompanied by muzzle flare, + //which looks bad when lerped + if (ent == &cl_entities[cl.viewentity]) + cl.viewent.lerpflags |= LERP_RESETANIM | LERP_RESETANIM2; + else + ent->lerpflags |= LERP_RESETANIM | LERP_RESETANIM2; +#endif + } + CL_NewDlight (i, ent->origin, state->effects); + if (VectorDistance_fast (state->msg_origins[1], ent->origin) + > (256 * 256)) + VectorCopy (ent->origin, state->msg_origins[1]); + if (ent->model->flags & EF_ROCKET) { + dl = R_AllocDlight (i); + if (dl) { + VectorCopy (ent->origin, dl->origin); + dl->radius = 200; + dl->die = cl.time + 0.1; + VectorCopy (r_firecolor->vec, dl->color); + dl->color[3] = 0.7; + } + R_RocketTrail (ent); + } else if (ent->model->flags & EF_GRENADE) + R_GrenadeTrail (ent); + else if (ent->model->flags & EF_GIB) + R_BloodTrail (ent); + else if (ent->model->flags & EF_ZOMGIB) + R_SlightBloodTrail (ent); + else if (ent->model->flags & EF_TRACER) + R_WizTrail (ent); + else if (ent->model->flags & EF_TRACER2) + R_FlameTrail (ent); + else if (ent->model->flags & EF_TRACER3) + R_VoorTrail (ent); + else if (ent->model->flags & EF_GLOWTRAIL) + R_GlowTrail (ent, state->glow_color); + + state->forcelink = false; + } +} diff --git a/nq/source/cl_main.c b/nq/source/cl_main.c index 7cfb88d62..59ffa6c6b 100644 --- a/nq/source/cl_main.c +++ b/nq/source/cl_main.c @@ -85,11 +85,6 @@ int fps_count; client_static_t cls; client_state_t cl; -// FIXME: put these on hunk? -entity_t cl_entities[MAX_EDICTS]; -cl_entity_state_t cl_baselines[MAX_EDICTS]; - - void CL_InitCvars (void) { @@ -146,8 +141,6 @@ CL_InitCvars (void) void CL_ClearState (void) { - int i; - if (!sv.active) Host_ClearMemory (); @@ -164,11 +157,6 @@ CL_ClearState (void) SZ_Clear (&cls.message); - // clear other arrays - memset (cl_entities, 0, sizeof (cl_entities)); - memset (cl_baselines, 0, sizeof (cl_baselines)); - memset (r_lightstyle, 0, sizeof (r_lightstyle)); - Skin_ClearTempSkins (); CL_ClearTEnts (); @@ -177,10 +165,7 @@ CL_ClearState (void) R_ClearDlights (); R_ClearParticles (); - for (i = 0; i < MAX_EDICTS; i++) { - cl_baselines[i].ent = &cl_entities[i]; - CL_Init_Entity (cl_entities + i); - } + CL_ClearEnts (); } /* @@ -363,300 +348,6 @@ CL_PrintEntities_f (void) } } -/* - SetPal - - Debugging tool, just flashes the screen -*/ -static void -SetPal (int i) -{ -#if 0 - byte pal[768]; - int c; - static int old; - - if (i == old) - return; - old = i; - - if (i == 0) - VID_SetPalette (vid.palette); - else if (i == 1) { - for (c = 0; c < 768; c += 3) { - pal[c] = 0; - pal[c + 1] = 255; - pal[c + 2] = 0; - } - VID_SetPalette (pal); - } else { - for (c = 0; c < 768; c += 3) { - pal[c] = 0; - pal[c + 1] = 0; - pal[c + 2] = 255; - } - VID_SetPalette (pal); - } -#endif -} - -static void -CL_NewDlight (int key, vec3_t org, int effects) -{ - float radius; - float time = 0.1; - dlight_t *dl; - static quat_t normal = {0.4, 0.2, 0.05, 0.7}; - static quat_t red = {0.5, 0.05, 0.05, 0.7}; - static quat_t blue = {0.05, 0.05, 0.5, 0.7}; - static quat_t purple = {0.5, 0.05, 0.5, 0.7}; - - if (!(effects & (EF_BLUE | EF_RED | EF_BRIGHTLIGHT | EF_DIMLIGHT))) - return; - - dl = R_AllocDlight (key); - if (!dl) - return; - VectorCopy (org, dl->origin); - radius = 200 + (rand () & 31); - if (effects & EF_BRIGHTLIGHT) { - radius += 200; - dl->origin[2] += 16; - } - if (effects & EF_DIMLIGHT) - if (effects & ~EF_DIMLIGHT) - radius -= 100; - dl->radius = radius; - dl->die = cl.time + time; - - switch (effects & (EF_BLUE | EF_RED)) { - case EF_RED | EF_BLUE: - QuatCopy (purple, dl->color); - break; - case EF_RED: - QuatCopy (red, dl->color); - break; - case EF_BLUE: - QuatCopy (blue, dl->color); - break; - default: - QuatCopy (normal, dl->color); - break; - } -} - -/* - CL_LerpPoint - - Determines the fraction between the last two messages that the objects - should be put at. -*/ -static float -CL_LerpPoint (void) -{ - float f, frac; - - f = cl.mtime[0] - cl.mtime[1]; - - if (!f || cl_nolerp->int_val || cls.timedemo || sv.active) { - cl.time = cl.mtime[0]; - return 1; - } - - if (f > 0.1) { // dropped packet, or start of demo - cl.mtime[1] = cl.mtime[0] - 0.1; - f = 0.1; - } - frac = (cl.time - cl.mtime[1]) / f; - - if (frac < 0) { - if (frac < -0.01) { - SetPal (1); - cl.time = cl.mtime[1]; - } - frac = 0; - } else if (frac > 1) { - if (frac > 1.01) { - SetPal (2); - cl.time = cl.mtime[0]; - } - frac = 1; - } else - SetPal (0); - - return frac; -} - -static void -CL_RelinkEntities (void) -{ - entity_t *ent; - cl_entity_state_t *state; - dlight_t *dl; - float bobjrotate, frac, f, d; - int i, j; - vec3_t delta; - - r_player_entity = &cl_entities[cl.viewentity]; - - // determine partial update time - frac = CL_LerpPoint (); - - // interpolate player info - for (i = 0; i < 3; i++) - cl.velocity[i] = cl.mvelocity[1][i] + - frac * (cl.mvelocity[0][i] - cl.mvelocity[1][i]); - - if (cls.demoplayback) { - // interpolate the angles - for (j = 0; j < 3; j++) { - d = cl.mviewangles[0][j] - cl.mviewangles[1][j]; - if (d > 180) - d -= 360; - else if (d < -180) - d += 360; - cl.viewangles[j] = cl.mviewangles[1][j] + frac * d; - } - } - - bobjrotate = anglemod (100 * cl.time); - - // start on the entity after the world - for (i = 1, state = cl_baselines + 1; i < cl.num_entities; i++, state++) { - ent = state->ent; - if (!ent->model) { // empty slot - if (ent->efrag) - R_RemoveEfrags (ent); // just became empty - continue; - } - // if the object wasn't included in the last packet, remove it - if (state->msgtime != cl.mtime[0]) { - ent->model = NULL; - //johnfitz -- next time this entity slot is reused, the lerp will - //need to be reset - ent->lerpflags |= LERP_RESETMOVE|LERP_RESETANIM; - if (ent->efrag) - R_RemoveEfrags (ent); // just became empty - continue; - } - - ent->colormod[3] = ENTALPHA_DECODE (state->alpha); - - VectorCopy (ent->origin, ent->old_origin); - - if (state->forcelink) { - // The entity was not updated in the last message so move to the - // final spot - VectorCopy (state->msg_origins[0], ent->origin); - VectorCopy (state->msg_angles[0], ent->angles); - if (i != cl.viewentity || chase_active->int_val) { - if (ent->efrag) - R_RemoveEfrags (ent); - R_AddEfrags (ent); - } - } else { - // If the delta is large, assume a teleport and don't lerp - f = frac; - VectorSubtract (state->msg_origins[0], - state->msg_origins[1], delta); - if (fabs (delta[0]) > 100 || fabs (delta[1] > 100) - || fabs (delta[2]) > 100) { - // assume a teleportation, not a motion - VectorCopy (state->msg_origins[0], ent->origin); - VectorCopy (state->msg_angles[0], ent->angles); - ent->lerpflags |= LERP_RESETMOVE; - } else { - // interpolate the origin and angles - // FIXME r_lerpmove.value && - if (ent->lerpflags & LERP_MOVESTEP) - f = 1; - VectorMultAdd (state->msg_origins[1], f, delta, ent->origin); - for (j = 0; j < 3; j++) { - d = state->msg_angles[0][j] - state->msg_angles[1][j]; - if (d > 180) - d -= 360; - else if (d < -180) - d += 360; - ent->angles[j] = state->msg_angles[1][j] + f * d; - } - } - if (i != cl.viewentity || chase_active->int_val) { - if (ent->efrag) { - if (!VectorCompare (ent->origin, ent->old_origin)) { - R_RemoveEfrags (ent); - R_AddEfrags (ent); - } - } else { - R_AddEfrags (ent); - } - } - } - - // rotate binary objects locally - if (ent->model->flags & EF_ROTATE) - ent->angles[1] = bobjrotate; - - if (state->effects & EF_BRIGHTFIELD) - R_EntityParticles (ent); - if (state->effects & EF_MUZZLEFLASH) { - vec3_t fv, rv, uv; - - dl = R_AllocDlight (i); - if (dl) { - AngleVectors (ent->angles, fv, rv, uv); - - VectorMultAdd (ent->origin, 18, fv, dl->origin); - dl->origin[2] += 16; - dl->radius = 200 + (rand () & 31); - dl->die = cl.time + 0.1; - dl->minlight = 32; - dl->color[0] = 0.2; - dl->color[1] = 0.1; - dl->color[2] = 0.05; - dl->color[3] = 0.7; - } -#if 0 //FIXME how much do we want this? - //johnfitz -- assume muzzle flash accompanied by muzzle flare, - //which looks bad when lerped - if (ent == &cl_entities[cl.viewentity]) - cl.viewent.lerpflags |= LERP_RESETANIM | LERP_RESETANIM2; - else - ent->lerpflags |= LERP_RESETANIM | LERP_RESETANIM2; -#endif - } - CL_NewDlight (i, ent->origin, state->effects); - if (VectorDistance_fast (state->msg_origins[1], ent->origin) - > (256 * 256)) - VectorCopy (ent->origin, state->msg_origins[1]); - if (ent->model->flags & EF_ROCKET) { - dl = R_AllocDlight (i); - if (dl) { - VectorCopy (ent->origin, dl->origin); - dl->radius = 200; - dl->die = cl.time + 0.1; - VectorCopy (r_firecolor->vec, dl->color); - dl->color[3] = 0.7; - } - R_RocketTrail (ent); - } else if (ent->model->flags & EF_GRENADE) - R_GrenadeTrail (ent); - else if (ent->model->flags & EF_GIB) - R_BloodTrail (ent); - else if (ent->model->flags & EF_ZOMGIB) - R_SlightBloodTrail (ent); - else if (ent->model->flags & EF_TRACER) - R_WizTrail (ent); - else if (ent->model->flags & EF_TRACER2) - R_FlameTrail (ent); - else if (ent->model->flags & EF_TRACER3) - R_VoorTrail (ent); - else if (ent->model->flags & EF_GLOWTRAIL) - R_GlowTrail (ent, state->glow_color); - - state->forcelink = false; - } -} - /* CL_ReadFromServer diff --git a/qw/source/cl_parse.c b/qw/source/cl_parse.c index 3312f04fd..07ef2074f 100644 --- a/qw/source/cl_parse.c +++ b/qw/source/cl_parse.c @@ -1301,7 +1301,7 @@ CL_ParseServerMessage (void) break; case svc_print: { - char p[2048]; + dstring_t *p = 0; i = MSG_ReadByte (net_message); s = MSG_ReadString (net_message); @@ -1313,13 +1313,12 @@ CL_ParseServerMessage (void) if (cl_nofake->int_val) { char *c; - strncpy (p, s, sizeof (p)); - p[sizeof (p) - 1] = 0; - for (c = p; *c; c++) { + p = dstring_strdup (s); + for (c = p->str; *c; c++) { if (*c == '\r') *c = '#'; } - s = p; + s = p->str; } Con_SetOrMask (128); S_LocalSound ("misc/talk.wav"); @@ -1328,6 +1327,8 @@ CL_ParseServerMessage (void) Team_ParseChat (s); } Sys_Printf ("%s", s); + if (p) + dstring_delete (p); Con_SetOrMask (0); break; } From 765b9ebb65800e2d81c3693bdf0433c5d4ca4b82 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 19 Jun 2011 21:34:48 +0900 Subject: [PATCH 095/334] Split up the qw entity handling code. More pre-merge organization. --- qw/include/cl_ents.h | 5 + qw/source/Makefile.am | 6 +- qw/source/cl_entparse.c | 663 ++++++++++++++++++++++++++++++++++++++++ qw/source/cl_ents.c | 603 +----------------------------------- 4 files changed, 672 insertions(+), 605 deletions(-) create mode 100644 qw/source/cl_entparse.c diff --git a/qw/include/cl_ents.h b/qw/include/cl_ents.h index 8fbfcbff7..413d19127 100644 --- a/qw/include/cl_ents.h +++ b/qw/include/cl_ents.h @@ -30,6 +30,7 @@ #define _CL_ENTS_H #include "QF/qtypes.h" +#include "QF/render.h" void CL_SetSolidPlayers (int playernum); void CL_ClearPredict (void); @@ -45,4 +46,8 @@ void CL_Ents_Init (void); extern struct cvar_s *cl_deadbodyfilter; extern struct cvar_s *cl_gibfilter; +extern entity_t cl_player_ents[]; +extern entity_t cl_flag_ents[]; +extern entity_t cl_packet_ents[]; + #endif diff --git a/qw/source/Makefile.am b/qw/source/Makefile.am index e46e41a15..6e081b605 100644 --- a/qw/source/Makefile.am +++ b/qw/source/Makefile.am @@ -106,9 +106,9 @@ client_LIBS= $(qw_client_LIBS) client_libs= libqw_client.a libqw_common.a libqw_client_a_SOURCES= \ - cl_cam.c cl_chat.c cl_cmd.c cl_cvar.c cl_demo.c cl_ents.c \ - cl_http.c cl_input.c cl_main.c cl_ngraph.c cl_parse.c cl_pred.c \ - cl_screen.c cl_skin.c cl_slist.c cl_tent.c cl_view.c \ + cl_cam.c cl_chat.c cl_cmd.c cl_cvar.c cl_demo.c cl_entparse.c \ + cl_ents.c cl_http.c cl_input.c cl_main.c cl_ngraph.c cl_parse.c \ + cl_pred.c cl_screen.c cl_skin.c cl_slist.c cl_tent.c cl_view.c \ locs.c sbar.c skin.c teamplay.c # Software-rendering clients diff --git a/qw/source/cl_entparse.c b/qw/source/cl_entparse.c new file mode 100644 index 000000000..11f2df7e5 --- /dev/null +++ b/qw/source/cl_entparse.c @@ -0,0 +1,663 @@ +/* + cl_ents.c + + entity parsing and management + + Copyright (C) 1996-1997 Id Software, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + + Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA + +*/ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +static __attribute__ ((used)) const char rcsid[] = + "$Id$"; + +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif + +#include "QF/cvar.h" +#include "QF/locs.h" +#include "QF/msg.h" +#include "QF/render.h" +#include "QF/skin.h" +#include "QF/sys.h" + +#include "qw/msg_ucmd.h" + +#include "qw/bothdefs.h" +#include "cl_cam.h" +#include "cl_ents.h" +#include "cl_main.h" +#include "cl_parse.h" +#include "cl_pred.h" +#include "cl_tent.h" +#include "compat.h" +#include "d_iface.h" +#include "host.h" +#include "qw/pmove.h" +#include "r_cvar.h" +#include "r_dynamic.h" +#include "clview.h" + +static struct predicted_player { + int flags; + qboolean active; + vec3_t origin; // predicted origin +} predicted_players[MAX_CLIENTS]; + + +// PACKET ENTITY PARSING / LINKING ============================================ + +/* + CL_ParseDelta + + Can go from either a baseline or a previous packet_entity +*/ +static void +CL_ParseDelta (entity_state_t *from, entity_state_t *to, int bits) +{ + int i; + + // set everything to the state we are delta'ing from + *to = *from; + + to->number = bits & 511; + bits &= ~511; + + if (bits & U_MOREBITS) { // read in the low order bits + i = MSG_ReadByte (net_message); + bits |= i; + } + + // LordHavoc: Endy neglected to mark this as being part of the QSG + // version 2 stuff... + if (bits & U_EXTEND1) { + bits |= MSG_ReadByte (net_message) << 16; + if (bits & U_EXTEND2) + bits |= MSG_ReadByte (net_message) << 24; + } + + to->flags = bits; + + if (bits & U_MODEL) + to->modelindex = MSG_ReadByte (net_message); + + if (bits & U_FRAME) + to->frame = MSG_ReadByte (net_message); + + if (bits & U_COLORMAP) + to->colormap = MSG_ReadByte (net_message); + + if (bits & U_SKIN) + to->skinnum = MSG_ReadByte (net_message); + + if (bits & U_EFFECTS) + to->effects = MSG_ReadByte (net_message); + + if (bits & U_ORIGIN1) + to->origin[0] = MSG_ReadCoord (net_message); + + if (bits & U_ANGLE1) + to->angles[0] = MSG_ReadAngle (net_message); + + if (bits & U_ORIGIN2) + to->origin[1] = MSG_ReadCoord (net_message); + + if (bits & U_ANGLE2) + to->angles[1] = MSG_ReadAngle (net_message); + + if (bits & U_ORIGIN3) + to->origin[2] = MSG_ReadCoord (net_message); + + if (bits & U_ANGLE3) + to->angles[2] = MSG_ReadAngle (net_message); + + if (bits & U_SOLID) { + // FIXME + } + + if (!(bits & U_EXTEND1)) + return; + + // LordHavoc: Endy neglected to mark this as being part of the QSG + // version 2 stuff... rearranged it and implemented missing effects +// Ender (QSG - Begin) + if (bits & U_ALPHA) + to->alpha = MSG_ReadByte (net_message); + if (bits & U_SCALE) + to->scale = MSG_ReadByte (net_message); + if (bits & U_EFFECTS2) + to->effects = (to->effects & 0xFF) | (MSG_ReadByte (net_message) << 8); + if (bits & U_GLOWSIZE) + to->glow_size = MSG_ReadByte (net_message); + if (bits & U_GLOWCOLOR) + to->glow_color = MSG_ReadByte (net_message); + if (bits & U_COLORMOD) + to->colormod = MSG_ReadByte (net_message); + + if (!(bits & U_EXTEND2)) + return; + + if (bits & U_FRAME2) + to->frame = (to->frame & 0xFF) | (MSG_ReadByte (net_message) << 8); +// Ender (QSG - End) +} + +static void +FlushEntityPacket (void) +{ + entity_state_t olde, newe; + int word; + + Sys_MaskPrintf (SYS_DEV, "FlushEntityPacket\n"); + + memset (&olde, 0, sizeof (olde)); + + cl.validsequence = 0; // can't render a frame + cl.frames[cls.netchan.incoming_sequence & UPDATE_MASK].invalid = true; + + // read it all, but ignore it + while (1) { + word = (unsigned short) MSG_ReadShort (net_message); + if (net_message->badread) { // something didn't parse right... + Host_Error ("msg_badread in packetentities"); + return; + } + + if (!word) + break; // done + + CL_ParseDelta (&olde, &newe, word); + } +} + +void +CL_ParsePacketEntities (qboolean delta) +{ + byte from; + int oldindex, newindex, newnum, oldnum, oldpacket, newpacket, word; + packet_entities_t *oldp, *newp, dummy; + qboolean full; + + newpacket = cls.netchan.incoming_sequence & UPDATE_MASK; + newp = &cl.frames[newpacket].packet_entities; + cl.frames[newpacket].invalid = false; + + if (delta) { + from = MSG_ReadByte (net_message); + + oldpacket = cl.frames[newpacket].delta_sequence; + if (cls.demoplayback2) + from = oldpacket = (cls.netchan.incoming_sequence - 1); + if ((from & UPDATE_MASK) != (oldpacket & UPDATE_MASK)) + Sys_MaskPrintf (SYS_DEV, "WARNING: from mismatch\n"); + } else + oldpacket = -1; + + full = false; + if (oldpacket != -1) { + if (cls.netchan.outgoing_sequence - oldpacket >= UPDATE_BACKUP - 1) { + // we can't use this, it is too old + FlushEntityPacket (); + return; + } + cl.validsequence = cls.netchan.incoming_sequence; + oldp = &cl.frames[oldpacket & UPDATE_MASK].packet_entities; + } else { // a full update that we can start delta compressing from now + oldp = &dummy; + dummy.num_entities = 0; + cl.validsequence = cls.netchan.incoming_sequence; + full = true; + } + + oldindex = 0; + newindex = 0; + newp->num_entities = 0; + + while (1) { + word = (unsigned short) MSG_ReadShort (net_message); + if (net_message->badread) { // something didn't parse right... + Host_Error ("msg_badread in packetentities"); + return; + } + + if (!word) { // copy rest of ents from old packet + while (oldindex < oldp->num_entities) { + if (newindex >= MAX_DEMO_PACKET_ENTITIES) + Host_Error ("CL_ParsePacketEntities: newindex == " + "MAX_DEMO_PACKET_ENTITIES"); + newp->entities[newindex] = oldp->entities[oldindex]; + newindex++; + oldindex++; + } + break; + } + newnum = word & 511; + oldnum = oldindex >= oldp->num_entities ? 9999 : + oldp->entities[oldindex].number; + + while (newnum > oldnum) { + if (full) { + Sys_Printf ("WARNING: oldcopy on full update"); + FlushEntityPacket (); + return; + } + // copy one of the old entities over to the new packet unchanged + if (newindex >= MAX_DEMO_PACKET_ENTITIES) + Host_Error ("CL_ParsePacketEntities: newindex == " + "MAX_DEMO_PACKET_ENTITIES"); + newp->entities[newindex] = oldp->entities[oldindex]; + newindex++; + oldindex++; + oldnum = oldindex >= oldp->num_entities ? 9999 : + oldp->entities[oldindex].number; + } + + if (newnum < oldnum) { // new from baseline + if (word & U_REMOVE) { + if (full) { + cl.validsequence = 0; + Sys_Printf ("WARNING: U_REMOVE on full update\n"); + FlushEntityPacket (); + return; + } + continue; + } + + if (newindex >= MAX_DEMO_PACKET_ENTITIES) + Host_Error ("CL_ParsePacketEntities: newindex == " + "MAX_DEMO_PACKET_ENTITIES"); + CL_ParseDelta (&cl_baselines[newnum], &newp->entities[newindex], + word); + newindex++; + continue; + } + + if (newnum == oldnum) { // delta from previous + if (full) { + cl.validsequence = 0; + Sys_Printf ("WARNING: delta on full update"); + } + if (word & U_REMOVE) { // Clear the entity + entity_t *ent = &cl_packet_ents[newnum]; + if (ent->efrag) + R_RemoveEfrags (ent); + memset (ent, 0, sizeof (entity_t)); + oldindex++; + continue; + } + CL_ParseDelta (&oldp->entities[oldindex], + &newp->entities[newindex], word); + newindex++; + oldindex++; + } + } + + newp->num_entities = newindex; +} + +static int +TranslateFlags (int src) +{ + int dst = 0; + + if (src & DF_EFFECTS) + dst |= PF_EFFECTS; + if (src & DF_SKINNUM) + dst |= PF_SKINNUM; + if (src & DF_DEAD) + dst |= PF_DEAD; + if (src & DF_GIB) + dst |= PF_GIB; + if (src & DF_WEAPONFRAME) + dst |= PF_WEAPONFRAME; + if (src & DF_MODEL) + dst |= PF_MODEL; + + return dst; +} + +static void +CL_ParseDemoPlayerinfo (int num) +{ + int flags, i; + player_info_t *info; + player_state_t *state, *prevstate; + static player_state_t dummy; + + info = &cl.players[num]; + state = &cl.frames[parsecountmod].playerstate[num]; + + state->pls.number = num; + + if (info->prevcount > cl.parsecount || !cl.parsecount) { + prevstate = &dummy; + } else { + if (cl.parsecount - info->prevcount >= UPDATE_BACKUP-1) + prevstate = &dummy; + else + prevstate = &cl.frames[info->prevcount + & UPDATE_MASK].playerstate[num]; + } + info->prevcount = cl.parsecount; + + if (cls.findtrack && info->stats[STAT_HEALTH] != 0) { + autocam = CAM_TRACK; + Cam_Lock (num); + ideal_track = num; + cls.findtrack = false; + } + + memcpy (state, prevstate, sizeof (player_state_t)); + + flags = MSG_ReadShort (net_message); + state->pls.flags = TranslateFlags (flags); + state->messagenum = cl.parsecount; + state->pls.cmd.msec = 0; + state->pls.frame = MSG_ReadByte (net_message); + state->state_time = parsecounttime; + for (i=0; i <3; i++) + if (flags & (DF_ORIGIN << i)) + state->pls.origin[i] = MSG_ReadCoord (net_message); + for (i=0; i <3; i++) + if (flags & (DF_ANGLES << i)) + state->pls.cmd.angles[i] = MSG_ReadAngle16 (net_message); + if (flags & DF_MODEL) + state->pls.modelindex = MSG_ReadByte (net_message); + if (flags & DF_SKINNUM) + state->pls.skinnum = MSG_ReadByte (net_message); + if (flags & DF_EFFECTS) + state->pls.effects = MSG_ReadByte (net_message); + if (flags & DF_WEAPONFRAME) + state->pls.weaponframe = MSG_ReadByte (net_message); + VectorCopy (state->pls.cmd.angles, state->viewangles); +} + +void +CL_ParsePlayerinfo (void) +{ + int flags, msec, num, i; + player_state_t *state; + + num = MSG_ReadByte (net_message); + if (num > MAX_CLIENTS) + Host_Error ("CL_ParsePlayerinfo: bad num"); + + if (cls.demoplayback2) { + CL_ParseDemoPlayerinfo (num); + return; + } + + state = &cl.frames[parsecountmod].playerstate[num]; + + state->pls.number = num; + + flags = state->pls.flags = MSG_ReadShort (net_message); + + state->messagenum = cl.parsecount; + MSG_ReadCoordV (net_message, state->pls.origin); + + state->pls.frame = MSG_ReadByte (net_message); + + // the other player's last move was likely some time + // before the packet was sent out, so accurately track + // the exact time it was valid at + if (flags & PF_MSEC) { + msec = MSG_ReadByte (net_message); + state->state_time = parsecounttime - msec * 0.001; + } else + state->state_time = parsecounttime; + + if (flags & PF_COMMAND) + MSG_ReadDeltaUsercmd (net_message, &nullcmd, &state->pls.cmd); + + for (i = 0; i < 3; i++) { + if (flags & (PF_VELOCITY1 << i)) + state->pls.velocity[i] = MSG_ReadShort (net_message); + else + state->pls.velocity[i] = 0; + } + if (flags & PF_MODEL) + i = MSG_ReadByte (net_message); + else + i = cl_playerindex; + state->pls.modelindex = i; + + if (flags & PF_SKINNUM) + state->pls.skinnum = MSG_ReadByte (net_message); + else + state->pls.skinnum = 0; + + if (flags & PF_EFFECTS) + state->pls.effects = MSG_ReadByte (net_message); + else + state->pls.effects = 0; + + if (flags & PF_WEAPONFRAME) + state->pls.weaponframe = MSG_ReadByte (net_message); + else + state->pls.weaponframe = 0; + + VectorCopy (state->pls.cmd.angles, state->viewangles); + + if (cl.stdver >= 2.0 && (flags & PF_QF)) { + // QSG2 + int bits; + byte val; + entity_t *ent; + + ent = &cl_player_ents[num]; + bits = MSG_ReadByte (net_message); + if (bits & PF_ALPHA) { + val = MSG_ReadByte (net_message); + ent->colormod[3] = val / 255.0; + } + if (bits & PF_SCALE) { + val = MSG_ReadByte (net_message); + ent->scale = val / 16.0; + } + if (bits & PF_EFFECTS2) { + state->pls.effects |= MSG_ReadByte (net_message) << 8; + } + if (bits & PF_GLOWSIZE) { + state->pls.glow_size = MSG_ReadByte (net_message); + } + if (bits & PF_GLOWCOLOR) { + state->pls.glow_color = MSG_ReadByte (net_message); + } + if (bits & PF_COLORMOD) { + float r = 1.0, g = 1.0, b = 1.0; + val = MSG_ReadByte (net_message); + if (val != 255) { + r = (float) ((val >> 5) & 7) * (1.0 / 7.0); + g = (float) ((val >> 2) & 7) * (1.0 / 7.0); + b = (float) (val & 3) * (1.0 / 3.0); + } + VectorSet (r, g, b, ent->colormod); + } + if (bits & PF_FRAME2) { + state->pls.frame |= MSG_ReadByte (net_message) << 8; + } + } +} + +/* + CL_SetSolid + + Builds all the pmove physents for the current frame +*/ +void +CL_SetSolidEntities (void) +{ + int i; + entity_state_t *state; + frame_t *frame; + packet_entities_t *pak; + + pmove.physents[0].model = cl.worldmodel; + VectorZero (pmove.physents[0].origin); + pmove.physents[0].info = 0; + pmove.numphysent = 1; + + frame = &cl.frames[parsecountmod]; + pak = &frame->packet_entities; + + for (i = 0; i < pak->num_entities; i++) { + state = &pak->entities[i]; + + if (!state->modelindex) + continue; + if (!cl.model_precache[state->modelindex]) + continue; + if (cl.model_precache[state->modelindex]->hulls[1].firstclipnode + || cl.model_precache[state->modelindex]->clipbox) { + if (pmove.numphysent == MAX_PHYSENTS) { + Sys_Printf ("WARNING: entity physent overflow, email " + "quakeforge-devel@lists.quakeforge.net\n"); + break; + } + pmove.physents[pmove.numphysent].model = + cl.model_precache[state->modelindex]; + VectorCopy (state->origin, + pmove.physents[pmove.numphysent].origin); + pmove.numphysent++; + } + } +} + +void +CL_ClearPredict (void) +{ + memset (predicted_players, 0, sizeof (predicted_players)); + //fixangle = 0; +} + +/* + Calculate the new position of players, without other player clipping + + We do this to set up real player prediction. + Players are predicted twice, first without clipping other players, + then with clipping against them. + This sets up the first phase. +*/ +void +CL_SetUpPlayerPrediction (qboolean dopred) +{ + double playertime; + frame_t *frame; + int msec, j; + player_state_t exact; + player_state_t *state; + struct predicted_player *pplayer; + + playertime = realtime - cls.latency + 0.02; + if (playertime > realtime) + playertime = realtime; + + frame = &cl.frames[cl.parsecount & UPDATE_MASK]; + + for (j = 0, pplayer = predicted_players, state = frame->playerstate; + j < MAX_CLIENTS; j++, pplayer++, state++) { + + pplayer->active = false; + + if (state->messagenum != cl.parsecount) + continue; // not present this frame + + if (!state->pls.modelindex) + continue; + + pplayer->active = true; + pplayer->flags = state->pls.flags; + + // note that the local player is special, since he moves locally + // we use his last predicted postition + if (j == cl.playernum) { + VectorCopy (cl.frames[cls.netchan.outgoing_sequence & UPDATE_MASK]. + playerstate[cl.playernum].pls.origin, pplayer->origin); + } else { + // predict only half the move to minimize overruns + msec = 500 * (playertime - state->state_time); + if (msec <= 0 || !dopred) { + VectorCopy (state->pls.origin, pplayer->origin); +// Sys_MaskPrintf (SYS_DEV, "nopredict\n"); + } else { + // predict players movement + state->pls.cmd.msec = msec = min (msec, 255); +// Sys_MaskPrintf (SYS_DEV, "predict: %i\n", msec); + + CL_PredictUsercmd (state, &exact, &state->pls.cmd, false); + VectorCopy (exact.pls.origin, pplayer->origin); + } + } + } +} + +/* + CL_SetSolid + + Builds all the pmove physents for the current frame + Note that CL_SetUpPlayerPrediction () must be called first! + pmove must be setup with world and solid entity hulls before calling + (via CL_PredictMove) +*/ +void +CL_SetSolidPlayers (int playernum) +{ + int j; + physent_t *pent; + struct predicted_player *pplayer; + + if (!cl_solid_players->int_val) + return; + + pent = pmove.physents + pmove.numphysent; + + for (j = 0, pplayer = predicted_players; j < MAX_CLIENTS; j++, pplayer++) { + if (!pplayer->active) + continue; // not present this frame + + // the player object never gets added + if (j == playernum) + continue; + + if (pplayer->flags & PF_DEAD) + continue; // dead players aren't solid + + if (pmove.numphysent == MAX_PHYSENTS) { + Sys_Printf ("WARNING: player physent overflow, email " + "quakeforge-devel@lists.quakeforge.net\n"); + break; + } + + pent->model = 0; + VectorCopy (pplayer->origin, pent->origin); + VectorCopy (player_mins, pent->mins); + VectorCopy (player_maxs, pent->maxs); + pmove.numphysent++; + pent++; + } +} diff --git a/qw/source/cl_ents.c b/qw/source/cl_ents.c index 37b1118dd..77a5effbd 100644 --- a/qw/source/cl_ents.c +++ b/qw/source/cl_ents.c @@ -28,7 +28,7 @@ # include "config.h" #endif -static __attribute__ ((used)) const char rcsid[] = +static __attribute__ ((used)) const char rcsid[] = "$Id$"; #ifdef HAVE_STRING_H @@ -62,18 +62,10 @@ static __attribute__ ((used)) const char rcsid[] = #include "r_dynamic.h" #include "clview.h" -static struct predicted_player { - int flags; - qboolean active; - vec3_t origin; // predicted origin -} predicted_players[MAX_CLIENTS]; - - entity_t cl_player_ents[MAX_CLIENTS]; entity_t cl_flag_ents[MAX_CLIENTS]; entity_t cl_packet_ents[512]; // FIXME: magic number - void CL_ClearEnts () { @@ -155,256 +147,6 @@ CL_NewDlight (int key, vec3_t org, int effects, byte glow_size, } } -// PACKET ENTITY PARSING / LINKING ============================================ - -/* - CL_ParseDelta - - Can go from either a baseline or a previous packet_entity -*/ -static void -CL_ParseDelta (entity_state_t *from, entity_state_t *to, int bits) -{ - int i; - - // set everything to the state we are delta'ing from - *to = *from; - - to->number = bits & 511; - bits &= ~511; - - if (bits & U_MOREBITS) { // read in the low order bits - i = MSG_ReadByte (net_message); - bits |= i; - } - - // LordHavoc: Endy neglected to mark this as being part of the QSG - // version 2 stuff... - if (bits & U_EXTEND1) { - bits |= MSG_ReadByte (net_message) << 16; - if (bits & U_EXTEND2) - bits |= MSG_ReadByte (net_message) << 24; - } - - to->flags = bits; - - if (bits & U_MODEL) - to->modelindex = MSG_ReadByte (net_message); - - if (bits & U_FRAME) - to->frame = MSG_ReadByte (net_message); - - if (bits & U_COLORMAP) - to->colormap = MSG_ReadByte (net_message); - - if (bits & U_SKIN) - to->skinnum = MSG_ReadByte (net_message); - - if (bits & U_EFFECTS) - to->effects = MSG_ReadByte (net_message); - - if (bits & U_ORIGIN1) - to->origin[0] = MSG_ReadCoord (net_message); - - if (bits & U_ANGLE1) - to->angles[0] = MSG_ReadAngle (net_message); - - if (bits & U_ORIGIN2) - to->origin[1] = MSG_ReadCoord (net_message); - - if (bits & U_ANGLE2) - to->angles[1] = MSG_ReadAngle (net_message); - - if (bits & U_ORIGIN3) - to->origin[2] = MSG_ReadCoord (net_message); - - if (bits & U_ANGLE3) - to->angles[2] = MSG_ReadAngle (net_message); - - if (bits & U_SOLID) { - // FIXME - } - - if (!(bits & U_EXTEND1)) - return; - - // LordHavoc: Endy neglected to mark this as being part of the QSG - // version 2 stuff... rearranged it and implemented missing effects -// Ender (QSG - Begin) - if (bits & U_ALPHA) - to->alpha = MSG_ReadByte (net_message); - if (bits & U_SCALE) - to->scale = MSG_ReadByte (net_message); - if (bits & U_EFFECTS2) - to->effects = (to->effects & 0xFF) | (MSG_ReadByte (net_message) << 8); - if (bits & U_GLOWSIZE) - to->glow_size = MSG_ReadByte (net_message); - if (bits & U_GLOWCOLOR) - to->glow_color = MSG_ReadByte (net_message); - if (bits & U_COLORMOD) - to->colormod = MSG_ReadByte (net_message); - - if (!(bits & U_EXTEND2)) - return; - - if (bits & U_FRAME2) - to->frame = (to->frame & 0xFF) | (MSG_ReadByte (net_message) << 8); -// Ender (QSG - End) -} - -static void -FlushEntityPacket (void) -{ - entity_state_t olde, newe; - int word; - - Sys_MaskPrintf (SYS_DEV, "FlushEntityPacket\n"); - - memset (&olde, 0, sizeof (olde)); - - cl.validsequence = 0; // can't render a frame - cl.frames[cls.netchan.incoming_sequence & UPDATE_MASK].invalid = true; - - // read it all, but ignore it - while (1) { - word = (unsigned short) MSG_ReadShort (net_message); - if (net_message->badread) { // something didn't parse right... - Host_Error ("msg_badread in packetentities"); - return; - } - - if (!word) - break; // done - - CL_ParseDelta (&olde, &newe, word); - } -} - -void -CL_ParsePacketEntities (qboolean delta) -{ - byte from; - int oldindex, newindex, newnum, oldnum, oldpacket, newpacket, word; - packet_entities_t *oldp, *newp, dummy; - qboolean full; - - newpacket = cls.netchan.incoming_sequence & UPDATE_MASK; - newp = &cl.frames[newpacket].packet_entities; - cl.frames[newpacket].invalid = false; - - if (delta) { - from = MSG_ReadByte (net_message); - - oldpacket = cl.frames[newpacket].delta_sequence; - if (cls.demoplayback2) - from = oldpacket = (cls.netchan.incoming_sequence - 1); - if ((from & UPDATE_MASK) != (oldpacket & UPDATE_MASK)) - Sys_MaskPrintf (SYS_DEV, "WARNING: from mismatch\n"); - } else - oldpacket = -1; - - full = false; - if (oldpacket != -1) { - if (cls.netchan.outgoing_sequence - oldpacket >= UPDATE_BACKUP - 1) { - // we can't use this, it is too old - FlushEntityPacket (); - return; - } - cl.validsequence = cls.netchan.incoming_sequence; - oldp = &cl.frames[oldpacket & UPDATE_MASK].packet_entities; - } else { // a full update that we can start delta compressing from now - oldp = &dummy; - dummy.num_entities = 0; - cl.validsequence = cls.netchan.incoming_sequence; - full = true; - } - - oldindex = 0; - newindex = 0; - newp->num_entities = 0; - - while (1) { - word = (unsigned short) MSG_ReadShort (net_message); - if (net_message->badread) { // something didn't parse right... - Host_Error ("msg_badread in packetentities"); - return; - } - - if (!word) { // copy rest of ents from old packet - while (oldindex < oldp->num_entities) { - if (newindex >= MAX_DEMO_PACKET_ENTITIES) - Host_Error ("CL_ParsePacketEntities: newindex == " - "MAX_DEMO_PACKET_ENTITIES"); - newp->entities[newindex] = oldp->entities[oldindex]; - newindex++; - oldindex++; - } - break; - } - newnum = word & 511; - oldnum = oldindex >= oldp->num_entities ? 9999 : - oldp->entities[oldindex].number; - - while (newnum > oldnum) { - if (full) { - Sys_Printf ("WARNING: oldcopy on full update"); - FlushEntityPacket (); - return; - } - // copy one of the old entities over to the new packet unchanged - if (newindex >= MAX_DEMO_PACKET_ENTITIES) - Host_Error ("CL_ParsePacketEntities: newindex == " - "MAX_DEMO_PACKET_ENTITIES"); - newp->entities[newindex] = oldp->entities[oldindex]; - newindex++; - oldindex++; - oldnum = oldindex >= oldp->num_entities ? 9999 : - oldp->entities[oldindex].number; - } - - if (newnum < oldnum) { // new from baseline - if (word & U_REMOVE) { - if (full) { - cl.validsequence = 0; - Sys_Printf ("WARNING: U_REMOVE on full update\n"); - FlushEntityPacket (); - return; - } - continue; - } - - if (newindex >= MAX_DEMO_PACKET_ENTITIES) - Host_Error ("CL_ParsePacketEntities: newindex == " - "MAX_DEMO_PACKET_ENTITIES"); - CL_ParseDelta (&cl_baselines[newnum], &newp->entities[newindex], - word); - newindex++; - continue; - } - - if (newnum == oldnum) { // delta from previous - if (full) { - cl.validsequence = 0; - Sys_Printf ("WARNING: delta on full update"); - } - if (word & U_REMOVE) { // Clear the entity - entity_t *ent = &cl_packet_ents[newnum]; - if (ent->efrag) - R_RemoveEfrags (ent); - memset (ent, 0, sizeof (entity_t)); - oldindex++; - continue; - } - CL_ParseDelta (&oldp->entities[oldindex], - &newp->entities[newindex], word); - newindex++; - oldindex++; - } - } - - newp->num_entities = newindex; -} - // Hack hack hack static inline int is_dead_body (entity_state_t *s1) @@ -570,191 +312,6 @@ CL_LinkPacketEntities (void) } } -static int -TranslateFlags (int src) -{ - int dst = 0; - - if (src & DF_EFFECTS) - dst |= PF_EFFECTS; - if (src & DF_SKINNUM) - dst |= PF_SKINNUM; - if (src & DF_DEAD) - dst |= PF_DEAD; - if (src & DF_GIB) - dst |= PF_GIB; - if (src & DF_WEAPONFRAME) - dst |= PF_WEAPONFRAME; - if (src & DF_MODEL) - dst |= PF_MODEL; - - return dst; -} - -static void -CL_ParseDemoPlayerinfo (int num) -{ - int flags, i; - player_info_t *info; - player_state_t *state, *prevstate; - static player_state_t dummy; - - info = &cl.players[num]; - state = &cl.frames[parsecountmod].playerstate[num]; - - state->pls.number = num; - - if (info->prevcount > cl.parsecount || !cl.parsecount) { - prevstate = &dummy; - } else { - if (cl.parsecount - info->prevcount >= UPDATE_BACKUP-1) - prevstate = &dummy; - else - prevstate = &cl.frames[info->prevcount - & UPDATE_MASK].playerstate[num]; - } - info->prevcount = cl.parsecount; - - if (cls.findtrack && info->stats[STAT_HEALTH] != 0) { - autocam = CAM_TRACK; - Cam_Lock (num); - ideal_track = num; - cls.findtrack = false; - } - - memcpy (state, prevstate, sizeof (player_state_t)); - - flags = MSG_ReadShort (net_message); - state->pls.flags = TranslateFlags (flags); - state->messagenum = cl.parsecount; - state->pls.cmd.msec = 0; - state->pls.frame = MSG_ReadByte (net_message); - state->state_time = parsecounttime; - for (i=0; i <3; i++) - if (flags & (DF_ORIGIN << i)) - state->pls.origin[i] = MSG_ReadCoord (net_message); - for (i=0; i <3; i++) - if (flags & (DF_ANGLES << i)) - state->pls.cmd.angles[i] = MSG_ReadAngle16 (net_message); - if (flags & DF_MODEL) - state->pls.modelindex = MSG_ReadByte (net_message); - if (flags & DF_SKINNUM) - state->pls.skinnum = MSG_ReadByte (net_message); - if (flags & DF_EFFECTS) - state->pls.effects = MSG_ReadByte (net_message); - if (flags & DF_WEAPONFRAME) - state->pls.weaponframe = MSG_ReadByte (net_message); - VectorCopy (state->pls.cmd.angles, state->viewangles); -} - -void -CL_ParsePlayerinfo (void) -{ - int flags, msec, num, i; - player_state_t *state; - - num = MSG_ReadByte (net_message); - if (num > MAX_CLIENTS) - Host_Error ("CL_ParsePlayerinfo: bad num"); - - if (cls.demoplayback2) { - CL_ParseDemoPlayerinfo (num); - return; - } - - state = &cl.frames[parsecountmod].playerstate[num]; - - state->pls.number = num; - - flags = state->pls.flags = MSG_ReadShort (net_message); - - state->messagenum = cl.parsecount; - MSG_ReadCoordV (net_message, state->pls.origin); - - state->pls.frame = MSG_ReadByte (net_message); - - // the other player's last move was likely some time - // before the packet was sent out, so accurately track - // the exact time it was valid at - if (flags & PF_MSEC) { - msec = MSG_ReadByte (net_message); - state->state_time = parsecounttime - msec * 0.001; - } else - state->state_time = parsecounttime; - - if (flags & PF_COMMAND) - MSG_ReadDeltaUsercmd (net_message, &nullcmd, &state->pls.cmd); - - for (i = 0; i < 3; i++) { - if (flags & (PF_VELOCITY1 << i)) - state->pls.velocity[i] = MSG_ReadShort (net_message); - else - state->pls.velocity[i] = 0; - } - if (flags & PF_MODEL) - i = MSG_ReadByte (net_message); - else - i = cl_playerindex; - state->pls.modelindex = i; - - if (flags & PF_SKINNUM) - state->pls.skinnum = MSG_ReadByte (net_message); - else - state->pls.skinnum = 0; - - if (flags & PF_EFFECTS) - state->pls.effects = MSG_ReadByte (net_message); - else - state->pls.effects = 0; - - if (flags & PF_WEAPONFRAME) - state->pls.weaponframe = MSG_ReadByte (net_message); - else - state->pls.weaponframe = 0; - - VectorCopy (state->pls.cmd.angles, state->viewangles); - - if (cl.stdver >= 2.0 && (flags & PF_QF)) { - // QSG2 - int bits; - byte val; - entity_t *ent; - - ent = &cl_player_ents[num]; - bits = MSG_ReadByte (net_message); - if (bits & PF_ALPHA) { - val = MSG_ReadByte (net_message); - ent->colormod[3] = val / 255.0; - } - if (bits & PF_SCALE) { - val = MSG_ReadByte (net_message); - ent->scale = val / 16.0; - } - if (bits & PF_EFFECTS2) { - state->pls.effects |= MSG_ReadByte (net_message) << 8; - } - if (bits & PF_GLOWSIZE) { - state->pls.glow_size = MSG_ReadByte (net_message); - } - if (bits & PF_GLOWCOLOR) { - state->pls.glow_color = MSG_ReadByte (net_message); - } - if (bits & PF_COLORMOD) { - float r = 1.0, g = 1.0, b = 1.0; - val = MSG_ReadByte (net_message); - if (val != 255) { - r = (float) ((val >> 5) & 7) * (1.0 / 7.0); - g = (float) ((val >> 2) & 7) * (1.0 / 7.0); - b = (float) (val & 3) * (1.0 / 3.0); - } - VectorSet (r, g, b, ent->colormod); - } - if (bits & PF_FRAME2) { - state->pls.frame |= MSG_ReadByte (net_message) << 8; - } - } -} - /* CL_AddFlagModels @@ -929,164 +486,6 @@ CL_LinkPlayers (void) } } -/* - CL_SetSolid - - Builds all the pmove physents for the current frame -*/ -void -CL_SetSolidEntities (void) -{ - int i; - entity_state_t *state; - frame_t *frame; - packet_entities_t *pak; - - pmove.physents[0].model = cl.worldmodel; - VectorZero (pmove.physents[0].origin); - pmove.physents[0].info = 0; - pmove.numphysent = 1; - - frame = &cl.frames[parsecountmod]; - pak = &frame->packet_entities; - - for (i = 0; i < pak->num_entities; i++) { - state = &pak->entities[i]; - - if (!state->modelindex) - continue; - if (!cl.model_precache[state->modelindex]) - continue; - if (cl.model_precache[state->modelindex]->hulls[1].firstclipnode - || cl.model_precache[state->modelindex]->clipbox) { - if (pmove.numphysent == MAX_PHYSENTS) { - Sys_Printf ("WARNING: entity physent overflow, email " - "quakeforge-devel@lists.quakeforge.net\n"); - break; - } - pmove.physents[pmove.numphysent].model = - cl.model_precache[state->modelindex]; - VectorCopy (state->origin, - pmove.physents[pmove.numphysent].origin); - pmove.numphysent++; - } - } -} - -void -CL_ClearPredict (void) -{ - memset (predicted_players, 0, sizeof (predicted_players)); - //fixangle = 0; -} - -/* - Calculate the new position of players, without other player clipping - - We do this to set up real player prediction. - Players are predicted twice, first without clipping other players, - then with clipping against them. - This sets up the first phase. -*/ -void -CL_SetUpPlayerPrediction (qboolean dopred) -{ - double playertime; - frame_t *frame; - int msec, j; - player_state_t exact; - player_state_t *state; - struct predicted_player *pplayer; - - playertime = realtime - cls.latency + 0.02; - if (playertime > realtime) - playertime = realtime; - - frame = &cl.frames[cl.parsecount & UPDATE_MASK]; - - for (j = 0, pplayer = predicted_players, state = frame->playerstate; - j < MAX_CLIENTS; j++, pplayer++, state++) { - - pplayer->active = false; - - if (state->messagenum != cl.parsecount) - continue; // not present this frame - - if (!state->pls.modelindex) - continue; - - pplayer->active = true; - pplayer->flags = state->pls.flags; - - // note that the local player is special, since he moves locally - // we use his last predicted postition - if (j == cl.playernum) { - VectorCopy (cl.frames[cls.netchan.outgoing_sequence & UPDATE_MASK]. - playerstate[cl.playernum].pls.origin, pplayer->origin); - } else { - // predict only half the move to minimize overruns - msec = 500 * (playertime - state->state_time); - if (msec <= 0 || !dopred) { - VectorCopy (state->pls.origin, pplayer->origin); -// Sys_MaskPrintf (SYS_DEV, "nopredict\n"); - } else { - // predict players movement - state->pls.cmd.msec = msec = min (msec, 255); -// Sys_MaskPrintf (SYS_DEV, "predict: %i\n", msec); - - CL_PredictUsercmd (state, &exact, &state->pls.cmd, false); - VectorCopy (exact.pls.origin, pplayer->origin); - } - } - } -} - -/* - CL_SetSolid - - Builds all the pmove physents for the current frame - Note that CL_SetUpPlayerPrediction () must be called first! - pmove must be setup with world and solid entity hulls before calling - (via CL_PredictMove) -*/ -void -CL_SetSolidPlayers (int playernum) -{ - int j; - physent_t *pent; - struct predicted_player *pplayer; - - if (!cl_solid_players->int_val) - return; - - pent = pmove.physents + pmove.numphysent; - - for (j = 0, pplayer = predicted_players; j < MAX_CLIENTS; j++, pplayer++) { - if (!pplayer->active) - continue; // not present this frame - - // the player object never gets added - if (j == playernum) - continue; - - if (pplayer->flags & PF_DEAD) - continue; // dead players aren't solid - - if (pmove.numphysent == MAX_PHYSENTS) { - Sys_Printf ("WARNING: player physent overflow, email " - "quakeforge-devel@lists.quakeforge.net\n"); - break; - } - - pent->model = 0; - VectorCopy (pplayer->origin, pent->origin); - VectorCopy (player_mins, pent->mins); - VectorCopy (player_maxs, pent->maxs); - pmove.numphysent++; - pent++; - } -} - /* CL_EmitEntities From fb9a095586156f9eedd0bf3e051e2f461cfdd215 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 19 Jun 2011 21:39:35 +0900 Subject: [PATCH 096/334] Fix include style mixup. "" for local, <> for system --- nq/source/cl_cmd.c | 2 +- qw/source/game.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nq/source/cl_cmd.c b/nq/source/cl_cmd.c index a58639cdd..e0bbd1793 100644 --- a/nq/source/cl_cmd.c +++ b/nq/source/cl_cmd.c @@ -25,7 +25,7 @@ */ #ifdef HAVE_CONFIG_H -# include +# include "config.h" #endif #ifdef HAVE_STRING_H # include diff --git a/qw/source/game.c b/qw/source/game.c index 162a89830..5c7b824f3 100644 --- a/qw/source/game.c +++ b/qw/source/game.c @@ -27,7 +27,7 @@ */ #ifdef HAVE_CONFIG_H -# include +# include "config.h" #endif #ifdef HAVE_STRING_H # include From 73d11aedcaa1651ab0b025de2f3b380282ffa49b Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 22 Aug 2011 20:00:17 +0900 Subject: [PATCH 097/334] Do a lot of diff reduction. --- nq/source/sbar.c | 313 ++++++++++++++++++++--------------------- qw/source/sbar.c | 356 +++++++++++++++++++++-------------------------- 2 files changed, 309 insertions(+), 360 deletions(-) diff --git a/nq/source/sbar.c b/nq/source/sbar.c index 5dc0bc7f7..88e8b4050 100644 --- a/nq/source/sbar.c +++ b/nq/source/sbar.c @@ -28,13 +28,20 @@ # include "config.h" #endif -static __attribute__ ((used)) const char rcsid[] = +static __attribute__ ((used)) const char rcsid[] = "$Id$"; +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif + #include -#include "QF/console.h" #include "QF/cmd.h" +#include "QF/console.h" #include "QF/cvar.h" #include "QF/draw.h" #include "QF/dstring.h" @@ -42,8 +49,8 @@ static __attribute__ ((used)) const char rcsid[] = #include "QF/plugin.h" #include "QF/screen.h" #include "QF/sys.h" -#include "QF/vid.h" #include "QF/va.h" +#include "QF/vid.h" #include "QF/view.h" #include "QF/wad.h" @@ -57,6 +64,7 @@ static __attribute__ ((used)) const char rcsid[] = int sb_updates; // if >= vid.numpages, no update needed #define STAT_MINUS 10 // num frame for '-' stats digit + qpic_t *sb_nums[2][11]; qpic_t *sb_colon, *sb_slash; qpic_t *sb_ibar; @@ -79,6 +87,7 @@ qpic_t *sb_face_invis_invuln; qboolean sb_showscores; int sb_lines; // scan lines to draw +qboolean hudswap; qpic_t *rsb_invbar[2]; qpic_t *rsb_weapons[5]; @@ -115,6 +124,7 @@ static view_t *stuff_view; static void hud_swap_f (cvar_t *var) { + hudswap = var->int_val; if (var->int_val) { hud_armament_view->gravity = grav_southwest; hud_armament_view->children[0]->gravity = grav_northwest; @@ -225,53 +235,32 @@ viewsize_f (cvar_t *var) static int Sbar_ColorForMap (int m) { - return m + 8; // FIXME: Might want this to be - // return (bound (0, m, 13) * 16) + 8; + return (bound (0, m, 13) * 16) + 8; } - -/* - Sbar_ShowScores - - Tab key has been pressed, inform sbar it needs to show scores -*/ static void Sbar_ShowScores (void) { if (sb_showscores) return; + sb_showscores = true; sb_updates = 0; } - -/* - Sbar_DontShowScores - - Tab key up, show normal sbar again -*/ static void Sbar_DontShowScores (void) { - if (!sb_showscores) - return; sb_showscores = false; sb_updates = 0; } - -/* - Sbar_Changed - - Call this to signal sbar to redraw next frame. -*/ void Sbar_Changed (void) { sb_updates = 0; // update next frame } - static void draw_pic (view_t *view, int x, int y, qpic_t *pic) { @@ -389,10 +378,133 @@ draw_smallnum (view_t *view, int x, int y, int n, int packed, int colored) static void draw_tile (view_t *view) -{ +{ Draw_TileClear (view->xabs, view->yabs, view->xlen, view->ylen); } +static void +draw_ammo_sbar (view_t *view) +{ + int i, count; + + // ammo counts + for (i = 0; i < 4; i++) { + count = cl.stats[STAT_SHELLS + i]; + draw_smallnum (view, (6 * i + 1) * 8 + 2, 0, count, 0, 1); + } +} + +static void +draw_ammo_hud (view_t *view) +{ + int i, count; + + // ammo counts + for (i = 0; i < 4; i++) { + count = cl.stats[STAT_SHELLS + i]; + draw_subpic (view, 0, i * 11, sb_ibar, 3 + (i * 48), 0, 42, 11); + draw_smallnum (view, 7, i * 11, count, 0, 1); + } +} + +static int +calc_flashon (float time, int mask) +{ + int flashon; + + flashon = (int) ((cl.time - time) * 10); + if (flashon < 0) + flashon = 0; + if (flashon >= 10) { + if (cl.stats[STAT_ACTIVEWEAPON] == mask) + flashon = 1; + else + flashon = 0; + } else + flashon = (flashon % 5) + 2; + return flashon; +} + +static void +draw_weapons_sbar (view_t *view) +{ + int flashon, i; + + for (i = 0; i < 7; i++) { + if (cl.stats[STAT_ITEMS] & (IT_SHOTGUN << i)) { + flashon = calc_flashon (cl.item_gettime[i], IT_SHOTGUN << i); + draw_pic (view, i * 24, 0, sb_weapons[flashon][i]); + if (flashon > 1) + sb_updates = 0; // force update to remove flash + } + } +} + +static void +draw_weapons_hud (view_t *view) +{ + int flashon, i, x = 0; + + if (view->parent->gravity == grav_southeast) + x = view->xlen - 24; + + for (i = vid.conheight < 204; i < 7; i++) { + if (cl.stats[STAT_ITEMS] & (IT_SHOTGUN << i)) { + flashon = calc_flashon (cl.item_gettime[i], IT_SHOTGUN << i); + draw_subpic (view, x, i * 16, sb_weapons[flashon][i], 0, 0, 24, 16); + if (flashon > 1) + sb_updates = 0; // force update to remove flash + } + } +} + +static void +draw_items (view_t *view) +{ + float time; + int flashon = 0, i; + + for (i = 0; i < 6; i++) { + if (cl.stats[STAT_ITEMS] & (1 << (17 + i))) { + time = cl.item_gettime[17 + i]; + if (time && time > cl.time - 2 && flashon) { // Flash frame + sb_updates = 0; + } else { + draw_pic (view, i * 16, 0, sb_items[i]); + } + if (time && time > cl.time - 2) + sb_updates = 0; + } + } +} + +static void +draw_sigils (view_t *view) +{ + float time; + int flashon = 0, i; + + for (i = 0; i < 4; i++) { + if (cl.stats[STAT_ITEMS] & (1 << (28 + i))) { + time = cl.item_gettime[28 + i]; + if (time && time > cl.time - 2 && flashon) { // flash frame + sb_updates = 0; + } else { + draw_pic (view, i * 8, 0, sb_sigil[i]); + } + if (time && time > cl.time - 2) + sb_updates = 0; + } + } +} + +static void +draw_inventory_sbar (view_t *view) +{ + draw_pic (view, 0, 0, sb_ibar); + view_draw (view); +} + int fragsort[MAX_SCOREBOARD]; char scoreboardtext[MAX_SCOREBOARD][20]; @@ -459,125 +571,6 @@ draw_solo (view_t *view) draw_string (view, max (l, 152), 12, cl.levelname); } -static void -draw_ammo_sbar (view_t *view) -{ - int i, count; - - for (i = 0; i < 4; i++) { - count = cl.stats[STAT_SHELLS + i]; - draw_smallnum (view, (6 * i + 1) * 8 - 2, 0, count, 0, 1); - } -} - -static void -draw_ammo_hud (view_t *view) -{ - int i, count; - - for (i = 0; i < 4; i++) { - count = cl.stats[STAT_SHELLS + i]; - draw_subpic (view, 0, i * 11, sb_ibar, 3 + (i * 48), 0, 42, 11); - draw_smallnum (view, 7, i * 11, count, 0, 1); - } -} - -static int -calc_flashon (float time, int mask) -{ - int flashon; - - flashon = (int) ((cl.time - time) * 10); - if (flashon < 0) - flashon = 0; - if (flashon >= 10) { - if (cl.stats[STAT_ACTIVEWEAPON] == mask) - flashon = 1; - else - flashon = 0; - } else - flashon = (flashon % 5) + 2; - return flashon; -} - -static void -draw_weapons_sbar (view_t *view) -{ - int flashon, i; - - // weapons - for (i = 0; i < 7; i++) { - if (cl.stats[STAT_ITEMS] & (IT_SHOTGUN << i)) { - flashon = calc_flashon (cl.item_gettime[i], IT_SHOTGUN << i); - draw_pic (view, i * 24, 0, sb_weapons[flashon][i]); - if (flashon > 1) - sb_updates = 0; // force update to remove flash - } - } -} - -static void -draw_weapons_hud (view_t *view) -{ - int flashon, i; - - for (i = vid.conheight < 204; i < 7; i++) { - if (cl.stats[STAT_ITEMS] & (IT_SHOTGUN << i)) { - flashon = calc_flashon (cl.item_gettime[i], IT_SHOTGUN << i); - draw_subpic (view, 0, i * 16, sb_weapons[flashon][i], 0, 0, 24, 16); - if (flashon > 1) - sb_updates = 0; // force update to remove flash - } - } -} - -static void -draw_items (view_t *view) -{ - float time; - int flashon = 0, i; - - for (i = 0; i < 6; i++) { - if (cl.stats[STAT_ITEMS] & (1 << (17 + i))) { - time = cl.item_gettime[17 + i]; - if (time && time > (cl.time - 2) && flashon) { // Flash frame - sb_updates = 0; - } else { - draw_pic (view, i * 16, 0, sb_items[i]); - } - if (time && time > cl.time - 2) - sb_updates = 0; - } - } -} - -static void -draw_sigils (view_t *view) -{ - float time; - int flashon = 0, i; - - for (i = 0; i < 4; i++) { - if (cl.stats[STAT_ITEMS] & (1 << (28 + i))) { - time = cl.item_gettime[28 + i]; - if (time && time > cl.time - 2 && flashon) { // flash frame - sb_updates = 0; - } else { - draw_pic (view, i * 8, 0, sb_sigil[i]); - } - if (time && time > cl.time - 2) - sb_updates = 0; - } - } -} - -static void -draw_inventory_sbar (view_t *view) -{ - draw_pic (view, 0, 0, sb_ibar); - view_draw (view); -} - static void draw_frags (view_t *view) { @@ -603,8 +596,8 @@ draw_frags (view_t *view) continue; // draw background - top = s->colors & 0xf0; - bottom = (s->colors & 15) << 4; + top = (((unsigned) s->colors) >> 4) & 0x0f; + bottom = s->colors & 0x0f; top = Sbar_ColorForMap (top); bottom = Sbar_ColorForMap (bottom); @@ -615,6 +608,7 @@ draw_frags (view_t *view) if (k == cl.viewentity - 1) p = i; + x += 32; } if (p != -1) { @@ -817,8 +811,8 @@ draw_rogue_face (view_t *view) s = &cl.scores[cl.viewentity - 1]; - top = (s->colors & 0xf0); - bottom = ((s->colors & 15) << 4); + top = (((unsigned) s->colors) >> 4) & 0x0f; + bottom = s->colors & 0x0f; top = Sbar_ColorForMap (top); bottom = Sbar_ColorForMap (bottom); @@ -1057,8 +1051,8 @@ Sbar_DeathmatchOverlay (view_t *view) continue; // draw background - top = s->colors & 0xf0; - bottom = (s->colors & 15) << 4; + top = (((unsigned) s->colors) >> 4) & 0x0f; + bottom = s->colors & 0x0f; top = Sbar_ColorForMap (top); bottom = Sbar_ColorForMap (bottom); @@ -1118,7 +1112,7 @@ draw_time (view_t *view) static void draw_fps (view_t *view) { - static char st[80]; //FIXME: overflow + static char st[80]; double t; static double lastframetime; static double lastfps; @@ -1638,11 +1632,6 @@ Sbar_GIB_Print_Center_f (void) Sbar_CenterPrint (GIB_Argv(1)); } -/* - Sbar_Init - - Initialize the status bar's data -*/ void Sbar_Init (void) { @@ -1724,8 +1713,10 @@ Sbar_Init (void) sb_face_invis_invuln = Draw_PicFromWad ("face_inv2"); sb_face_quad = Draw_PicFromWad ("face_quad"); - Cmd_AddCommand ("+showscores", Sbar_ShowScores, "No Description"); - Cmd_AddCommand ("-showscores", Sbar_DontShowScores, "No Description"); + Cmd_AddCommand ("+showscores", Sbar_ShowScores, + "Display information on everyone playing"); + Cmd_AddCommand ("-showscores", Sbar_DontShowScores, + "Stop displaying information on everyone playing"); sb_sbar = Draw_PicFromWad ("sbar"); sb_ibar = Draw_PicFromWad ("ibar"); @@ -1786,7 +1777,7 @@ Sbar_Init (void) r_viewsize_callback = viewsize_f; hud_sbar = Cvar_Get ("hud_sbar", "0", CVAR_ARCHIVE, hud_sbar_f, - "status bar mode"); + "status bar mode: 0 = hud, 1 = oldstyle"); hud_swap = Cvar_Get ("hud_swap", "0", CVAR_ARCHIVE, hud_swap_f, "new HUD on left side?"); hud_scoreboard_gravity = Cvar_Get ("hud_scoreboard_gravity", "center", diff --git a/qw/source/sbar.c b/qw/source/sbar.c index 762e849a8..676958f71 100644 --- a/qw/source/sbar.c +++ b/qw/source/sbar.c @@ -28,7 +28,7 @@ # include "config.h" #endif -static __attribute__ ((used)) const char rcsid[] = +static __attribute__ ((used)) const char rcsid[] = "$Id$"; #ifdef HAVE_STRING_H @@ -39,7 +39,6 @@ static __attribute__ ((used)) const char rcsid[] = #endif #include - #include #include "QF/cmd.h" @@ -99,7 +98,6 @@ static qboolean largegame = false; cvar_t *fs_fraglog; cvar_t *cl_fraglog; cvar_t *hud_sbar; -cvar_t *hud_sbar_separator; cvar_t *hud_swap; cvar_t *hud_scoreboard_gravity; cvar_t *hud_scoreboard_uid; @@ -227,11 +225,12 @@ viewsize_f (cvar_t *var) } -/* - Sbar_ShowTeamScores +static int +Sbar_ColorForMap (int m) +{ + return (bound (0, m, 13) * 16) + 8; +} - Tab key down -*/ static void Sbar_ShowTeamScores (void) { @@ -242,11 +241,6 @@ Sbar_ShowTeamScores (void) sb_updates = 0; } -/* - Sbar_DontShowTeamScores - - Tab key up -*/ static void Sbar_DontShowTeamScores (void) { @@ -254,11 +248,6 @@ Sbar_DontShowTeamScores (void) sb_updates = 0; } -/* - Sbar_ShowScores - - Tab key down -*/ static void Sbar_ShowScores (void) { @@ -269,11 +258,6 @@ Sbar_ShowScores (void) sb_updates = 0; } -/* - Sbar_DontShowScores - - Tab key up -*/ static void Sbar_DontShowScores (void) { @@ -294,10 +278,11 @@ draw_pic (view_t *view, int x, int y, qpic_t *pic) } static inline void -draw_cachepic (view_t *view, int x, int y, const char *name) +draw_cachepic (view_t *view, int x, int y, const char *name, int cent) { qpic_t *pic = Draw_CachePic (name, true); - x += (view->xlen - pic->width) / 2; + if (cent) + x += (view->xlen - pic->width) / 2; Draw_Pic (view->xabs + x, view->yabs + y, pic); } @@ -480,19 +465,13 @@ Sbar_SortTeams (void) } } -static int -Sbar_ColorForMap (int m) -{ - return (bound (0, m, 13) * 16) + 8; -} - static void draw_solo (view_t *view) { char str[80]; int minutes, seconds; - draw_pic (view, 0, 0, sb_scorebar); + draw_pic (view, 0, 0, sb_scorebar); minutes = cl.time / 60; seconds = cl.time - 60 * minutes; @@ -524,6 +503,140 @@ draw_smallnum (view_t *view, int x, int y, int n, int packed, int colored) draw_character (view, x + 16 - packed, y, num[2]); } +static void +draw_tile (view_t *view) +{ + Draw_TileClear (view->xabs, view->yabs, view->xlen, view->ylen); +} + +static void +draw_ammo_sbar (view_t *view) +{ + int i, count; + + // ammo counts + for (i = 0; i < 4; i++) { + count = cl.stats[STAT_SHELLS + i]; + draw_smallnum (view, (6 * i + 1) * 8 + 2, 0, count, 0, 1); + } +} + +static void +draw_ammo_hud (view_t *view) +{ + int i, count; + + // ammo counts + for (i = 0; i < 4; i++) { + count = cl.stats[STAT_SHELLS + i]; + draw_subpic (view, 0, i * 11, sb_ibar, 3 + (i * 48), 0, 42, 11); + draw_smallnum (view, 7, i * 11, count, 0, 1); + } +} + +static int +calc_flashon (float time, int mask) +{ + int flashon; + + flashon = (int) ((cl.time - time) * 10); + if (flashon < 0) + flashon = 0; + if (flashon >= 10) { + if (cl.stats[STAT_ACTIVEWEAPON] == mask) + flashon = 1; + else + flashon = 0; + } else + flashon = (flashon % 5) + 2; + return flashon; +} + +static void +draw_weapons_sbar (view_t *view) +{ + int flashon, i; + + for (i = 0; i < 7; i++) { + if (cl.stats[STAT_ITEMS] & (IT_SHOTGUN << i)) { + flashon = calc_flashon (cl.item_gettime[i], IT_SHOTGUN << i); + draw_pic (view, i * 24, 0, sb_weapons[flashon][i]); + if (flashon > 1) + sb_updates = 0; // force update to remove flash + } + } +} + +static void +draw_weapons_hud (view_t *view) +{ + int flashon, i, x = 0; + + if (view->parent->gravity == grav_southeast) + x = view->xlen - 24; + + for (i = vid.conheight < 204; i < 7; i++) { + if (cl.stats[STAT_ITEMS] & (IT_SHOTGUN << i)) { + flashon = calc_flashon (cl.item_gettime[i], IT_SHOTGUN << i); + draw_subpic (view, x, i * 16, sb_weapons[flashon][i], 0, 0, 24, 16); + if (flashon > 1) + sb_updates = 0; // force update to remove flash + } + } +} + +static void +draw_items (view_t *view) +{ + float time; + int flashon = 0, i; + + for (i = 0; i < 6; i++) { + if (cl.stats[STAT_ITEMS] & (1 << (17 + i))) { + time = cl.item_gettime[17 + i]; + if (time && time > cl.time - 2 && flashon) { // Flash frame + sb_updates = 0; + } else { + draw_pic (view, i * 16, 0, sb_items[i]); + } + if (time && time > cl.time - 2) + sb_updates = 0; + } + } +} + +static void +draw_sigils (view_t *view) +{ + float time; + int flashon = 0, i; + + for (i = 0; i < 4; i++) { + if (cl.stats[STAT_ITEMS] & (1 << (28 + i))) { + time = cl.item_gettime[28 + i]; + if (time && time > cl.time - 2 && flashon) { // flash frame + sb_updates = 0; + } else { + draw_pic (view, i * 8, 0, sb_sigil[i]); + } + if (time && time > cl.time - 2) + sb_updates = 0; + } + } +} + +static void +draw_inventory_sbar (view_t *view) +{ + if (cl.spectator && autocam == CAM_TRACK) { + if (sbar_frags_view) + sbar_frags_view->draw (sbar_frags_view); + return; + } + draw_pic (view, 0, 0, sb_ibar); + view_draw (view); +} + static inline void dmo_ping (view_t *view, int x, int y, player_info_t *s) { @@ -595,7 +708,7 @@ dmo_main (view_t *view, int x, int y, player_info_t *s, int is_client) fph = calc_fph (f, total); snprintf (num, sizeof (num), "%3i", fph); draw_string (view, x, y, num); - + //draw time snprintf (num, sizeof (num), "%4i", minutes); draw_string (view, x + 32, y, num); @@ -630,151 +743,6 @@ dmo_name (view_t *view, int x, int y, player_info_t *s) draw_string (view, x, y, s->name); } -static int -calc_flashon (int ind) -{ - float time; - int flashon; - - time = cl.item_gettime[ind]; - flashon = (int) ((cl.time - time) * 10); - if (flashon < 0) - flashon = 0; - if (flashon >= 10) { - if (cl.stats[STAT_ACTIVEWEAPON] == (IT_SHOTGUN << ind)) - flashon = 1; - else - flashon = 0; - } else - flashon = (flashon % 5) + 2; - return flashon; -} - -static void -draw_weapons_sbar (view_t *view) -{ - int flashon, i; - - for (i = 0; i < 7; i++) { - if (cl.stats[STAT_ITEMS] & (IT_SHOTGUN << i)) { - flashon = calc_flashon (i); - draw_pic (view, i * 24, 0, sb_weapons[flashon][i]); - if (flashon > 1) - sb_updates = 0; // force update to remove flash - } - } -} - -static void -draw_weapons_hud (view_t *view) -{ - int flashon, i, x = 0; - - if (view->parent->gravity == grav_southeast) - x = view->xlen - 24; - - for (i = vid.conheight < 204; i < 7; i++) { - if (cl.stats[STAT_ITEMS] & (IT_SHOTGUN << i)) { - flashon = calc_flashon (i); - draw_subpic (view, x, i * 16, sb_weapons[flashon][i], 0, 0, 24, 16); - if (flashon > 1) - sb_updates = 0; // force update to remove flash - } - } -} - -static void -draw_ammo_sbar (view_t *view) -{ - char num[12]; - int i; - - // ammo counts -#define HUD_X(n, dist) ((6 * n + dist) * 8 + 2) - for (i = 0; i < 4; i++) { - snprintf (num, sizeof (num), "%3i", min (cl.stats[STAT_SHELLS + i], - 999)); - if (num[0] != ' ') - draw_character (view, HUD_X(i, 1), 0, 18 + num[0] - '0'); - if (num[1] != ' ') - draw_character (view, HUD_X(i, 2), 0, 18 + num[1] - '0'); - if (num[2] != ' ') - draw_character (view, HUD_X(i, 3), 0, 18 + num[2] - '0'); - } -#undef HUD_X -} - -static void -draw_ammo_hud (view_t *view) -{ - char num[12]; - int i; - - // ammo counts - for (i = 0; i < 4; i++) { - snprintf (num, sizeof (num), "%3i", min (cl.stats[STAT_SHELLS + i], - 999)); -#define HUD_X(dist) (dist + 4) - draw_subpic (view, 0, i * 11, sb_ibar, 3 + (i * 48), 0, 42, 11); - if (num[0] != ' ') - draw_character (view, HUD_X (3), i * 11, 18 + num[0] - '0'); - if (num[1] != ' ') - draw_character (view, HUD_X (11), i * 11, 18 + num[1] - '0'); - if (num[2] != ' ') - draw_character (view, HUD_X (19), i * 11, 18 + num[2] - '0'); -#undef HUD_X - } -} - -static void -draw_items (view_t *view) -{ - float time; - int flashon = 0, i; - - for (i = 0; i < 6; i++) - if (cl.stats[STAT_ITEMS] & (1 << (17 + i))) { - time = cl.item_gettime[17 + i]; - if (time && time > cl.time - 2 && flashon) { // flash frame - sb_updates = 0; - } else - draw_pic (view, i * 16, 0, sb_items[i]); - if (time && time > cl.time - 2) - sb_updates = 0; - } -} - -static void -draw_sigils (view_t *view) -{ - float time; - int flashon = 0, i; - - for (i = 0; i < 4; i++) - if (cl.stats[STAT_ITEMS] & (1 << (28 + i))) { - time = cl.item_gettime[28 + i]; - if (time && time > cl.time - 2 && flashon) { // flash frame - sb_updates = 0; - } else - draw_pic (view, i * 8, 0, sb_sigil[i]); - if (time && time > cl.time - 2) - sb_updates = 0; - } -} - -static void -draw_inventory_sbar (view_t *view) -{ - if (cl.spectator && autocam == CAM_TRACK) { - if (sbar_frags_view) - sbar_frags_view->draw (sbar_frags_view); - return; - } - draw_pic (view, 0, 0, sb_ibar); - - view_draw (view); -} - static void draw_frags (view_t *view) { @@ -944,12 +912,6 @@ draw_overlay (view_t *view) Sbar_TeamOverlay (view); } -static void -draw_tile (view_t *view) -{ - Draw_TileClear (view->xabs, view->yabs, view->xlen, view->ylen); -} - void Sbar_Draw (void) { @@ -958,11 +920,12 @@ Sbar_Draw (void) sbar_view->visible = 0; headsup = !(hud_sbar->int_val || scr_viewsize->int_val < 100); + if ((sb_updates >= vid.numpages) && !headsup) return; if (con_module && con_module->data->console->lines == vid.conheight) - return; + return; // console is full screen if (cls.state == ca_active && ((cl.stats[STAT_HEALTH] <= 0 && !cl.spectator) @@ -1005,7 +968,7 @@ Sbar_TeamOverlay (view_t *view) scr_copyeverything = 1; scr_fullupdate = 0; - draw_cachepic (view, 0, 0, "gfx/ranking.lmp"); + draw_cachepic (view, 0, 0, "gfx/ranking.lmp", 1); y = 24; x = 36; @@ -1066,7 +1029,7 @@ Sbar_TeamOverlay (view_t *view) /* Sbar_LogFrags - autologging of frags after a match ended + autologging of frags after a match ended (called by recived network packet with command scv_intermission) TODO: Find a new and better place for this function (i am nearly shure this is wrong place) @@ -1097,7 +1060,7 @@ Sbar_LogFrags (void) Qprintf (file, "%s\n%s %s\n", cls.servername->str, cl.worldmodel->name, cl.levelname); - // scores + // scores Sbar_SortFrags (true); // draw the text @@ -1138,7 +1101,7 @@ Sbar_LogFrags (void) for (cp = (byte *) s->name, d = 0; *cp; cp++, d++) name[d] = sys_char_map[*cp]; name[d] = 0; - + if (s->spectator) { Qprintf (file, "%-3i%% %s (spectator)", s->pl, name); } else { @@ -1159,7 +1122,7 @@ Sbar_LogFrags (void) free (name); Qwrite (file, "\n\n", 1); } - + Qclose (file); } @@ -1170,7 +1133,7 @@ Sbar_Draw_DMO_Team_Ping (view_t *view, int l, int y, int skip) player_info_t *s; x = 4; -// 0 40 64 104 152 192 +// 0 40 64 104 152 192 224 draw_string (view, x, y, "ping pl fph time frags team name"); y += 8; draw_string (view, x, y, "\x1d\x1e\x1e\x1f \x1d\x1f \x1d\x1e\x1f " @@ -1454,7 +1417,7 @@ Sbar_DeathmatchOverlay (view_t *view, int start) scr_fullupdate = 0; if (!start) { - draw_cachepic (view, 0, 0, "gfx/ranking.lmp"); + draw_cachepic (view, 0, 0, "gfx/ranking.lmp", 1); y = 24; } else y = start; @@ -1489,7 +1452,7 @@ draw_minifrags (view_t *view) scr_copyeverything = 1; scr_fullupdate = 0; - // scores + // scores Sbar_SortFrags (false); if (!scoreboardlines) @@ -1504,7 +1467,7 @@ draw_minifrags (view_t *view) if (fragsort[i] == cl.playernum) break; - if (i == scoreboardlines) // we're not there, we are probably a + if (i == scoreboardlines) // we're not there, we are probably a // spectator, just display top i = 0; else // figure out start @@ -1754,7 +1717,7 @@ Sbar_FinaleOverlay (void) scr_copyeverything = 1; - draw_cachepic (overlay_view, 0, 16, "gfx/finale.lmp"); + draw_cachepic (overlay_view, 0, 16, "gfx/finale.lmp", 1); // the finale prints the characters one at a time remaining = scr_printspeed->value * (realtime - centertime_start); Sbar_DrawCenterString (overlay_view, remaining); @@ -1862,9 +1825,6 @@ init_sbar_views (void) view->resize_y = 1; view_add (sbar_view, view); } - - //if (con_module) - // view_insert (con_module->data->console->view, sbar_view, 0); } static void @@ -2078,8 +2038,6 @@ Sbar_Init (void) "it on."); hud_sbar = Cvar_Get ("hud_sbar", "0", CVAR_ARCHIVE, hud_sbar_f, "status bar mode: 0 = hud, 1 = oldstyle"); - hud_sbar_separator = Cvar_Get ("hud_sbar_separator", "0", CVAR_ARCHIVE, - NULL, "turns on status bar separator"); hud_swap = Cvar_Get ("hud_swap", "0", CVAR_ARCHIVE, hud_swap_f, "new HUD on left side?"); hud_scoreboard_gravity = Cvar_Get ("hud_scoreboard_gravity", "center", From 85bcac3c8d30a164fd2a8e73da5d5d5ffe29eed4 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 24 Aug 2011 13:56:00 +0900 Subject: [PATCH 098/334] Reduce cl_cam diffs to spectator specifics. --- nq/source/cl_cam.c | 23 +++++++++--------- qw/source/cl_cam.c | 59 +++++++++++++++++++++++----------------------- 2 files changed, 41 insertions(+), 41 deletions(-) diff --git a/nq/source/cl_cam.c b/nq/source/cl_cam.c index 51abb1ec3..cc7550a7c 100644 --- a/nq/source/cl_cam.c +++ b/nq/source/cl_cam.c @@ -80,6 +80,7 @@ TraceLine (vec3_t start, vec3_t end, vec3_t impact) trace_t trace; memset (&trace, 0, sizeof (trace)); + trace.fraction = 1; MOD_TraceLine (cl.worldmodel->hulls, 0, start, end, &trace); VectorCopy (trace.endpos, impact); @@ -129,8 +130,8 @@ Chase_Update (void) // don't let camera get too far from player - VectorSubtract (camera_origin, player_origin, dir); - VectorCopy (dir, forward); + VectorSubtract (camera_origin, player_origin, dir); + VectorCopy (dir, forward); VectorNormalize (forward); if (VectorLength (dir) > chase_back->value) { @@ -198,25 +199,25 @@ Chase_Update (void) } if (in_speed.state & 1) { cmd.forwardmove *= cl_movespeedkey->value; - cmd.sidemove *= cl_movespeedkey->value; + cmd.sidemove *= cl_movespeedkey->value; } // mouse and joystick controllers add to movement - dir[1] = cl.viewangles[1] - camera_angles[1]; dir[0] = 0; dir[2] = 0; + VectorSet (0, cl.viewangles[1] - camera_angles[1], 0, dir); AngleVectors (dir, forward, right, up); - VectorScale (forward, viewdelta.position[2] * m_forward->value, + VectorScale (forward, viewdelta.position[2] * m_forward->value, forward); - VectorScale (right, viewdelta.position[0] * m_side->value, right); - VectorAdd (forward, right, dir); + VectorScale (right, viewdelta.position[0] * m_side->value, right); + VectorAdd (forward, right, dir); cmd.forwardmove += dir[0]; - cmd.sidemove -= dir[1]; + cmd.sidemove -= dir[1]; - dir[1] = camera_angles[1]; dir[0] = 0; dir[2] = 0; + VectorSet (0, camera_angles[1], 0, dir); AngleVectors (dir, forward, right, up); VectorScale (forward, cmd.forwardmove, forward); - VectorScale (right, cmd.sidemove, right); - VectorAdd (forward, right, dir); + VectorScale (right, cmd.sidemove, right); + VectorAdd (forward, right, dir); if (dir[1] || dir[0]) { cl.viewangles[YAW] = (atan2 (dir[1], dir[0]) * 180 / M_PI); diff --git a/qw/source/cl_cam.c b/qw/source/cl_cam.c index 7faba249d..e4c328057 100644 --- a/qw/source/cl_cam.c +++ b/qw/source/cl_cam.c @@ -678,7 +678,7 @@ CL_Cam_Init_Cvars (void) chase_active = Cvar_Get ("chase_active", "0", CVAR_NONE, NULL, "None"); } -static void +static inline void TraceLine (vec3_t start, vec3_t end, vec3_t impact) { trace_t trace; @@ -695,23 +695,23 @@ Chase_Update (void) { float pitch, yaw, fwd; int i; - vec3_t forward, up, right, stop, dir; usercmd_t cmd; // movement direction + vec3_t forward, up, right, stop, dir; // lazy camera, look toward player entity - if (chase_active->int_val == 2 || chase_active->int_val == 3) - { + if (chase_active->int_val == 2 || chase_active->int_val == 3) { // control camera angles with key/mouse/joy-look camera_angles[PITCH] += cl.viewangles[PITCH] - player_angles[PITCH]; camera_angles[YAW] += cl.viewangles[YAW] - player_angles[YAW]; camera_angles[ROLL] += cl.viewangles[ROLL] - player_angles[ROLL]; - if (chase_active->int_val == 2) - { - if (camera_angles[PITCH] < -60) camera_angles[PITCH] = -60; - if (camera_angles[PITCH] > 60) camera_angles[PITCH] = 60; + if (chase_active->int_val == 2) { + if (camera_angles[PITCH] < -60) + camera_angles[PITCH] = -60; + if (camera_angles[PITCH] > 60) + camera_angles[PITCH] = 60; } // move camera, it's not enough to just change the angles because @@ -724,8 +724,7 @@ Chase_Update (void) VectorScale (forward, chase_back->value, forward); VectorSubtract (player_origin, forward, camera_origin); - if (chase_active->int_val == 2) - { + if (chase_active->int_val == 2) { VectorCopy (r_refdef.vieworg, player_origin); // don't let camera get too low @@ -739,8 +738,7 @@ Chase_Update (void) VectorCopy (dir, forward); VectorNormalize (forward); - if (VectorLength (dir) > chase_back->value) - { + if (VectorLength (dir) > chase_back->value) { VectorScale (forward, chase_back->value, dir); VectorAdd (player_origin, dir, camera_origin); } @@ -753,32 +751,32 @@ Chase_Update (void) if (VectorLength (stop) != 0) VectorSubtract (stop, forward, camera_origin); - VectorSubtract (camera_origin, r_refdef.vieworg, dir); + VectorSubtract (camera_origin, r_refdef.vieworg, dir); VectorCopy (dir, forward); VectorNormalize (forward); - if (chase_active->int_val == 2) - { - if (dir[1] == 0 && dir[0] == 0) - { + if (chase_active->int_val == 2) { + if (dir[1] == 0 && dir[0] == 0) { // look straight up or down // camera_angles[YAW] = r_refdef.viewangles[YAW]; if (dir[2] > 0) camera_angles[PITCH] = 90; else camera_angles[PITCH] = 270; - } - else - { + } else { yaw = (atan2 (dir[1], dir[0]) * 180 / M_PI); - if (yaw < 0) yaw += 360; - if (yaw < 180) yaw += 180; - else yaw -= 180; + if (yaw < 0) + yaw += 360; + if (yaw < 180) + yaw += 180; + else + yaw -= 180; camera_angles[YAW] = yaw; fwd = sqrt (dir[0] * dir[0] + dir[1] * dir[1]); pitch = (atan2 (dir[2], fwd) * 180 / M_PI); - if (pitch < 0) pitch += 360; + if (pitch < 0) + pitch += 360; camera_angles[PITCH] = pitch; } } @@ -809,7 +807,7 @@ Chase_Update (void) } // mouse and joystick controllers add to movement - dir[1] = cl.viewangles[1] - camera_angles[1]; dir[0] = 0; dir[2] = 0; + VectorSet (0, cl.viewangles[1] - camera_angles[1], 0, dir); AngleVectors (dir, forward, right, up); VectorScale (forward, viewdelta.position[2] * m_forward->value, forward); @@ -818,19 +816,20 @@ Chase_Update (void) cmd.forwardmove += dir[0]; cmd.sidemove -= dir[1]; - dir[1] = camera_angles[1]; dir[0] = 0; dir[2] = 0; + VectorSet (0, camera_angles[1], 0, dir); AngleVectors (dir, forward, right, up); VectorScale (forward, cmd.forwardmove, forward); VectorScale (right, cmd.sidemove, right); VectorAdd (forward, right, dir); - if (dir[1] || dir[0]) - { + if (dir[1] || dir[0]) { cl.viewangles[YAW] = (atan2 (dir[1], dir[0]) * 180 / M_PI); if (cl.viewangles[YAW] < 0) cl.viewangles[YAW] += 360; -// if (cl.viewangles[YAW] < 180) cl.viewangles[YAW] += 180; -// else cl.viewangles[YAW] -= 180; +// if (cl.viewangles[YAW] < 180) +// cl.viewangles[YAW] += 180; +// else +// cl.viewangles[YAW] -= 180; } cl.viewangles[PITCH] = 0; From d508da3cf02dbefe0405a9deb6cdcefd82d4b2cb Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 24 Aug 2011 13:59:42 +0900 Subject: [PATCH 099/334] Reduce cl_cmd.c diffs down to protocol specifics. --- nq/source/cl_cmd.c | 5 ++++- qw/source/cl_cmd.c | 3 +-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/nq/source/cl_cmd.c b/nq/source/cl_cmd.c index e0bbd1793..126ad5291 100644 --- a/nq/source/cl_cmd.c +++ b/nq/source/cl_cmd.c @@ -1,7 +1,7 @@ /* cl_cmd.c - script command processing module + Client-side script command processing module Copyright (C) 1996-1997 Id Software, Inc. @@ -27,6 +27,9 @@ #ifdef HAVE_CONFIG_H # include "config.h" #endif + +static __attribute__ ((used)) const char rcsid[] = "$Id$"; + #ifdef HAVE_STRING_H # include #endif diff --git a/qw/source/cl_cmd.c b/qw/source/cl_cmd.c index b13f01580..9e4711583 100644 --- a/qw/source/cl_cmd.c +++ b/qw/source/cl_cmd.c @@ -28,8 +28,7 @@ # include "config.h" #endif -static __attribute__ ((used)) const char rcsid[] = - "$Id$"; +static __attribute__ ((used)) const char rcsid[] = "$Id$"; #ifdef HAVE_STRING_H # include From 514f085e8880a071cdc666b84e5b94ce5fba210d Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 24 Aug 2011 20:33:05 +0900 Subject: [PATCH 100/334] Reduce the diffs in cl_demo.c. Starting to look like a change in protocol rather than a complete rewrite. --- nq/include/client.h | 1 + nq/source/cl_demo.c | 261 +++++++++++++++++--------- qw/include/cl_demo.h | 10 +- qw/source/cl_demo.c | 422 ++++++++++++++++++++++--------------------- qw/source/cl_main.c | 16 +- 5 files changed, 402 insertions(+), 308 deletions(-) diff --git a/nq/include/client.h b/nq/include/client.h index 41bdf561c..27ca00f17 100644 --- a/nq/include/client.h +++ b/nq/include/client.h @@ -348,6 +348,7 @@ float CL_KeyState (kbutton_t *key); // cl_demo.c void CL_StopPlayback (void); void CL_StopRecording (void); +void CL_Record (const char *argv1, int track); int CL_GetMessage (void); void CL_Demo_Init (void); diff --git a/nq/source/cl_demo.c b/nq/source/cl_demo.c index 6ba232087..6b9d9968b 100644 --- a/nq/source/cl_demo.c +++ b/nq/source/cl_demo.c @@ -1,7 +1,7 @@ /* cl_demo.c - @description@ + demo playback support Copyright (C) 1996-1997 Id Software, Inc. @@ -56,50 +56,59 @@ typedef struct { double fps; } td_stats_t; +int demo_timeframes_isactive; +int demo_timeframes_index; char demoname[1024]; +double *demo_timeframes_array; +#define CL_TIMEFRAMES_ARRAYBLOCK 4096 int timedemo_count; int timedemo_runs; td_stats_t *timedemo_data; -static void CL_FinishTimeDemo (void); +static void CL_FinishTimeDemo (void); +static void CL_TimeFrames_DumpLog (void); +static void CL_TimeFrames_AddTimestamp (void); +static void CL_TimeFrames_Reset (void); cvar_t *demo_gzip; cvar_t *demo_speed; cvar_t *demo_quit; +cvar_t *demo_timeframes; + +#define MAX_DEMMSG (MAX_MSGLEN) /* -DEMO CODE + DEMO CODE -When a demo is playing back, all NET_SendMessages are skipped, and -NET_GetMessages are read from the demo file. + When a demo is playing back, all NET_SendMessages are skipped, and + NET_GetMessages are read from the demo file. -Whenever cl.time gets past the last received message, another message is -read from the demo file. + Whenever cl.time gets past the last received message, another message is + read from the demo file. */ - /* CL_WriteDemoMessage Dumps the current net message, prefixed by the length and view angles */ static void -CL_WriteDemoMessage (void) +CL_WriteDemoMessage (sizebuf_t *msg) { + float f; int len; int i; - float f; - len = LittleLong (net_message->message->cursize); + len = LittleLong (msg->cursize); Qwrite (cls.demofile, &len, 4); for (i = 0; i < 3; i++) { f = LittleFloat (cl.viewangles[i]); Qwrite (cls.demofile, &f, 4); } - Qwrite (cls.demofile, net_message->message->data, - net_message->message->cursize); + Qwrite (cls.demofile, msg->data, msg->cursize); + Qflush (cls.demofile); } @@ -115,78 +124,75 @@ CL_StopPlayback (void) return; Qclose (cls.demofile); - cls.demoplayback = false; cls.demofile = NULL; CL_SetState (ca_disconnected); + cls.demoplayback = 0; if (cls.timedemo) CL_FinishTimeDemo (); } - void CL_StopRecording (void) { -// write a disconnect message to the demo file + // write a disconnect message to the demo file SZ_Clear (net_message->message); MSG_WriteByte (net_message->message, svc_disconnect); - CL_WriteDemoMessage (); + CL_WriteDemoMessage (net_message->message); -// finish up + // finish up Qclose (cls.demofile); cls.demofile = NULL; cls.demorecording = false; Sys_Printf ("Completed demo\n"); } - -/* - CL_GetMessage - - Handles recording and playback of demos, on top of NET_ code -*/ -int -CL_GetMessage (void) +static int +CL_GetDemoMessage (void) { - int r, i; + int i, r; float f; - if (cls.demoplayback) { - // decide if it is time to grab the next message - if (cls.signon == SIGNONS) { // always grab until fully connected - if (cls.timedemo) { - if (host_framecount == cls.td_lastframe) - return 0; // already read this frame's message - cls.td_lastframe = host_framecount; - // if this is the second frame, grab the real td_starttime - // so the bogus time on the first frame doesn't count - if (host_framecount == cls.td_startframe + 1) - cls.td_starttime = realtime; - } else if ( /* cl.time > 0 && */ cl.time <= cl.mtime[0]) { - return 0; // don't need another message yet - } + // decide if it is time to grab the next message + if (cls.signon == SIGNONS) { // always grab until fully connected + if (cls.timedemo) { + if (host_framecount == cls.td_lastframe) + return 0; // already read this frame's message + cls.td_lastframe = host_framecount; + // if this is the second frame, grab the real td_starttime + // so the bogus time on the first frame doesn't count + if (host_framecount == cls.td_startframe + 1) + cls.td_starttime = realtime; + } else if ( /* cl.time > 0 && */ cl.time <= cl.mtime[0]) { + return 0; // don't need another message yet } - // get the next message - Qread (cls.demofile, &net_message->message->cursize, 4); - VectorCopy (cl.mviewangles[0], cl.mviewangles[1]); - for (i = 0; i < 3; i++) { - r = Qread (cls.demofile, &f, 4); - cl.mviewangles[0][i] = LittleFloat (f); - } - - net_message->message->cursize = - LittleLong (net_message->message->cursize); - if (net_message->message->cursize > MAX_MSGLEN) - Sys_Error ("Demo message > MAX_MSGLEN"); - r = Qread (cls.demofile, net_message->message->data, - net_message->message->cursize); - if (r != net_message->message->cursize) { - CL_StopPlayback (); - return 0; - } - - return 1; } + // get the next message + Qread (cls.demofile, &net_message->message->cursize, 4); + net_message->message->cursize = + LittleLong (net_message->message->cursize); + if (net_message->message->cursize > MAX_DEMMSG) + Host_Error ("Demo message > MAX_DEMMSG: %d/%d", + net_message->message->cursize, MAX_DEMMSG); + VectorCopy (cl.mviewangles[0], cl.mviewangles[1]); + for (i = 0; i < 3; i++) { + r = Qread (cls.demofile, &f, 4); + cl.mviewangles[0][i] = LittleFloat (f); + } + r = Qread (cls.demofile, net_message->message->data, + net_message->message->cursize); + if (r != net_message->message->cursize) { + CL_StopPlayback (); + return 0; + } + + return 1; +} + +static int +CL_GetPacket (void) +{ + int r; while (1) { r = NET_GetMessage (cls.netcon); @@ -201,13 +207,34 @@ CL_GetMessage (void) else break; } - - if (cls.demorecording) - CL_WriteDemoMessage (); - return r; } +/* + CL_GetMessage + + Handles recording and playback of demos, on top of NET_ code +*/ +int +CL_GetMessage (void) +{ + if (cls.demoplayback) { + int ret = CL_GetDemoMessage (); + + if (!ret && demo_timeframes_isactive && cls.td_starttime) { + CL_TimeFrames_AddTimestamp (); + } + return ret; + } + + if (!CL_GetPacket ()) + return 0; + + if (cls.demorecording) + CL_WriteDemoMessage (net_message->message); + + return 1; +} /* CL_Stop_f @@ -227,7 +254,6 @@ CL_Stop_f (void) CL_StopRecording (); } - /* CL_Record_f @@ -237,7 +263,6 @@ static void CL_Record_f (void) { int c; - dstring_t *name; int track; if (cmd_source != src_command) @@ -266,16 +291,23 @@ CL_Record_f (void) } else track = -1; - name = dstring_new (); - dsprintf (name, "%s/%s", qfs_gamedir->dir.def, Cmd_Argv (1)); - // start the map up // if (c > 2) Cmd_ExecuteString (va ("map %s", Cmd_Argv (2)), src_command); -// open the demo file -// + CL_Record (Cmd_Argv (1), track); +} + +void +CL_Record (const char *argv1, int track) +{ + dstring_t *name; + + name = dstring_new (); + dsprintf (name, "%s/%s", qfs_gamedir->dir.def, argv1); + + // open the demo file #ifdef HAVE_ZLIB if (demo_gzip->int_val) { QFS_DefaultExtension (name, ".dem.gz"); @@ -299,7 +331,6 @@ CL_Record_f (void) dstring_delete (name); } - static void CL_StartDemo (void) { @@ -307,12 +338,10 @@ CL_StartDemo (void) int c; qboolean neg = false; -// disconnect from server -// + // disconnect from server CL_Disconnect (); -// open the demo file -// + // open the demo file name = dstring_strdup (demoname); QFS_DefaultExtension (name, ".dem"); @@ -356,7 +385,7 @@ CL_PlayDemo_f (void) Sys_Printf ("play : plays a demo\n"); return; } - timedemo_runs = timedemo_count = 1; // make sure looped timedemos stop + timedemo_runs = timedemo_count = 1; // make sure looped timedemos stop strncpy (demoname, Cmd_Argv (1), sizeof (demoname)); CL_StartDemo (); } @@ -373,6 +402,10 @@ CL_StartTimeDemo (void) cls.td_starttime = 0; cls.td_startframe = host_framecount; cls.td_lastframe = -1; // get a new message this frame + + CL_TimeFrames_Reset (); + if (demo_timeframes->int_val) + demo_timeframes_isactive = 1; } static inline double @@ -397,6 +430,9 @@ CL_FinishTimeDemo (void) Sys_Printf ("%i frame%s %.4g seconds %.4g fps\n", frames, frames == 1 ? "" : "s", time, frames / time); + CL_TimeFrames_DumpLog (); + demo_timeframes_isactive = 0; + timedemo_count--; if (timedemo_data) { timedemo_data[timedemo_count].frames = frames; @@ -432,7 +468,6 @@ CL_FinishTimeDemo (void) } } - /* CL_TimeDemo_f @@ -450,15 +485,15 @@ CL_TimeDemo_f (void) Sys_Printf ("timedemo [count]: gets demo speeds\n"); return; } - timedemo_runs = timedemo_count = 1; // make sure looped timedemos stop + timedemo_runs = timedemo_count = 1; // make sure looped timedemos stop if (Cmd_Argc () == 3) count = atoi (Cmd_Argv (2)); - timedemo_runs = timedemo_count = 1; if (timedemo_data) { free (timedemo_data); timedemo_data = 0; } + timedemo_data = calloc (timedemo_runs, sizeof (td_stats_t)); strncpy (demoname, Cmd_Argv (1), sizeof (demoname)); CL_StartTimeDemo (); timedemo_runs = timedemo_count = max (count, 1); @@ -468,6 +503,10 @@ CL_TimeDemo_f (void) void CL_Demo_Init (void) { + demo_timeframes_isactive = 0; + demo_timeframes_index = 0; + demo_timeframes_array = NULL; + demo_gzip = Cvar_Get ("demo_gzip", "0", CVAR_ARCHIVE, NULL, "Compress demos using gzip. 0 = none, 1 = least " "compression, 9 = most compression. Compressed " @@ -477,8 +516,60 @@ CL_Demo_Init (void) "< 1 slow-mo, > 1 timelapse"); demo_quit = Cvar_Get ("demo_quit", "0", CVAR_NONE, NULL, "automaticly quit after a timedemo has finished"); - Cmd_AddCommand ("record", CL_Record_f, "No Description"); - Cmd_AddCommand ("stop", CL_Stop_f, "No Description"); - Cmd_AddCommand ("playdemo", CL_PlayDemo_f, "No Description"); - Cmd_AddCommand ("timedemo", CL_TimeDemo_f, "No Description"); + demo_timeframes = Cvar_Get ("demo_timeframes", "0", CVAR_NONE, NULL, + "write timestamps for every frame"); + Cmd_AddCommand ("record", CL_Record_f, "Record a demo, if no filename " + "argument is given\n" + "the demo will be called Year-Month-Day-Hour-Minute-" + "Mapname"); + Cmd_AddCommand ("stop", CL_Stop_f, "Stop recording a demo"); + Cmd_AddCommand ("playdemo", CL_PlayDemo_f, "Play a recorded demo"); + Cmd_AddCommand ("timedemo", CL_TimeDemo_f, "Play a demo as fast as your " + "hardware can. Useful for benchmarking."); +} + +static void +CL_TimeFrames_Reset (void) +{ + demo_timeframes_index = 0; + free (demo_timeframes_array); + demo_timeframes_array = NULL; +} + +static void +CL_TimeFrames_AddTimestamp (void) +{ + if (!(demo_timeframes_index % CL_TIMEFRAMES_ARRAYBLOCK)) + demo_timeframes_array = realloc + (demo_timeframes_array, sizeof (demo_timeframes_array[0]) * + ((demo_timeframes_index / CL_TIMEFRAMES_ARRAYBLOCK) + 1) * + CL_TIMEFRAMES_ARRAYBLOCK); + if (demo_timeframes_array == NULL) + Sys_Error ("Unable to allocate timeframes buffer"); + demo_timeframes_array[demo_timeframes_index] = Sys_DoubleTime (); + demo_timeframes_index++; +} + +static void +CL_TimeFrames_DumpLog (void) +{ + const char *filename = "timeframes.txt"; + int i; + long frame; + QFile *outputfile; + + if (demo_timeframes_isactive == 0) + return; + + Sys_Printf ("Dumping Timed Frames log: %s\n", filename); + outputfile = QFS_Open (filename, "w"); + if (!outputfile) { + Sys_Printf ("Could not open: %s\n", filename); + return; + } + for (i = 1; i < demo_timeframes_index; i++) { + frame = (demo_timeframes_array[i] - demo_timeframes_array[i - 1]) * 1e6; + Qprintf (outputfile, "%09ld\n", frame); + } + Qclose (outputfile); } diff --git a/qw/include/cl_demo.h b/qw/include/cl_demo.h index 6a1cb32fb..8038f2d18 100644 --- a/qw/include/cl_demo.h +++ b/qw/include/cl_demo.h @@ -33,15 +33,11 @@ #include "qw/protocol.h" void CL_StopPlayback (void); -qboolean CL_GetMessage (void); +int CL_GetMessage (void); void CL_WriteDemoCmd (usercmd_t *pcmd); -void CL_Stop_f (void); -void CL_Record_f (void); -void CL_Record (const char *argv1); -void CL_ReRecord_f (void); -void CL_PlayDemo_f (void); -void CL_TimeDemo_f (void); +void CL_StopRecording (void); +void CL_Record (const char *argv1, int track); // track ignored void CL_Demo_Init (void); diff --git a/qw/source/cl_demo.c b/qw/source/cl_demo.c index 5f2cb114c..a5d21b51c 100644 --- a/qw/source/cl_demo.c +++ b/qw/source/cl_demo.c @@ -1,7 +1,7 @@ /* cl_demo.c - (description) + demo playback support Copyright (C) 1996-1997 Id Software, Inc. @@ -28,8 +28,7 @@ # include "config.h" #endif -static __attribute__ ((used)) const char rcsid[] = - "$Id$"; +static __attribute__ ((used)) const char rcsid[] = "$Id$"; #ifdef HAVE_STRING_H # include @@ -70,29 +69,30 @@ typedef struct { double fps; } td_stats_t; -int demo_timeframes_isactive; -int demo_timeframes_index; -int demotime_cached; -float nextdemotime; -char demoname[1024]; -double *demo_timeframes_array; +int demo_timeframes_isactive; +int demo_timeframes_index; +int demotime_cached; +float nextdemotime; +char demoname[1024]; +double *demo_timeframes_array; #define CL_TIMEFRAMES_ARRAYBLOCK 4096 -int timedemo_count; -int timedemo_runs; +int timedemo_count; +int timedemo_runs; td_stats_t *timedemo_data; - static void CL_FinishTimeDemo (void); static void CL_TimeFrames_DumpLog (void); static void CL_TimeFrames_AddTimestamp (void); static void CL_TimeFrames_Reset (void); -cvar_t *demo_speed; cvar_t *demo_gzip; +cvar_t *demo_speed; cvar_t *demo_quit; cvar_t *demo_timeframes; +#define MAX_DEMMSG (MAX_MSGLEN + 8) //+8 for header + /* DEMO CODE @@ -104,6 +104,31 @@ cvar_t *demo_timeframes; */ +/* + CL_WriteDemoMessage + + Dumps the current net message, prefixed by the length and view angles +*/ +static void +CL_WriteDemoMessage (sizebuf_t *msg) +{ + byte c; + float f; + int len; + + f = LittleFloat ((float) realtime); + Qwrite (cls.demofile, &f, sizeof (f)); + + c = dem_read; + Qwrite (cls.demofile, &c, sizeof (c)); + + len = LittleLong (msg->cursize); + Qwrite (cls.demofile, &len, 4); + Qwrite (cls.demofile, msg->data, msg->cursize); + + Qflush (cls.demofile); +} + /* CL_StopPlayback @@ -127,70 +152,21 @@ CL_StopPlayback (void) CL_FinishTimeDemo (); } -/* - CL_WriteDemoCmd - - Writes the current user cmd -*/ void -CL_WriteDemoCmd (usercmd_t *pcmd) +CL_StopRecording (void) { - byte c; - float fl; - int i; - usercmd_t cmd; + // write a disconnect message to the demo file + SZ_Clear (net_message->message); + MSG_WriteLong (net_message->message, -1); // -1 sequence means out of band + MSG_WriteByte (net_message->message, svc_disconnect); + MSG_WriteString (net_message->message, "EndOfDemo"); + CL_WriteDemoMessage (net_message->message); - fl = LittleFloat ((float) realtime); - Qwrite (cls.demofile, &fl, sizeof (fl)); - - c = dem_cmd; - Qwrite (cls.demofile, &c, sizeof (c)); - - // correct for byte order, bytes don't matter - cmd = *pcmd; - - for (i = 0; i < 3; i++) - cmd.angles[i] = LittleFloat (cmd.angles[i]); - cmd.forwardmove = LittleShort (cmd.forwardmove); - cmd.sidemove = LittleShort (cmd.sidemove); - cmd.upmove = LittleShort (cmd.upmove); - - Qwrite (cls.demofile, &cmd, sizeof (cmd)); - - for (i = 0; i < 3; i++) { - fl = LittleFloat (cl.viewangles[i]); - Qwrite (cls.demofile, &fl, 4); - } - - Qflush (cls.demofile); -} - -/* - CL_WriteDemoMessage - - Dumps the current net message, prefixed by the length and view angles -*/ -static void -CL_WriteDemoMessage (sizebuf_t *msg) -{ - byte c; - float fl; - int len; - - if (!cls.demorecording) - return; - - fl = LittleFloat ((float) realtime); - Qwrite (cls.demofile, &fl, sizeof (fl)); - - c = dem_read; - Qwrite (cls.demofile, &c, sizeof (c)); - - len = LittleLong (msg->cursize); - Qwrite (cls.demofile, &len, 4); - Qwrite (cls.demofile, msg->data, msg->cursize); - - Qflush (cls.demofile); + // finish up + Qclose (cls.demofile); + cls.demofile = NULL; + cls.demorecording = false; + Sys_Printf ("Completed demo\n"); } #if 0 @@ -206,7 +182,7 @@ static const char *dem_names[] = { }; #endif -static qboolean +static int CL_GetDemoMessage (void) { byte c, newtime; @@ -326,11 +302,11 @@ nextdemomessage: readit: // get the next message Qread (cls.demofile, &net_message->message->cursize, 4); - net_message->message->cursize = LittleLong - (net_message->message->cursize); - if (net_message->message->cursize > MAX_MSGLEN + 8) //+8 for header - Host_Error ("Demo message > MAX_MSGLEN + 8: %d/%d", - net_message->message->cursize, MAX_MSGLEN + 8); + net_message->message->cursize = + LittleLong (net_message->message->cursize); + if (net_message->message->cursize > MAX_DEMMSG) + Host_Error ("Demo message > MAX_DEMMSG: %d/%d", + net_message->message->cursize, MAX_DEMMSG); r = Qread (cls.demofile, net_message->message->data, net_message->message->cursize); if (r != net_message->message->cursize) { @@ -352,7 +328,6 @@ readit: } } break; - case dem_set: Qread (cls.demofile, &i, 4); cls.netchan.outgoing_sequence = LittleLong (i); @@ -364,7 +339,6 @@ readit: goto nextdemomessage; } break; - case dem_multiple: r = Qread (cls.demofile, &i, 4); if (r != 4) { @@ -374,41 +348,42 @@ readit: cls.lastto = LittleLong (i); cls.lasttype = dem_multiple; goto readit; - case dem_single: cls.lastto = c >> 3; cls.lasttype = dem_single; goto readit; - case dem_stats: cls.lastto = c >> 3; cls.lasttype = dem_stats; goto readit; - case dem_all: cls.lastto = 0; cls.lasttype = dem_all; goto readit; - default: Sys_Printf ("Corrupted demo.\n"); CL_StopPlayback (); return 0; } - return 1; } +static int +CL_GetPacket (void) +{ + return NET_GetPacket (); +} + /* CL_GetMessage Handles recording and playback of demos, on top of NET_ code */ -qboolean +int CL_GetMessage (void) { if (cls.demoplayback) { - qboolean ret = CL_GetDemoMessage (); + int ret = CL_GetDemoMessage (); if (!ret && demo_timeframes_isactive && cls.td_starttime) { CL_TimeFrames_AddTimestamp (); @@ -416,16 +391,56 @@ CL_GetMessage (void) return ret; } - if (!NET_GetPacket ()) - return false; + if (!CL_GetPacket ()) + return 0; if (net_packetlog->int_val) Log_Incoming_Packet (net_message->message->data, net_message->message->cursize, 1); - CL_WriteDemoMessage (net_message->message); - return true; + if (cls.demorecording) + CL_WriteDemoMessage (net_message->message); + + return 1; +} + +/* + CL_WriteDemoCmd + + Writes the current user cmd +*/ +void +CL_WriteDemoCmd (usercmd_t *pcmd) +{ + byte c; + float fl; + int i; + usercmd_t cmd; + + fl = LittleFloat ((float) realtime); + Qwrite (cls.demofile, &fl, sizeof (fl)); + + c = dem_cmd; + Qwrite (cls.demofile, &c, sizeof (c)); + + // correct for byte order, bytes don't matter + cmd = *pcmd; + + for (i = 0; i < 3; i++) + cmd.angles[i] = LittleFloat (cmd.angles[i]); + cmd.forwardmove = LittleShort (cmd.forwardmove); + cmd.sidemove = LittleShort (cmd.sidemove); + cmd.upmove = LittleShort (cmd.upmove); + + Qwrite (cls.demofile, &cmd, sizeof (cmd)); + + for (i = 0; i < 3; i++) { + fl = LittleFloat (cl.viewangles[i]); + Qwrite (cls.demofile, &fl, 4); + } + + Qflush (cls.demofile); } /* @@ -433,29 +448,90 @@ CL_GetMessage (void) stop recording a demo */ -void +static void CL_Stop_f (void) { if (!cls.demorecording) { Sys_Printf ("Not recording a demo.\n"); return; } - // write a disconnect message to the demo file - SZ_Clear (net_message->message); - MSG_WriteLong (net_message->message, -1); // -1 sequence means out of band - MSG_WriteByte (net_message->message, svc_disconnect); - MSG_WriteString (net_message->message, "EndOfDemo"); - CL_WriteDemoMessage (net_message->message); - - // finish up - Qclose (cls.demofile); - cls.demofile = NULL; - cls.demorecording = false; - Sys_Printf ("Completed demo\n"); + CL_StopRecording (); } /* - CL_WriteDemoMessage + CL_Record_f + + record +*/ +static void +CL_Record_f (void) +{ + if (Cmd_Argc () > 2) { + // we use a demo name like year-month-day-hours-minutes-mapname.qwd + // if there is no argument + Sys_Printf ("record [demoname]\n"); + return; + } + + if (cls.demoplayback || cls.state != ca_active) { + Sys_Printf ("You must be connected to record.\n"); + return; + } + + if (cls.demorecording) + CL_Stop_f (); + if (Cmd_Argc () == 2) + CL_Record (Cmd_Argv (1), -1); + else + CL_Record (0, -1); +} + +/* + CL_ReRecord_f + + record +*/ +static void +CL_ReRecord_f (void) +{ + dstring_t *name; + int c; + + c = Cmd_Argc (); + if (c != 2) { + Sys_Printf ("rerecord \n"); + return; + } + + if (!cls.servername || !cls.servername->str) { + Sys_Printf ("No server to which to reconnect...\n"); + return; + } + + if (cls.demorecording) + CL_Stop_f (); + + name = dstring_newstr (); + dsprintf (name, "%s/%s", qfs_gamedir->dir.def, Cmd_Argv (1)); + + // open the demo file + QFS_DefaultExtension (name, ".qwd"); + + cls.demofile = QFS_WOpen (name->str, 0); + if (!cls.demofile) { + Sys_Printf ("ERROR: couldn't open.\n"); + } else { + Sys_Printf ("recording to %s.\n", name->str); + cls.demorecording = true; + + CL_Disconnect (); + CL_BeginServerConnect (); + } + dstring_delete (name); +} + +/* + CL_WriteRecordDemoMessage Dumps the current net message, prefixed by the length and view angles */ @@ -512,7 +588,7 @@ CL_WriteSetDemoMessage (void) } void -CL_Record (const char *argv1) +CL_Record (const char *argv1, int track) { byte buf_data[MAX_MSGLEN + 10]; // + 10 for header dstring_t *name; @@ -803,93 +879,21 @@ CL_Record (const char *argv1) // done } -/* - CL_Record_f - - record -*/ -void -CL_Record_f (void) -{ - if (Cmd_Argc () > 2) { - // we use a demo name like year-month-day-hours-minutes-mapname.qwd - // if there is no argument - Sys_Printf ("record [demoname]\n"); - return; - } - - if (cls.demoplayback || cls.state != ca_active) { - Sys_Printf ("You must be connected to record.\n"); - return; - } - - if (cls.demorecording) - CL_Stop_f (); - if (Cmd_Argc () == 2) - CL_Record (Cmd_Argv (1)); - else - CL_Record (0); -} - -/* - CL_ReRecord_f - - record -*/ -void -CL_ReRecord_f (void) -{ - dstring_t *name; - int c; - - c = Cmd_Argc (); - if (c != 2) { - Sys_Printf ("rerecord \n"); - return; - } - - if (!cls.servername || !cls.servername->str) { - Sys_Printf ("No server to which to reconnect...\n"); - return; - } - - if (cls.demorecording) - CL_Stop_f (); - - name = dstring_newstr (); - dsprintf (name, "%s/%s", qfs_gamedir->dir.def, Cmd_Argv (1)); - - // open the demo file - QFS_DefaultExtension (name, ".qwd"); - - cls.demofile = QFS_WOpen (name->str, 0); - if (!cls.demofile) { - Sys_Printf ("ERROR: couldn't open.\n"); - } else { - Sys_Printf ("recording to %s.\n", name->str); - cls.demorecording = true; - - CL_Disconnect (); - CL_BeginServerConnect (); - } - dstring_delete (name); -} - static void CL_StartDemo (void) { - dstring_t *name = dstring_newstr (); + dstring_t *name; // open the demo file - dstring_copystr (name, demoname); + name = dstring_strdup (demoname); QFS_DefaultExtension (name, ".qwd"); Sys_Printf ("Playing demo from %s.\n", name->str); QFS_FOpenFile (name->str, &cls.demofile); + dstring_delete (name); if (!cls.demofile) { Sys_Printf ("ERROR: couldn't open.\n"); cls.demonum = -1; // stop demo loop - dstring_delete (name); return; } @@ -921,7 +925,7 @@ CL_StartDemo (void) play [demoname] */ -void +static void CL_PlayDemo_f (void) { if (Cmd_Argc () != 2) { @@ -966,8 +970,8 @@ sqr (double x) static void CL_FinishTimeDemo (void) { - float time; - int frames; + int frames; + float time; cls.timedemo = false; @@ -983,13 +987,15 @@ CL_FinishTimeDemo (void) demo_timeframes_isactive = 0; timedemo_count--; - timedemo_data[timedemo_count].frames = frames; - timedemo_data[timedemo_count].time = time; - timedemo_data[timedemo_count].fps = frames / time; + if (timedemo_data) { + timedemo_data[timedemo_count].frames = frames; + timedemo_data[timedemo_count].time = time; + timedemo_data[timedemo_count].fps = frames / time; + } if (timedemo_count > 0) { CL_StartTimeDemo (); } else { - if (--timedemo_runs > 0) { + if (--timedemo_runs > 0 && timedemo_data) { double average = 0; double variance = 0; double min, max; @@ -1010,8 +1016,6 @@ CL_FinishTimeDemo (void) Sys_Printf (" min/max fps: %.3f/%.3f\n", min, max); Sys_Printf ("std deviation: %.3f fps\n", sqrt (variance)); } - free (timedemo_data); - timedemo_data = 0; if (demo_quit->int_val) Cbuf_InsertText (cl_cbuf, "quit\n"); } @@ -1022,9 +1026,11 @@ CL_FinishTimeDemo (void) timedemo [demoname] */ -void +static void CL_TimeDemo_f (void) { + int count = 1; + if (Cmd_Argc () < 2 || Cmd_Argc () > 3) { Sys_Printf ("timedemo [count]: gets demo speeds\n"); return; @@ -1033,17 +1039,17 @@ CL_TimeDemo_f (void) // disconnect from server CL_Disconnect (); - if (Cmd_Argc () == 3) { - timedemo_count = atoi (Cmd_Argv (2)); - } else { - timedemo_count = 1; - } - timedemo_runs = timedemo_count = max (timedemo_count, 1); - if (timedemo_data) + if (Cmd_Argc () == 3) + count = atoi (Cmd_Argv (2)); + if (timedemo_data) { free (timedemo_data); + timedemo_data = 0; + } timedemo_data = calloc (timedemo_runs, sizeof (td_stats_t)); strncpy (demoname, Cmd_Argv (1), sizeof (demoname)); CL_StartTimeDemo (); + timedemo_runs = timedemo_count = max (count, 1); + timedemo_data = calloc (timedemo_runs, sizeof (td_stats_t)); } void @@ -1064,6 +1070,16 @@ CL_Demo_Init (void) "automaticly quit after a timedemo has finished"); demo_timeframes = Cvar_Get ("demo_timeframes", "0", CVAR_NONE, NULL, "write timestamps for every frame"); + Cmd_AddCommand ("record", CL_Record_f, "Record a demo, if no filename " + "argument is given\n" + "the demo will be called Year-Month-Day-Hour-Minute-" + "Mapname"); + Cmd_AddCommand ("rerecord", CL_ReRecord_f, "Rerecord a demo on the same " + "server"); + Cmd_AddCommand ("stop", CL_Stop_f, "Stop recording a demo"); + Cmd_AddCommand ("playdemo", CL_PlayDemo_f, "Play a recorded demo"); + Cmd_AddCommand ("timedemo", CL_TimeDemo_f, "Play a demo as fast as your " + "hardware can. Useful for benchmarking."); } static void @@ -1092,9 +1108,9 @@ static void CL_TimeFrames_DumpLog (void) { const char *filename = "timeframes.txt"; - int i; - long frame; - QFile *outputfile; + int i; + long frame; + QFile *outputfile; if (demo_timeframes_isactive == 0) return; diff --git a/qw/source/cl_main.c b/qw/source/cl_main.c index ca0f31989..aba395fc5 100644 --- a/qw/source/cl_main.c +++ b/qw/source/cl_main.c @@ -486,7 +486,7 @@ CL_Disconnect (void) CL_StopPlayback (); else if (cls.state != ca_disconnected) { if (cls.demorecording) - CL_Stop_f (); + CL_StopRecording (); final[0] = clc_stringcmd; strcpy ((char *) final + 1, "drop"); @@ -1155,7 +1155,7 @@ CL_SetState (cactive_t state) // Auto demo recorder stops here if (cl_autorecord->int_val && cls.demorecording) - CL_Stop_f (); + CL_StopRecording (); } else if (state == ca_active) { // entering active state VID_SetCaption (cls.servername->str); @@ -1167,7 +1167,7 @@ CL_SetState (cactive_t state) // Auto demo recorder starts here if (cl_autorecord->int_val && !cls.demoplayback && !cls.demorecording) - CL_Record (0); + CL_Record (0, -1); } } if (con_module) @@ -1192,18 +1192,8 @@ CL_Init (void) Cmd_AddCommand ("version", CL_Version_f, "Report version information"); Cmd_AddCommand ("changing", CL_Changing_f, "Used when maps are changing"); Cmd_AddCommand ("disconnect", CL_Disconnect_f, "Disconnect from server"); - Cmd_AddCommand ("record", CL_Record_f, "Record a demo, if no filename " - "argument is given\n" - "the demo will be called Year-Month-Day-Hour-Minute-" - "Mapname"); - Cmd_AddCommand ("rerecord", CL_ReRecord_f, "Rerecord a demo on the same " - "server"); Cmd_AddCommand ("snap", CL_RSShot_f, "Take a screenshot and upload it to " "the server"); - Cmd_AddCommand ("stop", CL_Stop_f, "Stop recording a demo"); - Cmd_AddCommand ("playdemo", CL_PlayDemo_f, "Play a recorded demo"); - Cmd_AddCommand ("timedemo", CL_TimeDemo_f, "Play a demo as fast as your " - "hardware can. Useful for benchmarking."); Cmd_AddCommand ("maplist", Con_Maplist_f, "List maps available"); Cmd_AddCommand ("skinlist", Con_Skinlist_f, "List skins available"); Cmd_AddCommand ("skyboxlist", Con_Skyboxlist_f, "List skyboxes available"); From 28d9c7234c42806516e260f1e6ff73924f143035 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 27 Aug 2011 10:25:41 +0900 Subject: [PATCH 101/334] A bit more diff reduction before attempting to merge client code. --- nq/source/cl_ents.c | 88 +++++++++++++++++++++++++++----------------- nq/source/cl_parse.c | 2 +- qw/source/cl_ents.c | 16 ++++---- qw/source/cl_parse.c | 58 +++++++++++++++++------------ 4 files changed, 96 insertions(+), 68 deletions(-) diff --git a/nq/source/cl_ents.c b/nq/source/cl_ents.c index fa4b2617b..cd5678840 100644 --- a/nq/source/cl_ents.c +++ b/nq/source/cl_ents.c @@ -1,5 +1,5 @@ /* - cl_main.c + cl_ents.c entity parsing and management @@ -28,8 +28,7 @@ # include "config.h" #endif -static __attribute__ ((used)) const char rcsid[] = - "$Id$"; +static __attribute__ ((used)) const char rcsid[] = "$Id$"; #include "QF/cbuf.h" #include "QF/cmd.h" @@ -63,7 +62,7 @@ cl_entity_state_t cl_baselines[MAX_EDICTS]; void CL_ClearEnts (void) { - int i; + size_t i; // clear other arrays memset (cl_entities, 0, sizeof (cl_entities)); @@ -77,56 +76,77 @@ CL_ClearEnts (void) } static void -CL_NewDlight (int key, vec3_t org, int effects) +CL_NewDlight (int key, vec3_t org, int effects, byte glow_size, + byte glow_color) { float radius; - float time = 0.1; dlight_t *dl; static quat_t normal = {0.4, 0.2, 0.05, 0.7}; static quat_t red = {0.5, 0.05, 0.05, 0.7}; static quat_t blue = {0.05, 0.05, 0.5, 0.7}; static quat_t purple = {0.5, 0.05, 0.5, 0.7}; - if (!(effects & (EF_BLUE | EF_RED | EF_BRIGHTLIGHT | EF_DIMLIGHT))) - return; + effects &= EF_BLUE | EF_RED | EF_BRIGHTLIGHT | EF_DIMLIGHT; + if (!effects) { + if (!glow_size) + return; + } dl = R_AllocDlight (key); if (!dl) return; VectorCopy (org, dl->origin); - radius = 200 + (rand () & 31); - if (effects & EF_BRIGHTLIGHT) { - radius += 200; - dl->origin[2] += 16; - } - if (effects & EF_DIMLIGHT) - if (effects & ~EF_DIMLIGHT) - radius -= 100; - dl->radius = radius; - dl->die = cl.time + time; + if (effects & (EF_BLUE | EF_RED | EF_BRIGHTLIGHT | EF_DIMLIGHT)) { + radius = 200 + (rand () & 31); + if (effects & EF_BRIGHTLIGHT) { + radius += 200; + dl->origin[2] += 16; + } + if (effects & EF_DIMLIGHT) + if (effects & ~EF_DIMLIGHT) + radius -= 100; + dl->radius = radius; + dl->die = cl.time + 0.1; - switch (effects & (EF_BLUE | EF_RED)) { - case EF_RED | EF_BLUE: - QuatCopy (purple, dl->color); - break; - case EF_RED: - QuatCopy (red, dl->color); - break; - case EF_BLUE: - QuatCopy (blue, dl->color); - break; - default: - QuatCopy (normal, dl->color); - break; + switch (effects & (EF_RED | EF_BLUE)) { + case EF_RED | EF_BLUE: + QuatCopy (purple, dl->color); + break; + case EF_RED: + QuatCopy (red, dl->color); + break; + case EF_BLUE: + QuatCopy (blue, dl->color); + break; + default: + QuatCopy (normal, dl->color); + break; + } + } + + if (glow_size) { + dl->radius += glow_size < 128 ? glow_size * 8.0 : + (glow_size - 256) * 8.0; + dl->die = cl.time + 0.1; + if (glow_color) { + if (glow_color == 255) { + dl->color[0] = dl->color[1] = dl->color[2] = 1.0; + } else { + byte *tempcolor; + + tempcolor = (byte *) &d_8to24table[glow_color]; + VectorScale (tempcolor, 1 / 255.0, dl->color); + } + } } } /* CL_LerpPoint - Determines the fraction between the last two messages that the objects - should be put at. + Determines the fraction between the last two messages at which the + objects should be put. */ static float CL_LerpPoint (void) @@ -296,7 +316,7 @@ CL_RelinkEntities (void) ent->lerpflags |= LERP_RESETANIM | LERP_RESETANIM2; #endif } - CL_NewDlight (i, ent->origin, state->effects); + CL_NewDlight (i, ent->origin, state->effects, 0, 0); if (VectorDistance_fast (state->msg_origins[1], ent->origin) > (256 * 256)) VectorCopy (ent->origin, state->msg_origins[1]); diff --git a/nq/source/cl_parse.c b/nq/source/cl_parse.c index 3eec14c44..c19bf4fef 100644 --- a/nq/source/cl_parse.c +++ b/nq/source/cl_parse.c @@ -101,7 +101,7 @@ const char *svc_strings[] = { "svc_foundsecret", "svc_spawnstaticsound", "svc_intermission", - "svc_finale", // [string] music [string] text + "svc_finale", // [string] text "svc_cdtrack", // [byte] track [byte] looptrack "svc_sellscreen", "svc_cutscene", diff --git a/qw/source/cl_ents.c b/qw/source/cl_ents.c index 77a5effbd..ffdcf2433 100644 --- a/qw/source/cl_ents.c +++ b/qw/source/cl_ents.c @@ -28,8 +28,7 @@ # include "config.h" #endif -static __attribute__ ((used)) const char rcsid[] = - "$Id$"; +static __attribute__ ((used)) const char rcsid[] = "$Id$"; #ifdef HAVE_STRING_H # include @@ -67,9 +66,9 @@ entity_t cl_flag_ents[MAX_CLIENTS]; entity_t cl_packet_ents[512]; // FIXME: magic number void -CL_ClearEnts () +CL_ClearEnts (void) { - unsigned int i; + size_t i; for (i = 0; i < sizeof (cl_packet_ents) / sizeof (cl_packet_ents[0]); i++) CL_Init_Entity (&cl_packet_ents[i]); @@ -83,7 +82,7 @@ static void CL_NewDlight (int key, vec3_t org, int effects, byte glow_size, byte glow_color) { - float radius; + float radius; dlight_t *dl; static quat_t normal = {0.4, 0.2, 0.05, 0.7}; static quat_t red = {0.5, 0.05, 0.05, 0.7}; @@ -112,6 +111,7 @@ CL_NewDlight (int key, vec3_t org, int effects, byte glow_size, radius -= 100; dl->radius = radius; dl->die = cl.time + 0.1; + switch (effects & (EF_RED | EF_BLUE)) { case EF_RED | EF_BLUE: QuatCopy (purple, dl->color); @@ -136,12 +136,10 @@ CL_NewDlight (int key, vec3_t org, int effects, byte glow_size, if (glow_color == 255) { dl->color[0] = dl->color[1] = dl->color[2] = 1.0; } else { - unsigned char *tempcolor; + byte *tempcolor; tempcolor = (byte *) &d_8to24table[glow_color]; - dl->color[0] = tempcolor[0] / 255.0; - dl->color[1] = tempcolor[1] / 255.0; - dl->color[2] = tempcolor[2] / 255.0; + VectorScale (tempcolor, 1 / 255.0, dl->color); } } } diff --git a/qw/source/cl_parse.c b/qw/source/cl_parse.c index 07ef2074f..f79f7bc8d 100644 --- a/qw/source/cl_parse.c +++ b/qw/source/cl_parse.c @@ -117,17 +117,13 @@ const char *svc_strings[] = { "svc_foundsecret", "svc_spawnstaticsound", "svc_intermission", - "svc_finale", - - "svc_cdtrack", + "svc_finale", // [string] text + "svc_cdtrack", // [byte] track "svc_sellscreen", - "svc_smallkick", "svc_bigkick", - "svc_updateping", "svc_updateentertime", - "svc_updatestatlong", "svc_muzzleflash", "svc_updateuserinfo", @@ -141,7 +137,6 @@ const char *svc_strings[] = { "svc_deltapacketentities", "svc_maxspeed", "svc_entgravity", - "svc_setinfo", "svc_serverinfo", "svc_updatepl", @@ -160,6 +155,7 @@ const char *svc_strings[] = { "NEW PROTOCOL" }; +dstring_t *centerprint; int oldparsecountmod; int parsecountmod; double parsecounttime; @@ -1173,6 +1169,10 @@ CL_ServerInfo (void) // movevars.ktjump = atof (value); // FIXME: need to set to 0.5 otherwise, outside of else structure } + if (!centerprint) + centerprint = dstring_newstr (); + else + dstring_clearstr (centerprint); } static void @@ -1246,7 +1246,7 @@ int received_framecount; void CL_ParseServerMessage (void) { - const char *s; + const char *str; static dstring_t *stuffbuf; int cmd = 0, i, j; @@ -1304,55 +1304,60 @@ CL_ParseServerMessage (void) dstring_t *p = 0; i = MSG_ReadByte (net_message); - s = MSG_ReadString (net_message); + str = MSG_ReadString (net_message); if (i == PRINT_CHAT) { - if (!CL_Chat_Allow_Message (s)) + if (!CL_Chat_Allow_Message (str)) break; // TODO: cl_nofake 2 -- accept fake messages from teammates if (cl_nofake->int_val) { char *c; - p = dstring_strdup (s); + p = dstring_strdup (str); for (c = p->str; *c; c++) { if (*c == '\r') *c = '#'; } - s = p->str; + str = p->str; } Con_SetOrMask (128); S_LocalSound ("misc/talk.wav"); if (cl_chat_e->func) - GIB_Event_Callback (cl_chat_e, 1, s); - Team_ParseChat (s); + GIB_Event_Callback (cl_chat_e, 1, str); + Team_ParseChat (str); } - Sys_Printf ("%s", s); + Sys_Printf ("%s", str); if (p) dstring_delete (p); Con_SetOrMask (0); break; } case svc_centerprint: - Sbar_CenterPrint (MSG_ReadString (net_message)); + str = MSG_ReadString (net_message); + if (strcmp (str, centerprint->str)) { + dstring_copystr (centerprint, str); + //FIXME logging + } + Sbar_CenterPrint (str); break; case svc_stufftext: - s = MSG_ReadString (net_message); - if (s[strlen (s) - 1] == '\n') { + str = MSG_ReadString (net_message); + if (str[strlen (str) - 1] == '\n') { if (stuffbuf && stuffbuf->str[0]) { Sys_MaskPrintf (SYS_DEV, "stufftext: %s%s\n", - stuffbuf->str, s); + stuffbuf->str, str); Cbuf_AddText (cl_stbuf, stuffbuf->str); dstring_clearstr (stuffbuf); } else { - Sys_MaskPrintf (SYS_DEV, "stufftext: %s\n", s); + Sys_MaskPrintf (SYS_DEV, "stufftext: %s\n", str); } - Cbuf_AddText (cl_stbuf, s); + Cbuf_AddText (cl_stbuf, str); } else { - Sys_MaskPrintf (SYS_DEV, "partial stufftext: %s\n", s); + Sys_MaskPrintf (SYS_DEV, "partial stufftext: %s\n", str); if (!stuffbuf) stuffbuf = dstring_newstr (); - dstring_appendstr (stuffbuf, s); + dstring_appendstr (stuffbuf, str); } break; @@ -1507,7 +1512,12 @@ CL_ParseServerMessage (void) r_force_fullscreen = 1; cl.completed_time = realtime; vid.recalc_refdef = true; // go to full screen - Sbar_CenterPrint (MSG_ReadString (net_message)); + str = MSG_ReadString (net_message); + if (strcmp (str, centerprint->str)) { + dstring_copystr (centerprint, str); + //FIXME logging + } + Sbar_CenterPrint (str); break; case svc_sellscreen: From eb205d73fd721ae7f3491b305a3e5a4c1d81ae99 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 18 Oct 2010 23:27:42 +0900 Subject: [PATCH 102/334] Add a function to convert a quaternion to a rotation matrix. --- include/QF/mathlib.h | 2 ++ libs/util/mathlib.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/include/QF/mathlib.h b/include/QF/mathlib.h index 0164fe8bd..4dde62a38 100644 --- a/include/QF/mathlib.h +++ b/include/QF/mathlib.h @@ -251,6 +251,8 @@ void RotatePointAroundVector (vec3_t dst, const vec3_t axis, void QuatMult (const quat_t q1, const quat_t q2, quat_t out); void QuatInverse (const quat_t in, quat_t out); +void QuatToMatrix (const quat_t q, vec_t *m, int homogenous, int vertical); + #define BOX_ON_PLANE_SIDE(emins, emaxs, p) \ (((p)->type < 3)? \ ( \ diff --git a/libs/util/mathlib.c b/libs/util/mathlib.c index a728225fb..1003f028c 100644 --- a/libs/util/mathlib.c +++ b/libs/util/mathlib.c @@ -195,6 +195,49 @@ QuatInverse (const quat_t in, quat_t out) QuatScale (q, 1 / m, out); } +VISIBLE void +QuatToMatrix (const quat_t q, vec_t *m, int homogenous, int vertical) +{ + vec_t aa, ab, ac, ad, bb, bc, bd, cc, cd, dd; + vec_t *_m[4] = { + m + homogenous ? 0 : 0, + m + homogenous ? 4 : 3, + m + homogenous ? 8 : 6, + m + homogenous ? 12 : 9, + }; + + aa = q[0] * q[0]; + ab = q[0] * q[1]; + ac = q[0] * q[2]; + ad = q[0] * q[3]; + + bb = q[1] * q[1]; + bc = q[1] * q[2]; + bd = q[1] * q[3]; + + cc = q[2] * q[2]; + cd = q[2] * q[3]; + + dd = q[3] * q[3]; + + if (vertical) { + VectorSet (aa + bb - cc - dd, 2 * (bc + ad), 2 * (bd - ac), _m[0]); + VectorSet (2 * (bc - ad), aa - bb + cc - dd, 2 * (cd + ab), _m[1]); + VectorSet (2 * (bd + ac), 2 * (cd - ab), aa - bb - cc + dd, _m[2]); + } else { + VectorSet (aa + bb - cc - dd, 2 * (bc - ad), 2 * (bd + ac), _m[0]); + VectorSet (2 * (bc + ad), aa - bb + cc - dd, 2 * (cd - ab), _m[1]); + VectorSet (2 * (bd - ac), 2 * (cd + ab), aa - bb - cc + dd, _m[2]); + } + if (homogenous) { + _m[0][3] = 0; + _m[1][3] = 0; + _m[2][3] = 0; + VectorZero (_m[3]); + _m[3][3] = 1; + } +} + #if defined(_WIN32) && !defined(__GNUC__) # pragma optimize( "", on ) #endif From fe3cdbcf5a88e913d69b7462f20dc022adac5b5d Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 19 Oct 2010 23:41:57 +0900 Subject: [PATCH 103/334] fix a snafu in quattomat --- libs/util/mathlib.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libs/util/mathlib.c b/libs/util/mathlib.c index 1003f028c..a9b3d8e41 100644 --- a/libs/util/mathlib.c +++ b/libs/util/mathlib.c @@ -200,10 +200,10 @@ QuatToMatrix (const quat_t q, vec_t *m, int homogenous, int vertical) { vec_t aa, ab, ac, ad, bb, bc, bd, cc, cd, dd; vec_t *_m[4] = { - m + homogenous ? 0 : 0, - m + homogenous ? 4 : 3, - m + homogenous ? 8 : 6, - m + homogenous ? 12 : 9, + m + (homogenous ? 0 : 0), + m + (homogenous ? 4 : 3), + m + (homogenous ? 8 : 6), + m + (homogenous ? 12 : 9), }; aa = q[0] * q[0]; From 1c47f9e16d10ce622ba61c0f282dcb8bcd0ca75d Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 27 Aug 2011 14:35:48 +0900 Subject: [PATCH 104/334] Kill some magic numbers. --- libs/video/renderer/gl/gl_rmain.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libs/video/renderer/gl/gl_rmain.c b/libs/video/renderer/gl/gl_rmain.c index e7427b161..3242ac1d8 100644 --- a/libs/video/renderer/gl/gl_rmain.c +++ b/libs/video/renderer/gl/gl_rmain.c @@ -205,10 +205,9 @@ R_RotateForEntity (entity_t *e) { qfglTranslatef (e->origin[0], e->origin[1], e->origin[2]); - qfglRotatef (e->angles[1], 0, 0, 1); - qfglRotatef (-e->angles[0], 0, 1, 0); - // ZOID: fixed z angle - qfglRotatef (e->angles[2], 1, 0, 0); + qfglRotatef ( e->angles[YAW], 0, 0, 1); + qfglRotatef (-e->angles[PITCH], 0, 1, 0); + qfglRotatef ( e->angles[ROLL], 1, 0, 0); } /* From 12e238f806f1a89931b4dee1a0b645ead67a9f4e Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 27 Aug 2011 14:38:33 +0900 Subject: [PATCH 105/334] Add a function to convert quake angles to a quaternion. The test works by comparing the result of AngleVectors with forward, right, and up vectors rotated by the quaternion resulting from AngleQuat. --- include/QF/mathlib.h | 1 + libs/util/mathlib.c | 25 +++++++++- libs/util/test/Makefile.am | 6 ++- libs/util/test/test-quat.c | 96 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 libs/util/test/test-quat.c diff --git a/include/QF/mathlib.h b/include/QF/mathlib.h index 4dde62a38..b16b6b70a 100644 --- a/include/QF/mathlib.h +++ b/include/QF/mathlib.h @@ -240,6 +240,7 @@ int GreatestCommonDivisor (int i1, int i2); void AngleVectors (const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up); +void AngleQuat (const vec3_t angles, quat_t q); void VectorVectors (const vec3_t forward, vec3_t right, vec3_t up); int BoxOnPlaneSide (const vec3_t emins, const vec3_t emaxs, struct mplane_s *plane); diff --git a/libs/util/mathlib.c b/libs/util/mathlib.c index a9b3d8e41..8e4871ec1 100644 --- a/libs/util/mathlib.c +++ b/libs/util/mathlib.c @@ -385,7 +385,7 @@ BoxOnPlaneSide (const vec3_t emins, const vec3_t emaxs, mplane_t *p) the math in AngleVectors has the entity frame as left handed with x (forward) axis forward, y (right) axis to the right and z (up) up. However, - the world is a right (?) handed system with x to the right, y forward and + the world is a right handed system with x to the right, y forward and z up. pitch = @@ -437,6 +437,29 @@ AngleVectors (const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up) up[2] = cr * cp; } +VISIBLE void +AngleQuat (const vec3_t angles, quat_t q) +{ + float alpha, sr, sp, sy, cr, cp, cy; + + // alpha is half the angle + alpha = angles[YAW] * (M_PI / 360); + sy = sin (alpha); + cy = cos (alpha); + alpha = angles[PITCH] * (M_PI / 360); + sp = sin (alpha); + cp = cos (alpha); + alpha = angles[ROLL] * (M_PI / 360); + sr = sin (alpha); + cr = cos (alpha); + + QuatSet (cy * cp * cr + sy * sp * sr, + cy * cp * sr - sy * sp * cr, + cy * sp * cr + sy * cp * sr, + sy * cp * cr - cy * sp * sr, + q); +} + VISIBLE int _VectorCompare (const vec3_t v1, const vec3_t v2) { diff --git a/libs/util/test/Makefile.am b/libs/util/test/Makefile.am index 750682068..e10bbac59 100644 --- a/libs/util/test/Makefile.am +++ b/libs/util/test/Makefile.am @@ -2,10 +2,14 @@ AUTOMAKE_OPTIONS= foreign INCLUDES= -I$(top_srcdir)/include -check_PROGRAMS=test-qfs +check_PROGRAMS=test-qfs test-quat test_qfs_SOURCES=test-qfs.c test_qfs_LDADD=$(top_builddir)/libs/util/libQFutil.la test_qfs_DEPENDENCIES=$(top_builddir)/libs/util/libQFutil.la +test_quat_SOURCES=test-quat.c +test_quat_LDADD=$(top_builddir)/libs/util/libQFutil.la +test_quat_DEPENDENCIES=$(top_builddir)/libs/util/libQFutil.la + TESTS=$(check_PROGRAMS) diff --git a/libs/util/test/test-quat.c b/libs/util/test/test-quat.c new file mode 100644 index 000000000..0b2defb13 --- /dev/null +++ b/libs/util/test/test-quat.c @@ -0,0 +1,96 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "QF/mathlib.h" + +//PITCH YAW ROLL +static vec3_t test_angles[] = { + {0, 0, 0}, + {45, 0, 0}, + {0, 45, 0}, + {0, 0, 45}, + {45, 45, 0}, + {0, 45, 45}, + {45, 0, 45}, + {45, 45, 45}, +}; +#define num_angle_tests (sizeof (test_angles) / sizeof (test_angles[0])) + +// return true if a and b are close enough (yay, floats) +static int +compare (vec_t a, vec_t b) +{ + vec_t diff = a - b; + return diff * diff < 0.001; +} + +static int +test_rotation (const vec3_t angles) +{ + int i; + vec3_t forward, right, up; + + quat_t quat, f, r, u, t; + quat_t qf = {0, 1, 0, 0}; + quat_t qr = {0, 0, -1, 0}; + quat_t qu = {0, 0, 0, 1}; + + AngleVectors (angles, forward, right, up); + + AngleQuat (angles, quat); + // rotate forward vector + QuatConj (quat, t); + QuatMult (qf, t, t); + QuatMult (quat, t, f); + // rotate right vector + QuatConj (quat, t); + QuatMult (qr, t, t); + QuatMult (quat, t, r); + // rotate up vector + QuatConj (quat, t); + QuatMult (qu, t, t); + QuatMult (quat, t, u); + + if (!compare (f[0], 0)) + goto fail; + for (i = 0; i < 3; i++) + if (!compare (forward[i], f[i + 1])) + goto fail; + + if (!compare (r[0], 0)) + goto fail; + for (i = 0; i < 3; i++) + if (!compare (right[i], r[i + 1])) + goto fail; + + if (!compare (u[0], 0)) + goto fail; + for (i = 0; i < 3; i++) + if (!compare (up[i], u[i + 1])) + goto fail; + return 1; +fail: + printf ("\n\n%g %g %g\n\n", angles[0], angles[1], angles[2]); + printf ("%g %g %g\n", forward[0], forward[1], forward[2]); + printf ("%g %g %g\n", right[0], right[1], right[2]); + printf ("%g %g %g\n\n", up[0], up[1], up[2]); + + printf ("%g %g %g %g\n", f[0], f[1], f[2], f[3]); + printf ("%g %g %g %g\n", r[0], r[1], r[2], r[3]); + printf ("%g %g %g %g\n", u[0], u[1], u[2], u[3]); + return 0; +} + +int +main (int argc, const char **argv) +{ + int res = 0; + size_t i; + + for (i = 0; i < num_angle_tests; i ++) { + if (!test_rotation (test_angles[i])) + res = 1; + } + return res; +} From 9ace9f2bfabacdc3b37ce751d7dc2ffbb97e1c6a Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 28 Aug 2011 12:54:50 +0900 Subject: [PATCH 106/334] Fix some bad timing with a dstring_delete. Opps :P, double free. --- nq/source/cl_demo.c | 3 ++- qw/source/cl_demo.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/nq/source/cl_demo.c b/nq/source/cl_demo.c index 6b9d9968b..abcb8b1ec 100644 --- a/nq/source/cl_demo.c +++ b/nq/source/cl_demo.c @@ -347,10 +347,10 @@ CL_StartDemo (void) Sys_Printf ("Playing demo from %s.\n", name->str); QFS_FOpenFile (name->str, &cls.demofile); - dstring_delete (name); if (!cls.demofile) { Sys_Printf ("ERROR: couldn't open.\n"); cls.demonum = -1; // stop demo loop + dstring_delete (name); return; } @@ -368,6 +368,7 @@ CL_StartDemo (void) if (neg) cls.forcetrack = -cls.forcetrack; + dstring_delete (name); } /* diff --git a/qw/source/cl_demo.c b/qw/source/cl_demo.c index a5d21b51c..1c9c00f4d 100644 --- a/qw/source/cl_demo.c +++ b/qw/source/cl_demo.c @@ -890,10 +890,10 @@ CL_StartDemo (void) Sys_Printf ("Playing demo from %s.\n", name->str); QFS_FOpenFile (name->str, &cls.demofile); - dstring_delete (name); if (!cls.demofile) { Sys_Printf ("ERROR: couldn't open.\n"); cls.demonum = -1; // stop demo loop + dstring_delete (name); return; } From 9afb691dd9ba24da46afeaf95d79d9b7f42afbbe Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 28 Aug 2011 18:29:46 +0900 Subject: [PATCH 107/334] Change MSG_ReadShort to return an unsigned short. Avoiding the sign extension by default seems to be more useful. --- libs/util/msg.c | 20 ++++++++------------ nq/source/cl_parse.c | 10 +++++----- nq/source/sv_user.c | 6 +++--- qtv/source/sv_parse.c | 2 +- qw/source/cl_entparse.c | 6 +++--- qw/source/cl_parse.c | 2 +- qw/source/net_packetlog.c | 33 +++++++++++++++++---------------- 7 files changed, 38 insertions(+), 41 deletions(-) diff --git a/libs/util/msg.c b/libs/util/msg.c index cc7d1d29d..3c72d422d 100644 --- a/libs/util/msg.c +++ b/libs/util/msg.c @@ -250,8 +250,8 @@ MSG_ReadShort (qmsg_t *msg) int c; if (msg->readcount + 2 <= msg->message->cursize) { - c = (short) (msg->message->data[msg->readcount] - + (msg->message->data[msg->readcount + 1] << 8)); + c = (msg->message->data[msg->readcount] + + (msg->message->data[msg->readcount + 1] << 8)); msg->readcount += 2; return c; } @@ -354,7 +354,7 @@ MSG_ReadBytes (qmsg_t *msg, void *buf, int len) VISIBLE float MSG_ReadCoord (qmsg_t *msg) { - return MSG_ReadShort (msg) * (1.0 / 8.0); + return (short) MSG_ReadShort (msg) * (1.0 / 8.0); } VISIBLE void @@ -363,7 +363,7 @@ MSG_ReadCoordV (qmsg_t *msg, vec3_t coord) int i; for (i = 0; i < 3; i++) - coord[i] = MSG_ReadShort (msg) * (1.0 / 8.0); + coord[i] = (short) MSG_ReadShort (msg) * (1.0 / 8.0); } VISIBLE void @@ -372,7 +372,7 @@ MSG_ReadCoordAngleV (qmsg_t *msg, vec3_t coord, vec3_t angles) int i; for (i = 0; i < 3; i++) { - coord[i] = MSG_ReadShort (msg) * (1.0 / 8.0); + coord[i] = (short) MSG_ReadShort (msg) * (1.0 / 8.0); angles[i] = ((signed char) MSG_ReadByte (msg)) * (360.0 / 256.0); } } @@ -395,20 +395,16 @@ MSG_ReadAngleV (qmsg_t *msg, vec3_t angles) VISIBLE float MSG_ReadAngle16 (qmsg_t *msg) { - return MSG_ReadShort (msg) * (360.0 / 65536.0); + return (short) MSG_ReadShort (msg) * (360.0 / 65536.0); } VISIBLE void MSG_ReadAngle16V (qmsg_t *msg, vec3_t angles) { int i; - short ang; - for (i = 0; i < 3; i++) { - ang = MSG_ReadByte (msg); - ang |= MSG_ReadByte (msg) << 8; - angles[i] = ang * (360.0 / 65536.0); - } + for (i = 0; i < 3; i++) + angles[i] = (short) MSG_ReadShort (msg) * (360.0 / 65536.0); } VISIBLE int diff --git a/nq/source/cl_parse.c b/nq/source/cl_parse.c index c19bf4fef..f49c18107 100644 --- a/nq/source/cl_parse.c +++ b/nq/source/cl_parse.c @@ -185,16 +185,16 @@ CL_ParseStartSoundPacket (void) attenuation = DEFAULT_SOUND_PACKET_ATTENUATION; if (field_mask & SND_LARGEENTITY) { - ent = (uint16_t) MSG_ReadShort (net_message); + ent = MSG_ReadShort (net_message); channel = MSG_ReadByte (net_message); } else { - channel = (uint16_t) MSG_ReadShort (net_message); + channel = MSG_ReadShort (net_message); ent = channel >> 3; channel &= 7; } if (field_mask & SND_LARGESOUND) - sound_num = (uint16_t) MSG_ReadShort (net_message); + sound_num = MSG_ReadShort (net_message); else sound_num = MSG_ReadByte (net_message); @@ -688,7 +688,7 @@ CL_ParseClientdata (void) int i, j; int bits; - bits = (uint16_t) MSG_ReadShort (net_message); + bits = MSG_ReadShort (net_message); if (bits & SU_EXTEND1) bits |= MSG_ReadByte (net_message) << 16; if (bits & SU_EXTEND2) @@ -1006,7 +1006,7 @@ CL_ParseServerMessage (void) if (i >= cl.maxclients) Host_Error ("CL_ParseServerMessage: svc_updatefrags > " "MAX_SCOREBOARD"); - cl.scores[i].frags = MSG_ReadShort (net_message); + cl.scores[i].frags = (short) MSG_ReadShort (net_message); break; case svc_updatecolors: diff --git a/nq/source/sv_user.c b/nq/source/sv_user.c index 9708aef25..3772c3a2d 100644 --- a/nq/source/sv_user.c +++ b/nq/source/sv_user.c @@ -435,9 +435,9 @@ SV_ReadClientMove (usercmd_t *move) VectorCopy (angle, SVvector (host_client->edict, v_angle)); // read movement - move->forwardmove = MSG_ReadShort (net_message); - move->sidemove = MSG_ReadShort (net_message); - move->upmove = MSG_ReadShort (net_message); + move->forwardmove = (short) MSG_ReadShort (net_message); + move->sidemove = (short) MSG_ReadShort (net_message); + move->upmove = (short) MSG_ReadShort (net_message); // read buttons bits = MSG_ReadByte (net_message); diff --git a/qtv/source/sv_parse.c b/qtv/source/sv_parse.c index 2ebbd5bc8..5beba83ab 100644 --- a/qtv/source/sv_parse.c +++ b/qtv/source/sv_parse.c @@ -527,7 +527,7 @@ parse_player_delta (qmsg_t *msg, plent_state_t *from, plent_state_t *to) MSG_ReadDeltaUsercmd (msg, &from->cmd, &to->cmd); for (i = 0; i < 3; i++) { if (flags & (PF_VELOCITY1 << i)) - to->velocity[i] = MSG_ReadShort (msg); + to->velocity[i] = (short) MSG_ReadShort (msg); } if (flags & PF_MODEL) to->modelindex = MSG_ReadByte (msg); diff --git a/qw/source/cl_entparse.c b/qw/source/cl_entparse.c index 11f2df7e5..29e4ccecc 100644 --- a/qw/source/cl_entparse.c +++ b/qw/source/cl_entparse.c @@ -181,7 +181,7 @@ FlushEntityPacket (void) // read it all, but ignore it while (1) { - word = (unsigned short) MSG_ReadShort (net_message); + word = MSG_ReadShort (net_message); if (net_message->badread) { // something didn't parse right... Host_Error ("msg_badread in packetentities"); return; @@ -238,7 +238,7 @@ CL_ParsePacketEntities (qboolean delta) newp->num_entities = 0; while (1) { - word = (unsigned short) MSG_ReadShort (net_message); + word = MSG_ReadShort (net_message); if (net_message->badread) { // something didn't parse right... Host_Error ("msg_badread in packetentities"); return; @@ -436,7 +436,7 @@ CL_ParsePlayerinfo (void) for (i = 0; i < 3; i++) { if (flags & (PF_VELOCITY1 << i)) - state->pls.velocity[i] = MSG_ReadShort (net_message); + state->pls.velocity[i] = (short) MSG_ReadShort (net_message); else state->pls.velocity[i] = 0; } diff --git a/qw/source/cl_parse.c b/qw/source/cl_parse.c index f79f7bc8d..b47f8f9af 100644 --- a/qw/source/cl_parse.c +++ b/qw/source/cl_parse.c @@ -1412,7 +1412,7 @@ CL_ParseServerMessage (void) if (i >= MAX_CLIENTS) Host_Error ("CL_ParseServerMessage: svc_updatefrags > " "MAX_SCOREBOARD"); - cl.players[i].frags = MSG_ReadShort (net_message); + cl.players[i].frags = (short) MSG_ReadShort (net_message); break; case svc_updateping: diff --git a/qw/source/net_packetlog.c b/qw/source/net_packetlog.c index 86932e0e5..1aa679900 100644 --- a/qw/source/net_packetlog.c +++ b/qw/source/net_packetlog.c @@ -470,7 +470,8 @@ Parse_Server_Packet (int has_sequence) break; case svc_updatefrags: Net_LogPrintf ("player: %d ", MSG_ReadByte (&packet)); - Net_LogPrintf ("frags: %d", MSG_ReadShort (&packet)); + Net_LogPrintf ("frags: %d", + (short) MSG_ReadShort (&packet)); break; case svc_clientdata: Net_LogPrintf ("**QW OBSOLETE**"); @@ -538,8 +539,8 @@ Parse_Server_Packet (int has_sequence) case 5: case 6: case 9: - Net_LogPrintf (" created by %d", MSG_ReadShort - (&packet)); + Net_LogPrintf (" created by %d", + MSG_ReadShort (&packet)); Net_LogPrintf (" origin:"); for (i = 0; i < 3; i++) Net_LogPrintf ("%c%f", i ? ',' : ' ', @@ -663,14 +664,14 @@ Parse_Server_Packet (int has_sequence) Net_LogPrintf (" Roll: %f", MSG_ReadAngle16 (&packet)); if (mask2 & 0x04) - Net_LogPrintf (" Speed1: %d", MSG_ReadShort - (&packet)); + Net_LogPrintf (" Speed1: %d", + MSG_ReadShort (&packet)); if (mask2 & 0x08) - Net_LogPrintf (" Speed2: %d", MSG_ReadShort - (&packet)); + Net_LogPrintf (" Speed2: %d", + MSG_ReadShort (&packet)); if (mask2 & 0x10) - Net_LogPrintf (" Speed3: %d", MSG_ReadShort - (&packet)); + Net_LogPrintf (" Speed3: %d", + MSG_ReadShort (&packet)); if (mask2 & 0x20) Net_LogPrintf (" Flag: %d", MSG_ReadByte (&packet)); @@ -782,7 +783,7 @@ Parse_Server_Packet (int has_sequence) case svc_packetentities: packetentities: while (1) { - mask1 = (unsigned short) MSG_ReadShort (&packet); + mask1 = MSG_ReadShort (&packet); if (packet.badread) { Net_LogPrintf ("Badread\n"); return; @@ -897,14 +898,14 @@ Parse_Client_Packet (int has_sequence) Net_LogPrintf (" Roll: %f", MSG_ReadAngle16 (&packet)); if (mask & 0x04) - Net_LogPrintf (" Fwd: %d", MSG_ReadShort - (&packet)); + Net_LogPrintf (" Fwd: %d", + MSG_ReadShort (&packet)); if (mask & 0x08) - Net_LogPrintf (" Right: %d", MSG_ReadShort - (&packet)); + Net_LogPrintf (" Right: %d", + MSG_ReadShort (&packet)); if (mask & 0x10) - Net_LogPrintf (" Up: %d", MSG_ReadShort - (&packet)); + Net_LogPrintf (" Up: %d", + MSG_ReadShort (&packet)); if (mask & 0x20) Net_LogPrintf (" Flags: %d", MSG_ReadByte (&packet)); From deddb5cb6abe26af4ce854b4c5e4616e40b55eb7 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 28 Aug 2011 18:33:29 +0900 Subject: [PATCH 108/334] Partially document the message api. --- include/QF/msg.h | 170 +++++++++++++++++++++++++++++++++++++++++++++++ libs/util/msg.c | 16 ++--- 2 files changed, 178 insertions(+), 8 deletions(-) diff --git a/include/QF/msg.h b/include/QF/msg.h index 3442e2f5d..569dba089 100644 --- a/include/QF/msg.h +++ b/include/QF/msg.h @@ -58,22 +58,192 @@ typedef struct msg_s { char *badread_string; } qmsg_t; +/** Reset the message read status. + + Clears the error flag and resets the read index to 0. + + \param msg The message to be reset. +*/ void MSG_BeginReading (qmsg_t *msg); + +/** Get the number of bytes that have been read from the message. + + The result can also be used as the index to the next byte to be read. + + \param msg The message to check. + \return The number of bytes that have been read. +*/ int MSG_GetReadCount(qmsg_t *msg); + +/** Read a single byte from the message. + + Advances the read index. + + \param msg The message from which the byte will be read. + \return The byte value (0 - 255), or -1 if already at the end of + the message. +*/ int MSG_ReadByte (qmsg_t *msg); + +/** Read a single unsigned short from the message. + + Advances the read index. + + \param msg The message from which the short will be read. + \return The short value (0 - 65535), or -1 if already at + the end of the message. +*/ int MSG_ReadShort (qmsg_t *msg); + +/** Read a single long from the message. + + Advances the read index. + + \param msg The message from which the long will be read. + \return The signed long value or -1 if already at the end of + the message. + \note -1 may be either an error or a value. Check qmsg_t::badread to + differentiate the two cases (false for a value). + \todo Fix? +*/ int MSG_ReadLong (qmsg_t *msg); + +/** Read a single float from the message. + + Advances the read index. + + \param msg The message from which the float will be read. + \return The float value or -1 if already at the end of the + message. + \note -1 may be either an error or a value. Check qmsg_t::badread to + differentiate the two cases (false for a value). + \todo Fix? +*/ float MSG_ReadFloat (qmsg_t *msg); + +/** Read a nul terminated string from the message. + + Advances the read index to the first byte after the string. + + The returned string is guaranteed to be valid. If the string in the + message is not nul terminated, the string will be safely extracted, + qmst_t::badread set to true, and the extracted string will be returned. + + \param msg The message from which the string will be read. + \return The string within the message, or "" if alread at the + end of the message. + \note "" may be either an error or a value. Check qmsg_t::badread to + differentiate the two cases (false for a value). + \todo Fix? +*/ const char *MSG_ReadString (qmsg_t *msg); + +/** Read a block of bytes from the message. + + Advances the read index to the first byte after the block. + + If not all bytes could be read, qmsg_t::badread will be set to true. + + \param msg The message from which the string will be read. + \param buf Pointer to the buffer into which the bytes will be + placed. + \param len The number of bytes to read. + \return The number of bytes read from the message. +*/ int MSG_ReadBytes (qmsg_t *msg, void *buf, int len); +/** Read a 16-bit fixed point (13.3) coordinate value from the message. + + Advances the read index to the first byte after the block. + + \param msg The message from which the coordinate will be read. + \return The coordinate value converted to floating point. + + \note -0.125 may be either an error or a value. Check qmsg_t::badread + to differentiate the two cases (false for a value). + \todo Fix? +*/ float MSG_ReadCoord (qmsg_t *msg); + +/** Read three 16-bit fixed point (s12.3) coordinate values from the message. + + Advances the read index. + + \param msg The message from which the coordinates will be read. + \param coord The vector into which the three coordinates will be + placed. + + \note -0.125 may be either an error or a value. Check qmsg_t::badread + to differentiate the two cases (false for a value). + \todo Fix? +*/ void MSG_ReadCoordV (qmsg_t *msg, vec3_t coord); + +/** Read an 8-bit encoded angle from the message. + + Advances the read index. + + \param msg The message from which the angle will be read. + \return The angle converted to the range -180 - 180. +*/ float MSG_ReadAngle (qmsg_t *msg); + +/** Read interleaved 16-bit coordinate/8-bit angle vectors from the message. + + Advances the read index. + + \param msg The message from which the angle will be read. + \param coord The vector into which the converted coordinate vector + will be placed. + \param angles The vector into which the converted coordinate angles + will be placed. + \see MSG_ReadCoord + \see MSG_ReadAngle +*/ void MSG_ReadCoordAngleV (qmsg_t *msg, vec3_t coord, vec3_t angles); + +/** Read three 8-bit encoded angle values from the message. + + Advances the read index. + + \param msg The message from which the angles will be read. + \param angles The vector into which the three angles will be placed. + + \note The angles will be converted to the range -180 - 180. +*/ void MSG_ReadAngleV (qmsg_t *msg, vec3_t angles); + +/** Read a 16-bit encoded angle from the message. + + Advances the read index. + + \param msg The message from which the angle will be read. + \return The angle converted to the range -180 - 180. +*/ float MSG_ReadAngle16 (qmsg_t *msg); + +/** Read three 16-bit encoded angle values from the message. + + Advances the read index. + + \param msg The message from which the angles will be read. + \param angles The vector into which the three angles will be placed. + + \note The angles will be converted to the range -180 - 180. +*/ void MSG_ReadAngle16V (qmsg_t *msg, vec3_t angles); + +/** Read a single UTF-8 encoded value. + + Advances the read index the the first byte after the value. However, + the read index will not be advanced if any error is detected. + + A successfull read will read between 1 and 6 bytes from the message. + + \param msg The message from which the UTF-8 encoded value will be + read. + \return The 31-bit value, or -1 on error. +*/ int MSG_ReadUTF8 (qmsg_t *msg); //@} diff --git a/libs/util/msg.c b/libs/util/msg.c index 3c72d422d..ce773c731 100644 --- a/libs/util/msg.c +++ b/libs/util/msg.c @@ -420,28 +420,28 @@ MSG_ReadUTF8 (qmsg_t *msg) buf = start = msg->message->data + msg->readcount; c = *buf++; - if (c < 0x80) { + if (c < 0x80) { // 0x00 - 0x7f 1,7,7 val = c; count = 1; - } else if (c < 0xc0) { + } else if (c < 0xc0) { // 0x80 - 0xbf not a valid first byte msg->badread = true; return -1; - } else if (c < 0xe0) { + } else if (c < 0xe0) { // 0xc0 - 0xdf 2,5,11 count = 2; val = c & 0x1f; - } else if (c < 0xf0) { + } else if (c < 0xf0) { // 0xe0 - 0xef 3,4,16 count = 3; val = c & 0x0f; - } else if (c < 0xf8) { + } else if (c < 0xf8) { // 0xf0 - 0xf7 4,3,21 count = 4; val = c & 0x07; - } else if (c < 0xfc) { + } else if (c < 0xfc) { // 0xf8 - 0xfb 5,2,26 count = 5; val = c & 0x03; - } else if (c < 0xfe) { + } else if (c < 0xfe) { // 0xfc - 0xfd 6,1,31 count = 6; val = c & 0x01; - } else { + } else { // 0xfe - 0xff never valid msg->badread = true; return -1; } From be8277c8c49247165064e4df39381718ffda395f Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 28 Aug 2011 21:05:35 +0900 Subject: [PATCH 109/334] Sanitize some of the differences in cl_parse.c. Most of the differences in CL_ParseServerMessage are now protocol specific. --- nq/source/cl_parse.c | 69 +++++++++++++++++++++++------------------ qw/source/cl_parse.c | 73 ++++++++++++++++++++------------------------ 2 files changed, 72 insertions(+), 70 deletions(-) diff --git a/nq/source/cl_parse.c b/nq/source/cl_parse.c index f49c18107..b2d65bac0 100644 --- a/nq/source/cl_parse.c +++ b/nq/source/cl_parse.c @@ -319,6 +319,7 @@ CL_NewMap (const char *mapname) { R_NewMap (cl.worldmodel, cl.model_precache, MAX_MODELS); Con_NewMap (); + Hunk_Check (); // make sure nothing is hurt Sbar_CenterPrint (0); if (cl.model_precache[1] && cl.model_precache[1]->entities) { @@ -865,6 +866,14 @@ CL_ParseStaticSound (int version) S_StaticSound (cl.sound_precache[sound_num], org, vol, atten); } +static void +CL_SetStat (int stat, int value) +{ + if (stat < 0 || stat >= MAX_CL_STATS) + Host_Error ("CL_SetStat: %i is invalid", stat); + cl.stats[stat] = value; +} + #define SHOWNET(x) \ if (cl_shownet->int_val == 2) \ Sys_Printf ("%3i:%s\n", net_message->readcount - 1, x); @@ -874,7 +883,7 @@ int viewentity; void CL_ParseServerMessage (void) { - int cmd, i; + int cmd = 0, i, j; const char *str; // if recording demos, copy the message out @@ -890,13 +899,16 @@ CL_ParseServerMessage (void) while (1) { if (net_message->badread) - Host_Error ("CL_ParseServerMessage: Bad server message"); + Host_Error ("CL_ParseServerMessage: Bad server message: %s\n", + svc_strings[cmd]); cmd = MSG_ReadByte (net_message); if (cmd == -1) { + net_message->readcount++; // so the EOM SHOWNET has the right + // value SHOWNET ("END OF MESSAGE"); - return; // end of message + break; // end of message } // if the high bit of the command byte is set, it is a fast update if (cmd & U_SIGNAL) { @@ -911,7 +923,7 @@ CL_ParseServerMessage (void) switch (cmd) { default: Host_Error ("CL_ParseServerMessage: Illegible server " - "message\n"); + "message %d\n", cmd); break; case svc_nop: @@ -965,9 +977,12 @@ CL_ParseServerMessage (void) break; case svc_setangle: - MSG_ReadAngleV (net_message, cl.viewangles); - break; + { + vec_t *dest = cl.viewangles; + MSG_ReadAngleV (net_message, dest); + break; + } case svc_setview: cl.viewentity = MSG_ReadShort (net_message); viewentity = cl.viewentity; // FIXME: evil hack @@ -976,7 +991,7 @@ CL_ParseServerMessage (void) case svc_lightstyle: i = MSG_ReadByte (net_message); if (i >= MAX_LIGHTSTYLES) - Sys_Error ("svc_lightstyle > MAX_LIGHTSTYLES"); + Host_Error ("svc_lightstyle > MAX_LIGHTSTYLES"); strcpy (r_lightstyle[i].map, MSG_ReadString (net_message)); r_lightstyle[i].length = strlen (r_lightstyle[i].map); // FIXME extra info @@ -991,15 +1006,6 @@ CL_ParseServerMessage (void) S_StopSound (i >> 3, i & 7); break; - case svc_updatename: - Sbar_Changed (); - i = MSG_ReadByte (net_message); - if (i >= cl.maxclients) - Host_Error ("CL_ParseServerMessage: svc_updatename > " - "MAX_SCOREBOARD"); - strcpy (cl.scores[i].name, MSG_ReadString (net_message)); - break; - case svc_updatefrags: Sbar_Changed (); i = MSG_ReadByte (net_message); @@ -1009,6 +1015,15 @@ CL_ParseServerMessage (void) cl.scores[i].frags = (short) MSG_ReadShort (net_message); break; + case svc_updatename: + Sbar_Changed (); + i = MSG_ReadByte (net_message); + if (i >= cl.maxclients) + Host_Error ("CL_ParseServerMessage: svc_updatename > " + "MAX_SCOREBOARD"); + strcpy (cl.scores[i].name, MSG_ReadString (net_message)); + break; + case svc_updatecolors: Sbar_Changed (); i = MSG_ReadByte (net_message); @@ -1037,21 +1052,20 @@ CL_ParseServerMessage (void) case svc_spawnstatic: CL_ParseStatic (1); break; + case svc_spawnstaticsound: + CL_ParseStaticSound (1); + break; case svc_temp_entity: CL_ParseTEnt (); break; case svc_setpause: - { r_paused = cl.paused = MSG_ReadByte (net_message); - - if (cl.paused) { + if (cl.paused) CDAudio_Pause (); - } else { + else CDAudio_Resume (); - } - } - break; + break; case svc_signonnum: i = MSG_ReadByte (net_message); @@ -1072,13 +1086,8 @@ CL_ParseServerMessage (void) case svc_updatestat: i = MSG_ReadByte (net_message); - if (i < 0 || i >= MAX_CL_STATS) - Sys_Error ("svc_updatestat: %i is invalid", i); - cl.stats[i] = MSG_ReadLong (net_message); - break; - - case svc_spawnstaticsound: - CL_ParseStaticSound (1); + j = MSG_ReadLong (net_message); + CL_SetStat (i, j); break; case svc_cdtrack: diff --git a/qw/source/cl_parse.c b/qw/source/cl_parse.c index b47f8f9af..10b5a5e9f 100644 --- a/qw/source/cl_parse.c +++ b/qw/source/cl_parse.c @@ -1239,16 +1239,16 @@ CL_MuzzleFlash (void) #define SHOWNET(x) \ if (cl_shownet->int_val == 2) \ - Sys_Printf ("%3i:%s\n", net_message->readcount-1, x); + Sys_Printf ("%3i:%s\n", net_message->readcount - 1, x); int received_framecount; void CL_ParseServerMessage (void) { + int cmd = 0, i, j; const char *str; static dstring_t *stuffbuf; - int cmd = 0, i, j; received_framecount = host_framecount; cl.last_servermessage = realtime; @@ -1265,11 +1265,9 @@ CL_ParseServerMessage (void) // parse the message while (1) { - if (net_message->badread) { + if (net_message->badread) Host_Error ("CL_ParseServerMessage: Bad server message: %s\n", svc_strings[cmd]); - break; - } cmd = MSG_ReadByte (net_message); @@ -1277,10 +1275,10 @@ CL_ParseServerMessage (void) net_message->readcount++; // so the EOM SHOWNET has the right // value SHOWNET ("END OF MESSAGE"); - break; + break; // end of message } - SHOWNET (svc_strings[cmd]); + SHOWNET (va ("%s(%d)", svc_strings[cmd], cmd)); // other commands switch (cmd) { @@ -1300,7 +1298,8 @@ CL_ParseServerMessage (void) Host_EndGame ("Server disconnected"); break; - case svc_print: { + case svc_print: + { dstring_t *p = 0; i = MSG_ReadByte (net_message); @@ -1365,6 +1364,24 @@ CL_ParseServerMessage (void) V_ParseDamage (); break; + case svc_serverinfo: + CL_ServerInfo (); + break; + + case svc_setangle: + { + vec_t *dest = cl.viewangles; + vec3_t dummy; + + if (cls.demoplayback2) { + j = MSG_ReadByte (net_message); +// fixangle |= 1 << j; + if (j != Cam_TrackNum ()) + dest = dummy; + } + MSG_ReadAngleV (net_message, dest); + break; + } case svc_serverdata: // make sure any stuffed commands are done Cbuf_Execute_Stack (cl_stbuf); @@ -1372,23 +1389,6 @@ CL_ParseServerMessage (void) vid.recalc_refdef = true; // leave full screen intermission break; - case svc_setangle: - if (!cls.demoplayback2) { - MSG_ReadAngleV (net_message, cl.viewangles); - } else { - j = MSG_ReadByte (net_message); -// fixangle |= 1 << j; - if (j != Cam_TrackNum ()) { - MSG_ReadAngle (net_message); - MSG_ReadAngle (net_message); - MSG_ReadAngle (net_message); - } else { - MSG_ReadAngleV (net_message, cl.viewangles); - } - } -// FIXME cl.viewangles[PITCH] = cl.viewangles[ROLL] = 0; - break; - case svc_lightstyle: i = MSG_ReadByte (net_message); if (i >= MAX_LIGHTSTYLES) @@ -1445,19 +1445,24 @@ CL_ParseServerMessage (void) i = MSG_ReadShort (net_message); CL_ParseBaseline (&cl_baselines[i]); break; - case svc_spawnstatic: CL_ParseStatic (); break; - case svc_spawnstaticsound: CL_ParseStaticSound (); break; - case svc_temp_entity: CL_ParseTEnt (); break; + case svc_setpause: + r_paused = cl.paused = MSG_ReadByte (net_message); + if (cl.paused) + CDAudio_Pause (); + else + CDAudio_Resume (); + break; + case svc_killedmonster: cl.stats[STAT_MONSTERS]++; break; @@ -1544,10 +1549,6 @@ CL_ParseServerMessage (void) CL_SetInfo (); break; - case svc_serverinfo: - CL_ServerInfo (); - break; - case svc_download: CL_ParseDownload (); break; @@ -1594,14 +1595,6 @@ CL_ParseServerMessage (void) case svc_entgravity: movevars.entgravity = MSG_ReadFloat (net_message); break; - - case svc_setpause: - r_paused = cl.paused = MSG_ReadByte (net_message); - if (cl.paused) - CDAudio_Pause (); - else - CDAudio_Resume (); - break; } } From a55f490b47e26ba4aab80698bb48bb350d340545 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 28 Aug 2011 21:11:08 +0900 Subject: [PATCH 110/334] Add support for map specified fog and skys to qw. --- qw/include/client.h | 3 +++ qw/source/cl_parse.c | 48 ++++++++++++++++++++++++++++++++++++++++++++ qw/source/sv_progs.c | 8 +++++--- 3 files changed, 56 insertions(+), 3 deletions(-) diff --git a/qw/include/client.h b/qw/include/client.h index 2d62df2be..722c4987a 100644 --- a/qw/include/client.h +++ b/qw/include/client.h @@ -276,6 +276,9 @@ typedef struct struct model_s *model_precache[MAX_MODELS]; struct sfx_s *sound_precache[MAX_SOUNDS]; + struct plitem_s *edicts; + struct plitem_s *worldspawn; + char levelname[40]; // for display on solo scoreboard int playernum; int viewentity; diff --git a/qw/source/cl_parse.c b/qw/source/cl_parse.c index 10b5a5e9f..0c9243ae0 100644 --- a/qw/source/cl_parse.c +++ b/qw/source/cl_parse.c @@ -55,6 +55,8 @@ static __attribute__ ((used)) const char rcsid[] = #include "QF/hash.h" #include "QF/idparse.h" #include "QF/msg.h" +#include "QF/progs.h" +#include "QF/qfplist.h" #include "QF/quakeio.h" #include "QF/screen.h" #include "QF/sound.h" @@ -174,6 +176,23 @@ extern cvar_t *hud_scoreboard_uid; entity_t *cl_static_entities; static entity_t **cl_static_tail; +static void +CL_LoadSky (void) +{ + plitem_t *item; + const char *name = 0; + + if (!cl.worldspawn) { + R_LoadSkys (0); + return; + } + if ((item = PL_ObjectForKey (cl.worldspawn, "sky")) // Q2/DarkPlaces + || (item = PL_ObjectForKey (cl.worldspawn, "skyname")) // old QF + || (item = PL_ObjectForKey (cl.worldspawn, "qlsky"))) /* QuakeLives */ { + name = PL_String (item); + } + R_LoadSkys (name); +} int CL_CalcNet (void) @@ -258,6 +277,26 @@ CL_CheckOrDownloadFile (const char *filename) return false; } +static plitem_t * +map_ent (const char *mapname) +{ + static progs_t edpr; + char *name = malloc (strlen (mapname) + 4 + 1); + char *buf; + plitem_t *edicts = 0; + + QFS_StripExtension (mapname, name); + strcat (name, ".ent"); + if ((buf = (char *) QFS_LoadFile (name, 0))) { + edicts = ED_Parse (&edpr, buf); + free (buf); + } else { + edicts = ED_Parse (&edpr, cl.model_precache[1]->entities); + } + free (name); + return edicts; +} + static void CL_NewMap (const char *mapname) { @@ -269,6 +308,15 @@ CL_NewMap (const char *mapname) Hunk_Check (); // make sure nothing is hurt Sbar_CenterPrint (0); + if (cl.model_precache[1] && cl.model_precache[1]->entities) { + cl.edicts = map_ent (mapname); + if (cl.edicts) { + cl.worldspawn = PL_ObjectAtIndex (cl.edicts, 0); + CL_LoadSky (); + Fog_ParseWorldspawn (cl.worldspawn); + } + } + map_cfg (mapname, 1); } diff --git a/qw/source/sv_progs.c b/qw/source/sv_progs.c index 766a6ea43..fb3d6b07a 100644 --- a/qw/source/sv_progs.c +++ b/qw/source/sv_progs.c @@ -186,12 +186,14 @@ parse_field (progs_t *pr, const char *key, const char *value) If skyname is set, set what the map thinks the skybox name should be. "qlsky" is supported since at least one other map uses it. */ - if (strcaseequal (key, "skyname") // QuakeForge - || strcaseequal (key, "sky") // Q2/DarkPlaces - || strcaseequal (key, "qlsky")) { // QuakeLives + if (strequal (key, "skyname") // QuakeForge + || strequal (key, "sky") // Q2/DarkPlaces + || strequal (key, "qlsky")) { // QuakeLives Info_SetValueForKey (svs.info, "sky", value, 0); return 1; } + if (strequal (key, "fog")) + return 1; if (*key == '_') // ignore _fields return 1; return 0; From 6b5b2a162294ffc8fa2533f2badef2301e913e6a Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 3 Sep 2011 13:10:03 +0900 Subject: [PATCH 111/334] Specified the endianess of the reads. --- include/QF/msg.h | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/include/QF/msg.h b/include/QF/msg.h index 569dba089..77f60cf42 100644 --- a/include/QF/msg.h +++ b/include/QF/msg.h @@ -85,7 +85,7 @@ int MSG_GetReadCount(qmsg_t *msg); */ int MSG_ReadByte (qmsg_t *msg); -/** Read a single unsigned short from the message. +/** Read a single little-endian unsigned short from the message. Advances the read index. @@ -95,7 +95,7 @@ int MSG_ReadByte (qmsg_t *msg); */ int MSG_ReadShort (qmsg_t *msg); -/** Read a single long from the message. +/** Read a single little-endian long from the message. Advances the read index. @@ -108,7 +108,7 @@ int MSG_ReadShort (qmsg_t *msg); */ int MSG_ReadLong (qmsg_t *msg); -/** Read a single float from the message. +/** Read a single little-endian float from the message. Advances the read index. @@ -152,7 +152,8 @@ const char *MSG_ReadString (qmsg_t *msg); */ int MSG_ReadBytes (qmsg_t *msg, void *buf, int len); -/** Read a 16-bit fixed point (13.3) coordinate value from the message. +/** Read a little-endian 16-bit fixed point (13.3) coordinate value from the + message. Advances the read index to the first byte after the block. @@ -165,7 +166,8 @@ int MSG_ReadBytes (qmsg_t *msg, void *buf, int len); */ float MSG_ReadCoord (qmsg_t *msg); -/** Read three 16-bit fixed point (s12.3) coordinate values from the message. +/** Read three little-endian 16-bit fixed point (s12.3) coordinate values + from the message. Advances the read index. @@ -188,7 +190,8 @@ void MSG_ReadCoordV (qmsg_t *msg, vec3_t coord); */ float MSG_ReadAngle (qmsg_t *msg); -/** Read interleaved 16-bit coordinate/8-bit angle vectors from the message. +/** Read interleaved little-endian 16-bit coordinate/8-bit angle vectors + from the message. Advances the read index. @@ -213,7 +216,7 @@ void MSG_ReadCoordAngleV (qmsg_t *msg, vec3_t coord, vec3_t angles); */ void MSG_ReadAngleV (qmsg_t *msg, vec3_t angles); -/** Read a 16-bit encoded angle from the message. +/** Read a little-endian 16-bit encoded angle from the message. Advances the read index. @@ -222,7 +225,7 @@ void MSG_ReadAngleV (qmsg_t *msg, vec3_t angles); */ float MSG_ReadAngle16 (qmsg_t *msg); -/** Read three 16-bit encoded angle values from the message. +/** Read three little-endian 16-bit encoded angle values from the message. Advances the read index. From 8d853589e3c243417a7956a41476d349049b2560 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 3 Sep 2011 14:18:35 +0900 Subject: [PATCH 112/334] Use the gamedir callback for the serverinfo key. This gits rid of a bit of nastiness in the gamedir code :) --- qw/include/server.h | 1 - qw/source/cl_sys_sdl.c | 1 - qw/source/cl_sys_unix.c | 1 - qw/source/cl_sys_win.c | 2 -- qw/source/game.c | 4 ---- qw/source/sv_main.c | 13 +++++++++++++ qw/source/sv_sys_unix.c | 1 - qw/source/sv_sys_win.c | 2 -- 8 files changed, 13 insertions(+), 12 deletions(-) diff --git a/qw/include/server.h b/qw/include/server.h index f0d03d2f4..24b1b3a8b 100644 --- a/qw/include/server.h +++ b/qw/include/server.h @@ -432,7 +432,6 @@ extern struct cvar_s *fraglimit; extern struct cvar_s *timelimit; extern server_static_t svs; // persistant server info -extern struct info_s **svs_info; extern server_t sv; // local server extern client_t *host_client; diff --git a/qw/source/cl_sys_sdl.c b/qw/source/cl_sys_sdl.c index 4e7cf833d..0d3361405 100644 --- a/qw/source/cl_sys_sdl.c +++ b/qw/source/cl_sys_sdl.c @@ -69,7 +69,6 @@ static __attribute__ ((used)) const char rcsid[] = #include "host.h" qboolean is_server = false; -char *svs_info; int noconinput; diff --git a/qw/source/cl_sys_unix.c b/qw/source/cl_sys_unix.c index 61109b5f9..492cd547e 100644 --- a/qw/source/cl_sys_unix.c +++ b/qw/source/cl_sys_unix.c @@ -62,7 +62,6 @@ static __attribute__ ((used)) const char rcsid[] = int noconinput = 0; qboolean is_server = false; -char *svs_info; static void shutdown (void) diff --git a/qw/source/cl_sys_win.c b/qw/source/cl_sys_win.c index af6e5ed7e..d33ba050f 100644 --- a/qw/source/cl_sys_win.c +++ b/qw/source/cl_sys_win.c @@ -63,8 +63,6 @@ static __attribute__ ((used)) const char rcsid[] = // minimization #define NOT_FOCUS_SLEEP 20 // sleep time when not focus -char *svs_info; - qboolean ActiveApp, Minimized, WinNT; qboolean is_server = false; diff --git a/qw/source/game.c b/qw/source/game.c index 5c7b824f3..83fed6d6a 100644 --- a/qw/source/game.c +++ b/qw/source/game.c @@ -77,10 +77,6 @@ SV_Gamedir_f (void) } QFS_Gamedir (dir); - - if (is_server) { - Info_SetValueForStarKey (*svs_info, "*gamedir", dir, 0); - } } void diff --git a/qw/source/sv_main.c b/qw/source/sv_main.c index 4f8b2a102..24ecfab57 100644 --- a/qw/source/sv_main.c +++ b/qw/source/sv_main.c @@ -2032,6 +2032,18 @@ maxclients_f (cvar_t *var) } } +static void +gamedir_f (int phase) +{ + if (!phase) + return; + if (qfs_gamedir->gamedir) + Info_SetValueForStarKey (svs.info, "*gamedir", + qfs_gamedir->gamedir, 0); + else + Info_RemoveKey (svs.info, "*gamedir"); +} + static void SV_InitLocal (void) { @@ -2522,6 +2534,7 @@ SV_Init (void) SV_Init_Memory (); + QFS_GamedirCallback (gamedir_f); svs.maxclients = MAX_CLIENTS; svs.info = Info_ParseString ("", MAX_SERVERINFO_STRING, 0); localinfo = Info_ParseString ("", 0, 0); // unlimited diff --git a/qw/source/sv_sys_unix.c b/qw/source/sv_sys_unix.c index deb4d2055..4ec7c8f66 100644 --- a/qw/source/sv_sys_unix.c +++ b/qw/source/sv_sys_unix.c @@ -61,7 +61,6 @@ static __attribute__ ((used)) const char rcsid[] = qboolean is_server = true; server_static_t svs; -info_t **svs_info = &svs.info; #ifdef __alpha__ static inline unsigned long diff --git a/qw/source/sv_sys_win.c b/qw/source/sv_sys_win.c index 98099c045..c3e234cae 100644 --- a/qw/source/sv_sys_win.c +++ b/qw/source/sv_sys_win.c @@ -46,8 +46,6 @@ static __attribute__ ((used)) const char rcsid[] = qboolean is_server = true; qboolean WinNT; server_static_t svs; -info_t **svs_info = &svs.info; - static void startup (void) From db8eee502f9a8a15d6ddeaa944b17b7e39621350 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 3 Sep 2011 14:26:11 +0900 Subject: [PATCH 113/334] Eliminate the is_server global. More ugliness gone :) --- include/netchan.h | 8 ++++---- qw/source/cl_demo.c | 2 +- qw/source/cl_main.c | 2 +- qw/source/cl_sys_sdl.c | 2 -- qw/source/cl_sys_unix.c | 1 - qw/source/cl_sys_win.c | 1 - qw/source/net_packetlog.c | 4 ++-- qw/source/sv_main.c | 2 +- qw/source/sv_sys_unix.c | 1 - qw/source/sv_sys_win.c | 1 - 10 files changed, 9 insertions(+), 15 deletions(-) diff --git a/include/netchan.h b/include/netchan.h index 52b591ee5..0226c9d46 100644 --- a/include/netchan.h +++ b/include/netchan.h @@ -67,15 +67,15 @@ extern struct cvar_s *qport; int Net_Log_Init (const char **sound_precache); void Net_LogPrintf (const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); -void Log_Incoming_Packet (const byte *p, int len, int has_sequence); -void Log_Outgoing_Packet (const byte *p, int len, int has_sequence); +void Log_Incoming_Packet (const byte *p, int len, int has_sequence, + int is_server); +void Log_Outgoing_Packet (const byte *p, int len, int has_sequence, + int is_server); void Net_LogStop (void); void Analyze_Client_Packet (const byte * data, int len, int has_sequence); void Analyze_Server_Packet (const byte * data, int len, int has_sequence); extern struct cvar_s *net_packetlog; - -extern qboolean is_server; //@} /** \defgroup qw-udp QuakeWorld udp support. diff --git a/qw/source/cl_demo.c b/qw/source/cl_demo.c index 1c9c00f4d..f45b6ac27 100644 --- a/qw/source/cl_demo.c +++ b/qw/source/cl_demo.c @@ -396,7 +396,7 @@ CL_GetMessage (void) if (net_packetlog->int_val) Log_Incoming_Packet (net_message->message->data, - net_message->message->cursize, 1); + net_message->message->cursize, 1, 0); if (cls.demorecording) diff --git a/qw/source/cl_main.c b/qw/source/cl_main.c index aba395fc5..f4d945e73 100644 --- a/qw/source/cl_main.c +++ b/qw/source/cl_main.c @@ -1025,7 +1025,7 @@ CL_ReadPackets (void) if (cls.demoplayback && net_packetlog->int_val) Log_Incoming_Packet (net_message->message->data, - net_message->message->cursize, 0); + net_message->message->cursize, 0, 0); // remote command packet if (*(int *) net_message->message->data == -1) { diff --git a/qw/source/cl_sys_sdl.c b/qw/source/cl_sys_sdl.c index 0d3361405..912803538 100644 --- a/qw/source/cl_sys_sdl.c +++ b/qw/source/cl_sys_sdl.c @@ -68,8 +68,6 @@ static __attribute__ ((used)) const char rcsid[] = #include "compat.h" #include "host.h" -qboolean is_server = false; - int noconinput; #ifdef _WIN32 diff --git a/qw/source/cl_sys_unix.c b/qw/source/cl_sys_unix.c index 492cd547e..d5fdb3623 100644 --- a/qw/source/cl_sys_unix.c +++ b/qw/source/cl_sys_unix.c @@ -61,7 +61,6 @@ static __attribute__ ((used)) const char rcsid[] = #include "netchan.h" int noconinput = 0; -qboolean is_server = false; static void shutdown (void) diff --git a/qw/source/cl_sys_win.c b/qw/source/cl_sys_win.c index d33ba050f..d1502e5df 100644 --- a/qw/source/cl_sys_win.c +++ b/qw/source/cl_sys_win.c @@ -64,7 +64,6 @@ static __attribute__ ((used)) const char rcsid[] = #define NOT_FOCUS_SLEEP 20 // sleep time when not focus qboolean ActiveApp, Minimized, WinNT; -qboolean is_server = false; HWND hwnd_dialog; // startup dialog box diff --git a/qw/source/net_packetlog.c b/qw/source/net_packetlog.c index 1aa679900..e70f61263 100644 --- a/qw/source/net_packetlog.c +++ b/qw/source/net_packetlog.c @@ -226,7 +226,7 @@ ascii_dump_buf (unsigned char *buf, int len) } */ void -Log_Incoming_Packet (const byte *p, int len, int has_sequence) +Log_Incoming_Packet (const byte *p, int len, int has_sequence, int is_server) { if (!net_loglevel->int_val) return; @@ -250,7 +250,7 @@ Log_Incoming_Packet (const byte *p, int len, int has_sequence) } void -Log_Outgoing_Packet (const byte *p, int len, int has_sequence) +Log_Outgoing_Packet (const byte *p, int len, int has_sequence, int is_server) { if (!net_loglevel->int_val) return; diff --git a/qw/source/sv_main.c b/qw/source/sv_main.c index 24ecfab57..fb1a77db9 100644 --- a/qw/source/sv_main.c +++ b/qw/source/sv_main.c @@ -1762,7 +1762,7 @@ SV_ReadPackets (void) while (NET_GetPacket ()) { if (net_packetlog->int_val) Log_Incoming_Packet (net_message->message->data, - net_message->message->cursize, 1); + net_message->message->cursize, 1, 1); if (SV_FilterIP (net_from.ip, &until)) { SV_SendBan (until); // tell them we aren't listening... continue; diff --git a/qw/source/sv_sys_unix.c b/qw/source/sv_sys_unix.c index 4ec7c8f66..2f2d5ff3b 100644 --- a/qw/source/sv_sys_unix.c +++ b/qw/source/sv_sys_unix.c @@ -59,7 +59,6 @@ static __attribute__ ((used)) const char rcsid[] = # include #endif -qboolean is_server = true; server_static_t svs; #ifdef __alpha__ diff --git a/qw/source/sv_sys_win.c b/qw/source/sv_sys_win.c index c3e234cae..787bb891c 100644 --- a/qw/source/sv_sys_win.c +++ b/qw/source/sv_sys_win.c @@ -43,7 +43,6 @@ static __attribute__ ((used)) const char rcsid[] = #include "compat.h" #include "server.h" -qboolean is_server = true; qboolean WinNT; server_static_t svs; From cca9983a48b471d3bef6ed1cf2aeaedb28c7da69 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 3 Sep 2011 19:58:03 +0900 Subject: [PATCH 114/334] Clean up the startup file diffs. This also makes functionality consistent across the platforms, such as adding support for -dedicated to sdl based nq, and various timing calculations are now consistent. --- nq/source/sdl_link.c | 4 +- nq/source/sys_sdl.c | 66 +++++++++-------- nq/source/sys_unix.c | 26 +++---- nq/source/sys_unixd.c | 16 ++-- nq/source/sys_win.c | 157 ++++++++++++++++++++-------------------- nq/source/sys_wind.c | 51 ++++++------- qw/source/cl_sys_sdl.c | 36 ++++----- qw/source/cl_sys_unix.c | 37 ++++------ qw/source/cl_sys_win.c | 60 ++++----------- qw/source/sdl_link.c | 4 +- qw/source/sv_sys_unix.c | 15 +--- qw/source/sv_sys_win.c | 13 +--- 12 files changed, 204 insertions(+), 281 deletions(-) diff --git a/nq/source/sdl_link.c b/nq/source/sdl_link.c index 6b72f3806..853dbe450 100644 --- a/nq/source/sdl_link.c +++ b/nq/source/sdl_link.c @@ -34,6 +34,6 @@ static __attribute__ ((used)) const char rcsid[] = "$Id$"; -extern int noconinput; +extern int qf_sdl_link; -static __attribute__ ((used)) int *const _noconinput = &noconinput; +static __attribute__ ((used)) int *const _qf_sdl_link = &qf_sdl_link; diff --git a/nq/source/sys_sdl.c b/nq/source/sys_sdl.c index fe9c38cab..ac22c3bf6 100644 --- a/nq/source/sys_sdl.c +++ b/nq/source/sys_sdl.c @@ -31,12 +31,6 @@ static __attribute__ ((used)) const char rcsid[] = "$Id$"; -#ifdef HAVE_CONIO_H -# include -#endif -#ifdef HAVE_IO_H -# include -#endif #ifdef HAVE_STRING_H # include #endif @@ -47,35 +41,29 @@ static __attribute__ ((used)) const char rcsid[] = # include #endif -#include -#include -#include -#include -#include - -#ifndef _WIN32 -# include +#ifdef HAVE_FCNTL_H +# include +#else +# include #endif #include #include -#include "QF/console.h" +#include "QF/cvar.h" #include "QF/qargs.h" #include "QF/sys.h" #include "client.h" -#include "compat.h" #include "host.h" -qboolean isDedicated = false; - -int noconinput; - #ifdef _WIN32 # include "winquake.h" #endif +int qf_sdl_link; +qboolean isDedicated = false; + static void startup (void) { @@ -103,7 +91,9 @@ static void shutdown_f (void) { #ifndef _WIN32 + // change stdin to blocking fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~O_NONBLOCK); + fflush (stdout); #endif } @@ -112,7 +102,7 @@ shutdown_f (void) #endif int -SDL_main (int c, char **v) +SDL_main (int argc, const char **argv) { double time, oldtime, newtime; @@ -120,29 +110,43 @@ SDL_main (int c, char **v) memset (&host_parms, 0, sizeof (host_parms)); - COM_InitArgv (c, (const char **)v); + COM_InitArgv (argc, argv); host_parms.argc = com_argc; host_parms.argv = com_argv; -#ifndef _WIN32 - noconinput = COM_CheckParm ("-noconinput"); - if (!noconinput) - fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) | O_NONBLOCK); -#endif + isDedicated = (COM_CheckParm ("-dedicated") != 0); Sys_RegisterShutdown (Host_Shutdown); Sys_RegisterShutdown (shutdown_f); Host_Init (); - oldtime = Sys_DoubleTime (); - while (1) { +#ifndef _WIN32 + if (!sys_nostdout->int_val) { + fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) | O_NONBLOCK); + Sys_Printf ("Quake -- Version %s\n", NQ_VERSION); + } +#endif + + oldtime = Sys_DoubleTime () - 0.1; + while (1) { // Main message loop // find time spent rendering last frame newtime = Sys_DoubleTime (); time = newtime - oldtime; + if (cls.state == ca_dedicated) { // play vcrfiles at max speed + if (time < sys_ticrate->value && (!vcrFile || recording)) { + usleep (1); + continue; // not time to run a server-only tic yet + } + time = sys_ticrate->value; + } + + if (time > sys_ticrate->value * 2) + oldtime = newtime; + else + oldtime += time; + Host_Frame (time); - oldtime = newtime; } - return 0; // shouldn't be reachable, but mingw gcc 3.1 is being weird } diff --git a/nq/source/sys_unix.c b/nq/source/sys_unix.c index 895c6aba1..057655355 100644 --- a/nq/source/sys_unix.c +++ b/nq/source/sys_unix.c @@ -29,7 +29,7 @@ # include "config.h" #endif -static __attribute__ ((used)) const char rcsid[] = +static __attribute__ ((used)) const char rcsid[] = "$Id$"; #ifdef HAVE_STRING_H @@ -42,14 +42,11 @@ static __attribute__ ((used)) const char rcsid[] = # include #endif -#include -#include -#include -#include -#include -#include -#include -#include +#ifdef HAVE_FCNTL_H +# include +#else +# include +#endif #include "QF/cvar.h" #include "QF/qargs.h" @@ -57,7 +54,6 @@ static __attribute__ ((used)) const char rcsid[] = #include "client.h" #include "host.h" -#include "server.h" qboolean isDedicated = false; @@ -66,24 +62,22 @@ shutdown_f (void) { // change stdin to blocking fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~O_NONBLOCK); + fflush (stdout); } int -main (int c, const char *v[]) +main (int argc, const char **argv) { - double time, oldtime, newtime; memset (&host_parms, 0, sizeof (host_parms)); - COM_InitArgv (c, v); + COM_InitArgv (argc, argv); host_parms.argc = com_argc; host_parms.argv = com_argv; isDedicated = (COM_CheckParm ("-dedicated") != 0); - fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) | O_NONBLOCK); - Sys_RegisterShutdown (Host_Shutdown); Sys_RegisterShutdown (shutdown_f); @@ -95,7 +89,7 @@ main (int c, const char *v[]) } oldtime = Sys_DoubleTime () - 0.1; - while (1) { + while (1) { // Main message loop // find time spent rendering last frame newtime = Sys_DoubleTime (); time = newtime - oldtime; diff --git a/nq/source/sys_unixd.c b/nq/source/sys_unixd.c index 9a19e326a..1cafac092 100644 --- a/nq/source/sys_unixd.c +++ b/nq/source/sys_unixd.c @@ -1,7 +1,7 @@ /* sys_unixd.c - @description@ + (description) Copyright (C) 1996-1997 Id Software, Inc. @@ -28,7 +28,7 @@ # include "config.h" #endif -static __attribute__ ((used)) const char rcsid[] = +static __attribute__ ((used)) const char rcsid[] = "$Id$"; #ifdef HAVE_STRING_H @@ -49,19 +49,16 @@ static __attribute__ ((used)) const char rcsid[] = #include "QF/cvar.h" #include "QF/qargs.h" -#include "QF/qtypes.h" #include "QF/sys.h" -#include "client.h" #include "host.h" qboolean isDedicated = true; -int nostdout = 0; - static void shutdown_f (void) { + // change stdin to blocking fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~O_NONBLOCK); fflush (stdout); } @@ -92,13 +89,13 @@ main (int argc, const char **argv) host_parms.argc = com_argc; host_parms.argv = com_argv; - fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) | O_NONBLOCK); - Sys_RegisterShutdown (Host_Shutdown); Sys_RegisterShutdown (shutdown_f); Host_Init (); + fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) | O_NONBLOCK); + oldtime = Sys_DoubleTime () - 0.1; while (1) { // Main message loop Sys_CheckInput (0, -1); @@ -108,7 +105,7 @@ main (int argc, const char **argv) time = newtime - oldtime; if (time < sys_ticrate->value) { usleep (1); - continue; + continue; // not time to run a server-only tic yet } time = sys_ticrate->value; @@ -119,5 +116,4 @@ main (int argc, const char **argv) Host_Frame (time); } - return true; // return success } diff --git a/nq/source/sys_win.c b/nq/source/sys_win.c index d9660d6c1..5261ff030 100644 --- a/nq/source/sys_win.c +++ b/nq/source/sys_win.c @@ -28,24 +28,22 @@ # include "config.h" #endif -static __attribute__ ((used)) const char rcsid[] = +static __attribute__ ((used)) const char rcsid[] = "$Id$"; #include "winquake.h" #include "win32/resources/resource.h" -#include "QF/console.h" #include "QF/cvar.h" #include "QF/qargs.h" -#include "QF/quakeio.h" #include "QF/screen.h" #include "QF/sys.h" #include "client.h" -#include "compat.h" -#include "game.h" #include "host.h" +qboolean isDedicated = false; + #define MINIMUM_WIN_MEMORY 0x0880000 #define MAXIMUM_WIN_MEMORY 0x1000000 @@ -59,11 +57,8 @@ qboolean WinNT; static double pfreq; static int lowshift; -qboolean isDedicated; HANDLE hinput, houtput; -static const char tracking_tag[] = "Clams & Mooses"; - static HANDLE tevent; // SYSTEM IO ================================================================== @@ -132,60 +127,11 @@ const char *argv[MAX_NUM_ARGVS]; static const char *empty_string = ""; HWND hwnd_dialog; -int WINAPI -WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, - int nCmdShow) +static void +init_handles (HINSTANCE hInstance) { - double time, oldtime, newtime; - MEMORYSTATUS lpBuffer; - static char cwd[1024]; RECT rect; - // previous instances do not exist in Win32 - if (hPrevInstance) - return 0; - - startup (); - - global_hInstance = hInstance; - global_nCmdShow = nCmdShow; - - lpBuffer.dwLength = sizeof (MEMORYSTATUS); - GlobalMemoryStatus (&lpBuffer); - - if (!GetCurrentDirectory (sizeof (cwd), cwd)) - Sys_Error ("Couldn't determine current directory"); - - if (cwd[strlen (cwd) - 1] == '/') - cwd[strlen (cwd) - 1] = 0; - - host_parms.argc = 1; - argv[0] = empty_string; - - while (*lpCmdLine && (host_parms.argc < MAX_NUM_ARGVS)) { - while (*lpCmdLine && ((*lpCmdLine <= 32) || (*lpCmdLine > 126))) - lpCmdLine++; - - if (*lpCmdLine) { - argv[host_parms.argc] = lpCmdLine; - host_parms.argc++; - - while (*lpCmdLine && ((*lpCmdLine > 32) && (*lpCmdLine <= 126))) - lpCmdLine++; - - if (*lpCmdLine) { - *lpCmdLine = 0; - lpCmdLine++; - } - } - } - - COM_InitArgv (host_parms.argc, argv); - host_parms.argc = com_argc; - host_parms.argv = com_argv; - - isDedicated = (COM_CheckParm ("-dedicated") != 0); - if (!isDedicated) { hwnd_dialog = CreateDialog (hInstance, MAKEINTRESOURCE (IDD_DIALOG1), NULL, NULL); @@ -210,26 +156,68 @@ WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, if (!tevent) Sys_Error ("Couldn't create event"); +} - Host_Init (); +int WINAPI +WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, + int nCmdShow) +{ + double time, oldtime, newtime; + MEMORYSTATUS lpBuffer; + int argc; + + // previous instances do not exist in Win32 + if (hPrevInstance) + return 0; + + startup (); + + global_hInstance = hInstance; + global_nCmdShow = nCmdShow; + + lpBuffer.dwLength = sizeof (MEMORYSTATUS); + GlobalMemoryStatus (&lpBuffer); + + argc = 1; + argv[0] = empty_string; + + while (*lpCmdLine && (argc < MAX_NUM_ARGVS)) { + while (*lpCmdLine && ((*lpCmdLine <= 32) || (*lpCmdLine > 126))) + lpCmdLine++; + + if (*lpCmdLine) { + argv[argc] = lpCmdLine; + argc++; + + while (*lpCmdLine && ((*lpCmdLine > 32) && (*lpCmdLine <= 126))) + lpCmdLine++; + + if (*lpCmdLine) { + *lpCmdLine = 0; + lpCmdLine++; + } + } + } + + memset (&host_parms, 0, sizeof (host_parms)); + + COM_InitArgv (argc, argv); + host_parms.argc = com_argc; + host_parms.argv = com_argv; + + isDedicated = (COM_CheckParm ("-dedicated") != 0); + + if (!isDedicated) + init_handles (hInstance); Sys_RegisterShutdown (Host_Shutdown); Sys_RegisterShutdown (shutdown_f); - oldtime = Sys_DoubleTime (); + Host_Init (); - // main window message loop - while (1) { - if (isDedicated) { - newtime = Sys_DoubleTime (); - time = newtime - oldtime; - - while (time < sys_ticrate->value) { - Sleep (1); - newtime = Sys_DoubleTime (); - time = newtime - oldtime; - } - } else { + oldtime = Sys_DoubleTime () - 0.1; + while (1) { // Main message loop + if (!isDedicated) { // yield the CPU for a little while when paused, minimized, or // not the focus if ((cl.paused && !ActiveApp) || Minimized) { @@ -238,15 +226,24 @@ WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, } else if (!ActiveApp) { SleepUntilInput (NOT_FOCUS_SLEEP); } + } + // find time spent rendering last frame + newtime = Sys_DoubleTime (); + time = newtime - oldtime; - newtime = Sys_DoubleTime (); - time = newtime - oldtime; + if (cls.state == ca_dedicated) { // play vcrfiles at max speed + if (time < sys_ticrate->value && (!vcrFile || recording)) { + Sleep (1); + continue; // not time to run a server-only tic yet + } + time = sys_ticrate->value; } - Host_Frame (time); - oldtime = newtime; - } + if (time > sys_ticrate->value * 2) + oldtime = newtime; + else + oldtime += time; - // return success of application - return TRUE; + Host_Frame (time); + } } diff --git a/nq/source/sys_wind.c b/nq/source/sys_wind.c index c85ee0076..91f0c67e0 100644 --- a/nq/source/sys_wind.c +++ b/nq/source/sys_wind.c @@ -1,7 +1,7 @@ /* sys_wind.c - @description@ + (description) Copyright (C) 1996-1997 Id Software, Inc. @@ -28,24 +28,18 @@ # include "config.h" #endif -static __attribute__ ((used)) const char rcsid[] = +static __attribute__ ((used)) const char rcsid[] = "$Id$"; -#include -#include -#include +#include "winquake.h" -#include "QF/console.h" #include "QF/cvar.h" #include "QF/qargs.h" #include "QF/sys.h" -#include "game.h" #include "host.h" -#include "winquake.h" - -qboolean isDedicated = true; +qboolean isDedicated = true; static void shutdown_f (void) @@ -55,16 +49,11 @@ shutdown_f (void) int main (int argc, const char **argv) { - double time, oldtime; + double time, oldtime, newtime; int i; memset (&host_parms, 0, sizeof (host_parms)); -#if 0 - _getcwd (cwd, sizeof (cwd)); - if (cwd[Q_strlen (cwd) - 1] == '\\') - cwd[Q_strlen (cwd) - 1] = 0; -#endif // dedicated server ONLY! for (i = 1; i < argc; i++) if (!strcmp (argv[i], "-dedicated")) @@ -72,8 +61,8 @@ main (int argc, const char **argv) if (i == argc) { const char **newargv; - newargv = malloc ((argc + 2) * sizeof (*newargv)); - memcpy (newargv, argv, argc * 4); + newargv = malloc ((argc + 2) * sizeof (char *)); + memcpy (newargv, argv, argc * sizeof (char *)); newargv[argc++] = "-dedicated"; newargv[argc] = 0; argv = newargv; @@ -88,20 +77,22 @@ main (int argc, const char **argv) Host_Init (); - oldtime = Sys_DoubleTime (); - - /* main window message loop */ - while (1) { - time = Sys_DoubleTime (); - if (time - oldtime < sys_ticrate->value) { + oldtime = Sys_DoubleTime () - 0.1; + while (1) { // Main message loop + // find time spent rendering last frame + newtime = Sys_DoubleTime (); + time = newtime - oldtime; + if (time < sys_ticrate->value) { Sleep (1); - continue; + continue; // not time to run a server-only tic yet } + time = sys_ticrate->value; - Host_Frame (time - oldtime); - oldtime = time; + if (time > sys_ticrate->value * 2) + oldtime = newtime; + else + oldtime += time; + + Host_Frame (time); } - - /* return success of application */ - return TRUE; } diff --git a/qw/source/cl_sys_sdl.c b/qw/source/cl_sys_sdl.c index 912803538..9e23e7700 100644 --- a/qw/source/cl_sys_sdl.c +++ b/qw/source/cl_sys_sdl.c @@ -47,11 +47,11 @@ static __attribute__ ((used)) const char rcsid[] = # include #endif -#include -#include -#include -#include -#include +#ifdef HAVE_FCNTL_H +# include +#else +# include +#endif #ifndef _WIN32 # include @@ -60,20 +60,18 @@ static __attribute__ ((used)) const char rcsid[] = #include #include -#include "QF/console.h" #include "QF/qargs.h" #include "QF/sys.h" -#include "client.h" -#include "compat.h" #include "host.h" - -int noconinput; +#include "netchan.h" #ifdef _WIN32 # include "winquake.h" #endif +int qf_sdl_link; + static void startup (void) { @@ -98,10 +96,12 @@ startup (void) } static void -shutdown (void) +shutdown_f (void) { #ifndef _WIN32 + // change stdin to blocking fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~O_NONBLOCK); + fflush (stdout); #endif } @@ -110,7 +110,7 @@ shutdown (void) #endif int -SDL_main (int c, char **v) +SDL_main (int argc, const char **argv) { double time, oldtime, newtime; @@ -118,24 +118,21 @@ SDL_main (int c, char **v) memset (&host_parms, 0, sizeof (host_parms)); - COM_InitArgv (c, (const char **)v); + COM_InitArgv (argc, argv); host_parms.argc = com_argc; host_parms.argv = com_argv; -#ifndef _WIN32 - noconinput = COM_CheckParm ("-noconinput"); - if (!noconinput) + if (!COM_CheckParm ("-noconinput")) fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) | O_NONBLOCK); -#endif Sys_RegisterShutdown (Host_Shutdown); Sys_RegisterShutdown (Net_LogStop); - Sys_RegisterShutdown (shutdown); + Sys_RegisterShutdown (shutdown_f); Host_Init (); oldtime = Sys_DoubleTime (); - while (1) { + while (1) { // Main message loop // find time spent rendering last frame newtime = Sys_DoubleTime (); time = newtime - oldtime; @@ -143,5 +140,4 @@ SDL_main (int c, char **v) Host_Frame (time); oldtime = newtime; } - return 0; // shouldn't be reachable, but mingw gcc 3.1 is being weird } diff --git a/qw/source/cl_sys_unix.c b/qw/source/cl_sys_unix.c index d5fdb3623..866957df4 100644 --- a/qw/source/cl_sys_unix.c +++ b/qw/source/cl_sys_unix.c @@ -29,7 +29,7 @@ # include "config.h" #endif -static __attribute__ ((used)) const char rcsid[] = +static __attribute__ ((used)) const char rcsid[] = "$Id$"; #ifdef HAVE_STRING_H @@ -42,59 +42,48 @@ static __attribute__ ((used)) const char rcsid[] = # include #endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#ifdef HAVE_FCNTL_H +# include +#else +# include +#endif -#include "QF/console.h" #include "QF/qargs.h" #include "QF/sys.h" #include "host.h" #include "netchan.h" -int noconinput = 0; - static void -shutdown (void) +shutdown_f (void) { // change stdin to blocking fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~O_NONBLOCK); + fflush (stdout); } -int skipframes; - int -main (int c, const char *v[]) +main (int argc, const char **argv) { -// static char cwd[1024]; double time, oldtime, newtime; memset (&host_parms, 0, sizeof (host_parms)); - COM_InitArgv (c, v); + COM_InitArgv (argc, argv); host_parms.argc = com_argc; host_parms.argv = com_argv; - noconinput = COM_CheckParm ("-noconinput"); - if (!noconinput) + if (!COM_CheckParm ("-noconinput")) fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) | O_NONBLOCK); Sys_RegisterShutdown (Host_Shutdown); Sys_RegisterShutdown (Net_LogStop); - Sys_RegisterShutdown (shutdown); + Sys_RegisterShutdown (shutdown_f); Host_Init (); oldtime = Sys_DoubleTime (); - while (1) { + while (1) { // Main message loop // find time spent rendering last frame newtime = Sys_DoubleTime (); time = newtime - oldtime; diff --git a/qw/source/cl_sys_win.c b/qw/source/cl_sys_win.c index d1502e5df..c6b18f418 100644 --- a/qw/source/cl_sys_win.c +++ b/qw/source/cl_sys_win.c @@ -28,33 +28,17 @@ # include "config.h" #endif -static __attribute__ ((used)) const char rcsid[] = +static __attribute__ ((used)) const char rcsid[] = "$Id$"; -#ifdef HAVE_CONIO_H -# include -#endif -#ifdef HAVE_IO_H -# include -#endif - -#include -#include -#include -#include #include "winquake.h" #include "QF/qargs.h" #include "QF/screen.h" -#include "QF/sound.h" #include "QF/sys.h" -#include "QF/vid.h" #include "client.h" -#include "compat.h" #include "host.h" -#include "netchan.h" -#include "win32/resources/resource.h" #define MAXIMUM_WIN_MEMORY 0x1000000 #define MINIMUM_WIN_MEMORY 0x0c00000 @@ -112,7 +96,7 @@ startup (void) } static void -shutdown (void) +shutdown_f (void) { if (tevent) CloseHandle (tevent); @@ -129,18 +113,17 @@ SleepUntilInput (int time) HINSTANCE global_hInstance; int global_nCmdShow; -const char *argv[MAX_NUM_ARGVS]; static const char *empty_string = ""; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { -// MSG msg; - static char cwd[1024]; - double time, oldtime, newtime; + int argc; + const char *argv[MAX_NUM_ARGVS]; + double time, oldtime, newtime; #ifdef SPLASH_SCREEN - RECT rect; + RECT rect; #endif // previous instances do not exist in Win32 @@ -152,22 +135,16 @@ WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, global_hInstance = hInstance; global_nCmdShow = nCmdShow; - if (!GetCurrentDirectory (sizeof (cwd), cwd)) - Sys_Error ("Couldn't determine current directory"); - - if (cwd[strlen (cwd) - 1] == '/') - cwd[strlen (cwd) - 1] = 0; - - host_parms.argc = 1; + argc = 1; argv[0] = empty_string; - while (*lpCmdLine && (host_parms.argc < MAX_NUM_ARGVS)) { + while (*lpCmdLine && (argc < MAX_NUM_ARGVS)) { while (*lpCmdLine && ((*lpCmdLine <= 32) || (*lpCmdLine > 126))) lpCmdLine++; if (*lpCmdLine) { - argv[host_parms.argc] = lpCmdLine; - host_parms.argc++; + argv[argc] = lpCmdLine; + argc++; while (*lpCmdLine && ((*lpCmdLine > 32) && (*lpCmdLine <= 126))) lpCmdLine++; @@ -179,7 +156,7 @@ WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, } } - COM_InitArgv (host_parms.argc, argv); + COM_InitArgv (argc, argv); host_parms.argc = com_argc; host_parms.argv = com_argv; @@ -207,17 +184,14 @@ WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, if (!tevent) Sys_Error ("Couldn't create event"); - Sys_Printf ("Host_Init\n"); - Host_Init (); - Sys_RegisterShutdown (Host_Shutdown); Sys_RegisterShutdown (Net_LogStop); - Sys_RegisterShutdown (shutdown); + Sys_RegisterShutdown (shutdown_f); + + Host_Init (); oldtime = Sys_DoubleTime (); - - // main window message loop - while (1) { + while (1) { // Main message loop // yield CPU for a little bit when paused, minimized, or not the focus if ((cl.paused && (!ActiveApp)) || Minimized) { SleepUntilInput (PAUSE_SLEEP); @@ -228,10 +202,8 @@ WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, newtime = Sys_DoubleTime (); time = newtime - oldtime; + Host_Frame (time); oldtime = newtime; } - - // return success of application - return TRUE; } diff --git a/qw/source/sdl_link.c b/qw/source/sdl_link.c index 6b72f3806..c96610fac 100644 --- a/qw/source/sdl_link.c +++ b/qw/source/sdl_link.c @@ -34,6 +34,6 @@ static __attribute__ ((used)) const char rcsid[] = "$Id$"; -extern int noconinput; +extern int qf_sdl_link; -static __attribute__ ((used)) int *const _noconinput = &noconinput; +static __attribute__ ((used)) int *const _sdl_link = &qf_sdl_link; diff --git a/qw/source/sv_sys_unix.c b/qw/source/sv_sys_unix.c index 2f2d5ff3b..c61ffd44b 100644 --- a/qw/source/sv_sys_unix.c +++ b/qw/source/sv_sys_unix.c @@ -29,7 +29,7 @@ # include "config.h" #endif -static __attribute__ ((used)) const char rcsid[] = +static __attribute__ ((used)) const char rcsid[] = "$Id$"; #ifdef HAVE_STRING_H @@ -42,13 +42,6 @@ static __attribute__ ((used)) const char rcsid[] = # include #endif -#include -#include -#include -#include -#include -#include - #include "QF/cvar.h" #include "QF/qargs.h" #include "QF/sys.h" @@ -118,7 +111,7 @@ startup (void) } int -main (int argc, const char *argv[]) +main (int argc, const char **argv) { double time, oldtime, newtime; @@ -137,9 +130,8 @@ main (int argc, const char *argv[]) // run one frame immediately for first heartbeat SV_Frame (0.1); - // main loop oldtime = Sys_DoubleTime () - 0.1; - while (1) { + while (1) { // Main message loop Sys_CheckInput (!svs.num_clients, net_socket); // find time passed since last cycle @@ -154,5 +146,4 @@ main (int argc, const char *argv[]) if (sys_extrasleep->int_val) usleep (sys_extrasleep->int_val); } - return 1; } diff --git a/qw/source/sv_sys_win.c b/qw/source/sv_sys_win.c index 787bb891c..89880a22f 100644 --- a/qw/source/sv_sys_win.c +++ b/qw/source/sv_sys_win.c @@ -28,7 +28,7 @@ # include "config.h" #endif -static __attribute__ ((used)) const char rcsid[] = +static __attribute__ ((used)) const char rcsid[] = "$Id$"; #include "winquake.h" @@ -36,11 +36,9 @@ static __attribute__ ((used)) const char rcsid[] = #include #include "QF/cvar.h" -#include "QF/info.h" #include "QF/qargs.h" #include "QF/sys.h" -#include "compat.h" #include "server.h" qboolean WinNT; @@ -70,12 +68,10 @@ startup (void) WinNT = false; } -char *newargv[256]; - int main (int argc, const char **argv) { - double newtime, time, oldtime; + double time, oldtime, newtime; startup (); @@ -105,9 +101,8 @@ main (int argc, const char **argv) // run one frame immediately for first heartbeat SV_Frame (0.1); - // main loop oldtime = Sys_DoubleTime () - 0.1; - while (1) { + while (1) { // Main message loop Sys_CheckInput (!svs.num_clients, net_socket); // find time passed since last cycle @@ -117,6 +112,4 @@ main (int argc, const char **argv) SV_Frame (time); } - - return true; } From dcbe23b3d3fc79cf5d1de401abad889af3cda046 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 4 Sep 2011 20:32:57 +0900 Subject: [PATCH 115/334] Abandon the runequake stuff for now. --- nq/source/sv_pr_cmds.c | 98 ------------------------------------------ 1 file changed, 98 deletions(-) diff --git a/nq/source/sv_pr_cmds.c b/nq/source/sv_pr_cmds.c index ae4a75643..d3e740677 100644 --- a/nq/source/sv_pr_cmds.c +++ b/nq/source/sv_pr_cmds.c @@ -1429,99 +1429,6 @@ PF_checkextension (progs_t *pr) R_FLOAT (pr) = 0; // FIXME: make this function actually useful } -// integer (entity client) CL_Active -static void -PF_CL_Active (progs_t *pr) -{ - client_t *client; - edict_t *ent; - int i; - - ent = P_EDICT (pr, 0); - i = NUM_FOR_EDICT (pr, ent); - if (i < 1 || i > svs.maxclients) - PR_RunError (pr, "Entity is not a client"); - - client = svs.clients + (i - 1); - R_INT (pr) = client->active; -} - -// vector (entity client) CL_Cmd -static void -PF_CL_Cmd (progs_t *pr) -{ - client_t *client; - edict_t *ent; - int i; - - ent = P_EDICT (pr, 0); - i = NUM_FOR_EDICT (pr, ent); - if (i < 1 || i > svs.maxclients) - PR_RunError (pr, "Entity is not a client"); - - client = svs.clients + (i - 1); - R_VECTOR (pr)[0] = client->cmd.forwardmove; - R_VECTOR (pr)[1] = client->cmd.sidemove; - R_VECTOR (pr)[2] = client->cmd.upmove; -} - -// integer (entity client) CL_Colors -static void -PF_CL_Colors (progs_t *pr) -{ - client_t *client; - edict_t *ent; - int i; - - ent = P_EDICT (pr, 0); - i = NUM_FOR_EDICT (pr, ent); - if (i < 1 || i > svs.maxclients) - PR_RunError (pr, "Entity is not a client"); - - client = svs.clients + (i - 1); - R_INT (pr) = client->colors; -} - -// integer (entity client) CL_Ping -static void -PF_CL_Ping (progs_t *pr) -{ - client_t *client; - edict_t *ent; - int i; - float ping = 0.0; - - ent = P_EDICT (pr, 0); - i = NUM_FOR_EDICT (pr, ent); - if (i < 1 || i > svs.maxclients) - PR_RunError (pr, "Entity is not a client"); - - client = svs.clients + (i - 1); - - for (i = 0; i < NUM_PING_TIMES; i++) - ping += client->ping_times[i] * 1000; - - ping = floor (ping / 16); - R_INT (pr) = ping; -} - -// string (entity client) CL_Address -static void -PF_CL_Address (progs_t *pr) -{ - client_t *client; - edict_t *ent; - int i; - - ent = P_EDICT (pr, 0); - i = NUM_FOR_EDICT (pr, ent); - if (i < 1 || i > svs.maxclients) - PR_RunError (pr, "Entity is not a client"); - - client = svs.clients + (i - 1); - RETURN_STRING (pr, client->netconnection->address); -} - #define QF (PR_RANGE_QF << PR_RANGE_SHIFT) | static builtin_t builtins[] = { @@ -1582,11 +1489,6 @@ static builtin_t builtins[] = { {"EntityParseFunction", ED_EntityParseFunction, -1}, - {"CL_Active", PF_CL_Active, -1}, - {"CL_Cmd", PF_CL_Cmd, -1}, - {"CL_Colors", PF_CL_Colors, -1}, - {"CL_Ping", PF_CL_Ping, -1}, - {"CL_Address", PF_CL_Address, -1}, {0} }; From e1b6f5034533cf76c964abe2b88347734612bf7d Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 4 Sep 2011 20:34:21 +0900 Subject: [PATCH 116/334] Clean up the diffs a bit between qw and nq sv_pr_cmds Add some missing functions to nq. In qw, Sys_Printf is mapped to SV_Printf, so no harm there. --- nq/include/sv_pr_cmds.h | 70 ---------- nq/source/sv_pr_cmds.c | 278 ++++++++++++++++++++++++---------------- nq/source/sys_unixd.c | 2 +- qw/source/sv_pr_cmds.c | 81 ++++++------ 4 files changed, 204 insertions(+), 227 deletions(-) diff --git a/nq/include/sv_pr_cmds.h b/nq/include/sv_pr_cmds.h index 9b7dfb3aa..2ab308feb 100644 --- a/nq/include/sv_pr_cmds.h +++ b/nq/include/sv_pr_cmds.h @@ -32,76 +32,6 @@ #ifndef __sv_pr_cmds_h #define __sv_pr_cmds_h -void PF_error (progs_t * pr); -void PF_objerror (progs_t * pr); -void PF_makevectors (progs_t * pr); -void PF_setorigin (progs_t * pr); -void PF_setsize (progs_t * pr); -void PF_setmodel (progs_t * pr); -void PF_bprint (progs_t * pr); -void PF_sprint (progs_t * pr); -void PF_centerprint (progs_t * pr); -void PF_normalize (progs_t * pr); -void PF_vlen (progs_t * pr); -void PF_vectoyaw (progs_t * pr); -void PF_vectoangles (progs_t * pr); -void PF_random (progs_t * pr); -void PF_particle (progs_t * pr); -void PF_ambientsound (progs_t * pr); -void PF_sound (progs_t * pr); -void PF_break (progs_t * pr); -void PF_traceline (progs_t * pr); -void PF_TraceToss (progs_t * pr); -void PF_checkpos (progs_t * pr); -int PF_newcheckclient (progs_t * pr, int check); -void PF_checkclient (progs_t * pr); -void PF_stuffcmd (progs_t * pr); -void PF_localcmd (progs_t * pr); -void PF_cvar (progs_t * pr); -void PF_cvar_set (progs_t * pr); -void PF_findradius (progs_t * pr); -void PF_dprint (progs_t * pr); -void PF_ftos (progs_t * pr); -void PF_fabs (progs_t * pr); -void PF_vtos (progs_t * pr); -void PF_etos (progs_t * pr); -void PF_Spawn (progs_t * pr); -void PF_Remove (progs_t * pr); -void PF_Find (progs_t * pr); -void PF_precache_file (progs_t * pr); -void PF_precache_sound (progs_t * pr); -void PF_precache_model (progs_t * pr); -void PF_coredump (progs_t * pr); -void PF_traceon (progs_t * pr); -void PF_traceoff (progs_t * pr); -void PF_eprint (progs_t * pr); -void PF_walkmove (progs_t * pr); -void PF_droptofloor (progs_t * pr); -void PF_lightstyle (progs_t * pr); -void PF_rint (progs_t * pr); -void PF_floor (progs_t * pr); -void PF_ceil (progs_t * pr); -void PF_checkbottom (progs_t * pr); -void PF_pointcontents (progs_t * pr); -void PF_nextent (progs_t * pr); -void PF_aim (progs_t * pr); void PF_changeyaw (progs_t * pr); -void PF_changepitch (progs_t * pr); -void PF_WriteByte (progs_t * pr); -void PF_WriteChar (progs_t * pr); -void PF_WriteShort (progs_t * pr); -void PF_WriteLong (progs_t * pr); -void PF_WriteAngle (progs_t * pr); -void PF_WriteCoord (progs_t * pr); -void PF_WriteString (progs_t * pr); -void PF_WriteEntity (progs_t * pr); -void PF_makestatic (progs_t * pr); -void PF_setspawnparms (progs_t * pr); -void PF_changelevel (progs_t * pr); -void PF_WaterMove (progs_t * pr); -void PF_sin (progs_t * pr); -void PF_cos (progs_t * pr); -void PF_sqrt (progs_t * pr); -void PF_Fixme (progs_t * pr); #endif // __sv_pr_cmds_h diff --git a/nq/source/sv_pr_cmds.c b/nq/source/sv_pr_cmds.c index d3e740677..852a92ea7 100644 --- a/nq/source/sv_pr_cmds.c +++ b/nq/source/sv_pr_cmds.c @@ -28,7 +28,7 @@ # include "config.h" #endif -static __attribute__ ((used)) const char rcsid[] = +static __attribute__ ((used)) const char rcsid[] = "$Id$"; #ifdef HAVE_STRING_H @@ -37,6 +37,7 @@ static __attribute__ ((used)) const char rcsid[] = #ifdef HAVE_STRINGS_H # include #endif +#include #include "QF/cbuf.h" #include "QF/clip_hull.h" @@ -65,7 +66,7 @@ static __attribute__ ((used)) const char rcsid[] = error (value) // void (string e) error */ -void +static void PF_error (progs_t *pr) { const char *s; @@ -89,7 +90,7 @@ PF_error (progs_t *pr) objerror (value) // void (string e) objerror */ -void +static void PF_objerror (progs_t *pr) { const char *s; @@ -109,9 +110,9 @@ PF_objerror (progs_t *pr) PF_makevectors Writes new values for v_forward, v_up, and v_right based on angles - void (entity e) makevectors + void (vector angles) makevectors */ -void +static void PF_makevectors (progs_t *pr) { AngleVectors (P_VECTOR (pr, 0), *sv_globals.v_forward, @@ -130,7 +131,7 @@ PF_makevectors (progs_t *pr) setorigin (entity, origin) // void (entity e, vector o) setorigin */ -void +static void PF_setorigin (progs_t *pr) { edict_t *e; @@ -220,7 +221,7 @@ SetMinMaxSize (progs_t *pr, edict_t *e, const vec3_t min, const vec3_t max, setsize (entity, minvector, maxvector) // void (entity e, vector min, vector max) setsize */ -void +static void PF_setsize (progs_t *pr) { edict_t *e; @@ -238,7 +239,7 @@ PF_setsize (progs_t *pr) setmodel (entity, model) // void (entity e, string m) setmodel */ -void +static void PF_setmodel (progs_t *pr) { edict_t *e; @@ -258,9 +259,9 @@ PF_setmodel (progs_t *pr) PR_RunError (pr, "no precache: %s\n", m); SVstring (e, model) = PR_SetString (pr, m); - SVfloat (e, modelindex) = i; // SV_ModelIndex (m); + SVfloat (e, modelindex) = i; - mod = sv.models[(int) SVfloat (e, modelindex)]; // Mod_ForName (m, true); + mod = sv.models[i]; if (mod) { // FIXME disabled for now as setting clipmins/maxs is currently @@ -282,7 +283,7 @@ PF_setmodel (progs_t *pr) bprint (value) // void (string s) bprint */ -void +static void PF_bprint (progs_t *pr) { const char *s; @@ -299,7 +300,7 @@ PF_bprint (progs_t *pr) sprint (clientent, value) // void (entity client, string s) sprint */ -void +static void PF_sprint (progs_t *pr) { const char *s; @@ -328,7 +329,7 @@ PF_sprint (progs_t *pr) centerprint (clientent, value) // void (...) centerprint */ -void +static void PF_centerprint (progs_t *pr) { const char *s; @@ -350,7 +351,7 @@ PF_centerprint (progs_t *pr) } // void (vector o, vector d, float color, float count) particle -void +static void PF_particle (progs_t *pr) { float *org, *dir; @@ -368,7 +369,7 @@ PF_particle (progs_t *pr) PF_ambientsound // void (vector pos, string samp, float vol, float atten) ambientsound */ -void +static void PF_ambientsound (progs_t *pr) { const char **check; @@ -424,7 +425,7 @@ PF_ambientsound (progs_t *pr) Larger attenuations will drop off. // void (entity e, float chan, string samp) sound */ -void +static void PF_sound (progs_t *pr) { const char *sample; @@ -458,7 +459,7 @@ PF_sound (progs_t *pr) traceline (vector1, vector2, tryents) // float (vector v1, vector v2, float tryents) traceline */ -void +static void PF_traceline (progs_t *pr) { float *v1, *v2; @@ -488,6 +489,45 @@ PF_traceline (progs_t *pr) *sv_globals.trace_ent = EDICT_TO_PROG (pr, sv.edicts); } +/* + PF_tracebox + // void (vector start, vector mins, vector maxs, vector end, float type, + // entity passent) tracebox + + Wrapper around SV_Move, this makes PF_movetoground and PF_traceline + redundant. +*/ +static void +PF_tracebox (progs_t *pr) +{ + edict_t *ent; + float *start, *end, *mins, *maxs; + int type; + trace_t trace; + + start = P_VECTOR (pr, 0); + mins = P_VECTOR (pr, 1); + maxs = P_VECTOR (pr, 2); + end = P_VECTOR (pr, 3); + type = P_FLOAT (pr, 4); + ent = P_EDICT (pr, 5); + + trace = SV_Move (start, mins, maxs, end, type, ent); + + *sv_globals.trace_allsolid = trace.allsolid; + *sv_globals.trace_startsolid = trace.startsolid; + *sv_globals.trace_fraction = trace.fraction; + *sv_globals.trace_inwater = trace.inwater; + *sv_globals.trace_inopen = trace.inopen; + VectorCopy (trace.endpos, *sv_globals.trace_endpos); + VectorCopy (trace.plane.normal, *sv_globals.trace_plane_normal); + *sv_globals.trace_plane_dist = trace.plane.dist; + if (trace.ent) + *sv_globals.trace_ent = EDICT_TO_PROG (pr, trace.ent); + else + *sv_globals.trace_ent = EDICT_TO_PROG (pr, sv.edicts); +} + /* PF_checkpos @@ -496,14 +536,14 @@ PF_traceline (progs_t *pr) FIXME: make work... scalar checkpos (entity, vector) */ -void +static void __attribute__ ((used)) PF_checkpos (progs_t *pr) { } byte checkpvs[MAX_MAP_LEAFS / 8]; -int +static int PF_newcheckclient (progs_t *pr, int check) { byte *pvs; @@ -538,6 +578,7 @@ PF_newcheckclient (progs_t *pr, int check) continue; if ((int) SVfloat (ent, flags) & FL_NOTARGET) continue; + // anything that is a client, or has a client as an enemy break; } @@ -566,9 +607,9 @@ int c_invis, c_notvis; it is not returned at all. name checkclient () -// entity () clientlist + // entity () clientlist */ -void +static void PF_checkclient (progs_t *pr) { edict_t *ent, *self; @@ -610,7 +651,7 @@ PF_checkclient (progs_t *pr) stuffcmd (clientent, value) // void (entity client, string s) stuffcmd */ -void +static void PF_stuffcmd (progs_t *pr) { const char *str; @@ -636,7 +677,7 @@ PF_stuffcmd (progs_t *pr) localcmd (string) // void (string s) localcmd */ -void +static void PF_localcmd (progs_t *pr) { const char *str; @@ -653,20 +694,20 @@ PF_localcmd (progs_t *pr) findradius (origin, radius) // entity (vector org, float rad) findradius */ -void +static void PF_findradius (progs_t *pr) { edict_t *ent, *chain; - float rad; - float *eorigin, *emins, *emaxs, *org; + float rsqr; + vec_t *emins, *emaxs, *org; int i, j; vec3_t eorg; chain = (edict_t *) sv.edicts; org = P_VECTOR (pr, 0); - rad = P_FLOAT (pr, 1); - rad *= rad; // Square early, sqrt never + rsqr = P_FLOAT (pr, 1); + rsqr *= rsqr; // Square early, sqrt never ent = NEXT_EDICT (pr, sv.edicts); for (i = 1; i < sv.num_edicts; i++, ent = NEXT_EDICT (pr, ent)) { @@ -674,12 +715,11 @@ PF_findradius (progs_t *pr) continue; if (SVfloat (ent, solid) == SOLID_NOT) continue; - eorigin = SVvector (ent, origin); - emins = SVvector (ent, mins); - emaxs = SVvector (ent, maxs); + emins = SVvector (ent, absmin); + emaxs = SVvector (ent, absmax); for (j = 0; j < 3; j++) - eorg[j] = org[j] - eorigin[j] - 0.5 * (emins[j] + emaxs[j]); - if (DotProduct (eorg, eorg) > rad) + eorg[j] = org[j] - 0.5 * (emins[j] + emaxs[j]); + if (DotProduct (eorg, eorg) > rsqr) continue; SVentity (ent, chain) = EDICT_TO_PROG (pr, chain); @@ -690,7 +730,7 @@ PF_findradius (progs_t *pr) } // entity () spawn -void +static void PF_Spawn (progs_t *pr) { edict_t *ed; @@ -700,7 +740,7 @@ PF_Spawn (progs_t *pr) } // void (entity e) remove -void +static void PF_Remove (progs_t *pr) { edict_t *ed; @@ -716,9 +756,43 @@ PR_CheckEmptyString (progs_t *pr, const char *s) PR_RunError (pr, "Bad string"); } +static void +do_precache (progs_t *pr, const char **cache, int max, const char *name, + const char *func) +{ + int i; + char *s; + + if (sv.state != ss_loading) + PR_RunError (pr, "%s: Precache can be done only in spawn functions", + func); + + PR_CheckEmptyString (pr, name); + + s = Hunk_TempAlloc (strlen (name) + 1); + for (i = 0; *name; i++, name++) { + int c = (byte) *name; + s[i] = tolower (c); + } + s[i] = 0; + + for (i = 0; i < MAX_SOUNDS; i++) { + if (!cache[i]) { + char *c = Hunk_Alloc (strlen (s) + 1); + strcpy (c, s); + cache[i] = c; // blah, const + Sys_MaskPrintf (SYS_DEV, "%s: %3d %s\n", func, i, s); + return; + } + if (!strcmp (cache[i], s)) + return; + } + PR_RunError (pr, "%s: overflow", func); +} + // string (string s) precache_file // string (string s) precache_file2 -void +static void PF_precache_file (progs_t *pr) { // precache_file is used only to copy files with qcc, it does nothing @@ -727,57 +801,22 @@ PF_precache_file (progs_t *pr) // void (string s) precache_sound // string (string s) precache_sound2 -void +static void PF_precache_sound (progs_t *pr) { - const char *s; - int i; - - if (sv.state != ss_loading) - PR_RunError (pr, "PF_Precache_*: Precache can be done only in spawn " - "functions"); - - s = P_GSTRING (pr, 0); + do_precache (pr, sv.sound_precache, MAX_SOUNDS, P_GSTRING (pr, 0), + "precache_sound"); R_INT (pr) = P_INT (pr, 0); - PR_CheckEmptyString (pr, s); - - for (i = 0; i < MAX_SOUNDS; i++) { - if (!sv.sound_precache[i]) { - sv.sound_precache[i] = s; - return; - } - if (!strcmp (sv.sound_precache[i], s)) - return; - } - PR_RunError (pr, "PF_precache_sound: overflow"); } // void (string s) precache_model // string (string s) precache_model2 -void +static void PF_precache_model (progs_t *pr) { - const char *s; - int i; - - if (sv.state != ss_loading) - PR_RunError (pr, "PF_Precache_*: Precache can be done only in spawn " - "functions"); - - s = P_GSTRING (pr, 0); + do_precache (pr, sv.model_precache, MAX_MODELS, P_GSTRING (pr, 0), + "precache_model"); R_INT (pr) = P_INT (pr, 0); - PR_CheckEmptyString (pr, s); - - for (i = 0; i < MAX_MODELS; i++) { - if (!sv.model_precache[i]) { - sv.model_precache[i] = s; - sv.models[i] = Mod_ForName (s, true); - return; - } - if (!strcmp (sv.model_precache[i], s)) - return; - } - PR_RunError (pr, "PF_precache_model: overflow"); } /* @@ -786,7 +825,7 @@ PF_precache_model (progs_t *pr) float (float yaw, float dist) walkmove // float (float yaw, float dist) walkmove */ -void +static void PF_walkmove (progs_t *pr) { edict_t *ent; @@ -824,7 +863,7 @@ PF_walkmove (progs_t *pr) void () droptofloor // float () droptofloor */ -void +static void PF_droptofloor (progs_t *pr) { edict_t *ent; @@ -856,11 +895,11 @@ PF_droptofloor (progs_t *pr) void (float style, string value) lightstyle // void (float style, string value) lightstyle */ -void +static void PF_lightstyle (progs_t *pr) { const char *val; - client_t *client; + client_t *cl; int style, j; style = P_FLOAT (pr, 0); @@ -873,16 +912,16 @@ PF_lightstyle (progs_t *pr) if (sv.state != ss_active) return; - for (j = 0, client = svs.clients; j < svs.maxclients; j++, client++) - if (client->active || client->spawned) { - MSG_WriteByte (&client->message, svc_lightstyle); - MSG_WriteByte (&client->message, style); - MSG_WriteString (&client->message, val); + for (j = 0, cl = svs.clients; j < svs.maxclients; j++, cl++) + if (cl->active || cl->spawned) { + MSG_WriteByte (&cl->message, svc_lightstyle); + MSG_WriteByte (&cl->message, style); + MSG_WriteString (&cl->message, val); } } // float (entity e) checkbottom -void +static void PF_checkbottom (progs_t *pr) { edict_t *ent; @@ -893,7 +932,7 @@ PF_checkbottom (progs_t *pr) } // float (vector v) pointcontents -void +static void PF_pointcontents (progs_t *pr) { float *v; @@ -912,7 +951,7 @@ cvar_t *sv_aim; vector aim (entity, missilespeed) // vector (entity e, float speed) aim */ -void +static void PF_aim (progs_t *pr) { edict_t *ent, *check, *bestent; @@ -924,7 +963,7 @@ PF_aim (progs_t *pr) ent = P_EDICT (pr, 0); speed = P_FLOAT (pr, 1); - (void)speed; //FIXME + (void) speed; //FIXME VectorCopy (SVvector (ent, origin), start); start[2] += 20; @@ -1077,42 +1116,42 @@ PF_WriteBytes (progs_t *pr) } // void (float to, float f) WriteByte -void +static void PF_WriteByte (progs_t *pr) { MSG_WriteByte (WriteDest (pr), P_FLOAT (pr, 1)); } // void (float to, float f) WriteChar -void +static void PF_WriteChar (progs_t *pr) { MSG_WriteByte (WriteDest (pr), P_FLOAT (pr, 1)); } // void (float to, float f) WriteShort -void +static void PF_WriteShort (progs_t *pr) { MSG_WriteShort (WriteDest (pr), P_FLOAT (pr, 1)); } // void (float to, float f) WriteLong -void +static void PF_WriteLong (progs_t *pr) { MSG_WriteLong (WriteDest (pr), P_FLOAT (pr, 1)); } - // void (float to, float f) WriteAngle -void +// void (float to, float f) WriteAngle +static void PF_WriteAngle (progs_t *pr) { MSG_WriteAngle (WriteDest (pr), P_FLOAT (pr, 1)); } // void (float to, float f) WriteCoord -void +static void PF_WriteCoord (progs_t *pr) { MSG_WriteCoord (WriteDest (pr), P_FLOAT (pr, 1)); @@ -1137,23 +1176,21 @@ PF_WriteCoordV (progs_t *pr) } // void (float to, string s) WriteString -void +static void PF_WriteString (progs_t *pr) { MSG_WriteString (WriteDest (pr), P_GSTRING (pr, 1)); } // void (float to, entity s) WriteEntity -void +static void PF_WriteEntity (progs_t *pr) { MSG_WriteShort (WriteDest (pr), P_EDICTNUM (pr, 1)); } -// ============================================================================ - // void (entity e) makestatic -void +static void PF_makestatic (progs_t *pr) { const char *model; @@ -1211,7 +1248,7 @@ nosend: } // void (entity e) setspawnparms -void +static void PF_setspawnparms (progs_t *pr) { client_t *client; @@ -1231,7 +1268,7 @@ PF_setspawnparms (progs_t *pr) } // void (string s) changelevel -void +static void PF_changelevel (progs_t *pr) { const char *s; @@ -1245,6 +1282,14 @@ PF_changelevel (progs_t *pr) Cbuf_AddText (host_cbuf, va ("changelevel %s\n", s)); } +// entity (entity ent) testentitypos +static void +PF_testentitypos (progs_t *pr) +{ + edict_t *ent = P_EDICT (pr, 0); + ent = SV_TestEntityPosition (ent); + RETURN_EDICT (pr, ent ? ent : sv.edicts); +} #define MAX_PF_HULLS 64 // FIXME make dynamic? clip_hull_t *pf_hull_list[MAX_PF_HULLS]; @@ -1416,12 +1461,6 @@ PF_rotate_bbox (progs_t *pr) } } -void -PF_Fixme (progs_t *pr) -{ - PR_RunError (pr, "unimplemented bulitin function called"); -} - // float () checkextension static void PF_checkextension (progs_t *pr) @@ -1436,29 +1475,38 @@ static builtin_t builtins[] = { {"setorigin", PF_setorigin, 2}, {"setmodel", PF_setmodel, 3}, {"setsize", PF_setsize, 4}, - {"fixme", PF_Fixme, 5}, + {"sound", PF_sound, 8}, + {"error", PF_error, 10}, {"objerror", PF_objerror, 11}, {"spawn", PF_Spawn, 14}, {"remove", PF_Remove, 15}, {"traceline", PF_traceline, 16}, {"checkclient", PF_checkclient, 17}, + {"precache_sound", PF_precache_sound, 19}, {"precache_model", PF_precache_model, 20}, {"stuffcmd", PF_stuffcmd, 21}, {"findradius", PF_findradius, 22}, {"bprint", PF_bprint, 23}, {"sprint", PF_sprint, 24}, + {"walkmove", PF_walkmove, 32}, + {"droptofloor", PF_droptofloor, 34}, {"lightstyle", PF_lightstyle, 35}, + {"checkbottom", PF_checkbottom, 40}, {"pointcontents", PF_pointcontents, 41}, + {"aim", PF_aim, 44}, + {"localcmd", PF_localcmd, 46}, + {"particle", PF_particle, 48}, {"changeyaw", PF_changeyaw, 49}, + {"writebyte", PF_WriteByte, 52}, {"WriteBytes", PF_WriteBytes, -1}, {"writechar", PF_WriteChar, 53}, @@ -1470,26 +1518,30 @@ static builtin_t builtins[] = { {"WriteAngleV", PF_WriteAngleV, -1}, {"writestring", PF_WriteString, 58}, {"writeentity", PF_WriteEntity, 59}, + {"movetogoal", SV_MoveToGoal, 67}, {"precache_file", PF_precache_file, 68}, {"makestatic", PF_makestatic, 69}, {"changelevel", PF_changelevel, 70}, + {"centerprint", PF_centerprint, 73}, {"ambientsound", PF_ambientsound, 74}, {"precache_model2", PF_precache_model, 75}, {"precache_sound2", PF_precache_sound, 76}, {"precache_file2", PF_precache_file, 77}, {"setspawnparms", PF_setspawnparms, 78}, + + {"testentitypos", PF_testentitypos, QF 92}, {"hullpointcontents", PF_hullpointcontents, QF 93}, {"getboxbounds", PF_getboxbounds, QF 94}, {"getboxhull", PF_getboxhull, QF 95}, {"freeboxhull", PF_freeboxhull, QF 96}, {"rotate_bbox", PF_rotate_bbox, QF 97}, + {"tracebox", PF_tracebox, QF 98}, {"checkextension", PF_checkextension, QF 99}, {"EntityParseFunction", ED_EntityParseFunction, -1}, - {0} }; @@ -1502,5 +1554,3 @@ SV_PR_Cmds_Init () PR_RegisterBuiltins (&sv_pr_state, builtins); } -// void (entity e, vector min, vector max) setabssize -// void (float step) movetogoal diff --git a/nq/source/sys_unixd.c b/nq/source/sys_unixd.c index 1cafac092..4e6e8d25c 100644 --- a/nq/source/sys_unixd.c +++ b/nq/source/sys_unixd.c @@ -40,12 +40,12 @@ static __attribute__ ((used)) const char rcsid[] = #ifdef HAVE_UNISTD_H # include #endif - #ifdef HAVE_FCNTL_H # include #else # include #endif +#include #include "QF/cvar.h" #include "QF/qargs.h" diff --git a/qw/source/sv_pr_cmds.c b/qw/source/sv_pr_cmds.c index 2da1365e3..8ddf1e363 100644 --- a/qw/source/sv_pr_cmds.c +++ b/qw/source/sv_pr_cmds.c @@ -28,7 +28,7 @@ # include "config.h" #endif -static __attribute__ ((used)) const char rcsid[] = +static __attribute__ ((used)) const char rcsid[] = "$Id$"; #ifdef HAVE_STRING_H @@ -44,7 +44,6 @@ static __attribute__ ((used)) const char rcsid[] = #include "QF/cmd.h" #include "QF/cvar.h" #include "QF/msg.h" -#include "QF/progs.h" #include "QF/ruamoko.h" #include "QF/sys.h" #include "QF/va.h" @@ -53,7 +52,6 @@ static __attribute__ ((used)) const char rcsid[] = #include "crudefile.h" #include "server.h" #include "sv_gib.h" -#include "sv_pr_cmds.h" #include "sv_progs.h" #include "sv_recorder.h" #include "world.h" @@ -77,7 +75,7 @@ PF_error (progs_t *pr) edict_t *ed; s = PF_VarString (pr, 0); - SV_Printf ("======SERVER ERROR in %s:\n%s\n", + Sys_Printf ("======SERVER ERROR in %s:\n%s\n", PR_GetString (pr, pr->pr_xfunction->descriptor->s_name), s); ed = PROG_TO_EDICT (pr, *sv_globals.self); ED_Print (pr, ed); @@ -101,7 +99,7 @@ PF_objerror (progs_t *pr) edict_t *ed; s = PF_VarString (pr, 0); - SV_Printf ("======OBJECT ERROR in %s:\n%s\n", + Sys_Printf ("======OBJECT ERROR in %s:\n%s\n", PR_GetString (pr, pr->pr_xfunction->descriptor->s_name), s); ed = PROG_TO_EDICT (pr, *sv_globals.self); ED_Print (pr, ed); @@ -114,8 +112,7 @@ PF_objerror (progs_t *pr) PF_makevectors Writes new values for v_forward, v_up, and v_right based on angles - makevectors (vector) - // void (entity e) makevectors + void (vector angles) makevectors */ static void PF_makevectors (progs_t *pr) @@ -174,7 +171,7 @@ PF_setsize (progs_t *pr) /* PF_setmodel - setmodel(entity, model) + setmodel (entity, model) // void (entity e, string m) setmodel Also sets size, mins, and maxs for inline bmodels */ @@ -249,7 +246,7 @@ PF_sprint (progs_t *pr) level = P_FLOAT (pr, 1); if (entnum < 1 || entnum > MAX_CLIENTS) { - SV_Printf ("tried to sprint to a non-client\n"); + Sys_Printf ("tried to sprint to a non-client\n"); return; } @@ -265,11 +262,11 @@ PF_sprint (progs_t *pr) /* PF_centerprint - // void (...) centerprint single print to a specific client centerprint (clientent, value) + // void (...) centerprint */ static void PF_centerprint (progs_t *pr) @@ -281,7 +278,7 @@ PF_centerprint (progs_t *pr) entnum = P_EDICTNUM (pr, 0); if (entnum < 1 || entnum > MAX_CLIENTS) { - SV_Printf ("tried to sprint to a non-client\n"); + Sys_Printf ("tried to sprint to a non-client\n"); return; } @@ -327,7 +324,7 @@ PF_ambientsound (progs_t *pr) break; if (!*check) { - SV_Printf ("no precache: %s\n", samp); + Sys_Printf ("no precache: %s\n", samp); return; } @@ -342,7 +339,6 @@ PF_ambientsound (progs_t *pr) /* PF_sound - // void (entity e, float chan, string samp) sound Each entity can have eight independant sound sources, like voice, weapon, feet, etc. @@ -352,6 +348,7 @@ PF_ambientsound (progs_t *pr) An attenuation of 0 will play full volume everywhere in the level. Larger attenuations will drop off. + // void (entity e, float chan, string samp) sound */ static void PF_sound (progs_t *pr) @@ -403,6 +400,7 @@ PF_traceline (progs_t *pr) VectorCopy (trace.endpos, *sv_globals.trace_endpos); VectorCopy (trace.plane.normal, *sv_globals.trace_plane_normal); *sv_globals.trace_plane_dist = trace.plane.dist; + if (trace.ent) *sv_globals.trace_ent = EDICT_TO_PROG (pr, trace.ent); else @@ -411,7 +409,8 @@ PF_traceline (progs_t *pr) /* PF_tracebox - // void (vector start, vector mins, vector maxs, vector end, float type, entity passent) tracebox + // void (vector start, vector mins, vector maxs, vector end, float type, + // entity passent) tracebox Wrapper around SV_Move, this makes PF_movetoground and PF_traceline redundant. @@ -419,10 +418,10 @@ PF_traceline (progs_t *pr) static void PF_tracebox (progs_t *pr) { - edict_t *ent; - float *start, *end, *mins, *maxs; - int type; - trace_t trace; + edict_t *ent; + float *start, *end, *mins, *maxs; + int type; + trace_t trace; start = P_VECTOR (pr, 0); mins = P_VECTOR (pr, 1); @@ -516,15 +515,17 @@ int c_invis, c_notvis; /* PF_checkclient - // entity () clientlist Returns a client (or object that has a client enemy) that would be a valid target. If there are more than one valid options, they are cycled each frame - If (self.origin + self.viewofs) is not in the PVS of the current target, it - is not returned at all. + If (self.origin + self.viewofs) is not in the PVS of the current target, + it is not returned at all. + + name checkclient () + // entity () clientlist */ static void PF_checkclient (progs_t *pr) @@ -620,11 +621,11 @@ PF_stuffcmd (progs_t *pr) /* PF_localcmd - // void (string s) localcmd Inserts text into the server console's execution buffer localcmd (string) + // void (string s) localcmd */ static void PF_localcmd (progs_t *pr) @@ -648,15 +649,15 @@ PF_findradius (progs_t *pr) { edict_t *ent, *chain; float rsqr; - //float *eorigin; - float *emins, *emaxs, *org; + vec_t *emins, *emaxs, *org; int i, j; vec3_t eorg; chain = (edict_t *) sv.edicts; org = P_VECTOR (pr, 0); - rsqr = P_FLOAT (pr, 1) * P_FLOAT (pr, 1); // Square early, sqrt never + rsqr = P_FLOAT (pr, 1); + rsqr *= rsqr; // Square early, sqrt never ent = NEXT_EDICT (pr, sv.edicts); for (i = 1; i < sv.num_edicts; i++, ent = NEXT_EDICT (pr, ent)) { @@ -665,14 +666,10 @@ PF_findradius (progs_t *pr) if (SVfloat (ent, solid) == SOLID_NOT && !((int) SVfloat (ent, flags) & FL_FINDABLE_NONSOLID)) continue; - //eorigin = SVvector (ent, origin); - //emins = SVvector (ent, mins); - //emaxs = SVvector (ent, maxs); emins = SVvector (ent, absmin); emaxs = SVvector (ent, absmax); for (j = 0; j < 3; j++) eorg[j] = org[j] - 0.5 * (emins[j] + emaxs[j]); - //eorg[j] = org[j] - eorigin[j] - 0.5 * (emins[j] + emaxs[j]); if (DotProduct (eorg, eorg) > rsqr) continue; @@ -705,14 +702,14 @@ PF_Remove (progs_t *pr) if (NUM_FOR_EDICT (pr, ed) < *pr->reserved_edicts) { if (pr_double_remove->int_val == 1) { PR_DumpState (pr); - SV_Printf ("Reserved entity remove\n"); + Sys_Printf ("Reserved entity remove\n"); } else // == 2 PR_RunError (pr, "Reserved entity remove\n"); } if (ed->free && pr_double_remove->int_val) { if (pr_double_remove->int_val == 1) { PR_DumpState (pr); - SV_Printf ("Double entity remove\n"); + Sys_Printf ("Double entity remove\n"); } else // == 2 PR_RunError (pr, "Double entity remove\n"); } @@ -734,7 +731,7 @@ do_precache (progs_t *pr, const char **cache, int max, const char *name, char *s; if (sv.state != ss_loading) - PR_RunError (pr, "%s: Precache can be done in only spawn functions", + PR_RunError (pr, "%s: Precache can be done only in spawn functions", func); PR_CheckEmptyString (pr, name); @@ -764,8 +761,8 @@ do_precache (progs_t *pr, const char **cache, int max, const char *name, // string (string s) precache_file2 static void PF_precache_file (progs_t *pr) -{ // precache_file is used only to copy - // files with qcc, it does nothing +{ + // precache_file is used only to copy files with qcc, it does nothing R_INT (pr) = P_INT (pr, 0); } @@ -784,10 +781,9 @@ PF_precache_sound (progs_t *pr) static void PF_precache_model (progs_t *pr) { - R_INT (pr) = P_INT (pr, 0); - do_precache (pr, sv.model_precache, MAX_MODELS, P_GSTRING (pr, 0), "precache_model"); + R_INT (pr) = P_INT (pr, 0); } /* @@ -925,10 +921,10 @@ cvar_t *sv_aim; /* PF_aim - // vector (entity e, float speed) aim Pick a vector for the player to shoot along vector aim (entity, missilespeed) + // vector (entity e, float speed) aim */ static void PF_aim (progs_t *pr) @@ -1021,9 +1017,9 @@ PF_aim (progs_t *pr) /* PF_changeyaw - // void () ChangeYaw This was a major timewaster in progs, so it was converted to C + // void () ChangeYaw */ void PF_changeyaw (progs_t *pr) @@ -1065,7 +1061,7 @@ PF_changeyaw (progs_t *pr) #define MSG_INIT 3 // write to the init string #define MSG_MULTICAST 4 // for multicast () -static sizebuf_t * +static sizebuf_t * WriteDest (progs_t *pr) { int dest; @@ -1971,6 +1967,7 @@ static builtin_t builtins[] = { {"aim", PF_aim, 44}, {"localcmd", PF_localcmd, 46}, + {"changeyaw", PF_changeyaw, 49}, {"writebyte", PF_WriteByte, 52}, @@ -2000,13 +1997,13 @@ static builtin_t builtins[] = { {"logfrag", PF_logfrag, 79}, {"infokey", PF_infokey, 80}, {"multicast", PF_multicast, 82}, + {"testentitypos", PF_testentitypos, QF 92}, {"hullpointcontents", PF_hullpointcontents, QF 93}, {"getboxbounds", PF_getboxbounds, QF 94}, {"getboxhull", PF_getboxhull, QF 95}, {"freeboxhull", PF_freeboxhull, QF 96}, {"rotate_bbox", PF_rotate_bbox, QF 97}, - {"tracebox", PF_tracebox, QF 98}, {"checkextension", PF_checkextension, QF 99}, {"setinfokey", PF_setinfokey, QF 102}, @@ -2025,6 +2022,7 @@ static builtin_t builtins[] = { {"SV_Spawn", PR_SV_Spawn, -1}, {"EntityParseFunction", ED_EntityParseFunction, -1}, + {0} }; @@ -2042,5 +2040,4 @@ SV_PR_Cmds_Init () bi->proc = PF_sv_cvar; PR_RegisterBuiltins (&sv_pr_state, builtins); -}; -// void (float step) movetogoal +} From 39190c5e2c673246c8c00b1825c8dfd7ee0677c7 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 4 Sep 2011 20:35:57 +0900 Subject: [PATCH 117/334] Remove an unnecessary include. Don't need that :P --- libs/net/nm/net_dgrm.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libs/net/nm/net_dgrm.c b/libs/net/nm/net_dgrm.c index d3d9b6f4b..d31eba0b4 100644 --- a/libs/net/nm/net_dgrm.c +++ b/libs/net/nm/net_dgrm.c @@ -52,7 +52,6 @@ static __attribute__ ((used)) const char rcsid[] = #include "../nq/include/client.h" #include "../nq/include/server.h" #include "../nq/include/game.h" -#include "../nq/include/sv_progs.h" // This is enables a simple IP banning mechanism #define BAN_TEST From f0a145a537f58163eebc7d82b151d6c07493e5fa Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 5 Sep 2011 09:45:13 +0900 Subject: [PATCH 118/334] Compress entity_state_t a little. Use byte and short instead of int. --- include/qw/protocol.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/qw/protocol.h b/include/qw/protocol.h index 315222716..c3a058dd4 100644 --- a/include/qw/protocol.h +++ b/include/qw/protocol.h @@ -307,11 +307,11 @@ typedef struct { unsigned int flags; // nolerp, etc vec3_t origin; vec3_t angles; - int modelindex; - int frame; - int colormap; - int skinnum; + unsigned short modelindex; + unsigned short frame; int effects; + byte colormap; + byte skinnum; // QSG 2 byte alpha; From 937ea854d6fea0f9bc85214cb8f0e642eb84e350 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 5 Sep 2011 11:30:04 +0900 Subject: [PATCH 119/334] Give QW NQ's explode-box jumping code. It seems that QW already allowed explode-box jumping, but this makes code a little more consistent. Still need to figure out what to do about the player physics code: the client prediction is wrong, though the server gets it right (before the change). --- qw/include/server.h | 2 ++ qw/source/sv_main.c | 1 + qw/source/sv_phys.c | 16 +++++++++++++++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/qw/include/server.h b/qw/include/server.h index 24b1b3a8b..0a17f8af2 100644 --- a/qw/include/server.h +++ b/qw/include/server.h @@ -537,6 +537,7 @@ void SV_SetMoveVars(void); struct trace_s; int SV_FlyMove (struct edict_s *ent, float time, struct trace_s *steptrace); struct trace_s SV_PushEntity (struct edict_s *ent, vec3_t push); +int SV_EntCanSupportJump (struct edict_s *ent); // // sv_send.c @@ -621,6 +622,7 @@ extern struct cvar_s *sv_timefmt; extern struct cvar_s *sv_phs; extern struct cvar_s *sv_maxvelocity; extern struct cvar_s *sv_gravity; +extern struct cvar_s *sv_jump_any; extern struct cvar_s *sv_aim; extern struct cvar_s *sv_stopspeed; extern struct cvar_s *sv_spectatormaxspeed; diff --git a/qw/source/sv_main.c b/qw/source/sv_main.c index fb1a77db9..b7bd606b0 100644 --- a/qw/source/sv_main.c +++ b/qw/source/sv_main.c @@ -2131,6 +2131,7 @@ SV_InitLocal (void) "clients"); sv_gravity = Cvar_Get ("sv_gravity", "800", CVAR_NONE, NULL, "Sets the global value for the amount of gravity"); + sv_jump_any = Cvar_Get ("sv_jump_any", "1", CVAR_NONE, NULL, "None"); sv_stopspeed = Cvar_Get ("sv_stopspeed", "100", CVAR_NONE, NULL, "Sets the value that determines how fast the " "player should come to a complete stop"); diff --git a/qw/source/sv_phys.c b/qw/source/sv_phys.c index 940dcc080..48b39b3ae 100644 --- a/qw/source/sv_phys.c +++ b/qw/source/sv_phys.c @@ -58,6 +58,7 @@ static __attribute__ ((used)) const char rcsid[] = */ cvar_t *sv_gravity; +cvar_t *sv_jump_any; cvar_t *sv_stopspeed; cvar_t *sv_maxspeed; cvar_t *sv_maxvelocity; @@ -211,6 +212,19 @@ ClipVelocity (vec3_t in, vec3_t normal, vec3_t out, float overbounce) return blocked; } +int +SV_EntCanSupportJump (edict_t *ent) +{ + int solid = SVfloat (ent, solid); + if (solid == SOLID_BSP) + return 1; + if (!sv_jump_any->int_val) + return 0; + if (solid == SOLID_NOT || solid == SOLID_SLIDEBOX) + return 0; + return 1; +} + #define MAX_CLIP_PLANES 5 /* @@ -271,7 +285,7 @@ SV_FlyMove (edict_t *ent, float time, trace_t *steptrace) if (trace.plane.normal[2] > 0.7) { blocked |= 1; // floor - if (SVfloat (trace.ent, solid) == SOLID_BSP) { + if (SV_EntCanSupportJump (trace.ent)) { SVfloat (ent, flags) = (int) SVfloat (ent, flags) | FL_ONGROUND; SVentity (ent, groundentity) = EDICT_TO_PROG (&sv_pr_state, From 9bd4bbee5298ad315fcd5163d08808014cdce45d Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 5 Sep 2011 11:47:48 +0900 Subject: [PATCH 120/334] Make sure tossed entities with upward velocity can always move. If a tossed entity has ONGROUND set, it won't move, but if it has an upward velocity, it can't possibly be ONGROUND, so clear the flag if the entity is moving upwards. --- nq/source/sv_phys.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nq/source/sv_phys.c b/nq/source/sv_phys.c index e65c8bc76..e95e3c714 100644 --- a/nq/source/sv_phys.c +++ b/nq/source/sv_phys.c @@ -673,6 +673,9 @@ SV_Physics_Toss (edict_t *ent) if (!SV_RunThink (ent)) return; + if (SVvector (ent, velocity)[2] > 0) + SVfloat (ent, flags) = (int) SVfloat (ent, flags) & ~FL_ONGROUND; + // if onground, return without moving if (((int) SVfloat (ent, flags) & FL_ONGROUND)) return; @@ -729,6 +732,7 @@ SV_Physics_Toss (edict_t *ent) This is also used for objects that have become still on the ground, but will fall if the floor is pulled out from under them. + FIXME: is this true? */ static void SV_Physics_Step (edict_t *ent) From 89ec14e0fc05892772289e46ec93ccea939731b1 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 5 Sep 2011 12:55:03 +0900 Subject: [PATCH 121/334] Make very tiny movements no-ops. This affects pushers in their think code. This makes NQ a little more like QW, but doesn't really seem to change much. --- nq/source/sv_phys.c | 13 +++++++++++-- nq/source/world.c | 2 +- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/nq/source/sv_phys.c b/nq/source/sv_phys.c index e95e3c714..e65cf4f88 100644 --- a/nq/source/sv_phys.c +++ b/nq/source/sv_phys.c @@ -411,7 +411,7 @@ SV_PushEntity (edict_t *ent, vec3_t push) } static qboolean -SV_Push (edict_t *pusher, vec3_t tmove, vec3_t amove) +SV_Push (edict_t *pusher, const vec3_t tmove, const vec3_t amove) { float solid_save; int num_moved, i, e; @@ -566,6 +566,8 @@ static void SV_Physics_Pusher (edict_t *ent) { float movetime, oldltime, thinktime; + float l; + vec3_t oldorg, move; oldltime = SVfloat (ent, ltime); @@ -583,13 +585,20 @@ SV_Physics_Pusher (edict_t *ent) } if (thinktime > oldltime && thinktime <= SVfloat (ent, ltime)) { + VectorCopy (SVvector (ent, origin), oldorg); SVfloat (ent, nextthink) = 0; *sv_globals.time = sv.time; sv_pr_think (ent); if (ent->free) return; - } + VectorSubtract (SVvector (ent, origin), oldorg, move); + l = VectorLength (move); + if (l > (1.0 / 64.0)) { + VectorCopy (oldorg, SVvector (ent, origin)); + SV_Push (ent, move, vec3_origin); //FIXME angle + } + } } /* diff --git a/nq/source/world.c b/nq/source/world.c index 7a1f024ac..2ae9aa700 100644 --- a/nq/source/world.c +++ b/nq/source/world.c @@ -645,7 +645,7 @@ SV_ClipMoveToEntity (edict_t *touched, const vec3_t start, // trace a line through the apropriate clipping hull MOD_TraceLine (hull, hull->firstclipnode, start_l, end_l, &trace); - // fix trace up by the rotation and offset + // fix up trace by the rotation and offset if (trace.fraction != 1) { if (rot) { vec_t t; From a3f0a559a52d839aff2d619753f7dd8db5376801 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 5 Sep 2011 16:27:54 +0900 Subject: [PATCH 122/334] Fix a segfault when centerprinting. The dstring wasn't getting initialized :/ --- qw/include/client.h | 2 ++ qw/source/cl_main.c | 3 +++ qw/source/cl_parse.c | 4 ---- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/qw/include/client.h b/qw/include/client.h index 722c4987a..837b6dfc9 100644 --- a/qw/include/client.h +++ b/qw/include/client.h @@ -381,4 +381,6 @@ void CL_RSShot_f (void); #define RSSHOT_WIDTH 320 #define RSSHOT_HEIGHT 200 +extern struct dstring_s *centerprint; + #endif // _CLIENT_H diff --git a/qw/source/cl_main.c b/qw/source/cl_main.c index f4d945e73..b4fbc38b9 100644 --- a/qw/source/cl_main.c +++ b/qw/source/cl_main.c @@ -433,6 +433,8 @@ CL_ClearState (void) // clear other arrays memset (cl_efrags, 0, sizeof (cl_efrags)); memset (r_lightstyle, 0, sizeof (r_lightstyle)); + + dstring_clearstr (centerprint); } /* @@ -1751,6 +1753,7 @@ Host_Init (void) pr_gametype = "quakeworld"; + centerprint = dstring_newstr (); cls.userinfo = Info_ParseString ("", MAX_INFO_STRING, 0); cls.servername = dstring_newstr (); cls.downloadtempname = dstring_newstr (); diff --git a/qw/source/cl_parse.c b/qw/source/cl_parse.c index 0c9243ae0..b80d53e1e 100644 --- a/qw/source/cl_parse.c +++ b/qw/source/cl_parse.c @@ -1217,10 +1217,6 @@ CL_ServerInfo (void) // movevars.ktjump = atof (value); // FIXME: need to set to 0.5 otherwise, outside of else structure } - if (!centerprint) - centerprint = dstring_newstr (); - else - dstring_clearstr (centerprint); } static void From 94362cc01080f1d327689da5446f9980a9973890 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 5 Sep 2011 18:10:02 +0900 Subject: [PATCH 123/334] Add macros to ease printing of vectors and quaternions. I got sick of having to pass all those parameters to printf. Let the compiler do it for me. --- include/QF/mathlib.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/QF/mathlib.h b/include/QF/mathlib.h index b16b6b70a..7fbf0e828 100644 --- a/include/QF/mathlib.h +++ b/include/QF/mathlib.h @@ -114,6 +114,9 @@ extern const vec_t * const quat_origin; (v)[2] = (v1)[2] * (1 - (b)) + (v2)[2] * (b); \ } while (0) +//For printf etc +#define VectorExpand(v) (v)[0], (v)[1], (v)[2] + #define QDotProduct(a,b) ((a)[0] * (b)[0] + (a)[1] * (b)[1] \ + (a)[2] * (b)[2] + (a)[3] * (b)[3]) #define QuatSubtract(a,b,c) \ @@ -196,6 +199,9 @@ extern const vec_t * const quat_origin; (v)[3] = (v1)[3] * (1 - (b)) + (v2)[3] * (b); \ } while (0) +//For printf etc +#define QuatExpand(q) (q)[0], (q)[1], (q)[2], (q)[3] + /* * VectorDistance, the distance between two points. * Yes, this is the same as sqrt(VectorSubtract then DotProduct), From 91f6b7f5554352eb827006ed8bd46d9e40fea81c Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 5 Sep 2011 20:50:30 +0900 Subject: [PATCH 124/334] Better use of Sys_Printf. --- libs/gamecode/engine/pr_debug.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/libs/gamecode/engine/pr_debug.c b/libs/gamecode/engine/pr_debug.c index 7eadc523d..a88c66051 100644 --- a/libs/gamecode/engine/pr_debug.c +++ b/libs/gamecode/engine/pr_debug.c @@ -1087,11 +1087,9 @@ ED_Print (progs_t *pr, edict_t *ed) PR_Error (pr, "ED_Print: Unhandled type %d", type); } - Sys_Printf ("%s", name); - l = strlen (name); - while (l++ < 15) - Sys_Printf (" "); - - Sys_Printf ("%s\n", value_string (pr, d->type, v)); + l = 15 - strlen (name); + if (l < 1) + l = 1; + Sys_Printf ("%s%*s%s\n", name, l, "", value_string (pr, d->type, v)); } } From 71be8510e55c7254a64e1f73122d29a73187366c Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 5 Sep 2011 20:51:10 +0900 Subject: [PATCH 125/334] Don't do anything when the message is empty. This clears up some fun valgrind noise in SV_Print. --- qw/source/sv_send.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/qw/source/sv_send.c b/qw/source/sv_send.c index c47669093..ec7b0ed6f 100644 --- a/qw/source/sv_send.c +++ b/qw/source/sv_send.c @@ -178,6 +178,8 @@ SV_Print (const char *fmt, va_list args) in = premsg; out = msg; + if (!*premsg) + return; // expand FFnickFF to nick do { switch ((byte) *in) { @@ -213,7 +215,7 @@ SV_Print (const char *fmt, va_list args) if (sv_redirected) { // Add to redirected message dstring_appendstr (&outputbuf, (char *) msg); } - if (!con_printf_no_log) { + if (*msg && !con_printf_no_log) { // We want to output to console and maybe logfile if (sv_timestamps && sv_timefmt && sv_timefmt->string && sv_timestamps->int_val && !pending) From e6e1b10c58ba37e218fd89579ca888aa7a2ac023 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 5 Sep 2011 21:05:09 +0900 Subject: [PATCH 126/334] Add support for rotating entities to QW. Same as the rotating entities in NQ. Unfortunately, I have some problems with certain entities doing really weird things during collisions. I'll sort that out later. --- include/qw/pmove.h | 1 + qw/source/cl_entparse.c | 3 ++ qw/source/pmovetst.c | 40 +++++++++++++++++++++++- qw/source/sv_phys.c | 47 ++++++++++++++++++++++------ qw/source/sv_user.c | 1 + qw/source/world.c | 68 ++++++++++++++++++++++++++++++++++++----- 6 files changed, 142 insertions(+), 18 deletions(-) diff --git a/include/qw/pmove.h b/include/qw/pmove.h index 606e7d176..ac5adb413 100644 --- a/include/qw/pmove.h +++ b/include/qw/pmove.h @@ -40,6 +40,7 @@ #define MAX_PHYSENTS (MAX_CLIENTS + MAX_PACKET_ENTITIES) typedef struct { vec3_t origin; + vec3_t angles; model_t *model; // only for bsp models vec3_t mins, maxs; // only for non-bsp models hull_t *hull; // hey, magic :) diff --git a/qw/source/cl_entparse.c b/qw/source/cl_entparse.c index 29e4ccecc..477af00f2 100644 --- a/qw/source/cl_entparse.c +++ b/qw/source/cl_entparse.c @@ -519,6 +519,7 @@ CL_SetSolidEntities (void) pmove.physents[0].model = cl.worldmodel; VectorZero (pmove.physents[0].origin); + VectorZero (pmove.physents[0].angles); pmove.physents[0].info = 0; pmove.numphysent = 1; @@ -543,6 +544,8 @@ CL_SetSolidEntities (void) cl.model_precache[state->modelindex]; VectorCopy (state->origin, pmove.physents[pmove.numphysent].origin); + VectorCopy (state->angles, + pmove.physents[pmove.numphysent].angles); pmove.numphysent++; } } diff --git a/qw/source/pmovetst.c b/qw/source/pmovetst.c index c368a3290..bca6f1bc5 100644 --- a/qw/source/pmovetst.c +++ b/qw/source/pmovetst.c @@ -214,6 +214,9 @@ PM_PlayerMove (const vec3_t start, const vec3_t end) trace_t trace, total; vec3_t maxs, mins, offset, start_l, end_l; vec3_t move[2]; + vec3_t forward, right, up; + int rot = 0; + vec3_t temp; // fill in a default trace memset (&total, 0, sizeof (trace_t)); @@ -249,6 +252,23 @@ PM_PlayerMove (const vec3_t start, const vec3_t end) VectorSubtract (start, offset, start_l); VectorSubtract (end, offset, end_l); + if (1 && pe->model && pe->model->type == mod_brush + && !VectorIsZero (pe->angles)) { + rot = 1; + AngleVectors (pe->angles, forward, right, up); + VectorNegate (right, right); // convert lhs to rhs + + VectorCopy (start_l, temp); + start_l[0] = DotProduct (temp, forward); + start_l[1] = DotProduct (temp, right); + start_l[2] = DotProduct (temp, up); + + VectorCopy (end_l, temp); + end_l[0] = DotProduct (temp, forward); + end_l[1] = DotProduct (temp, right); + end_l[2] = DotProduct (temp, up); + } + // fill in a default trace memset (&trace, 0, sizeof (trace_t)); @@ -289,7 +309,25 @@ PM_PlayerMove (const vec3_t start, const vec3_t end) // did we clip the move? if (trace.fraction < total.fraction) { - // fix trace up by the offset + // fix up trace by the offset + if (rot) { + vec_t t; + + // transpose the rotation matrix to get its inverse + t = forward[1]; forward[1] = right[0]; right[0] = t; + t = forward[2]; forward[2] = up[0]; up[0] = t; + t = right[2]; right[2] = up[1]; up[1] = t; + + VectorCopy (trace.endpos, temp); + trace.endpos[0] = DotProduct (temp, forward); + trace.endpos[1] = DotProduct (temp, right); + trace.endpos[2] = DotProduct (temp, up); + + VectorCopy (trace.plane.normal, temp); + trace.plane.normal[0] = DotProduct (temp, forward); + trace.plane.normal[1] = DotProduct (temp, right); + trace.plane.normal[2] = DotProduct (temp, up); + } VectorAdd (trace.endpos, offset, trace.endpos); total = trace; total.ent = (struct edict_s *) &pmove.physents[i]; diff --git a/qw/source/sv_phys.c b/qw/source/sv_phys.c index 48b39b3ae..7bed3f488 100644 --- a/qw/source/sv_phys.c +++ b/qw/source/sv_phys.c @@ -398,23 +398,35 @@ SV_PushEntity (edict_t *ent, vec3_t push) } static qboolean -SV_Push (edict_t *pusher, vec3_t move) +SV_Push (edict_t *pusher, const vec3_t tmove, const vec3_t amove) { float solid_save; int num_moved, i, e; edict_t *check, *block; edict_t **moved_edict; - vec3_t mins, maxs, pushorig; + vec3_t move, org, org2; + vec3_t mins, maxs, pushtorig, pushaorig; vec3_t *moved_from; + vec3_t forward = {1, 0, 0}; + vec3_t right = {0, -1, 0}; + vec3_t up = {0, 0, 1}; int mark; - VectorAdd (SVvector (pusher, absmin), move, mins); - VectorAdd (SVvector (pusher, absmax), move, maxs); + VectorAdd (SVvector (pusher, absmin), tmove, mins); + VectorAdd (SVvector (pusher, absmax), tmove, maxs); - VectorCopy (SVvector (pusher, origin), pushorig); + if (!VectorIsZero (amove)) { + vec3_t a; + VectorSubtract (vec3_origin, amove, a); + AngleVectors (a, forward, right, up); + } + + VectorCopy (SVvector (pusher, origin), pushtorig); + VectorCopy (SVvector (pusher, angles), pushaorig); // move the pusher to it's final position - VectorAdd (SVvector (pusher, origin), move, SVvector (pusher, origin)); + VectorAdd (SVvector (pusher, origin), tmove, SVvector (pusher, origin)); + VectorAdd (SVvector (pusher, angles), amove, SVvector (pusher, angles)); SV_LinkEdict (pusher, false); mark = Hunk_LowMark (); @@ -462,6 +474,15 @@ SV_Push (edict_t *pusher, vec3_t move) moved_edict[num_moved] = check; num_moved++; + // calculate destination position + VectorSubtract (SVvector (check, origin), + SVvector (pusher, origin), org); + org2[0] = DotProduct (org, forward); + org2[1] = -DotProduct (org, right); + org2[2] = DotProduct (org, up); + VectorSubtract (org2, org, move); + VectorAdd (move, tmove, move); + // try moving the contacted entity VectorAdd (SVvector (check, origin), move, SVvector (check, origin)); block = SV_TestEntityPosition (check); @@ -490,7 +511,8 @@ SV_Push (edict_t *pusher, vec3_t move) continue; } - VectorCopy (pushorig, SVvector (pusher, origin)); + VectorCopy (pushtorig, SVvector (pusher, origin)); + VectorCopy (pushaorig, SVvector (pusher, angles)); SV_LinkEdict (pusher, false); // if the pusher has a "blocked" function, call it @@ -501,6 +523,8 @@ SV_Push (edict_t *pusher, vec3_t move) // move back any entities we already moved for (i = 0; i < num_moved; i++) { VectorCopy (moved_from[i], SVvector (moved_edict[i], origin)); + VectorSubtract (SVvector (moved_edict[i], angles), amove, + SVvector (moved_edict[i], angles)); SV_LinkEdict (moved_edict[i], false); } Hunk_FreeToLowMark (mark); @@ -514,15 +538,18 @@ static void SV_PushMove (edict_t *pusher, float movetime) { vec3_t move; + vec3_t amove; - if (VectorIsZero (SVvector (pusher, velocity))) { + if (VectorIsZero (SVvector (pusher, velocity)) + && VectorIsZero (SVvector (pusher, avelocity))) { SVfloat (pusher, ltime) += movetime; return; } VectorScale (SVvector (pusher, velocity), movetime, move); + VectorScale (SVvector (pusher, avelocity), movetime, amove); - if (SV_Push (pusher, move)) + if (SV_Push (pusher, move, amove)) SVfloat (pusher, ltime) += movetime; } @@ -560,7 +587,7 @@ SV_Physics_Pusher (edict_t *ent) l = VectorLength (move); if (l > (1.0 / 64.0)) { VectorCopy (oldorg, SVvector (ent, origin)); - SV_Push (ent, move); + SV_Push (ent, move, vec3_origin); //FIXME angle } } } diff --git a/qw/source/sv_user.c b/qw/source/sv_user.c index bb32c293e..192ea77ac 100644 --- a/qw/source/sv_user.c +++ b/qw/source/sv_user.c @@ -1540,6 +1540,7 @@ AddLinksToPmove (areanode_t *node) pmove.numphysent++; VectorCopy (SVvector (check, origin), pe->origin); + VectorCopy (SVvector (check, angles), pe->angles); pe->info = NUM_FOR_EDICT (&sv_pr_state, check); if (sv_fields.rotated_bbox != -1 diff --git a/qw/source/world.c b/qw/source/world.c index f07d4ee6a..2ae9aa700 100644 --- a/qw/source/world.c +++ b/qw/source/world.c @@ -455,11 +455,25 @@ SV_LinkEdict (edict_t *ent, qboolean touch_triggers) if (ent->free) return; - // set the abs box - VectorAdd (SVvector (ent, origin), SVvector (ent, mins), - SVvector (ent, absmin)); - VectorAdd (SVvector (ent, origin), SVvector (ent, maxs), - SVvector (ent, absmax)); + if (SVfloat (ent, solid) == SOLID_BSP + && !VectorIsZero (SVvector (ent, angles)) && ent != sv.edicts) { + float m, v; + vec3_t r; + m = DotProduct (SVvector (ent, mins), SVvector (ent, mins)); + v = DotProduct (SVvector (ent, maxs), SVvector (ent, maxs)); + if (m < v) + m = v; + m = sqrt (m); + VectorSet (m, m, m, r); + VectorSubtract (SVvector (ent, origin), r, SVvector (ent, absmin)); + VectorAdd (SVvector (ent, origin), r, SVvector (ent, absmax)); + } else { + // set the abs box + VectorAdd (SVvector (ent, origin), SVvector (ent, mins), + SVvector (ent, absmin)); + VectorAdd (SVvector (ent, origin), SVvector (ent, maxs), + SVvector (ent, absmax)); + } // to make items easier to pick up and allow them to be grabbed off // of shelves, the abs sizes are expanded @@ -591,6 +605,9 @@ SV_ClipMoveToEntity (edict_t *touched, const vec3_t start, hull_t *hull; trace_t trace; vec3_t offset, start_l, end_l; + vec3_t forward, right, up; + int rot = 0; + vec3_t temp; // fill in a default trace memset (&trace, 0, sizeof (trace_t)); @@ -607,12 +624,49 @@ SV_ClipMoveToEntity (edict_t *touched, const vec3_t start, VectorSubtract (start, offset, start_l); VectorSubtract (end, offset, end_l); + if (SVfloat (touched, solid) == SOLID_BSP + && !VectorIsZero (SVvector (touched, angles)) + && touched != sv.edicts) { + rot = 1; + AngleVectors (SVvector (touched, angles), forward, right, up); + VectorNegate (right, right); // convert lhs to rhs + + VectorCopy (start_l, temp); + start_l[0] = DotProduct (temp, forward); + start_l[1] = DotProduct (temp, right); + start_l[2] = DotProduct (temp, up); + + VectorCopy (end_l, temp); + end_l[0] = DotProduct (temp, forward); + end_l[1] = DotProduct (temp, right); + end_l[2] = DotProduct (temp, up); + } + // trace a line through the apropriate clipping hull MOD_TraceLine (hull, hull->firstclipnode, start_l, end_l, &trace); - // fix trace up by the offset - if (trace.fraction != 1) + // fix up trace by the rotation and offset + if (trace.fraction != 1) { + if (rot) { + vec_t t; + + // transpose the rotation matrix to get its inverse + t = forward[1]; forward[1] = right[0]; right[0] = t; + t = forward[2]; forward[2] = up[0]; up[0] = t; + t = right[2]; right[2] = up[1]; up[1] = t; + + VectorCopy (trace.endpos, temp); + trace.endpos[0] = DotProduct (temp, forward); + trace.endpos[1] = DotProduct (temp, right); + trace.endpos[2] = DotProduct (temp, up); + + VectorCopy (trace.plane.normal, temp); + trace.plane.normal[0] = DotProduct (temp, forward); + trace.plane.normal[1] = DotProduct (temp, right); + trace.plane.normal[2] = DotProduct (temp, up); + } VectorAdd (trace.endpos, offset, trace.endpos); + } // did we clip the move? if (trace.fraction < 1 || trace.startsolid) From 505660dffe3140ce6b08a03b6e1ab453886e3114 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 6 Sep 2011 18:41:42 +0900 Subject: [PATCH 127/334] Nuke another buffer. Though snprintf was used, not having a buffer just makes things cleaner. --- tools/qfbsp/source/brush.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tools/qfbsp/source/brush.c b/tools/qfbsp/source/brush.c index 03070b5bf..f3dbfd89a 100644 --- a/tools/qfbsp/source/brush.c +++ b/tools/qfbsp/source/brush.c @@ -28,6 +28,7 @@ #endif #include "QF/sys.h" +#include "QF/va.h" #include "compat.h" @@ -330,7 +331,7 @@ CreateBrushFaces (void) winding_t *w; vec3_t offset, point; - offset[0] = offset[1] = offset[2] = 0; + VectorZero (offset); brush_mins[0] = brush_mins[1] = brush_mins[2] = BOGUS_RANGE; brush_maxs[0] = brush_maxs[1] = brush_maxs[2] = -BOGUS_RANGE; @@ -340,16 +341,14 @@ CreateBrushFaces (void) if (rotate) { entity_t *FoundEntity; const char *searchstring; - char text[20]; searchstring = ValueForKey (CurrentEntity, "target"); FoundEntity = FindTargetEntity (searchstring); if (FoundEntity) GetVectorForKey (FoundEntity, "origin", offset); - snprintf (text, sizeof (text), "%g %g %g", - offset[0], offset[1], offset[2]); - SetKeyValue (CurrentEntity, "origin", text); + SetKeyValue (CurrentEntity, "origin", + va ("%g %g %g", VectorExpand (offset))); } for (i = 0; i < numbrushfaces; i++) { From 581539f7af168c53e023054ae96d6e2a9345af6b Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 6 Sep 2011 23:48:31 +0900 Subject: [PATCH 128/334] Make debug printing a little smarter. When a field or global name is used, the printed value reflects the type of that variable. --- libs/gamecode/engine/pr_debug.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/libs/gamecode/engine/pr_debug.c b/libs/gamecode/engine/pr_debug.c index a88c66051..654269ff3 100644 --- a/libs/gamecode/engine/pr_debug.c +++ b/libs/gamecode/engine/pr_debug.c @@ -126,17 +126,22 @@ pr_debug_expression_error (script_t *script, const char *msg) Sys_Printf ("%s\n", msg); } -static pr_type_t * +static ddef_t parse_expression (progs_t *pr, const char *expr, int conditional) { script_t *es; char *e; pr_type_t *expr_ptr; + ddef_t d; + d.ofs = 0; + d.type = ev_invalid; + d.s_name = 0; es = Script_New (); es->error = pr_debug_expression_error; Script_Start (es, "", expr); expr_ptr = 0; + es->single = "{}()':[]."; if (Script_GetToken (es, 1)) { if (strequal (es->token->str, "[")) { edict_t *ent; @@ -156,16 +161,21 @@ parse_expression (progs_t *pr, const char *expr, int conditional) field = PR_FindField (pr, es->token->str); if (!field) goto error; + d = *field; expr_ptr = &ent->v[field->ofs]; + d.ofs = PR_SetPointer (pr, expr_ptr); } else if (isdigit (es->token->str[0])) { expr_ptr = PR_GetPointer (pr, strtol (es->token->str, 0, 0)); + d.type = ev_void; + d.ofs = PR_SetPointer (pr, expr_ptr); } else { ddef_t *global = PR_FindGlobal (pr, es->token->str); if (!global) goto error; - expr_ptr = PR_GetPointer (pr, global->ofs); + d = *global; } if (conditional) { + es->single = "{}()':[]"; pr->wp_conditional = 0; if (Script_TokenAvailable (es, 1)) { if (!Script_GetToken (es, 1) @@ -185,7 +195,8 @@ parse_expression (progs_t *pr, const char *expr, int conditional) Sys_Printf ("ignoring tail\n"); } error: - return expr_ptr; + Script_Delete (es); + return d; } void @@ -735,6 +746,7 @@ global_string (progs_t *pr, pr_int_t ofs, etype_t type, int contents) VISIBLE void PR_Debug_Watch (progs_t *pr, const char *expr) { + ddef_t watch; if (!expr) { Sys_Printf ("watch \n"); if (pr->watch) { @@ -749,7 +761,10 @@ PR_Debug_Watch (progs_t *pr, const char *expr) return; } - pr->watch = parse_expression (pr, expr, 1); + pr->watch = 0; + watch = parse_expression (pr, expr, 1); + if (watch.type != ev_invalid) + pr->watch = &pr->pr_globals[watch.ofs]; if (pr->watch) { Sys_Printf ("watchpoint set to [%d]\n", PR_SetPointer (pr, pr->watch)); if (pr->wp_conditional) @@ -762,7 +777,7 @@ PR_Debug_Watch (progs_t *pr, const char *expr) VISIBLE void PR_Debug_Print (progs_t *pr, const char *expr) { - pr_type_t *print; + ddef_t print; if (!expr) { Sys_Printf ("print \n"); @@ -770,10 +785,9 @@ PR_Debug_Print (progs_t *pr, const char *expr) } print = parse_expression (pr, expr, 0); - if (print) { - pr_int_t ofs = PR_SetPointer (pr, print); - const char *s = global_string (pr, ofs, ev_void, 1); - Sys_Printf ("[%d] = %s\n", ofs, s); + if (print.type != ev_invalid) { + const char *s = global_string (pr, print.ofs, print.type, 1); + Sys_Printf ("[%d] = %s\n", print.ofs, s); } } From e3c5f6e6081eccfe6fb18ce6d6308a3680ffee8e Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 7 Sep 2011 09:36:37 +0900 Subject: [PATCH 129/334] Fix the wonky rotation translations caused by rotation support. Damn loop in PM_PlayerMove messed up the rotation flag. To think, all that trouble caused by one little flag. --- qw/source/pmovetst.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qw/source/pmovetst.c b/qw/source/pmovetst.c index bca6f1bc5..57b9444b7 100644 --- a/qw/source/pmovetst.c +++ b/qw/source/pmovetst.c @@ -252,7 +252,8 @@ PM_PlayerMove (const vec3_t start, const vec3_t end) VectorSubtract (start, offset, start_l); VectorSubtract (end, offset, end_l); - if (1 && pe->model && pe->model->type == mod_brush + rot = 0; + if (i && pe->model && pe->model->type == mod_brush && !VectorIsZero (pe->angles)) { rot = 1; AngleVectors (pe->angles, forward, right, up); From 86c5b798164ff9ca0342274d09046f021a9443a4 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 7 Sep 2011 10:35:42 +0900 Subject: [PATCH 130/334] Nuke yet another stack buffer. Dn Dn Dn another one's gone, another one's gone, another one bites the dust --- qw/source/sv_user.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/qw/source/sv_user.c b/qw/source/sv_user.c index 192ea77ac..de9e52a27 100644 --- a/qw/source/sv_user.c +++ b/qw/source/sv_user.c @@ -2030,17 +2030,21 @@ SV_UserInit (void) static void OutofBandPrintf (netadr_t where, const char *fmt, ...) { - char send[1024]; + // 0 for davsprintf + static const char header[] = {0xff, 0xff, 0xff, 0xff, A2C_PRINT, 0}; + static dstring_t *send = 0; va_list argptr; + int len; - send[0] = 0xff; - send[1] = 0xff; - send[2] = 0xff; - send[3] = 0xff; - send[4] = A2C_PRINT; + if (!send) + send = dstring_new (); + send->size = sizeof (header); + dstring_adjust (send); + memcpy (send->str, header, sizeof (header)); va_start (argptr, fmt); - vsnprintf (send + 5, sizeof (send) - 5, fmt, argptr); + davsprintf (send, fmt, argptr); va_end (argptr); - Netchan_SendPacket (strlen (send) + 1, send, where); + len = min (send->size, 1024); + Netchan_SendPacket (len, send->str, where); } From 9ffa1f410a95fd78a9f8a49ee43fac6ecae7a0e5 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 7 Sep 2011 15:13:47 +0900 Subject: [PATCH 131/334] Detect the silent death of the jack client thread. When jackd gets an unhandled xrun, it stops all processing but neglects to tell the client about it. Thus, add a bit of a watchdog function to s_update() and assume the client thread is dead if there's no sign of life after one second. No more hanging on exit. --- TODO | 10 +++--- libs/audio/renderer/snd_jack.c | 58 +++++++++++++++++++++++++++++----- 2 files changed, 56 insertions(+), 12 deletions(-) diff --git a/TODO b/TODO index 8cced4db9..11797f1f9 100644 --- a/TODO +++ b/TODO @@ -14,28 +14,30 @@ X ~/.quakeforgerc should support all commands, not just set and setrom X software PCXs don't work in X11 at least if you're using 16/24/32 color X ogg support X server-side demos +X Scitech MGL used in win32 is screwed - dump it and use SDL +X kill MAX_STATIC_ENTITIES +X stateful console (eg, rcon mode, chat mode, normal command mode...) M it seems possible to crash a QF server still - need to fix this! M merge nq and qw code bases M mingw cross compiling -X Scitech MGL used in win32 is screwed - dump it and use SDL M software targets should mix color at 16/16 or 24/32 color I GL is still way too slow I Client side QuakeC. I menu rewrite I clean up TODO ;) -o kill MAX_STATIC_ENTITIES o doublesize modes (eg, render in 320x240 but display in 640x480) o allow qf clients to download .lit files from qf servers. o better server control of certain cvars o triggers (f_respawn, f_death, f_took; cl_triggers) -X stateful console (eg, rcon mode, chat mode, normal command mode...) o scripted hud o add a U_PHYSICAL field to entities. it should include a solid bit, a rotated bbox bit, and mins/maxs for the bbos o gui for serverlist -o add favorates serverlist manipulation +o add favorites serverlist manipulation o redo serverlist filtering for better flexability and/or easier use o add individual server ping/info request from console +? dynamically allocate missing fields, particularly ones not needed by the + progs. ? more direct intra-team comms (eg, talk to offense or defense directly) ? Draw_Pic and friends need a cleanup in GL at least ? Draw_Pic and other tex draw functions should use local palettes diff --git a/libs/audio/renderer/snd_jack.c b/libs/audio/renderer/snd_jack.c index f6d28d8de..664c2e1fd 100644 --- a/libs/audio/renderer/snd_jack.c +++ b/libs/audio/renderer/snd_jack.c @@ -53,6 +53,8 @@ static __attribute__ ((used)) const char rcsid[] = static int sound_started = 0; static int snd_blocked = 0; static int snd_shutdown = 0; +static int snd_alive = 0; +static double snd_alive_time = 0; static jack_client_t *jack_handle; static jack_port_t *jack_out[2]; static dma_t _snd_shm; @@ -78,12 +80,38 @@ s_start_sound (int entnum, int entchannel, sfx_t *sfx, const vec3_t origin, SND_StartSound (entnum, entchannel, sfx, origin, fvol, attenuation); } +static void +s_finish_channels (void) +{ + int i; + channel_t *ch; + + for (i = 0; i < MAX_CHANNELS; i++) { + ch = &snd_channels[i]; + ch->done = ch->stop = 1; + } +} + static void s_update (const vec3_t origin, const vec3_t forward, const vec3_t right, const vec3_t up) { + double now = Sys_DoubleTime (); + if (!sound_started) return; + if (snd_alive) { + snd_alive = 0; + snd_alive_time = now; + } else { + if (!snd_shutdown) { + if (now - snd_alive_time > 1.0) { + Sys_Printf ("jackd client thread seems to have died\n"); + s_finish_channels (); + snd_shutdown = 1; + } + } + } if (snd_shutdown) { if (snd_shutdown == 1) { snd_shutdown++; @@ -120,8 +148,10 @@ s_jack_activate (void) } ports = jack_get_ports (jack_handle, 0, 0, JackPortIsPhysical | JackPortIsInput); - //for (i = 0; ports[i]; i++) - // Sys_Printf ("%s\n", ports[i]); + if (developer->int_val & SYS_SND) { + for (i = 0; ports[i]; i++) + Sys_Printf ("%s\n", ports[i]); + } for (i = 0; i < 2; i++) jack_connect (jack_handle, jack_port_name (jack_out[i]), ports[i]); free (ports); @@ -254,6 +284,7 @@ snd_jack_process (jack_nframes_t nframes, void *arg) { int i; + snd_alive = 1; for (i = 0; i < 2; i++) output[i] = (float *) jack_port_get_buffer (jack_out[i], nframes); SND_PaintChannels (snd_paintedtime + nframes); @@ -263,13 +294,21 @@ snd_jack_process (jack_nframes_t nframes, void *arg) static void snd_jack_shutdown (void *arg) { - int i; - channel_t *ch; snd_shutdown = 1; - for (i = 0; i < MAX_CHANNELS; i++) { - ch = &snd_channels[i]; - ch->done = ch->stop = 1; - } + s_finish_channels (); +} + +static void +snd_jack_error (const char *desc) +{ + fprintf (stderr, "snd_jack: %s\n", desc); +} + +static int +snd_jack_xrun (void *arg) +{ + fprintf (stderr, "snd_jack: xrun\n"); + return 0; } static void @@ -291,12 +330,15 @@ s_init (void) SND_SFX_Init (); SND_Channels_Init (); + jack_set_error_function (snd_jack_error); if ((jack_handle = jack_client_open ("QuakeForge", JackServerName | JackNoStartServer, 0, snd_jack_server->string)) == 0) { Sys_Printf ("Could not connect to JACK\n"); return; } + if (jack_set_xrun_callback (jack_handle, snd_jack_xrun, 0)) + Sys_Printf ("Could not set xrun callback\n"); jack_set_process_callback (jack_handle, snd_jack_process, 0); jack_on_shutdown (jack_handle, snd_jack_shutdown, 0); for (i = 0; i < 2; i++) From a8ea3aaad934ca2d82f13d97df1cc494d959c44b Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 7 Sep 2011 17:00:18 +0900 Subject: [PATCH 132/334] Allow dma sound targets to specify an xfer function. --- include/snd_internal.h | 3 +++ libs/audio/renderer/snd_dma.c | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/include/snd_internal.h b/include/snd_internal.h index a69a4b51e..4ca22a502 100644 --- a/include/snd_internal.h +++ b/include/snd_internal.h @@ -81,6 +81,9 @@ struct dma_s { \param endtime sample end time (count = endtime - snd_paintedtime) */ void (*xfer) (int endtime); + /** Optional data for the xfer function. + */ + void *xfer_data; }; /** Describes the sound data. diff --git a/libs/audio/renderer/snd_dma.c b/libs/audio/renderer/snd_dma.c index 65731cfcc..5d95d3bcb 100644 --- a/libs/audio/renderer/snd_dma.c +++ b/libs/audio/renderer/snd_dma.c @@ -289,7 +289,8 @@ s_startup (void) sound_started = 0; return; } - snd_shm->xfer = s_xfer_paint_buffer; + if (!snd_shm->xfer) + snd_shm->xfer = s_xfer_paint_buffer; sound_started = 1; } From 2ae33a753acf1e72877e1063dd27888c8f39a665 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 7 Sep 2011 17:00:57 +0900 Subject: [PATCH 133/334] Support non-interleaved mmap sound. Unfortuanately, I can't test this properly as I don't have any such hardware, but as the code is mosly an edited copy of the interleaved code, any errors should be easy to fix. --- libs/audio/targets/snd_alsa.c | 98 +++++++++++++++++++++++++++++++++-- 1 file changed, 93 insertions(+), 5 deletions(-) diff --git a/libs/audio/targets/snd_alsa.c b/libs/audio/targets/snd_alsa.c index 81e337365..5db3d9afe 100644 --- a/libs/audio/targets/snd_alsa.c +++ b/libs/audio/targets/snd_alsa.c @@ -119,6 +119,85 @@ round_buffer_size (snd_pcm_uframes_t sz) return sz; } +static inline int +clamp_16 (int val) +{ + if (val > 0x7fff) + val = 0x7fff; + else if (val < -0x8000) + val = -0x8000; + return val; +} + +static inline int +clamp_8 (int val) +{ + if (val > 0x7f) + val = 0x7f; + else if (val < -0x80) + val = -0x80; + return val; +} + +static void +SNDDMA_ni_xfer (int endtime) +{ + const snd_pcm_channel_area_t *areas; + int count, out_idx, out_max; + float snd_vol; + float *p; + + areas = sn.xfer_data; + + p = (float *) snd_paintbuffer; + count = (endtime - snd_paintedtime); + out_max = sn.frames - 1; + out_idx = sn.framepos; + while (out_idx > out_max) + out_idx -= out_max + 1; + snd_vol = snd_volume->value; + + if (sn.samplebits == 16) { + short *out_0 = (short *) areas[0].addr; + short *out_1 = (short *) areas[1].addr; + + if (sn.channels == 2) { + while (count--) { + out_0[out_idx] = clamp_16 ((*p++ * snd_vol) * 0x8000); + out_1[out_idx] = clamp_16 ((*p++ * snd_vol) * 0x8000); + if (out_idx++ > out_max) + out_idx = 0; + } + } else { + while (count--) { + out_0[out_idx] = clamp_16 ((*p++ * snd_vol) * 0x8000); + p++; // skip right channel + if (out_idx++ > out_max) + out_idx = 0; + } + } + } else if (sn.samplebits == 8) { + byte *out_0 = (byte *) areas[0].addr; + byte *out_1 = (byte *) areas[1].addr; + + if (sn.channels == 2) { + while (count--) { + out_0[out_idx] = clamp_8 ((*p++ * snd_vol) * 0x80); + out_1[out_idx] = clamp_8 ((*p++ * snd_vol) * 0x80); + if (out_idx++ > out_max) + out_idx = 0; + } + } else { + while (count--) { + out_0[out_idx] = clamp_8 ((*p++ * snd_vol) * 0x8000); + p++; // skip right channel + if (out_idx++ > out_max) + out_idx = 0; + } + } + } +} + static volatile dma_t * SNDDMA_Init (void) { @@ -170,12 +249,20 @@ SNDDMA_Init (void) err = qfsnd_pcm_hw_params_set_access (pcm, hw, SND_PCM_ACCESS_MMAP_INTERLEAVED); if (0 > err) { - Sys_Printf ("ALSA: Failure to set noninterleaved PCM access. %s\n" - "Note: Interleaved is not supported\n", - qfsnd_strerror (err)); - goto error; + Sys_MaskPrintf (SYS_SND, "ALSA: Failure to set interleaved PCM " + "access. %s\n", qfsnd_strerror (err)); + err = qfsnd_pcm_hw_params_set_access (pcm, hw, + SND_PCM_ACCESS_MMAP_NONINTERLEAVED); + if (0 > err) { + Sys_MaskPrintf (SYS_SND, "ALSA: Failure to set noninterleaved PCM " + "access. %s\n", qfsnd_strerror (err)); + Sys_Printf ("ALSA: could not set mmap access"); + goto error; + } + sn.xfer = SNDDMA_ni_xfer; } + switch (bps) { case -1: err = qfsnd_pcm_hw_params_set_format (pcm, hw, @@ -371,7 +458,8 @@ SNDDMA_GetDMAPos (void) qfsnd_pcm_avail_update (pcm); qfsnd_pcm_mmap_begin (pcm, &areas, &offset, &nframes); sn.framepos = offset; - sn.buffer = areas->addr; //XXX FIXME there's an area per channel + sn.buffer = areas->addr; + sn.xfer_data = (void *) areas; return sn.framepos; } From e8e8dad5358bd8f324a0dac1e4009967aef5e893 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 7 Sep 2011 21:07:52 +0900 Subject: [PATCH 134/334] Fix a potential crash with the cvar reset command. --- libs/util/cvar.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libs/util/cvar.c b/libs/util/cvar.c index e61d8f947..383610fb1 100644 --- a/libs/util/cvar.c +++ b/libs/util/cvar.c @@ -697,6 +697,8 @@ Cvar_Get (const char *name, const char *string, int cvarflags, || strequal (var->description, USER_RO_CVAR) || strequal (var->description, USER_CVAR)) var->description = description; + if (!var->default_string) + var->default_string = strdup (string); } if (var->callback) var->callback (var); From 1e827485ef51baa619d469775ca09f0cec0cd9a0 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 7 Sep 2011 21:08:37 +0900 Subject: [PATCH 135/334] Do some work on the user documentation. Also document part of the cvar api. --- doc/Makefile.am | 2 +- doc/config.dox | 122 +++++++++++++++++++++++++++++++++++++++++++++ doc/faq.dox | 7 +++ doc/quakeforge.dox | 9 +--- include/QF/cvar.h | 73 ++++++++++++++++----------- 5 files changed, 174 insertions(+), 39 deletions(-) create mode 100644 doc/config.dox diff --git a/doc/Makefile.am b/doc/Makefile.am index a031ecbe6..ec55eb35f 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -3,7 +3,7 @@ AUTOMAKE_OPTIONS= foreign SUBDIRS= man DOX=\ - bind.dox connect.dox cshifts.dox dirconf.dox faq.dox \ + bind.dox config.dox connect.dox cshifts.dox dirconf.dox faq.dox \ filesystem.dox mapformat.dox property-list.dox qtv.dox quakeforge.dox \ qw-cap-spec.dox qw-download-spec.dox surround-sound.dox timestamps.dox diff --git a/doc/config.dox b/doc/config.dox new file mode 100644 index 000000000..98d0c32dd --- /dev/null +++ b/doc/config.dox @@ -0,0 +1,122 @@ +//unfortunately, have to wrap the docs in a C comment for doxygen +/** +\page run_config Runtime Configuration. + +\li \subpage cvars +\li \subpage filesystem +\li \subpage dirconf +\li \subpage tracklist +\li \subpage key_binding +\li \subpage cshift_cvars +\li \subpage server_timestamps + +*/ + +/** +\page cvars Configuration variables + +The core of \QF's configurabitly is the cvar. + +\section cvar_value Cvar values. +Depending how the engine's use of the cvar, the value will be treated as a +string, a floating point value, an integer value or even a vector value. + +If a space is needed in the value, the value must be "quoted". + +\section cvar_type Cvar types. +From the user's perspective, there are three types of cvar: +\li plain cvar: the value can be displayed or set, but will not be +automatically saved. +\li archive cvar: like a plain cvar, the value can be displayed or set, but +the cvar will be automatically saved to \c config.cfg by the engine on +shutdown or gamedir change (quakeworld). +\li read-only cvar: the value can be displayed but not changed in any way +(value or flags). If the cvar also happens to be an archive cvar (the +archive flag was set before the read-only flag), then the cvar will be +saved to \c config.cfg. + +\section cvar_cmds Cvar related commands. +\ [value]
+Display the current value of the specified cvar. If \c value is given, set +the cvar to \c value. Does not create a new cvar. + +set \ \
+Set the specified cvar to the specified value. If the cvar does not already +exist, a new cvar will be created. + +seta \ \
+Set the specified cvar to the specified value. If the cvar does not already +exist, a new cvar will be created. Sets the cvar's archive flag so it will +be automatically saved to \c config.cfg by the clients. + +setrom \ \
+Set the specified cvar to the specified value. If the cvar does not already +exist, a new cvar will be created. Sets the cvar's read-only flag so it can +no longer be modified in any way (not even by \c reset or \c resetall). + +toggle \
+Treat the cvar as a boolean value, changing it from off to on, or on to +off. Any non-zero integer value is considered to be on, while zero and +any string that parses as zero (does not start with a non-zero number) will +be treated as off. The new value will always be either one (1) or zero (0). +\note values smaller than 1 will be treated as off. + +cvarlist [foo]
+Print a list of all cvars known to the engine (engine created or user +created). If the foo parameter is given (any value), then extra +information (cvar description, flags) will also be printed. + +cycle \ \
+Cause the cvar to cycle through the list of values. Each time this command +is executed, the cvar will change to the value immediately after the cvar's +current value in the list, cycling back to the beginning when the current +value is the last value in the list. If the current value is not in the +list, the cvar will be set to the first value in the list. + +inc \ [amount]
+Add one (1) to the cvar's current numeric value. If the optional amount is +given, add that value to the cvar's current numeric value. Using -1 +(inc \ -1), this can be used as a \c dec command. + +reset \
+Reset the specified cvar to its default (engine specified) value. + +resetall
+Reset all cvars to their default (engine specified values). + +\section cvar_rom Read-only cvars. +Many cvars in \QF are read-only because changing them at runtime would +either have little meaning or be difficult to implement. However, there +is a way to change even a read-only cvarsing the \c set command, +the cvar can be created with the desired value before the engine creates +the cvar (and sets its read-only flag). There are exactly three places +where the cvar can be created before the engine does: +\li the command line (eg nq-glx +set snd_rate 48000) +\li the global configuration file specified by the \c fs_globalcfg cvar. +\li the user configuration file specified by the \c fs_usercfg cvar. + +The global and user configuration files are normal quake scripts, but only +\c set, \c seta, and \c setrom commands are executed. + +It might seem strange to have the global and user configuration files +specified by cvars, but \QF's startup sequence is quite intense: +\li execute any \c set commands given on the command line. This way, \c +fs_globalcfg can be set. +\li execute any \c set commands in the global configuration file. This way, +\c fs_usercfg can be set. +\li re-execute any \c set commands given on the command line. Thus it is +possible to override \c fs_usercfg if it is set by the global configuration +file (unless \c setrom is used: BOFH). +\li execute any \c set commands in the user configuration file. Any cvars +set in the user configuration file override those set in the global +configuration file. +\li once again, re-execute any \c set commands given on the command line. +Thus cvars set on the command line override those set in either the user +configuration file or the global configuration file (or both). + +During the above process, the only cvars created by the engine are \c +fs_globalcfg (just before reading the global configuration file) and \c +fs_usercfg (just before reading the user configuration file). Thus, it is +possible to set any cvar in \QF. + +*/ diff --git a/doc/faq.dox b/doc/faq.dox index 4a16182f1..4958eefe9 100644 --- a/doc/faq.dox +++ b/doc/faq.dox @@ -7,6 +7,7 @@ \li \ref git_compile_error \li \ref no_music \li \ref no_mp3 +\li \ref faq_cvar_rom \section gfx_wad What does "W_LoadWadFile: unable to load gfx.wad" mean? The most common cause of this error is QuakeForge is unable to find @@ -17,6 +18,8 @@ Linux (and other UNIX like operating systems), fs_userpath defaults to ~/.quakeforge and fs_sharepath defaults to $prefix/share/games/quakeforge (distribution packages might alter the exact path). +See \ref filesystem for more details. + \section pak0_pak Where can I get pak0.pak? See \ref game_data @@ -60,4 +63,8 @@ the value appropriate for your system: Because they are not free. MP3 support is a patent minefield, and we really don't want to wind up with lawyers at ten paces, especially since we'd be unarmed with no armor, and they have rocket launchers and quad-damage. + +\section faq_cvar_rom How do I set a read-only cvar (eg, snd_rate)? +Read-only cvars can be set by creating them before the engine does. See +\ref cvar_rom for details. */ diff --git a/doc/quakeforge.dox b/doc/quakeforge.dox index f5d354f62..c8a624a50 100644 --- a/doc/quakeforge.dox +++ b/doc/quakeforge.dox @@ -10,12 +10,5 @@ of players we can. \li \subpage build-install \li \subpage faq -\li \subpage key_binding -\li \subpage cshift_cvars -\li \subpage filesystem -\li \subpage dirconf -\li \subpage qw_cap_spec -\li \subpage qw_download_spec -\li \subpage server_timestamps -\li \subpage qtv_overview +\li \subpage run_config */ diff --git a/include/QF/cvar.h b/include/QF/cvar.h index 63070feef..7d664764f 100644 --- a/include/QF/cvar.h +++ b/include/QF/cvar.h @@ -38,42 +38,55 @@ #include "QF/quakeio.h" typedef struct cvar_s { - const char *name; - const char *string; - const char *default_string; - int flags; + const char *name; ///< The name of the cvar. + const char *string; ///< The current cvar value as a string. + const char *default_string; ///< The default value of the cvar. + int flags; ///< Cvar flags + /** Callback for when the cvar value changes. + + This allows for more flexibility in what happens when a cvar is + nodifed than can be achieved with flags alone. While a similar could + be done using commands, a cvar with a callback and CVAR_ARCHIVE set + allows the setting to be saved automatically. + + \param var This cvar. + */ void (*callback)(struct cvar_s *var); - const char *description; // for "help" command - float value; - int int_val; - vec3_t vec; - struct cvar_s *next; + const char *description; ///< for "help" command + float value; ///< The current cvar value as a float + int int_val; ///< The current cvar value as an integer + vec3_t vec; ///< The current cvar value as a vector + struct cvar_s *next; ///< \internal Linked list of cvars. } cvar_t; typedef struct cvar_alias_s { - char *name; - cvar_t *cvar; - struct cvar_alias_s *next; + char *name; ///< The name of the alias. + cvar_t *cvar; ///< The cvar to which this alias refers + struct cvar_alias_s *next; ///< \internal LInked list of aliases. } cvar_alias_t; -#define CVAR_NONE 0 -#define CVAR_ARCHIVE 1 // set to cause it to be saved to vars.rc - // used for system variables, not for player - // specific configurations -#define CVAR_USERINFO 2 // sent to server on connect or change -#define CVAR_SERVERINFO 4 // sent in response to front end requests -#define CVAR_NOTIFY 32 // Will notify players when changed. -#define CVAR_ROM 64 // display only, cannot be set by user at all -#define CVAR_USER_CREATED 128 // created by a set command -#define CVAR_LATCH 2048 // will change only when C code next does - // a Cvar_Get(), so it can't be changed - -// Zoid| A good CVAR_ROM example is userpath. The code should read "cvar_t -// *fs_userpath = CvarGet("fs_userpath", ".", CVAR_ROM); The user can -// override that with +set fs_userpath since the command line +set gets -// created _before_ the C code for fs_basepath setup is called. The code goes -// "look, the user made fs_basepath already", uses the users value, but sets -// CVAR_ROM as per the call. +/** \name cvar_flags + Zoid| A good CVAR_ROM example is userpath. The code should read "cvar_t + *fs_userpath = CvarGet("fs_userpath", ".", CVAR_ROM); The user can + override that with +set fs_userpath \ since the command line +set + gets created _before_ the C code for fs_basepath setup is called. The + code goes "look, the user made fs_basepath already", uses the users value, + but sets CVAR_ROM as per the call. +*/ +//@{ +#define CVAR_NONE 0 ///< normal cvar +#define CVAR_ARCHIVE 1 ///< set to cause it to be saved to + ///< config.cfg +#define CVAR_USERINFO 2 ///< sent to server on connect or change +#define CVAR_SERVERINFO 4 ///< sent in response to front end requests +#define CVAR_NOTIFY 32 ///< Will notify players when changed. + ///< (not implemented) +#define CVAR_ROM 64 ///< display only, cannot be set +#define CVAR_USER_CREATED 128 ///< created by a set command +#define CVAR_LATCH 2048 ///< will change only when C code next does + ///< a Cvar_Get(), so it can't be changed + ///< (not implemented) +//@} // Returns the Cvar if found, creates it with value if not. Description and From 6a7b316572a07df84c6ea41e91573595aac39677 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 8 Sep 2011 10:17:58 +0900 Subject: [PATCH 136/334] Put my text editing vim settings into the docs. Vim's autoformating doesn't like our style of comments, so I have to force it to do what I want. Having to set the appropriate options every time I edit a file got to be a RPITA, so time to get the computer to do it for me :) --- INSTALL | 1 + doc/bind.dox | 1 + doc/config.dox | 1 + doc/connect.dox | 1 + doc/cshifts.dox | 1 + doc/dirconf.dox | 1 + doc/faq.dox | 1 + doc/filesystem.dox | 1 + doc/mapformat.dox | 1 + doc/property-list.dox | 1 + doc/qtv.dox | 1 + doc/quakeforge.dox | 1 + doc/qw-cap-spec.dox | 1 + doc/qw-download-spec.dox | 1 + doc/surround-sound.dox | 1 + doc/timestamps.dox | 1 + doc/tracklist.dox | 1 + 17 files changed, 17 insertions(+) diff --git a/INSTALL b/INSTALL index 7e4c4be88..fe696aa1c 100644 --- a/INSTALL +++ b/INSTALL @@ -1,5 +1,6 @@ //This file is formatted for processing with doxygen. //unfortunatly, have to wrap the docs in a C comment for doxygen +// vim:tw=74:formatoptions-=l /** \page build-install Building and Installing QuakeForge diff --git a/doc/bind.dox b/doc/bind.dox index a5566d7a9..99b006a60 100644 --- a/doc/bind.dox +++ b/doc/bind.dox @@ -1,4 +1,5 @@ //unfortunately, have to wrap the docs in a C comment for doxygen +// vim:tw=74:formatoptions-=l /** \page key_binding New Bind System diff --git a/doc/config.dox b/doc/config.dox index 98d0c32dd..a047216c8 100644 --- a/doc/config.dox +++ b/doc/config.dox @@ -1,4 +1,5 @@ //unfortunately, have to wrap the docs in a C comment for doxygen +// vim:tw=74:formatoptions-=l /** \page run_config Runtime Configuration. diff --git a/doc/connect.dox b/doc/connect.dox index 44f7fcd27..44d83586a 100644 --- a/doc/connect.dox +++ b/doc/connect.dox @@ -1,4 +1,5 @@ //unfortunately, have to wrap the docs in a C comment for doxygen +// vim:tw=74:formatoptions-=l /** \page connection_sequence QW Connection Sequence \msc diff --git a/doc/cshifts.dox b/doc/cshifts.dox index 3514906a9..623419a8b 100644 --- a/doc/cshifts.dox +++ b/doc/cshifts.dox @@ -1,4 +1,5 @@ //unfortunately, have to wrap the docs in a C comment for doxygen +// vim:tw=74:formatoptions-=l /** \page cshift_cvars cshift control diff --git a/doc/dirconf.dox b/doc/dirconf.dox index 6886937a7..6e37df11c 100644 --- a/doc/dirconf.dox +++ b/doc/dirconf.dox @@ -1,4 +1,5 @@ //unfortunately, have to wrap the docs in a C comment for doxygen +// vim:tw=74:formatoptions-=l /** \page dirconf Directory Configuration diff --git a/doc/faq.dox b/doc/faq.dox index 4958eefe9..73c0d09e9 100644 --- a/doc/faq.dox +++ b/doc/faq.dox @@ -1,4 +1,5 @@ //unfortunately, have to wrap the docs in a C comment for doxygen +// vim:tw=74:formatoptions-=l /** \page faq Frequently Asked Questions diff --git a/doc/filesystem.dox b/doc/filesystem.dox index 699e7064a..cfdefb502 100644 --- a/doc/filesystem.dox +++ b/doc/filesystem.dox @@ -1,4 +1,5 @@ //unfortunately, have to wrap the docs in a C comment for doxygen +// vim:tw=74:formatoptions-=l /** \page filesystem QuakeForge Directory Trees diff --git a/doc/mapformat.dox b/doc/mapformat.dox index c3624800e..9a1c66ccc 100644 --- a/doc/mapformat.dox +++ b/doc/mapformat.dox @@ -1,4 +1,5 @@ //unfortunately, have to wrap the docs in a C comment for doxygen +// vim:tw=74:formatoptions-=l /** \page mapformat Map (.map) File Format diff --git a/doc/property-list.dox b/doc/property-list.dox index e2c680fb2..8be3f3b70 100644 --- a/doc/property-list.dox +++ b/doc/property-list.dox @@ -1,4 +1,5 @@ //unfortunately, have to wrap the docs in a C comment for doxygen +// vim:tw=74:formatoptions-=l /** \page property-list Property List diff --git a/doc/qtv.dox b/doc/qtv.dox index 9fedff083..90aba3bc8 100644 --- a/doc/qtv.dox +++ b/doc/qtv.dox @@ -1,4 +1,5 @@ //unfortunately, have to wrap the docs in a C comment for doxygen +// vim:tw=74:formatoptions-=l /** \page qtv_overview QF QTV overview/status. OVERVIEW: diff --git a/doc/quakeforge.dox b/doc/quakeforge.dox index c8a624a50..e21a7fd27 100644 --- a/doc/quakeforge.dox +++ b/doc/quakeforge.dox @@ -1,4 +1,5 @@ //unfortunately, have to wrap the docs in a C comment for doxygen +// vim:tw=74:formatoptions-=l /** \mainpage QuakeForge diff --git a/doc/qw-cap-spec.dox b/doc/qw-cap-spec.dox index 7bcb18500..05796a3d0 100644 --- a/doc/qw-cap-spec.dox +++ b/doc/qw-cap-spec.dox @@ -1,4 +1,5 @@ //unfortunately, have to wrap the docs in a C comment for doxygen +// vim:tw=74:formatoptions-=l /** \page qw_cap_spec QW Capabilities String diff --git a/doc/qw-download-spec.dox b/doc/qw-download-spec.dox index 140e71e55..852f12065 100644 --- a/doc/qw-download-spec.dox +++ b/doc/qw-download-spec.dox @@ -1,4 +1,5 @@ //unfortunately, have to wrap the docs in a C comment for doxygen +// vim:tw=74:formatoptions-=l /** \page qw_download_spec QW Download Specification diff --git a/doc/surround-sound.dox b/doc/surround-sound.dox index 881ad5547..d5a080685 100644 --- a/doc/surround-sound.dox +++ b/doc/surround-sound.dox @@ -1,4 +1,5 @@ //unfortunately, have to wrap the docs in a C comment for doxygen +// vim:tw=74:formatoptions-=l /** \page surround_sound_spec Description of Surround-Sound Channels diff --git a/doc/timestamps.dox b/doc/timestamps.dox index d024d7e41..4e8a75aae 100644 --- a/doc/timestamps.dox +++ b/doc/timestamps.dox @@ -1,4 +1,5 @@ //unfortunately, have to wrap the docs in a C comment for doxygen +// vim:tw=74:formatoptions-=l /** \page server_timestamps Server Log Timestamps diff --git a/doc/tracklist.dox b/doc/tracklist.dox index c298a88f0..de0dfc6d7 100644 --- a/doc/tracklist.dox +++ b/doc/tracklist.dox @@ -1,4 +1,5 @@ //unfortunately, have to wrap the docs in a C comment for doxygen +// vim:tw=74:formatoptions-=l /** \page tracklist Tracklist config file From e72d4923aad56be5f32e68d2909b772d4f22aa20 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 8 Sep 2011 10:21:41 +0900 Subject: [PATCH 137/334] Finish up the docs for cvars and config files. For now, anyway :) --- doc/config.dox | 42 ++++++++++++++++++++++++++++++++---------- doc/filesystem.dox | 3 ++- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/doc/config.dox b/doc/config.dox index a047216c8..2709b684e 100644 --- a/doc/config.dox +++ b/doc/config.dox @@ -19,7 +19,7 @@ The core of \QF's configurabitly is the cvar. \section cvar_value Cvar values. -Depending how the engine's use of the cvar, the value will be treated as a +Depending on the engine's use of the cvar, the value will be treated as a string, a floating point value, an integer value or even a vector value. If a space is needed in the value, the value must be "quoted". @@ -88,30 +88,39 @@ Reset all cvars to their default (engine specified values). \section cvar_rom Read-only cvars. Many cvars in \QF are read-only because changing them at runtime would either have little meaning or be difficult to implement. However, there -is a way to change even a read-only cvarsing the \c set command, -the cvar can be created with the desired value before the engine creates -the cvar (and sets its read-only flag). There are exactly three places -where the cvar can be created before the engine does: +is a way to change even a read-only cvars: using the \c set +command, the cvar can be created with the desired value before the engine +creates the cvar (and sets its read-only flag). There are exactly three +places where the cvar can be created before the engine does: \li the command line (eg nq-glx +set snd_rate 48000) \li the global configuration file specified by the \c fs_globalcfg cvar. \li the user configuration file specified by the \c fs_usercfg cvar. +\c fs_globalcfg defaults to \c /etc/quakeforge.conf on Linux and other +UNIX like systems, and ~/quakeforge.conf on Windows (\QF will +expand ~ to the value of the HOME environment variable if it +is set, or WINDOWS if not). + +\c fs_usercfg defaults to either ~/.quakeforgerc or +~/.config/quakeforge/quakeforge.conf on Linux and other UNIX +like systems, and \c ~/quakeforgerc on Windows. + The global and user configuration files are normal quake scripts, but only \c set, \c seta, and \c setrom commands are executed. It might seem strange to have the global and user configuration files specified by cvars, but \QF's startup sequence is quite intense: -\li execute any \c set commands given on the command line. This way, \c +\li Execute any \c set commands given on the command line. This way, \c fs_globalcfg can be set. -\li execute any \c set commands in the global configuration file. This way, +\li Execute any \c set commands in the global configuration file. This way, \c fs_usercfg can be set. -\li re-execute any \c set commands given on the command line. Thus it is +\li Re-execute any \c set commands given on the command line. Thus it is possible to override \c fs_usercfg if it is set by the global configuration file (unless \c setrom is used: BOFH). -\li execute any \c set commands in the user configuration file. Any cvars +\li Execute any \c set commands in the user configuration file. Any cvars set in the user configuration file override those set in the global configuration file. -\li once again, re-execute any \c set commands given on the command line. +\li Once again, re-execute any \c set commands given on the command line. Thus cvars set on the command line override those set in either the user configuration file or the global configuration file (or both). @@ -120,4 +129,17 @@ fs_globalcfg (just before reading the global configuration file) and \c fs_usercfg (just before reading the user configuration file). Thus, it is possible to set any cvar in \QF. +The above means that: +\li The command line can be used to set any cvar in \QF. +\li The global config file can be used to set any cvar but \c +fs_globalcfg. +\li The user config file can be used to set any cvar but \c fs_globalcfg +or \c fs_usercfg. +\li The user config file can be used to override settings made in the +global config file, unless those settings have been made read-only by the +global config file (by using \c setrom instead of \c set). +\li The command line can be used to override settings made in either the +user config file or the global config file. If \c setrom is used on the +command line, even \c setrom in the config files can be overridden. + */ diff --git a/doc/filesystem.dox b/doc/filesystem.dox index cfdefb502..93a66fabd 100644 --- a/doc/filesystem.dox +++ b/doc/filesystem.dox @@ -41,7 +41,8 @@ when the trees are in the same place. Once QuakeForge is running, \c fs_sharepath and \c fs_userpath cannot be altered. However, they may be altered by setting them in the system -configuration file, the user configuration file, or on the command line. +configuration file, the user configuration file, or on the command line +(see \ref cvar_rom). The internal layout of the shared and user data trees are, by default, the same as Quake (an \c id1 directory tree, plus other mod directories), but From 79cec9d7b588127c59574e9ff8b6595dcf5d97a6 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 8 Sep 2011 10:29:24 +0900 Subject: [PATCH 138/334] Create a template file for our documentation. --- doc/quakeforge.dox.conf.in | 3 +++ doc/template.dox | 6 ++++++ 2 files changed, 9 insertions(+) create mode 100644 doc/template.dox diff --git a/doc/quakeforge.dox.conf.in b/doc/quakeforge.dox.conf.in index 067381054..428ebfe4b 100644 --- a/doc/quakeforge.dox.conf.in +++ b/doc/quakeforge.dox.conf.in @@ -629,6 +629,9 @@ EXCLUDE += @TOPSRC@/tools/Forge EXCLUDE += @TOPSRC@/include/QF/GL EXCLUDE += @TOPSRC@/include/block16.h EXCLUDE += @TOPSRC@/include/block8.h +EXCLUDE += @TOPSRC@/doc/template.dox +EXCLUDE += @TOPSRC@/doc/template.c +EXCLUDE += @TOPSRC@/doc/template.h # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded diff --git a/doc/template.dox b/doc/template.dox new file mode 100644 index 000000000..75cea52ce --- /dev/null +++ b/doc/template.dox @@ -0,0 +1,6 @@ +//unfortunately, have to wrap the docs in a C comment for doxygen +// vim:tw=74:formatoptions-=l +/** +\page name Title +text +*/ From 6da725d5107ea4173194d70f88a46c4acfe629a5 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 8 Sep 2011 12:30:58 +0900 Subject: [PATCH 139/334] Simplify and slightly improve Cmd_StuffCmds(). Make use of dstring to manage the built command mini-script. Ensure + and - that do not come after whitespace do not start a new command. --- libs/util/cmd.c | 44 ++++++++++++++++++-------------------------- 1 file changed, 18 insertions(+), 26 deletions(-) diff --git a/libs/util/cmd.c b/libs/util/cmd.c index 090b63dc6..cad66dbe4 100644 --- a/libs/util/cmd.c +++ b/libs/util/cmd.c @@ -545,44 +545,36 @@ VISIBLE void Cmd_StuffCmds (cbuf_t *cbuf) { int i, j; - int s; - char *build, c; - char *cmdline; + dstring_t *build; - s = strlen (com_cmdline); - if (!s) + if (!*com_cmdline) return; - cmdline = strdup (com_cmdline); - // pull out the commands - build = malloc (s + 1); - SYS_CHECKMEM (build); - build[0] = 0; + build = dstring_newstr (); - for (i = 0; i < s - 1; i++) { - if (cmdline[i] == '+') { + // pull out the commands + for (i = 0; com_cmdline[i]; i++) { + if (com_cmdline[i] == '+') { i++; - for (j = i; !((cmdline[j] == '+') - || (cmdline[j] == '-' - && (j == 0 || cmdline[j - 1] == ' ')) - || (cmdline[j] == 0)); j++); + for (j = i; + (com_cmdline[j] + && !((j == 0 || isspace(com_cmdline[j - 1])) + && ((com_cmdline[j] == '+') + || (com_cmdline[j] == '-')))); + j++) + ; - c = cmdline[j]; - cmdline[j] = 0; - - strncat (build, cmdline + i, s - strlen (build)); - strncat (build, "\n", s - strlen (build)); - cmdline[j] = c; + dstring_appendsubstr (build, com_cmdline + i, j - i); + dstring_appendstr (build, "\n"); i = j - 1; } } - if (build[0]) - Cbuf_InsertText (cbuf, build); + if (build->str[0]) + Cbuf_InsertText (cbuf, build->str); - free (build); - free (cmdline); + dstring_delete (build); } static void From 1dda097c65a6da613fe4470847372ea8467abcc7 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 8 Sep 2011 13:06:11 +0900 Subject: [PATCH 140/334] Document the command line console command interface. --- doc/config.dox | 36 ++++++++++++++++++++++++++++++++++-- doc/filesystem.dox | 2 +- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/doc/config.dox b/doc/config.dox index 2709b684e..9a4a2eef5 100644 --- a/doc/config.dox +++ b/doc/config.dox @@ -3,6 +3,7 @@ /** \page run_config Runtime Configuration. +\li \subpage cmdline \li \subpage cvars \li \subpage filesystem \li \subpage dirconf @@ -13,6 +14,37 @@ */ +/** +\page cmdline Command Line +The \QF servers (\c nq-server, \c qw-server, and \c qtv), and clients +(\c nq-glx, \c nq-wgl, \c qw-client-glx, \c qw-client-wgl etc) all parse +the program command line looking for console commands. + +Console commands on the command line are marked with a \c + that follows +whitespace. They continue until the next \c + or \c - that follows +whitespace. This allows commands and arguments to contain \c + and \c - so +long as the preceeding character is not whitespace, but also prevents +command line switches (eg \c -nosound) from becoming part of the console +command. Using careful quoting, it is even possible for a command or +argument to beging with \c + or \c -. + +The following command line will fail to set m_pitch because the -0.022 +will not be part of the console command. usage: setrom \ +\ will be displayed instead. +\verbatim +nq-glx +setrom m_pitch -0.022 +\endverbatim + +The following command line will successfully set m_pitch to \c -0.022 +because \QF will see the \c " before the \c - and thus \c -0.022 will be +part of the console command. +\verbatim +nq-glx +setrom m_pitch \"-0.022\" +\endverbatim +\note The above works in bash. Other shells may vary. + +*/ + /** \page cvars Configuration variables @@ -110,7 +142,7 @@ The global and user configuration files are normal quake scripts, but only It might seem strange to have the global and user configuration files specified by cvars, but \QF's startup sequence is quite intense: -\li Execute any \c set commands given on the command line. This way, \c +\li Execute any \c set commands given on the \ref cmdline. This way, \c fs_globalcfg can be set. \li Execute any \c set commands in the global configuration file. This way, \c fs_usercfg can be set. @@ -130,7 +162,7 @@ fs_usercfg (just before reading the user configuration file). Thus, it is possible to set any cvar in \QF. The above means that: -\li The command line can be used to set any cvar in \QF. +\li The \ref cmdline can be used to set any cvar in \QF. \li The global config file can be used to set any cvar but \c fs_globalcfg. \li The user config file can be used to set any cvar but \c fs_globalcfg diff --git a/doc/filesystem.dox b/doc/filesystem.dox index 93a66fabd..9faf528e5 100644 --- a/doc/filesystem.dox +++ b/doc/filesystem.dox @@ -42,7 +42,7 @@ when the trees are in the same place. Once QuakeForge is running, \c fs_sharepath and \c fs_userpath cannot be altered. However, they may be altered by setting them in the system configuration file, the user configuration file, or on the command line -(see \ref cvar_rom). +(see \ref cvar_rom and \ref cmdline). The internal layout of the shared and user data trees are, by default, the same as Quake (an \c id1 directory tree, plus other mod directories), but From 6f4d918c661699c17b89d8af35dcba6a99479523 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 8 Sep 2011 14:38:57 +0900 Subject: [PATCH 141/334] Begin documenting sound and tidy up specifications. --- doc/Makefile.am | 3 +- doc/config.dox | 3 +- doc/quakeforge.dox | 1 + doc/sound.dox | 85 ++++++++++++++++++++++++++++++++++++++++++ doc/specifications.dox | 13 +++++++ 5 files changed, 103 insertions(+), 2 deletions(-) create mode 100644 doc/sound.dox create mode 100644 doc/specifications.dox diff --git a/doc/Makefile.am b/doc/Makefile.am index ec55eb35f..09ef0c2c0 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -5,7 +5,8 @@ SUBDIRS= man DOX=\ bind.dox config.dox connect.dox cshifts.dox dirconf.dox faq.dox \ filesystem.dox mapformat.dox property-list.dox qtv.dox quakeforge.dox \ - qw-cap-spec.dox qw-download-spec.dox surround-sound.dox timestamps.dox + qw-cap-spec.dox qw-download-spec.dox sound.dox specifications.dox \ + surround-sound.dox timestamps.dox EXTRA_DIST= qf.ico \ \ diff --git a/doc/config.dox b/doc/config.dox index 9a4a2eef5..ead8940f6 100644 --- a/doc/config.dox +++ b/doc/config.dox @@ -7,6 +7,7 @@ \li \subpage cvars \li \subpage filesystem \li \subpage dirconf +\li \subpage sound \li \subpage tracklist \li \subpage key_binding \li \subpage cshift_cvars @@ -117,7 +118,7 @@ Reset the specified cvar to its default (engine specified) value. resetall
Reset all cvars to their default (engine specified values). -\section cvar_rom Read-only cvars. +\section cvar_rom Read-only cvars Many cvars in \QF are read-only because changing them at runtime would either have little meaning or be difficult to implement. However, there is a way to change even a read-only cvars: using the \c set diff --git a/doc/quakeforge.dox b/doc/quakeforge.dox index e21a7fd27..bf3da2584 100644 --- a/doc/quakeforge.dox +++ b/doc/quakeforge.dox @@ -12,4 +12,5 @@ of players we can. \li \subpage build-install \li \subpage faq \li \subpage run_config +\li \subpage specs */ diff --git a/doc/sound.dox b/doc/sound.dox new file mode 100644 index 000000000..30dc44d0c --- /dev/null +++ b/doc/sound.dox @@ -0,0 +1,85 @@ +//unfortunately, have to wrap the docs in a C comment for doxygen +// vim:tw=74:formatoptions-=l +/** +\page sound \QF Sound System +The \QF sound system is designed to work with many sound systems. The +sound systems \QF supports are: +
+
Linux
ALSA, OSS, SDL
+
Other UNIX-like
OSS, SDL
+
Windows
DirectX, Win32, SDL
+
+There are others (SUN, SGI, MME), but their status is unkown. SUN sound +support will build (on OpenBSD), but whether it works is unknown. + +In the above list, the first sound system listed for each OS is the +default. To use one of the other supported drivers, set the \c snd_output +cvar to the appropriate name as shown below (all systems are shown). + + + + + + + + + + +
SystemALSAOSSDirectXWin32SUNSGIMMESDL
Driveralsaossdxwinsunsgimmesdl
+ +As \c snd_output is read-only, see \ref cvar_rom for how to set it. + +In addition to the above, \QF also supports JACK audio. \QF's JACK support +should work on any system that supports JACK. However, as JACK support +uses a different architecture (JACK audio is "pull", \QF default audio is +"push"), selecting JACK support uses a different cvar; Set \c snd_render +to \c jack (the following table shows the name for both render systems). + + + + + + + + +
SystemDefaultJACK
Renderdefaultjack
+ +\section snd_comcc Common Cvars and Commands +\c ambient_level
+\c ambient_fade
+\c precache
+\c snd_swapchannelside
+\c snd_volumesep
+\c snd_phasesep
+\c volume
+ +\c play
+\c playcenter
+\c playvol
+\c snd_force_unblock
+\c soundlist
+ +When \QF is built with MIDI support (using WildMidi):
+\c wildmidi_config
+\c wildmidi_volume
+ +\section snd_defcc QF Default Cvars and Commands +\c snd_noextraupdate
+\c snd_mixahead
+\c nosound
+ +\c stopsound
+\c soundinfo
+ +\c snd_stereo
+\c snd_rate
+\c snd_bits
+ +\c snd_device
+ +\c snd_oss_mmaped
+ +\section snd_jackcc JACK Cvars and Commands +\c snd_jack_server
+ +*/ diff --git a/doc/specifications.dox b/doc/specifications.dox new file mode 100644 index 000000000..423febed0 --- /dev/null +++ b/doc/specifications.dox @@ -0,0 +1,13 @@ +//unfortunately, have to wrap the docs in a C comment for doxygen +// vim:tw=74:formatoptions-=l +/** +\page specs Various Specifications + + +\li \subpage surround_sound_spec +\li \subpage connection_sequence +\li \subpage mapformat +\li \subpage property-list +\li \subpage qw_cap_spec +\li \subpage qw_download_spec +*/ From 881d4babce0b7284db1ccb1cb8a4c9606a687785 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 8 Sep 2011 18:10:09 +0900 Subject: [PATCH 142/334] Fix some undefined symbols in snd_alsa.c. Serves me right for testing with only my debug build :P --- include/snd_internal.h | 7 +++++-- libs/audio/renderer/snd_dma.c | 17 ++++++++--------- libs/audio/renderer/snd_jack.c | 9 +++------ libs/audio/renderer/snd_mix.c | 3 ++- libs/audio/targets/snd_alsa.c | 21 +++++++++------------ libs/audio/targets/snd_dx.c | 3 ++- libs/audio/targets/snd_sun.c | 3 ++- libs/audio/targets/snd_win.c | 3 ++- 8 files changed, 33 insertions(+), 33 deletions(-) diff --git a/include/snd_internal.h b/include/snd_internal.h index 4ca22a502..be684f8e3 100644 --- a/include/snd_internal.h +++ b/include/snd_internal.h @@ -78,9 +78,12 @@ struct dma_s { int framepos; //!< position of dma cursor unsigned char *buffer; //!< destination for mixed sound /** Transfer mixed samples to the output. - \param endtime sample end time (count = endtime - snd_paintedtime) + \param paintbuffer The buffer of mixed samples to be transferred. + \param count The number of sample to transfer. + \param volume The gain for the samples. */ - void (*xfer) (int endtime); + void (*xfer) (portable_samplepair_t *paintbuffer, int count, + float volume); /** Optional data for the xfer function. */ void *xfer_data; diff --git a/libs/audio/renderer/snd_dma.c b/libs/audio/renderer/snd_dma.c index 5d95d3bcb..727664112 100644 --- a/libs/audio/renderer/snd_dma.c +++ b/libs/audio/renderer/snd_dma.c @@ -73,26 +73,25 @@ static general_data_t plugin_info_general_data; static snd_output_funcs_t *snd_output_funcs; static void -s_xfer_paint_buffer (int endtime) +s_xfer_paint_buffer (portable_samplepair_t *paintbuffer, int count, + float volume) { - int count, out_idx, out_max, step, val; - float snd_vol; + int out_idx, out_max, step, val; float *p; - p = (float *) snd_paintbuffer; - count = (endtime - snd_paintedtime) * snd_shm->channels; + p = (float *) paintbuffer; + count *= snd_shm->channels; out_max = (snd_shm->frames * snd_shm->channels) - 1; - out_idx = snd_paintedtime * snd_shm->channels; + out_idx = snd_shm->framepos * snd_shm->channels; while (out_idx > out_max) out_idx -= out_max + 1; step = 3 - snd_shm->channels; - snd_vol = snd_volume->value; if (snd_shm->samplebits == 16) { short *out = (short *) snd_shm->buffer; while (count--) { - val = (*p * snd_vol) * 0x8000; + val = (*p * volume) * 0x8000; p += step; if (val > 0x7fff) val = 0x7fff; @@ -106,7 +105,7 @@ s_xfer_paint_buffer (int endtime) unsigned char *out = (unsigned char *) snd_shm->buffer; while (count--) { - val = (*p * snd_vol) * 128; + val = (*p * volume) * 128; p += step; if (val > 0x7f) val = 0x7f; diff --git a/libs/audio/renderer/snd_jack.c b/libs/audio/renderer/snd_jack.c index 664c2e1fd..a0fe9cb5d 100644 --- a/libs/audio/renderer/snd_jack.c +++ b/libs/audio/renderer/snd_jack.c @@ -258,13 +258,10 @@ s_channel_stop (channel_t *chan) } static void -snd_jack_xfer (int endtime) +snd_jack_xfer (portable_samplepair_t *paintbuffer, int count, float volume) { int i; - int count; - float snd_vol = snd_volume->value; - count = endtime - snd_paintedtime; if (snd_blocked) { for (i = 0; i < count; i++) { *output[0]++ = 0; @@ -274,8 +271,8 @@ snd_jack_xfer (int endtime) } for (i = 0; i < count; i++) { /* max is +/- 1.0. need to implement clamping. */ - *output[0]++ = snd_vol * snd_paintbuffer[i].left; - *output[1]++ = snd_vol * snd_paintbuffer[i].right; + *output[0]++ = volume * snd_paintbuffer[i].left; + *output[1]++ = volume * snd_paintbuffer[i].right; } } diff --git a/libs/audio/renderer/snd_mix.c b/libs/audio/renderer/snd_mix.c index dbf347d12..e288ae9d8 100644 --- a/libs/audio/renderer/snd_mix.c +++ b/libs/audio/renderer/snd_mix.c @@ -174,7 +174,8 @@ SND_PaintChannels (unsigned endtime) } // transfer out according to DMA format - snd_shm->xfer (end); + snd_shm->xfer (snd_paintbuffer, end - snd_paintedtime, + snd_volume->value); memmove (snd_paintbuffer, snd_paintbuffer + end - snd_paintedtime, max_overpaint * sizeof (snd_paintbuffer[0])); diff --git a/libs/audio/targets/snd_alsa.c b/libs/audio/targets/snd_alsa.c index 5db3d9afe..e64c8b1d3 100644 --- a/libs/audio/targets/snd_alsa.c +++ b/libs/audio/targets/snd_alsa.c @@ -140,22 +140,19 @@ clamp_8 (int val) } static void -SNDDMA_ni_xfer (int endtime) +SNDDMA_ni_xfer (portable_samplepair_t *paintbuffer, int count, float volume) { const snd_pcm_channel_area_t *areas; - int count, out_idx, out_max; - float snd_vol; + int out_idx, out_max; float *p; areas = sn.xfer_data; - p = (float *) snd_paintbuffer; - count = (endtime - snd_paintedtime); + p = (float *) paintbuffer; out_max = sn.frames - 1; out_idx = sn.framepos; while (out_idx > out_max) out_idx -= out_max + 1; - snd_vol = snd_volume->value; if (sn.samplebits == 16) { short *out_0 = (short *) areas[0].addr; @@ -163,14 +160,14 @@ SNDDMA_ni_xfer (int endtime) if (sn.channels == 2) { while (count--) { - out_0[out_idx] = clamp_16 ((*p++ * snd_vol) * 0x8000); - out_1[out_idx] = clamp_16 ((*p++ * snd_vol) * 0x8000); + out_0[out_idx] = clamp_16 ((*p++ * volume) * 0x8000); + out_1[out_idx] = clamp_16 ((*p++ * volume) * 0x8000); if (out_idx++ > out_max) out_idx = 0; } } else { while (count--) { - out_0[out_idx] = clamp_16 ((*p++ * snd_vol) * 0x8000); + out_0[out_idx] = clamp_16 ((*p++ * volume) * 0x8000); p++; // skip right channel if (out_idx++ > out_max) out_idx = 0; @@ -182,14 +179,14 @@ SNDDMA_ni_xfer (int endtime) if (sn.channels == 2) { while (count--) { - out_0[out_idx] = clamp_8 ((*p++ * snd_vol) * 0x80); - out_1[out_idx] = clamp_8 ((*p++ * snd_vol) * 0x80); + out_0[out_idx] = clamp_8 ((*p++ * volume) * 0x80); + out_1[out_idx] = clamp_8 ((*p++ * volume) * 0x80); if (out_idx++ > out_max) out_idx = 0; } } else { while (count--) { - out_0[out_idx] = clamp_8 ((*p++ * snd_vol) * 0x8000); + out_0[out_idx] = clamp_8 ((*p++ * volume) * 0x8000); p++; // skip right channel if (out_idx++ > out_max) out_idx = 0; diff --git a/libs/audio/targets/snd_dx.c b/libs/audio/targets/snd_dx.c index 0d5721ded..87c8e19a6 100644 --- a/libs/audio/targets/snd_dx.c +++ b/libs/audio/targets/snd_dx.c @@ -406,8 +406,9 @@ SNDDMA_GetDMAPos (void) s /= sn.channels; s %= sn.frames; + sn.framepos = s; - return s; + return sn.framepos; } /* diff --git a/libs/audio/targets/snd_sun.c b/libs/audio/targets/snd_sun.c index 8400487ad..058bff065 100644 --- a/libs/audio/targets/snd_sun.c +++ b/libs/audio/targets/snd_sun.c @@ -171,7 +171,8 @@ SNDDMA_GetDMAPos (void) return (0); } - return ((info.play.samples * sn.channels) % sn.frames); + sn.framepos = ((info.play.samples * sn.channels) % sn.frames); + return sn.framepos; } #if 0 static int diff --git a/libs/audio/targets/snd_win.c b/libs/audio/targets/snd_win.c index df46dcab5..1c319f8f8 100644 --- a/libs/audio/targets/snd_win.c +++ b/libs/audio/targets/snd_win.c @@ -298,8 +298,9 @@ SNDDMA_GetDMAPos (void) s /= sn.channels; s %= sn.frames; + sn.framepos = s; - return s; + return sn.framepos; } /* From 272e955f1870e63521d8bc2137650ac78b53b7e2 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 8 Sep 2011 19:11:43 +0900 Subject: [PATCH 143/334] Fix the version reporting. $Id doesn't work in git, and didn't really report the right version anyway. --- doc/config/gib/qfadmin.gib | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/doc/config/gib/qfadmin.gib b/doc/config/gib/qfadmin.gib index 94334f1d8..66b4bb9e3 100644 --- a/doc/config/gib/qfadmin.gib +++ b/doc/config/gib/qfadmin.gib @@ -73,7 +73,8 @@ domain qfadmin global uservote cmds mapvote config -global cvsheader = "$Id$" +//global cvsheader = "$Id$" +global qfadminversion = "1.17" // QFAdmin console interface function qfadmin { @@ -238,19 +239,20 @@ function qfadmin::doVersion { // Return the current version function qfadmin::getVersion { - local tmp tmp2 +// local tmp tmp2 - tmp = $(split $cvsheader) +// tmp = $(split $cvsheader) - if $(equal $tmp[6] "Exp") { - tmp2 = "Beta" - } else if $(equal $tmp[6] "Stab") { - tmp2 = "Stable" - } else if $(equal $tmp[6] "Rel") { - tmp2 = "Release" - } +// if $(equal $tmp[6] "Exp") { +// tmp2 = "Beta" +// } else if $(equal $tmp[6] "Stab") { +// tmp2 = "Stable" +// } else if $(equal $tmp[6] "Rel") { +// tmp2 = "Release" +// } - return "QFAdmin v", $tmp[2], " (", $tmp[3], " ", $tmp2, ") by Harry Roberts" +// return "QFAdmin v", $tmp[2], " (", $tmp[3], " ", $tmp2, ") by Harry Roberts" + return "QFAdmin v", $qfadminversion, " by Harry Roberts" } // Clear uservore & mapvote vars From 20d056e6c51c8c079fd8a737929c318ab46497f3 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 8 Sep 2011 21:05:33 +0900 Subject: [PATCH 144/334] Fix my broken warnings fixes. That's what you get for blinding working on code you don't grok :P --- libs/gib/regex.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/libs/gib/regex.c b/libs/gib/regex.c index 5e3b2e8b4..aa909a56f 100644 --- a/libs/gib/regex.c +++ b/libs/gib/regex.c @@ -889,7 +889,7 @@ static reg_errcode_t compile_range (const char **p_ptr, const char *pend, char * cast the subscript to translate because some data is declared as `char *', to avoid warnings when a string constant is passed. But when we use a character as a subscript we must make it unsigned. */ -#define TRANSLATE(d) (translate ? translate[(unsigned char) (d)] : (unsigned char)(d)) +#define TRANSLATE(d) (translate ? translate[(unsigned char) (d)] : (d)) /* Macros for outputting the compiled pattern into `buffer'. */ @@ -2217,7 +2217,7 @@ compile_range (p_ptr, pend, translate, syntax, b) reg_syntax_t syntax; unsigned char *b; { - unsigned this_char; + int this_char; const char *p = *p_ptr; int range_start, range_end; @@ -2247,7 +2247,7 @@ compile_range (p_ptr, pend, translate, syntax, b) char' -- the range is inclusive, so if `range_end' == 0xff (assuming 8-bit characters), we would otherwise go into an infinite loop, since all characters <= 0xff. */ - for (this_char = range_start; this_char <= (unsigned) range_end; this_char++) + for (this_char = range_start; this_char <= range_end; this_char++) { SET_LIST_BIT (TRANSLATE (this_char)); } @@ -2475,7 +2475,7 @@ typedef struct #define POP_FAILURE_POINT(str, pat, low_reg, high_reg, regstart, regend, reg_info)\ { \ DEBUG_STATEMENT (fail_stack_elt_t failure_id;) \ - unsigned int this_reg; \ + int this_reg; \ const unsigned char *string_temp; \ \ assert (!FAIL_STACK_EMPTY ()); \ @@ -2512,7 +2512,7 @@ typedef struct low_reg = (unsigned long) POP_FAILURE_ITEM (); \ DEBUG_PRINT2 (" Popping low active reg: %d\n", low_reg); \ \ - for (this_reg = high_reg; this_reg >= low_reg; this_reg--) \ + for (this_reg = high_reg; (unsigned) this_reg >= low_reg; this_reg--) \ { \ DEBUG_PRINT2 (" Popping reg: %d\n", this_reg); \ \ @@ -3181,7 +3181,7 @@ re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop) int stop; { /* General temporaries. */ - unsigned int mcnt; + int mcnt; unsigned char *p1; /* Just past the end of the corresponding string. */ @@ -3324,7 +3324,7 @@ re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop) /* Initialize subexpression text positions to -1 to mark ones that no start_memory/stop_memory has been seen for. Also initialize the register information struct. */ - for (mcnt = 1; mcnt < num_regs; mcnt++) + for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++) { regstart[mcnt] = regend[mcnt] = old_regstart[mcnt] = old_regend[mcnt] = REG_UNSET_VALUE; @@ -3414,7 +3414,7 @@ re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop) DEBUG_PRINT1 ("\nSAVING match as best so far.\n"); - for (mcnt = 1; mcnt < num_regs; mcnt++) + for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++) { best_regstart[mcnt] = regstart[mcnt]; best_regend[mcnt] = regend[mcnt]; @@ -3438,7 +3438,7 @@ re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop) dend = ((d >= string1 && d <= end1) ? end_match_1 : end_match_2); - for (mcnt = 1; mcnt < num_regs; mcnt++) + for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++) { regstart[mcnt] = best_regstart[mcnt]; regend[mcnt] = best_regend[mcnt]; @@ -3491,7 +3491,8 @@ re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop) /* Go through the first `min (num_regs, regs->num_regs)' registers, since that is all we initialized. */ - for (mcnt = 1; mcnt < MIN (num_regs, regs->num_regs); mcnt++) + for (mcnt = 1; (unsigned) mcnt < MIN (num_regs, regs->num_regs); + mcnt++) { if (REG_UNSET (regstart[mcnt]) || REG_UNSET (regend[mcnt])) regs->start[mcnt] = regs->end[mcnt] = -1; @@ -3507,7 +3508,7 @@ re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop) we (re)allocated the registers, this is the case, because we always allocate enough to have at least one -1 at the end. */ - for (mcnt = num_regs; mcnt < regs->num_regs; mcnt++) + for (mcnt = num_regs; (unsigned) mcnt < regs->num_regs; mcnt++) regs->start[mcnt] = regs->end[mcnt] = -1; } /* regs && !bufp->no_sub */ @@ -3840,7 +3841,7 @@ re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop) /* Want how many consecutive characters we can match in one shot, so, if necessary, adjust the count. */ - if (mcnt > (unsigned) (dend2 - d2)) + if ((unsigned) mcnt > (unsigned) (dend2 - d2)) mcnt = dend2 - d2; /* Compare that many; failure if mismatch, else move From 8c67a872c648caaaf416dbaa796807cb518428c4 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 9 Sep 2011 17:29:13 +0900 Subject: [PATCH 145/334] Add the gib docs to make dist. --- doc/Makefile.am | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/doc/Makefile.am b/doc/Makefile.am index 09ef0c2c0..8511d72f3 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -2,25 +2,32 @@ AUTOMAKE_OPTIONS= foreign SUBDIRS= man -DOX=\ +DOX= \ bind.dox config.dox connect.dox cshifts.dox dirconf.dox faq.dox \ filesystem.dox mapformat.dox property-list.dox qtv.dox quakeforge.dox \ qw-cap-spec.dox qw-download-spec.dox sound.dox specifications.dox \ surround-sound.dox timestamps.dox +GIB= \ + gib/GIB.lyx gib/break.gib gib/continue.gib gib/curly.gib gib/examples.sh \ + gib/for.gib gib/gib_head.eps gib/if-chain.gib gib/if-else.gib \ + gib/if-simple.gib gib/while.gib + +PROGS= \ + progs/vm-exec.c progs/vm-mem.fig + EXTRA_DIST= qf.ico \ \ skybox.fig template.c template.h \ quakeforge.dox.conf.in \ \ - ${DOX} \ + ${DOX} ${GIB} ${PROGS} \ \ config/glspeed-v1.cfg config/glspeed-v3.cfg config/swspeed.cfg \ \ config/gib/adjustvolume.gib config/gib/infobot.gib config/gib/ln.gib \ config/gib/qfadmin.gib config/gib/sshot.gib config/gib/zoom.gib \ \ - progs/vm-exec.c progs/vm-mem.fig \ qtv/qwtv.fig SUFFIXES=.eps .fig .png From 08fa6be9f49422809b17dd4c9a08437f1c7900c3 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 9 Sep 2011 17:30:07 +0900 Subject: [PATCH 146/334] Fix a potential buffer underflow. --- libs/util/quakefs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/util/quakefs.c b/libs/util/quakefs.c index 43fd0e30b..d5070bb4b 100644 --- a/libs/util/quakefs.c +++ b/libs/util/quakefs.c @@ -651,7 +651,7 @@ qfs_expand_path (dstring_t *full_path, const char *base, const char *path, if (*cpath == '/') separator = ""; len = strlen (base); - if (base[len -1] == '/') + if (len && base[len - 1] == '/') len--; dsprintf (full_path, "%.*s%s%s", len, base, separator, cpath); free (cpath); From 96ef0ffaea30a11c2975e49aefe6081ee9f2fc06 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 9 Sep 2011 17:33:29 +0900 Subject: [PATCH 147/334] Rewrite QFS_FileExtension() to be more correct. --- libs/util/quakefs.c | 16 ++++++++++++---- libs/util/test/test-qfs.c | 29 ++++++++++++++++++++++++++++- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/libs/util/quakefs.c b/libs/util/quakefs.c index d5070bb4b..fb780d228 100644 --- a/libs/util/quakefs.c +++ b/libs/util/quakefs.c @@ -1337,12 +1337,20 @@ QFS_StripExtension (const char *in, char *out) VISIBLE const char * QFS_FileExtension (const char *in) { - char *tmp; + const char *tmp; + const char *end = in + strlen (in); - if ((tmp = strrchr (in, '.'))) - return tmp; + for (tmp = end; tmp != in; tmp--) { + if (tmp[-1] == '/') + return end; + if (tmp[-1] == '.') { + if (tmp - 1 == in || tmp[-2] == '/') + return end; + return tmp - 1; + } + } - return in; + return end; } VISIBLE void diff --git a/libs/util/test/test-qfs.c b/libs/util/test/test-qfs.c index 8d475a8a8..3dc81bd89 100644 --- a/libs/util/test/test-qfs.c +++ b/libs/util/test/test-qfs.c @@ -30,6 +30,22 @@ struct { }; #define num_path_tests (sizeof (path_tests) / sizeof (path_tests[0])) +struct { + const char *path; + int expect_offset; +} ext_tests[] = { + {"foo", 3}, + {"foo.a", 3}, + {"foo.a.b", 5}, + {".foo", 4}, + {"bar/foo", 7}, + {"bar/foo.a", 7}, + {"bar/foo.a.b", 9}, + {"bar/.foo", 8}, + {"bar.a/foo", 9}, +}; +#define num_ext_tests (sizeof (ext_tests) / sizeof (ext_tests[0])) + int main (int argc, const char **argv) { @@ -37,12 +53,23 @@ main (int argc, const char **argv) int res = 0; for (i = 0; i < num_path_tests; i++) { - char *cpath = QFS_CompressPath (path_tests[i].path); + const char *cpath = QFS_CompressPath (path_tests[i].path); if (strcmp (cpath, path_tests[i].expect)) { fprintf (stderr, "FAIL: (%zd) \"%s\" -> \"%s\", got \"%s\"\n", i, path_tests[i].path, path_tests[i].expect, cpath); res = 1; } } + + for (i = 0; i < num_ext_tests; i++) { + const char *ext = QFS_FileExtension (ext_tests[i].path); + if (ext - ext_tests[i].path != ext_tests[i].expect_offset) { + fprintf (stderr, "FAIL: (%zd) \"%s\" -> %d (%s), got %d (%s)\n", i, + ext_tests[i].path, ext_tests[i].expect_offset, + ext_tests[i].path + ext_tests[i].expect_offset, + ext - ext_tests[i].path, ext); + res = 1; + } + } return res; } From 225f1cd06c419424a176eb88ee893a81e9d65d6e Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 9 Sep 2011 17:35:12 +0900 Subject: [PATCH 148/334] Rewrite QFS_StripExtension() to use QFS_FileExtension(). --- libs/util/quakefs.c | 4 ++-- libs/util/test/test-qfs.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/libs/util/quakefs.c b/libs/util/quakefs.c index fb780d228..7b815ac8a 100644 --- a/libs/util/quakefs.c +++ b/libs/util/quakefs.c @@ -1330,8 +1330,8 @@ QFS_StripExtension (const char *in, char *out) if (out != in) strcpy (out, in); - if ((tmp = strrchr (out, '.'))) - *tmp = 0; + tmp = out + (QFS_FileExtension (out) - out); + *tmp = 0; } VISIBLE const char * diff --git a/libs/util/test/test-qfs.c b/libs/util/test/test-qfs.c index 3dc81bd89..794bbb89c 100644 --- a/libs/util/test/test-qfs.c +++ b/libs/util/test/test-qfs.c @@ -7,6 +7,7 @@ #ifdef HAVE_STRINGS_H # include #endif +#include #include "QF/quakefs.h" @@ -46,6 +47,22 @@ struct { }; #define num_ext_tests (sizeof (ext_tests) / sizeof (ext_tests[0])) +struct { + const char *path; + const char *expect; +} strip_tests[] = { + {"foo", "foo"}, + {"foo.a", "foo"}, + {"foo.a.b", "foo.a"}, + {".foo", ".foo"}, + {"bar/foo", "bar/foo"}, + {"bar/foo.a", "bar/foo"}, + {"bar/foo.a.b", "bar/foo.a"}, + {"bar/.foo", "bar/.foo"}, + {"bar.a/foo", "bar.a/foo"}, +}; +#define num_strip_tests (sizeof (strip_tests) / sizeof (strip_tests[0])) + int main (int argc, const char **argv) { @@ -71,5 +88,16 @@ main (int argc, const char **argv) res = 1; } } + + for (i = 0; i < num_strip_tests; i++) { + char *strip = strdup (strip_tests[i].path); + QFS_StripExtension (strip, strip); + if (strcmp (strip, strip_tests[i].expect)) { + fprintf (stderr, "FAIL: (%zd) \"%s\" -> \"%s\", got \"%s\"\n", i, + strip_tests[i].path, strip_tests[i].expect, strip); + res = 1; + } + free (strip); + } return res; } From d92488ce9f41baf65df8c3d4b62e2c9c46048061 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 9 Sep 2011 17:37:45 +0900 Subject: [PATCH 149/334] Rewrite QFS_DefaultExtension() and QFS_SetExtension(). They now use QFS_FileExtension() to find the correct place for the extension. --- libs/util/quakefs.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/libs/util/quakefs.c b/libs/util/quakefs.c index 7b815ac8a..1c4149c1e 100644 --- a/libs/util/quakefs.c +++ b/libs/util/quakefs.c @@ -1357,16 +1357,13 @@ VISIBLE void QFS_DefaultExtension (dstring_t *path, const char *extension) { const char *src; + const char *ext; // if path doesn't have a .EXT, append extension // (extension should include the .) - src = path->str + strlen (path->str) - 1; - - while (*src != '/' && src != path->str) { - if (*src == '.') - return; // it has an extension - src--; - } + ext = QFS_FileExtension (path->str); + if (*ext) + return; // it has an extension dstring_appendstr (path, extension); } @@ -1375,10 +1372,12 @@ VISIBLE void QFS_SetExtension (struct dstring_s *path, const char *extension) { const char *ext = QFS_FileExtension (path->str); + ptrdiff_t offs = ext - path->str; - if (ext != path->str) { - path->str[ext - path->str] = 0; - path->size = ext - path->str + 1; + if (*ext) { + // path has an extension... cut it off + path->str[offs] = 0; + path->size = offs + 1; } dstring_appendstr (path, extension); } From d043e2bf17327b16471d76923ce1cfa1d43af109 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 9 Sep 2011 17:39:00 +0900 Subject: [PATCH 150/334] Rewrite QFS_FileBase(). It now uses QFS_SkipPath() and QFS_FileExtention() to find the file's base name. --- libs/util/quakefs.c | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/libs/util/quakefs.c b/libs/util/quakefs.c index 1c4149c1e..5c63dded0 100644 --- a/libs/util/quakefs.c +++ b/libs/util/quakefs.c @@ -667,26 +667,17 @@ qfs_expand_userpath (dstring_t *full_path, const char *path) VISIBLE char * QFS_FileBase (const char *in) { - const char *slash, *dot, *s; + const char *base; + const char *ext; + ptrdiff_t len; char *out; - slash = in; - dot = NULL; - s = in; - while (*s) { - if (*s == '/') - slash = s + 1; - if (*s == '.') - dot = s; - s++; - } - if (dot == NULL) - dot = s; - if (dot - slash < 2) - return strdup ("?model?"); - out = malloc (dot - slash + 1); - strncpy (out, slash, dot - slash); - out [dot - slash] = 0; + base = QFS_SkipPath (in); + ext = QFS_FileExtension (base); + len = ext - base; + out = malloc (len + 1); + strncpy (out, slash, len); + out [len] = 0; return out; } From 5914bb620889c02845e5f4420a5d44d47fc6cf8c Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 9 Sep 2011 17:40:15 +0900 Subject: [PATCH 151/334] QFS doc update and cleanup. --- include/QF/quakefs.h | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/include/QF/quakefs.h b/include/QF/quakefs.h index a84ab97ab..11985c23f 100644 --- a/include/QF/quakefs.h +++ b/include/QF/quakefs.h @@ -116,7 +116,7 @@ void QFS_Init (const char *game); Sets the fields in ::qfs_gamedir. Can be called at any time (and is, by the quakeworld clients and servers). - \param gamedir The directory to which to set the game directory. + \param gamedir The directory to which the game directory will be set. */ void QFS_Gamedir (const char *gamedir); @@ -275,7 +275,7 @@ int QFS_NextFilename (struct dstring_s *filename, const char *prefix, /** Extract the non-extension part of the file name from the path. - \param in The path from which to extract the name. + \param in The path from which the name will be extracted. \return The extracted name. \note It is the caller's responsibility to free the extracted name. */ @@ -304,13 +304,17 @@ void QFS_SetExtension (struct dstring_s *path, const char *extension); \param in The path from which to strip the extension. \param out The destination of the stripped path. May be the same as \a in. + \note No size checking is done on \a out. It use the + caller's responsibility to ensure out is large enough + to hold the stripped path. However, the stripped path + will never be longer than the original path. */ void QFS_StripExtension (const char *in, char *out); /** Create a canonical path. - Convert all \\ to /, remove all . elements from the path and resolve - all foo/.. + Convert all \c \\ to \c /, remove all \c . elements from the path and + resolve all \c foo/.. pairs. \param pth The path to make canonical \return The canonical path. @@ -331,7 +335,9 @@ const char *QFS_SkipPath (const char *pathname); \param in The path withing which to find the extention. \return Pointer to the beginning of the extention. This points - inside \a in. + inside \a in at all times. If the path has no extension, + the returned pointer will point to the terminating nul + of the path. */ const char *QFS_FileExtension (const char *in); @@ -374,6 +380,7 @@ void QFS_FilelistAdd (filelist_t *filelist, const char *fname, added to the list. \param ext The extension of the files to be added. \param strip If true, the extension of the files will be stripped. + \bug can escape the quake file system */ void QFS_FilelistFill (filelist_t *list, const char *path, const char *ext, int strip); From a426dacc8a9fb17c59b3f5350ccd2460b12b5df5 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 9 Sep 2011 17:07:47 +0900 Subject: [PATCH 152/334] Add a missing \n --- libs/audio/targets/snd_alsa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/audio/targets/snd_alsa.c b/libs/audio/targets/snd_alsa.c index e64c8b1d3..19af26ad3 100644 --- a/libs/audio/targets/snd_alsa.c +++ b/libs/audio/targets/snd_alsa.c @@ -253,7 +253,7 @@ SNDDMA_Init (void) if (0 > err) { Sys_MaskPrintf (SYS_SND, "ALSA: Failure to set noninterleaved PCM " "access. %s\n", qfsnd_strerror (err)); - Sys_Printf ("ALSA: could not set mmap access"); + Sys_Printf ("ALSA: could not set mmap access\n"); goto error; } sn.xfer = SNDDMA_ni_xfer; From 999912e49a4d671d7af848f39216ede0645c28cb Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 9 Sep 2011 19:55:54 +0900 Subject: [PATCH 153/334] I thought I'd tested those changes :( --- libs/util/quakefs.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libs/util/quakefs.c b/libs/util/quakefs.c index 5c63dded0..c25a65fa6 100644 --- a/libs/util/quakefs.c +++ b/libs/util/quakefs.c @@ -669,14 +669,14 @@ QFS_FileBase (const char *in) { const char *base; const char *ext; - ptrdiff_t len; + int len; char *out; base = QFS_SkipPath (in); ext = QFS_FileExtension (base); len = ext - base; out = malloc (len + 1); - strncpy (out, slash, len); + strncpy (out, base, len); out [len] = 0; return out; } @@ -1347,7 +1347,6 @@ QFS_FileExtension (const char *in) VISIBLE void QFS_DefaultExtension (dstring_t *path, const char *extension) { - const char *src; const char *ext; // if path doesn't have a .EXT, append extension @@ -1363,7 +1362,7 @@ VISIBLE void QFS_SetExtension (struct dstring_s *path, const char *extension) { const char *ext = QFS_FileExtension (path->str); - ptrdiff_t offs = ext - path->str; + int offs = ext - path->str; if (*ext) { // path has an extension... cut it off From bfd1680c151e8369d3efd182d7b31bdace9c5607 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 9 Sep 2011 19:56:16 +0900 Subject: [PATCH 154/334] Fix a 32/64 bit portability issue. --- libs/util/test/test-qfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/util/test/test-qfs.c b/libs/util/test/test-qfs.c index 794bbb89c..b9d7ba52a 100644 --- a/libs/util/test/test-qfs.c +++ b/libs/util/test/test-qfs.c @@ -84,7 +84,7 @@ main (int argc, const char **argv) fprintf (stderr, "FAIL: (%zd) \"%s\" -> %d (%s), got %d (%s)\n", i, ext_tests[i].path, ext_tests[i].expect_offset, ext_tests[i].path + ext_tests[i].expect_offset, - ext - ext_tests[i].path, ext); + (int) (ext - ext_tests[i].path), ext); res = 1; } } From da7ddc35c01ae0f1dacec2838134261592885ef9 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 10 Sep 2011 12:07:18 +0900 Subject: [PATCH 155/334] Fix the segaults when trying to use snd_disk. It's output is still bogus (and it writes to the current directory!), but at least the plugin can be used without any nasty issues. --- libs/audio/targets/snd_disk.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/libs/audio/targets/snd_disk.c b/libs/audio/targets/snd_disk.c index 1c8d36f39..ddbfee0b1 100644 --- a/libs/audio/targets/snd_disk.c +++ b/libs/audio/targets/snd_disk.c @@ -68,30 +68,29 @@ static snd_output_data_t plugin_info_snd_output_data; static snd_output_funcs_t plugin_info_snd_output_funcs; -/* FIXME static volatile dma_t * SNDDMA_Init (void) { - memset ((dma_t *) sn, 0, sizeof (sn)); + memset ((dma_t *) &sn, 0, sizeof (sn)); sn.channels = 2; sn.submission_chunk = 1; // don't mix less than this # - sn.samplepos = 0; // in mono samples + sn.framepos = 0; sn.samplebits = 16; - sn.samples = 16384; // mono samples in buffer + sn.frames = 16384; sn.speed = 44100; - sn.buffer = malloc (sn.samples * sn.channels * sn.samplebits / 8); + sn.buffer = malloc (sn.frames * sn.channels * sn.samplebits / 8); if (!sn.buffer) { Sys_Printf ("SNDDMA_Init: memory allocation failure\n"); return 0; } - Sys_Printf ("%5d stereo\n", sn.channels - 1); - Sys_Printf ("%5d samples\n", sn.samples); - Sys_Printf ("%5d samplepos\n", sn.samplepos); + Sys_Printf ("%5d channels\n", sn.channels - 1); + Sys_Printf ("%5d samples\n", sn.frames); + Sys_Printf ("%5d samplepos\n", sn.framepos); Sys_Printf ("%5d samplebits\n", sn.samplebits); Sys_Printf ("%5d submission_chunk\n", sn.submission_chunk); Sys_Printf ("%5d speed\n", sn.speed); - Sys_Printf ("0x%x dma buffer\n", (int) sn.buffer); + Sys_Printf ("0x%lx dma buffer\n", (long) sn.buffer); if (!(snd_file = Qopen ("qf.raw", "wb"))) return 0; @@ -99,7 +98,11 @@ SNDDMA_Init (void) snd_inited = 1; return &sn; } -*/ + +static void +SNDDMA_Init_Cvars (void) +{ +} static int SNDDMA_GetDMAPos (void) @@ -172,8 +175,10 @@ PLUGIN_INFO(snd_output, disk) plugin_info_funcs.input = NULL; plugin_info_funcs.snd_output = &plugin_info_snd_output_funcs; -// plugin_info_general_funcs.p_Init = SNDDMA_Init; // FIXME - plugin_info_general_funcs.p_Shutdown = SNDDMA_Shutdown; + plugin_info_general_funcs.p_Init = SNDDMA_Init_Cvars; + plugin_info_general_funcs.p_Shutdown = NULL; + plugin_info_snd_output_funcs.pS_O_Init = SNDDMA_Init; + plugin_info_snd_output_funcs.pS_O_Shutdown = SNDDMA_Shutdown; plugin_info_snd_output_funcs.pS_O_GetDMAPos = SNDDMA_GetDMAPos; plugin_info_snd_output_funcs.pS_O_Submit = SNDDMA_Submit; plugin_info_snd_output_funcs.pS_O_BlockSound = SNDDMA_BlockSound; From f3017edf0d76b92053c22c63b168b058907fcc27 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 10 Sep 2011 15:10:45 +0900 Subject: [PATCH 156/334] Fix RPM building. --- RPM/quakeforge.spec.in | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/RPM/quakeforge.spec.in b/RPM/quakeforge.spec.in index 7a4792f89..abee45b13 100644 --- a/RPM/quakeforge.spec.in +++ b/RPM/quakeforge.spec.in @@ -308,6 +308,7 @@ rm $RPM_BUILD_ROOT/usr/bin/nq-fbdev rm $RPM_BUILD_ROOT/usr/bin/nq-sdl32 rm $RPM_BUILD_ROOT/usr/bin/qw-client-fbdev rm $RPM_BUILD_ROOT/usr/bin/qw-client-sdl32 +rm $RPM_BUILD_ROOT/usr/bin/qfpc find $RPM_BUILD_ROOT/usr/lib -name 'libQFrenderer_sw32.*' -exec rm {} \; #FIXME until I feel like making packages rm $RPM_BUILD_ROOT/usr/bin/qtv @@ -327,7 +328,6 @@ rm -rf $RPM_BUILD_ROOT %attr(-,root,root) %{_prefix}/lib/libQFcd.so.* %attr(-,root,root) %{_prefix}/lib/libQFconsole.so.* %attr(-,root,root) %{_prefix}/lib/libQFgamecode.so.* -%attr(-,root,root) %{_prefix}/lib/libQFgamecode_builtins.so.* %attr(-,root,root) %{_prefix}/lib/libQFgib.so.* %attr(-,root,root) %{_prefix}/lib/libQFimage.so.* %attr(-,root,root) %{_prefix}/lib/libQFjs.so.* @@ -335,11 +335,11 @@ rm -rf $RPM_BUILD_ROOT %attr(-,root,root) %{_prefix}/lib/libQFruamoko.so.* %attr(-,root,root) %{_prefix}/lib/libQFsound.so.* %attr(-,root,root) %{_prefix}/lib/libQFutil.so.* -%attr(-,root,root) %{_prefix}/lib/quakeforge/cd_file.so* -%attr(-,root,root) %{_prefix}/lib/quakeforge/cd_linux.so* -%attr(-,root,root) %{_prefix}/lib/quakeforge/console_client.so* -%attr(-,root,root) %{_prefix}/lib/quakeforge/snd_output_disk.so* -%attr(-,root,root) %{_prefix}/lib/quakeforge/snd_render_default.so* +%attr(-,root,root) %{_prefix}/lib/quakeforge/plugins/cd_file.so* +%attr(-,root,root) %{_prefix}/lib/quakeforge/plugins/cd_linux.so* +%attr(-,root,root) %{_prefix}/lib/quakeforge/plugins/console_client.so* +%attr(-,root,root) %{_prefix}/lib/quakeforge/plugins/snd_output_disk.so* +%attr(-,root,root) %{_prefix}/lib/quakeforge/plugins/snd_render_default.so* %attr(-,root,root) %{fs_sharepath}/QF/menu.* %files devel @@ -349,8 +349,6 @@ rm -rf $RPM_BUILD_ROOT %attr(-,root,root) %{_prefix}/lib/libQFconsole.so %attr(-,root,root) %{_prefix}/lib/libQFgamecode.*a %attr(-,root,root) %{_prefix}/lib/libQFgamecode.so -%attr(-,root,root) %{_prefix}/lib/libQFgamecode_builtins.*a -%attr(-,root,root) %{_prefix}/lib/libQFgamecode_builtins.so %attr(-,root,root) %{_prefix}/lib/libQFgib.*a %attr(-,root,root) %{_prefix}/lib/libQFgib.so %attr(-,root,root) %{_prefix}/lib/libQFimage.*a @@ -395,7 +393,7 @@ rm -rf $RPM_BUILD_ROOT %attr(-,root,root) %{_prefix}/bin/nq-server %attr(-,root,root) %{_prefix}/bin/qw-master #%attr(-,root,root) %{_prefix}/bin/hw-master -%attr(-,root,root) %{_prefix}/lib/quakeforge/console_server.so* +%attr(-,root,root) %{_prefix}/lib/quakeforge/plugins/console_server.so* %if "%{HAVE_X11}"=="'yes'" %files glx @@ -405,8 +403,8 @@ rm -rf $RPM_BUILD_ROOT %if "%{HAVE_SDL}"=="'yes'" %files sdl-common -%attr(-,root,root) %{_prefix}/lib/quakeforge/cd_sdl.so* -%attr(-,root,root) %{_prefix}/lib/quakeforge/snd_output_sdl.so* +%attr(-,root,root) %{_prefix}/lib/quakeforge/plugins/cd_sdl.so* +%attr(-,root,root) %{_prefix}/lib/quakeforge/plugins/snd_output_sdl.so* %files sdl %attr(-,root,root) %{_prefix}/bin/qw-client-sdl @@ -431,17 +429,17 @@ rm -rf $RPM_BUILD_ROOT %if "%{HAVE_XMMS}"=="'yes'" %files xmms -%attr(-,root,root) %{_prefix}/lib/quakeforge/cd_xmms.so +%attr(-,root,root) %{_prefix}/lib/quakeforge/plugins/cd_xmms.so %endif %if "%{HAVE_ALSA}"=="'yes'" %files alsa -%attr(-,root,root) %{_prefix}/lib/quakeforge/snd_output_alsa.so* +%attr(-,root,root) %{_prefix}/lib/quakeforge/plugins/snd_output_alsa.so* %endif %if "%{HAVE_OSS}"=="'yes'" %files oss -%attr(-,root,root) %{_prefix}/lib/quakeforge/snd_output_oss.so* +%attr(-,root,root) %{_prefix}/lib/quakeforge/plugins/snd_output_oss.so* %endif %files -n qfcc @@ -466,6 +464,7 @@ rm -rf $RPM_BUILD_ROOT %attr(-,root,root) %{_prefix}/bin/bsp2img %attr(-,root,root) %{_prefix}/bin/qfbsp %attr(-,root,root) %{_prefix}/bin/qflight +%attr(-,root,root) %{_prefix}/bin/qflmp %attr(-,root,root) %{_prefix}/bin/qfmodelgen %attr(-,root,root) %{_prefix}/bin/qfvis %attr(-,root,root) %{_prefix}/bin/wad From 1f4a6daafb57b146bb314d4ad3fd788bae91df61 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 10 Sep 2011 15:37:10 +0900 Subject: [PATCH 157/334] Fixes for win32. I'd forgotten why SDL_main had such a lame prototype. It turns out my previous mingw testing wasing testing SDL :( --- nq/source/sys_sdl.c | 4 ++-- qw/source/cl_sys_sdl.c | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/nq/source/sys_sdl.c b/nq/source/sys_sdl.c index ac22c3bf6..053773e56 100644 --- a/nq/source/sys_sdl.c +++ b/nq/source/sys_sdl.c @@ -102,7 +102,7 @@ shutdown_f (void) #endif int -SDL_main (int argc, const char **argv) +SDL_main (int argc, char *argv[]) { double time, oldtime, newtime; @@ -110,7 +110,7 @@ SDL_main (int argc, const char **argv) memset (&host_parms, 0, sizeof (host_parms)); - COM_InitArgv (argc, argv); + COM_InitArgv (argc, (const char **) argv); host_parms.argc = com_argc; host_parms.argv = com_argv; diff --git a/qw/source/cl_sys_sdl.c b/qw/source/cl_sys_sdl.c index 9e23e7700..2414ccca0 100644 --- a/qw/source/cl_sys_sdl.c +++ b/qw/source/cl_sys_sdl.c @@ -110,7 +110,7 @@ shutdown_f (void) #endif int -SDL_main (int argc, const char **argv) +SDL_main (int argc, char *argv[]) { double time, oldtime, newtime; @@ -118,13 +118,13 @@ SDL_main (int argc, const char **argv) memset (&host_parms, 0, sizeof (host_parms)); - COM_InitArgv (argc, argv); + COM_InitArgv (argc, (const char **) argv); host_parms.argc = com_argc; host_parms.argv = com_argv; - +#ifndef _WIN32 if (!COM_CheckParm ("-noconinput")) fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) | O_NONBLOCK); - +#endif Sys_RegisterShutdown (Host_Shutdown); Sys_RegisterShutdown (Net_LogStop); Sys_RegisterShutdown (shutdown_f); From 8e30d3098e55925fcaa6490851eacf85f0babe79 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 10 Sep 2011 17:49:14 +0900 Subject: [PATCH 158/334] Fix asm ilnking in mingw. It seems that recent binutils/libtool doesn't like exporting symbols that don't begin with a _. --- libs/video/renderer/sw/d_draw.S | 290 ++++++++++++------------ libs/video/renderer/sw/d_parta.S | 50 ++--- libs/video/renderer/sw/d_polysa.S | 46 ++-- libs/video/renderer/sw/d_spr8.S | 330 ++++++++++++++-------------- libs/video/renderer/sw/d_varsa.S | 130 +++++------ libs/video/renderer/sw/fpua.S | 46 ++-- libs/video/renderer/sw/sw_raclipa.S | 16 +- libs/video/renderer/sw/sw_rdrawa.S | 12 +- libs/video/renderer/sw/sw_rvarsa.S | 54 ++--- 9 files changed, 488 insertions(+), 486 deletions(-) diff --git a/libs/video/renderer/sw/d_draw.S b/libs/video/renderer/sw/d_draw.S index 09864903c..15e33d33c 100644 --- a/libs/video/renderer/sw/d_draw.S +++ b/libs/video/renderer/sw/d_draw.S @@ -112,17 +112,17 @@ C(D_DrawSpans8): // // TODO: any overlap from rearranging? flds C(d_sdivzstepu) - fmuls fp_8 + fmuls C(fp_8) movl C(cacheblock),%edx flds C(d_tdivzstepu) - fmuls fp_8 + fmuls C(fp_8) movl pspans(%esp),%ebx // point to the first span descriptor flds C(d_zistepu) - fmuls fp_8 - movl %edx,pbase // pbase = cacheblock - fstps zi8stepu - fstps tdivz8stepu - fstps sdivz8stepu + fmuls C(fp_8) + movl %edx,C(pbase) // pbase = cacheblock + fstps C(zi8stepu) + fstps C(tdivz8stepu) + fstps C(sdivz8stepu) LSpanLoop: // @@ -175,7 +175,7 @@ LSpanLoop: fxch %st(2) // dv*d_zistepv | du*d_zistepu | t/z | s/z faddp %st(0),%st(1) // dv*d_zistepv + du*d_zistepu | t/z | s/z - flds fp_64k // fp_64k | dv*d_zistepv + du*d_zistepu | t/z | s/z + flds C(fp_64k) // fp_64k | dv*d_zistepv + du*d_zistepu | t/z | s/z fxch %st(1) // dv*d_zistepv + du*d_zistepu | fp_64k | t/z | s/z fadds C(d_ziorigin) // zi = d_ziorigin + dv*d_zistepv + // du*d_zistepu; stays in %st(0) at end @@ -190,7 +190,7 @@ LSpanLoop: // movl C(d_viewbuffer),%ecx movl espan_t_v(%ebx),%eax - movl %ebx,pspantemp // preserve spans pointer + movl %ebx,C(pspantemp) // preserve spans pointer movl C(tadjust),%edx movl C(sadjust),%esi @@ -208,7 +208,7 @@ LSpanLoop: decl %ecx jz LCleanup1 // if only one pixel, no need to start an FDIV - movl %ecx,spancountminus1 + movl %ecx,C(spancountminus1) // finish up the s and t calcs fxch %st(1) // z*64k | 1/z | t/z | s/z @@ -218,10 +218,10 @@ LSpanLoop: fxch %st(1) // z*64k | s | 1/z | t/z | s/z fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z fxch %st(1) // s | t | 1/z | t/z | s/z - fistpl s // 1/z | t | t/z | s/z - fistpl t // 1/z | t/z | s/z + fistpl C(s) // 1/z | t | t/z | s/z + fistpl C(t) // 1/z | t/z | s/z - fildl spancountminus1 + fildl C(spancountminus1) flds C(d_tdivzstepu) // C(d_tdivzstepu) | spancountminus1 flds C(d_zistepu) // C(d_zistepu) | C(d_tdivzstepu) | spancountminus1 @@ -238,7 +238,7 @@ LSpanLoop: faddp %st(0),%st(3) // C(d_sdivzstepu)*scm1 faddp %st(0),%st(3) - flds fp_64k + flds C(fp_64k) fdiv %st(1),%st(0) // this is what we've gone to all this trouble to // overlap jmp LFDIVInFlight1 @@ -252,8 +252,8 @@ LCleanup1: fxch %st(1) // z*64k | s | 1/z | t/z | s/z fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z fxch %st(1) // s | t | 1/z | t/z | s/z - fistpl s // 1/z | t | t/z | s/z - fistpl t // 1/z | t/z | s/z + fistpl C(s) // 1/z | t | t/z | s/z + fistpl C(t) // 1/z | t/z | s/z jmp LFDIVInFlight1 .align 4 @@ -266,41 +266,41 @@ LSetupNotLast1: fxch %st(1) // z*64k | s | 1/z | t/z | s/z fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z fxch %st(1) // s | t | 1/z | t/z | s/z - fistpl s // 1/z | t | t/z | s/z - fistpl t // 1/z | t/z | s/z + fistpl C(s) // 1/z | t | t/z | s/z + fistpl C(t) // 1/z | t/z | s/z - fadds zi8stepu + fadds C(zi8stepu) fxch %st(2) - fadds sdivz8stepu + fadds C(sdivz8stepu) fxch %st(2) - flds tdivz8stepu + flds C(tdivz8stepu) faddp %st(0),%st(2) - flds fp_64k + flds C(fp_64k) fdiv %st(1),%st(0) // z = 1/1/z // this is what we've gone to all this trouble to // overlap LFDIVInFlight1: - addl s,%esi - addl t,%edx + addl C(s),%esi + addl C(t),%edx movl C(bbextents),%ebx movl C(bbextentt),%ebp cmpl %ebx,%esi ja LClampHighOrLow0 LClampReentry0: - movl %esi,s - movl pbase,%ebx + movl %esi,C(s) + movl C(pbase),%ebx shll $16,%esi cmpl %ebp,%edx - movl %esi,sfracf + movl %esi,C(sfracf) ja LClampHighOrLow1 LClampReentry1: - movl %edx,t - movl s,%esi // sfrac = scans->sfrac; + movl %edx,C(t) + movl C(s),%esi // sfrac = scans->sfrac; shll $16,%edx - movl t,%eax // tfrac = scans->tfrac; + movl C(t),%eax // tfrac = scans->tfrac; sarl $16,%esi - movl %edx,tfracf + movl %edx,C(tfracf) // // calculate the texture starting address @@ -335,15 +335,15 @@ LNotLastSegment: fxch %st(1) fmul %st(3),%st(0) // t = t/z * z fxch %st(1) - fistpl snext - fistpl tnext - movl snext,%eax - movl tnext,%edx + fistpl C(snext) + fistpl C(tnext) + movl C(snext),%eax + movl C(tnext),%edx movb (%esi),%bl // get first source texel subl $8,%ecx // count off this segments' pixels movl C(sadjust),%ebp - movl %ecx,counttemp // remember count of remaining pixels + movl %ecx,C(counttemp) // remember count of remaining pixels movl C(tadjust),%ecx movb %bl,(%edi) // store first dest pixel @@ -366,11 +366,11 @@ LClampReentry2: ja LClampHigh3 LClampReentry3: - movl %ebp,snext - movl %ecx,tnext + movl %ebp,C(snext) + movl %ecx,C(tnext) - subl s,%ebp - subl t,%ecx + subl C(s),%ebp + subl C(t),%ecx // // set up advancetable @@ -392,61 +392,61 @@ LSetUp1: addl %edx,%eax // add in sstep // (tstep >> 16) * cachewidth + (sstep >> 16); - movl tfracf,%edx - movl %eax,advancetable+4 // advance base in t + movl C(tfracf),%edx + movl %eax,C(advancetable)+4 // advance base in t addl %ebx,%eax // ((tstep >> 16) + 1) * cachewidth + // (sstep >> 16); shll $13,%ebp // left-justify sstep fractional part - movl sfracf,%ebx + movl C(sfracf),%ebx shll $13,%ecx // left-justify tstep fractional part - movl %eax,advancetable // advance extra in t + movl %eax,C(advancetable) // advance extra in t - movl %ecx,tstep + movl %ecx,C(tstep) addl %ecx,%edx // advance tfrac fractional part by tstep frac sbbl %ecx,%ecx // turn tstep carry into -1 (0 if none) addl %ebp,%ebx // advance sfrac fractional part by sstep frac - adcl advancetable+4(,%ecx,4),%esi // point to next source texel + adcl C(advancetable)+4(,%ecx,4),%esi // point to next source texel - addl tstep,%edx + addl C(tstep),%edx sbbl %ecx,%ecx movb (%esi),%al addl %ebp,%ebx movb %al,1(%edi) - adcl advancetable+4(,%ecx,4),%esi + adcl C(advancetable)+4(,%ecx,4),%esi - addl tstep,%edx + addl C(tstep),%edx sbbl %ecx,%ecx addl %ebp,%ebx movb (%esi),%al - adcl advancetable+4(,%ecx,4),%esi + adcl C(advancetable)+4(,%ecx,4),%esi - addl tstep,%edx + addl C(tstep),%edx sbbl %ecx,%ecx movb %al,2(%edi) addl %ebp,%ebx movb (%esi),%al - adcl advancetable+4(,%ecx,4),%esi + adcl C(advancetable)+4(,%ecx,4),%esi - addl tstep,%edx + addl C(tstep),%edx sbbl %ecx,%ecx movb %al,3(%edi) addl %ebp,%ebx movb (%esi),%al - adcl advancetable+4(,%ecx,4),%esi + adcl C(advancetable)+4(,%ecx,4),%esi // // start FDIV for end of next segment in flight, so it can overlap // - movl counttemp,%ecx + movl C(counttemp),%ecx cmpl $8,%ecx // more than one segment after this? ja LSetupNotLast2 // yes decl %ecx jz LFDIVInFlight2 // if only one pixel, no need to start an FDIV - movl %ecx,spancountminus1 - fildl spancountminus1 + movl %ecx,C(spancountminus1) + fildl C(spancountminus1) flds C(d_zistepu) // C(d_zistepu) | spancountminus1 fmul %st(1),%st(0) // C(d_zistepu)*scm1 | scm1 @@ -458,7 +458,7 @@ LSetUp1: fmuls C(d_sdivzstepu) // C(d_sdivzstepu)*scm1 | C(d_tdivzstepu)*scm1 fxch %st(1) // C(d_tdivzstepu)*scm1 | C(d_sdivzstepu)*scm1 faddp %st(0),%st(3) // C(d_sdivzstepu)*scm1 - flds fp_64k // 64k | C(d_sdivzstepu)*scm1 + flds C(fp_64k) // 64k | C(d_sdivzstepu)*scm1 fxch %st(1) // C(d_sdivzstepu)*scm1 | 64k faddp %st(0),%st(4) // 64k @@ -468,49 +468,49 @@ LSetUp1: .align 4 LSetupNotLast2: - fadds zi8stepu + fadds C(zi8stepu) fxch %st(2) - fadds sdivz8stepu + fadds C(sdivz8stepu) fxch %st(2) - flds tdivz8stepu + flds C(tdivz8stepu) faddp %st(0),%st(2) - flds fp_64k + flds C(fp_64k) fdiv %st(1),%st(0) // z = 1/1/z // this is what we've gone to all this trouble to // overlap LFDIVInFlight2: - movl %ecx,counttemp + movl %ecx,C(counttemp) - addl tstep,%edx + addl C(tstep),%edx sbbl %ecx,%ecx movb %al,4(%edi) addl %ebp,%ebx movb (%esi),%al - adcl advancetable+4(,%ecx,4),%esi + adcl C(advancetable)+4(,%ecx,4),%esi - addl tstep,%edx + addl C(tstep),%edx sbbl %ecx,%ecx movb %al,5(%edi) addl %ebp,%ebx movb (%esi),%al - adcl advancetable+4(,%ecx,4),%esi + adcl C(advancetable)+4(,%ecx,4),%esi - addl tstep,%edx + addl C(tstep),%edx sbbl %ecx,%ecx movb %al,6(%edi) addl %ebp,%ebx movb (%esi),%al - adcl advancetable+4(,%ecx,4),%esi + adcl C(advancetable)+4(,%ecx,4),%esi addl $8,%edi - movl %edx,tfracf - movl snext,%edx - movl %ebx,sfracf - movl tnext,%ebx - movl %edx,s - movl %ebx,t + movl %edx,C(tfracf) + movl C(snext),%edx + movl %ebx,C(sfracf) + movl C(tnext),%ebx + movl %edx,C(s) + movl %ebx,C(t) - movl counttemp,%ecx // retrieve count + movl C(counttemp),%ecx // retrieve count // // determine whether last span or not @@ -540,16 +540,16 @@ LLastSegment: fxch %st(1) fmul %st(3),%st(0) // t = t/z * z fxch %st(1) - fistpl snext - fistpl tnext + fistpl C(snext) + fistpl C(tnext) movb (%esi),%al // load first texel in segment movl C(tadjust),%ebx movb %al,(%edi) // store first pixel in segment movl C(sadjust),%eax - addl snext,%eax - addl tnext,%ebx + addl C(snext),%eax + addl C(tnext),%ebx movl C(bbextents),%ebp movl C(bbextentt),%edx @@ -559,7 +559,7 @@ LLastSegment: cmpl %ebp,%eax ja LClampHigh4 LClampReentry4: - movl %eax,snext + movl %eax,C(snext) cmpl $2048,%ebx jl LClampLow5 @@ -570,25 +570,25 @@ LClampReentry5: cmpl $1,%ecx // don't bother je LOnlyOneStep // if two pixels in segment, there's only one step, // of the segment length - subl s,%eax - subl t,%ebx + subl C(s),%eax + subl C(t),%ebx addl %eax,%eax // convert to 15.17 format so multiply by 1.31 addl %ebx,%ebx // reciprocal yields 16.48 - imull reciprocal_table-8(,%ecx,4) // sstep = (snext - s) / (spancount-1) + imull C(reciprocal_table)-8(,%ecx,4) // sstep = (snext - s) / (spancount-1) movl %edx,%ebp movl %ebx,%eax - imull reciprocal_table-8(,%ecx,4) // tstep = (tnext - t) / (spancount-1) + imull C(reciprocal_table)-8(,%ecx,4) // tstep = (tnext - t) / (spancount-1) LSetEntryvec: // // set up advancetable // - movl entryvec_table(,%ecx,4),%ebx + movl C(entryvec_table)(,%ecx,4),%ebx movl %edx,%eax - movl %ebx,jumptemp // entry point into code for RET later + movl %ebx,C(jumptemp) // entry point into code for RET later movl %ebp,%ecx sarl $16,%edx // tstep >>= 16; movl C(cachewidth),%ebx @@ -597,23 +597,23 @@ LSetEntryvec: addl %ecx,%edx // add in sstep // (tstep >> 16) * cachewidth + (sstep >> 16); - movl tfracf,%ecx - movl %edx,advancetable+4 // advance base in t + movl C(tfracf),%ecx + movl %edx,C(advancetable)+4 // advance base in t addl %ebx,%edx // ((tstep >> 16) + 1) * cachewidth + // (sstep >> 16); shll $16,%ebp // left-justify sstep fractional part - movl sfracf,%ebx + movl C(sfracf),%ebx shll $16,%eax // left-justify tstep fractional part - movl %edx,advancetable // advance extra in t + movl %edx,C(advancetable) // advance extra in t - movl %eax,tstep + movl %eax,C(tstep) movl %ecx,%edx addl %eax,%edx sbbl %ecx,%ecx addl %ebp,%ebx - adcl advancetable+4(,%ecx,4),%esi + adcl C(advancetable)+4(,%ecx,4),%esi - jmp *jumptemp // jump to the number-of-pixels handler + jmp *C(jumptemp) // jump to the number-of-pixels handler //---------------------------------------- @@ -624,128 +624,128 @@ LNoSteps: LOnlyOneStep: - subl s,%eax - subl t,%ebx + subl C(s),%eax + subl C(t),%ebx movl %eax,%ebp movl %ebx,%edx jmp LSetEntryvec //---------------------------------------- -.globl Entry2_8 -Entry2_8: +.globl C(Entry2_8) +C(Entry2_8): subl $6,%edi // adjust for hardwired offsets movb (%esi),%al jmp LLEntry2_8 //---------------------------------------- -.globl Entry3_8 -Entry3_8: +.globl C(Entry3_8) +C(Entry3_8): subl $5,%edi // adjust for hardwired offsets addl %eax,%edx movb (%esi),%al sbbl %ecx,%ecx addl %ebp,%ebx - adcl advancetable+4(,%ecx,4),%esi + adcl C(advancetable)+4(,%ecx,4),%esi jmp LLEntry3_8 //---------------------------------------- -.globl Entry4_8 -Entry4_8: +.globl C(Entry4_8) +C(Entry4_8): subl $4,%edi // adjust for hardwired offsets addl %eax,%edx movb (%esi),%al sbbl %ecx,%ecx addl %ebp,%ebx - adcl advancetable+4(,%ecx,4),%esi - addl tstep,%edx + adcl C(advancetable)+4(,%ecx,4),%esi + addl C(tstep),%edx jmp LLEntry4_8 //---------------------------------------- -.globl Entry5_8 -Entry5_8: +.globl C(Entry5_8) +C(Entry5_8): subl $3,%edi // adjust for hardwired offsets addl %eax,%edx movb (%esi),%al sbbl %ecx,%ecx addl %ebp,%ebx - adcl advancetable+4(,%ecx,4),%esi - addl tstep,%edx + adcl C(advancetable)+4(,%ecx,4),%esi + addl C(tstep),%edx jmp LLEntry5_8 //---------------------------------------- -.globl Entry6_8 -Entry6_8: +.globl C(Entry6_8) +C(Entry6_8): subl $2,%edi // adjust for hardwired offsets addl %eax,%edx movb (%esi),%al sbbl %ecx,%ecx addl %ebp,%ebx - adcl advancetable+4(,%ecx,4),%esi - addl tstep,%edx + adcl C(advancetable)+4(,%ecx,4),%esi + addl C(tstep),%edx jmp LLEntry6_8 //---------------------------------------- -.globl Entry7_8 -Entry7_8: +.globl C(Entry7_8) +C(Entry7_8): decl %edi // adjust for hardwired offsets addl %eax,%edx movb (%esi),%al sbbl %ecx,%ecx addl %ebp,%ebx - adcl advancetable+4(,%ecx,4),%esi - addl tstep,%edx + adcl C(advancetable)+4(,%ecx,4),%esi + addl C(tstep),%edx jmp LLEntry7_8 //---------------------------------------- -.globl Entry8_8 -Entry8_8: +.globl C(Entry8_8) +C(Entry8_8): addl %eax,%edx movb (%esi),%al sbbl %ecx,%ecx addl %ebp,%ebx - adcl advancetable+4(,%ecx,4),%esi + adcl C(advancetable)+4(,%ecx,4),%esi - addl tstep,%edx + addl C(tstep),%edx sbbl %ecx,%ecx movb %al,1(%edi) addl %ebp,%ebx movb (%esi),%al - adcl advancetable+4(,%ecx,4),%esi - addl tstep,%edx + adcl C(advancetable)+4(,%ecx,4),%esi + addl C(tstep),%edx LLEntry7_8: sbbl %ecx,%ecx movb %al,2(%edi) addl %ebp,%ebx movb (%esi),%al - adcl advancetable+4(,%ecx,4),%esi - addl tstep,%edx + adcl C(advancetable)+4(,%ecx,4),%esi + addl C(tstep),%edx LLEntry6_8: sbbl %ecx,%ecx movb %al,3(%edi) addl %ebp,%ebx movb (%esi),%al - adcl advancetable+4(,%ecx,4),%esi - addl tstep,%edx + adcl C(advancetable)+4(,%ecx,4),%esi + addl C(tstep),%edx LLEntry5_8: sbbl %ecx,%ecx movb %al,4(%edi) addl %ebp,%ebx movb (%esi),%al - adcl advancetable+4(,%ecx,4),%esi - addl tstep,%edx + adcl C(advancetable)+4(,%ecx,4),%esi + addl C(tstep),%edx LLEntry4_8: sbbl %ecx,%ecx movb %al,5(%edi) addl %ebp,%ebx movb (%esi),%al - adcl advancetable+4(,%ecx,4),%esi + adcl C(advancetable)+4(,%ecx,4),%esi LLEntry3_8: movb %al,6(%edi) movb (%esi),%al @@ -760,7 +760,7 @@ LEndSpan: fstp %st(0) fstp %st(0) - movl pspantemp,%ebx // restore spans pointer + movl C(pspantemp),%ebx // restore spans pointer movl espan_t_pnext(%ebx),%ebx // point to next span testl %ebx,%ebx // any more spans? movb %al,7(%edi) @@ -811,10 +811,10 @@ C(D_DrawZSpans): testl %eax,%eax jz LFNegSpan - fmuls Float2ToThe31nd - fistpl izistep // note: we are relying on FP exceptions being turned + fmuls C(Float2ToThe31nd) + fistpl C(izistep) // note: we are relying on FP exceptions being turned // off here to avoid range problems - movl izistep,%ebx // remains loaded for all spans + movl C(izistep),%ebx // remains loaded for all spans LFSpanLoop: // set up the initial 1/z value @@ -831,7 +831,7 @@ LFSpanLoop: faddp %st(0),%st(1) // clamp if z is nearer than 2 (1/z > 0.5) - fcoms float_point5 + fcoms C(float_point5) addl %ecx,%edi movl espan_t_u(%esi),%edx addl %edx,%edx // word count @@ -842,11 +842,11 @@ LFSpanLoop: testb $0x45,%ah jz LClamp - fmuls Float2ToThe31nd - fistpl izi // note: we are relying on FP exceptions being turned + fmuls C(Float2ToThe31nd) + fistpl C(izi) // note: we are relying on FP exceptions being turned // off here to avoid problems when the span is closer // than 1/(2**31) - movl izi,%edx + movl C(izi),%edx // at this point: // %ebx = izistep @@ -926,10 +926,10 @@ LFSpanDone: jmp LFDone LFNegSpan: - fmuls FloatMinus2ToThe31nd - fistpl izistep // note: we are relying on FP exceptions being turned + fmuls C(FloatMinus2ToThe31nd) + fistpl C(izistep) // note: we are relying on FP exceptions being turned // off here to avoid range problems - movl izistep,%ebx // remains loaded for all spans + movl C(izistep),%ebx // remains loaded for all spans LFNegSpanLoop: // set up the initial 1/z value @@ -946,7 +946,7 @@ LFNegSpanLoop: faddp %st(0),%st(1) // clamp if z is nearer than 2 (1/z > 0.5) - fcoms float_point5 + fcoms C(float_point5) addl %ecx,%edi movl espan_t_u(%esi),%edx addl %edx,%edx // word count @@ -957,11 +957,11 @@ LFNegSpanLoop: testb $0x45,%ah jz LClampNeg - fmuls Float2ToThe31nd - fistpl izi // note: we are relying on FP exceptions being turned + fmuls C(Float2ToThe31nd) + fistpl C(izi) // note: we are relying on FP exceptions being turned // off here to avoid problems when the span is closer // than 1/(2**31) - movl izi,%edx + movl C(izi),%edx // at this point: // %ebx = izistep diff --git a/libs/video/renderer/sw/d_parta.S b/libs/video/renderer/sw/d_parta.S index 3a98cefe1..fb004638d 100644 --- a/libs/video/renderer/sw/d_parta.S +++ b/libs/video/renderer/sw/d_parta.S @@ -89,12 +89,12 @@ C(D_DrawParticle): faddp %st(0),%st(1) // z | local[0] | local[1] | local[2] fld %st(0) // z | z | local[0] | local[1] | // local[2] - fdivrs float_1 // 1/z | z | local[0] | local[1] | local[2] + fdivrs C(float_1) // 1/z | z | local[0] | local[1] | local[2] fxch %st(1) // z | 1/z | local[0] | local[1] | local[2] // if (transformed[2] < PARTICLE_Z_CLIP) // return; - fcomps float_particle_z_clip // 1/z | local[0] | local[1] | local[2] + fcomps C(float_particle_z_clip) // 1/z | local[0] | local[1] | local[2] fxch %st(3) // local[2] | local[0] | local[1] | 1/z flds C(r_pup) // r_pup[0] | local[2] | local[0] | local[1] | 1/z @@ -141,20 +141,20 @@ C(D_DrawParticle): fadds C(xcenter) // u | v | 1/z // FIXME: preadjust xcenter and ycenter fxch %st(1) // v | u | 1/z - fadds float_point5 // v | u | 1/z + fadds C(float_point5) // v | u | 1/z fxch %st(1) // u | v | 1/z - fadds float_point5 // u | v | 1/z + fadds C(float_point5) // u | v | 1/z fxch %st(2) // 1/z | v | u - fmuls DP_32768 // 1/z * 0x8000 | v | u + fmuls C(DP_32768) // 1/z * 0x8000 | v | u fxch %st(2) // u | v | 1/z * 0x8000 // FIXME: use Terje's fp->int trick here? // FIXME: check we're getting proper rounding here - fistpl DP_u // v | 1/z * 0x8000 - fistpl DP_v // 1/z * 0x8000 + fistpl C(DP_u) // v | 1/z * 0x8000 + fistpl C(DP_v) // 1/z * 0x8000 - movl DP_u,%eax - movl DP_v,%edx + movl C(DP_u),%eax + movl C(DP_v),%edx // if ((v > d_vrectbottom_particle) || // (u > d_vrectright_particle) || @@ -179,7 +179,7 @@ C(D_DrawParticle): jl LPop1AndDone flds pt_color(%edi) // color | 1/z * 0x8000 - fstps DP_Color // 1/z * 0x8000 + fstps C(DP_Color) // 1/z * 0x8000 movl C(d_viewbuffer),%ebx @@ -191,17 +191,17 @@ C(D_DrawParticle): leal (%edx,%eax,2),%edx movl C(d_pzbuffer),%eax - fistpl izi + fistpl C(izi) addl %ebx,%edi addl %eax,%edx // pix = izi >> d_pix_shift; - movl izi,%eax + movl C(izi),%eax movl C(d_pix_shift),%ecx shrl %cl,%eax - movl izi,%ebp + movl C(izi),%ebp // if (pix < d_pix_min) // pix = d_pix_min; @@ -221,7 +221,7 @@ LTestPixMax: movl %ecx,%eax LTestDone: - movb DP_Color,%ch + movb C(DP_Color),%ch movl C(d_y_aspect_shift),%ebx testl %ebx,%ebx @@ -230,11 +230,11 @@ LTestDone: cmpl $4,%eax ja LDefault - jmp *DP_EntryTable-4(,%eax,4) + jmp *C(DP_EntryTable)-4(,%eax,4) // 1x1 -.globl DP_1x1 -DP_1x1: +.globl C(DP_1x1) +C(DP_1x1): cmpw %bp,(%edx) // just one pixel to do jg LDone movw %bp,(%edx) @@ -242,8 +242,8 @@ DP_1x1: jmp LDone // 2x2 -.globl DP_2x2 -DP_2x2: +.globl C(DP_2x2) +C(DP_2x2): pushl %esi movl C(screenwidth),%ebx movl C(d_zrowbytes),%esi @@ -273,8 +273,8 @@ L2x2_4: jmp LDone // 3x3 -.globl DP_3x3 -DP_3x3: +.globl C(DP_3x3) +C(DP_3x3): pushl %esi movl C(screenwidth),%ebx movl C(d_zrowbytes),%esi @@ -332,8 +332,8 @@ L3x3_9: // 4x4 -.globl DP_4x4 -DP_4x4: +.globl C(DP_4x4) +C(DP_4x4): pushl %esi movl C(screenwidth),%ebx movl C(d_zrowbytes),%esi @@ -434,7 +434,7 @@ LDefault: // count = pix << d_y_aspect_shift; movl %eax,%ebx - movl %eax,DP_Pix + movl %eax,C(DP_Pix) movb C(d_y_aspect_shift),%cl shll %cl,%ebx @@ -451,7 +451,7 @@ LDefault: // } LGenRowLoop: - movl DP_Pix,%eax + movl C(DP_Pix),%eax LGenColLoop: cmpw %bp,-2(%edx,%eax,2) diff --git a/libs/video/renderer/sw/d_polysa.S b/libs/video/renderer/sw/d_polysa.S index 20f090c72..8ea71258c 100644 --- a/libs/video/renderer/sw/d_polysa.S +++ b/libs/video/renderer/sw/d_polysa.S @@ -183,7 +183,7 @@ C(D_PolysetCalcGradients): // t1*p00_minus_p20 - t0*p10_minus_p20 | // t1*p01_minus_p21 - t0*p11_minus_p21 | // xstepdenominv | p00_minus_p20 | p11_minus_p21 - fmuls float_minus_1 // ystepdenominv | + fmuls C(float_minus_1) // ystepdenominv | // t1*p00_minus_p20 - t0*p10_minus_p20 | // t1*p01_minus_p21 - t0*p11_minus_p21 | // xstepdenominv | p00_minus_p20 | p11_minus_p21 @@ -205,12 +205,12 @@ C(D_PolysetCalcGradients): // (t1*p01_minus_p21 - t0*p11_minus_p21)* // xstepdenominv | ystepdenominv | // xstepdenominv | p00_minus_p20 | p11_minus_p21 - fldcw r_ceil_cw + fldcw C(r_ceil_cw) fistpl C(r_lstepy) // r_lstepx | ystepdenominv | xstepdenominv | // p00_minus_p20 | p11_minus_p21 fistpl C(r_lstepx) // ystepdenominv | xstepdenominv | p00_minus_p20 | // p11_minus_p21 - fldcw r_single_cw + fldcw C(r_single_cw) // t0 = r_p0[2] - r_p2[2]; // t1 = r_p1[2] - r_p2[2]; @@ -822,16 +822,16 @@ LRightEdgeStepped: movl C(a_ststepxwhole),%ecx movl C(r_affinetridesc)+atd_skinwidth,%edx - movl %ecx,advancetable+4 // advance base in t + movl %ecx,C(advancetable)+4 // advance base in t addl %edx,%ecx - movl %ecx,advancetable // advance extra in t + movl %ecx,C(advancetable) // advance extra in t movl C(a_tstepxfrac),%ecx movw C(r_lstepx),%cx movl %eax,%edx // count - movl %ecx,tstep + movl %ecx,C(tstep) addl $7,%edx shrl $3,%edx // count of full and partial loops @@ -889,12 +889,12 @@ LDraw8: LPatch8: movb %al,(%edi) Lp1: - addl tstep,%edx + addl C(tstep),%edx sbbl %eax,%eax addl lzistepx,%ebp adcl $0,%ebp addl C(a_sstepxfrac),%ebx - adcl advancetable+4(,%eax,4),%esi + adcl C(advancetable)+4(,%eax,4),%esi LDraw7: cmpw 2(%ecx),%bp @@ -907,12 +907,12 @@ LDraw7: LPatch7: movb %al,1(%edi) Lp2: - addl tstep,%edx + addl C(tstep),%edx sbbl %eax,%eax addl lzistepx,%ebp adcl $0,%ebp addl C(a_sstepxfrac),%ebx - adcl advancetable+4(,%eax,4),%esi + adcl C(advancetable)+4(,%eax,4),%esi LDraw6: cmpw 4(%ecx),%bp @@ -925,12 +925,12 @@ LDraw6: LPatch6: movb %al,2(%edi) Lp3: - addl tstep,%edx + addl C(tstep),%edx sbbl %eax,%eax addl lzistepx,%ebp adcl $0,%ebp addl C(a_sstepxfrac),%ebx - adcl advancetable+4(,%eax,4),%esi + adcl C(advancetable)+4(,%eax,4),%esi LDraw5: cmpw 6(%ecx),%bp @@ -943,12 +943,12 @@ LDraw5: LPatch5: movb %al,3(%edi) Lp4: - addl tstep,%edx + addl C(tstep),%edx sbbl %eax,%eax addl lzistepx,%ebp adcl $0,%ebp addl C(a_sstepxfrac),%ebx - adcl advancetable+4(,%eax,4),%esi + adcl C(advancetable)+4(,%eax,4),%esi LDraw4: cmpw 8(%ecx),%bp @@ -961,12 +961,12 @@ LDraw4: LPatch4: movb %al,4(%edi) Lp5: - addl tstep,%edx + addl C(tstep),%edx sbbl %eax,%eax addl lzistepx,%ebp adcl $0,%ebp addl C(a_sstepxfrac),%ebx - adcl advancetable+4(,%eax,4),%esi + adcl C(advancetable)+4(,%eax,4),%esi LDraw3: cmpw 10(%ecx),%bp @@ -979,12 +979,12 @@ LDraw3: LPatch3: movb %al,5(%edi) Lp6: - addl tstep,%edx + addl C(tstep),%edx sbbl %eax,%eax addl lzistepx,%ebp adcl $0,%ebp addl C(a_sstepxfrac),%ebx - adcl advancetable+4(,%eax,4),%esi + adcl C(advancetable)+4(,%eax,4),%esi LDraw2: cmpw 12(%ecx),%bp @@ -997,12 +997,12 @@ LDraw2: LPatch2: movb %al,6(%edi) Lp7: - addl tstep,%edx + addl C(tstep),%edx sbbl %eax,%eax addl lzistepx,%ebp adcl $0,%ebp addl C(a_sstepxfrac),%ebx - adcl advancetable+4(,%eax,4),%esi + adcl C(advancetable)+4(,%eax,4),%esi LDraw1: cmpw 14(%ecx),%bp @@ -1015,12 +1015,12 @@ LDraw1: LPatch1: movb %al,7(%edi) Lp8: - addl tstep,%edx + addl C(tstep),%edx sbbl %eax,%eax addl lzistepx,%ebp adcl $0,%ebp addl C(a_sstepxfrac),%ebx - adcl advancetable+4(,%eax,4),%esi + adcl C(advancetable)+4(,%eax,4),%esi addl $8,%edi addl $16,%ecx @@ -1652,7 +1652,7 @@ LNDLoop: movl %eax,C(r_p0)+16 movl %esi,C(r_p0)+20 - fdivrs float_1 + fdivrs C(float_1) // r_p1[0] = index1->v[0]; // r_p1[1] = index1->v[1]; diff --git a/libs/video/renderer/sw/d_spr8.S b/libs/video/renderer/sw/d_spr8.S index 70abfc22c..5739f7ee1 100644 --- a/libs/video/renderer/sw/d_spr8.S +++ b/libs/video/renderer/sw/d_spr8.S @@ -108,25 +108,25 @@ C(D_SpriteDrawSpans): // // FIXME: any overlap from rearranging? flds C(d_sdivzstepu) - fmuls fp_8 + fmuls C(fp_8) movl C(cacheblock),%edx flds C(d_tdivzstepu) - fmuls fp_8 + fmuls C(fp_8) movl pspans(%esp),%ebx // point to the first span descriptor flds C(d_zistepu) - fmuls fp_8 - movl %edx,pbase // pbase = cacheblock + fmuls C(fp_8) + movl %edx,C(pbase) // pbase = cacheblock flds C(d_zistepu) - fmuls fp_64kx64k + fmuls C(fp_64kx64k) fxch %st(3) - fstps sdivz8stepu - fstps zi8stepu - fstps tdivz8stepu - fistpl izistep - movl izistep,%eax + fstps C(sdivz8stepu) + fstps C(zi8stepu) + fstps C(tdivz8stepu) + fistpl C(izistep) + movl C(izistep),%eax rorl $16,%eax // put upper 16 bits in low word movl sspan_t_count(%ebx),%ecx - movl %eax,izistep + movl %eax,C(izistep) cmpl $0,%ecx jle LNextSpan @@ -183,14 +183,14 @@ LSpanLoop: fxch %st(2) // dv*d_zistepv | du*d_zistepu | t/z | s/z faddp %st(0),%st(1) // dv*d_zistepv + du*d_zistepu | t/z | s/z - flds fp_64k // fp_64k | dv*d_zistepv + du*d_zistepu | t/z | s/z + flds C(fp_64k) // fp_64k | dv*d_zistepv + du*d_zistepu | t/z | s/z fxch %st(1) // dv*d_zistepv + du*d_zistepu | fp_64k | t/z | s/z fadds C(d_ziorigin) // zi = d_ziorigin + dv*d_zistepv + // du*d_zistepu; stays in %st(0) at end // 1/z | fp_64k | t/z | s/z fld %st(0) // FIXME: get rid of stall on FMUL? - fmuls fp_64kx64k + fmuls C(fp_64kx64k) fxch %st(1) // @@ -199,21 +199,21 @@ LSpanLoop: fdivr %st(0),%st(2) // 1/z | z*64k | t/z | s/z fxch %st(1) - fistpl izi // 0.32 fixed-point 1/z - movl izi,%ebp + fistpl C(izi) // 0.32 fixed-point 1/z + movl C(izi),%ebp // // set pz to point to the first z-buffer pixel in the span // rorl $16,%ebp // put upper 16 bits in low word movl sspan_t_v(%ebx),%eax - movl %ebp,izi + movl %ebp,C(izi) movl sspan_t_u(%ebx),%ebp imull C(d_zrowbytes) shll $1,%ebp // a word per pixel addl C(d_pzbuffer),%eax addl %ebp,%eax - movl %eax,pz + movl %eax,C(pz) // // point %edi to the first pixel in the span @@ -236,7 +236,7 @@ LSpanLoop: decl %ecx jz LCleanup1 // if only one pixel, no need to start an FDIV - movl %ecx,spancountminus1 + movl %ecx,C(spancountminus1) // finish up the s and t calcs fxch %st(1) // z*64k | 1/z | t/z | s/z @@ -246,10 +246,10 @@ LSpanLoop: fxch %st(1) // z*64k | s | 1/z | t/z | s/z fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z fxch %st(1) // s | t | 1/z | t/z | s/z - fistpl s // 1/z | t | t/z | s/z - fistpl t // 1/z | t/z | s/z + fistpl C(s) // 1/z | t | t/z | s/z + fistpl C(t) // 1/z | t/z | s/z - fildl spancountminus1 + fildl C(spancountminus1) flds C(d_tdivzstepu) // _d_tdivzstepu | spancountminus1 flds C(d_zistepu) // _d_zistepu | _d_tdivzstepu | spancountminus1 @@ -266,7 +266,7 @@ LSpanLoop: faddp %st(0),%st(3) // _d_sdivzstepu*scm1 faddp %st(0),%st(3) - flds fp_64k + flds C(fp_64k) fdiv %st(1),%st(0) // this is what we've gone to all this trouble to // overlap jmp LFDIVInFlight1 @@ -280,8 +280,8 @@ LCleanup1: fxch %st(1) // z*64k | s | 1/z | t/z | s/z fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z fxch %st(1) // s | t | 1/z | t/z | s/z - fistpl s // 1/z | t | t/z | s/z - fistpl t // 1/z | t/z | s/z + fistpl C(s) // 1/z | t | t/z | s/z + fistpl C(t) // 1/z | t/z | s/z jmp LFDIVInFlight1 .align 4 @@ -294,41 +294,41 @@ LSetupNotLast1: fxch %st(1) // z*64k | s | 1/z | t/z | s/z fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z fxch %st(1) // s | t | 1/z | t/z | s/z - fistpl s // 1/z | t | t/z | s/z - fistpl t // 1/z | t/z | s/z + fistpl C(s) // 1/z | t | t/z | s/z + fistpl C(t) // 1/z | t/z | s/z - fadds zi8stepu + fadds C(zi8stepu) fxch %st(2) - fadds sdivz8stepu + fadds C(sdivz8stepu) fxch %st(2) - flds tdivz8stepu + flds C(tdivz8stepu) faddp %st(0),%st(2) - flds fp_64k + flds C(fp_64k) fdiv %st(1),%st(0) // z = 1/1/z // this is what we've gone to all this trouble to // overlap LFDIVInFlight1: - addl s,%esi - addl t,%edx + addl C(s),%esi + addl C(t),%edx movl C(bbextents),%ebx movl C(bbextentt),%ebp cmpl %ebx,%esi ja LClampHighOrLow0 LClampReentry0: - movl %esi,s - movl pbase,%ebx + movl %esi,C(s) + movl C(pbase),%ebx shll $16,%esi cmpl %ebp,%edx - movl %esi,sfracf + movl %esi,C(sfracf) ja LClampHighOrLow1 LClampReentry1: - movl %edx,t - movl s,%esi // sfrac = scans->sfrac; + movl %edx,C(t) + movl C(s),%esi // sfrac = scans->sfrac; shll $16,%edx - movl t,%eax // tfrac = scans->tfrac; + movl C(t),%eax // tfrac = scans->tfrac; sarl $16,%esi - movl %edx,tfracf + movl %edx,C(tfracf) // // calculate the texture starting address @@ -362,10 +362,10 @@ LNotLastSegment: fxch %st(1) fmul %st(3),%st(0) // t = t/z * z fxch %st(1) - fistpl snext - fistpl tnext - movl snext,%eax - movl tnext,%edx + fistpl C(snext) + fistpl C(tnext) + movl C(snext),%eax + movl C(tnext),%edx subl $8,%ecx // count off this segments' pixels movl C(sadjust),%ebp @@ -390,11 +390,11 @@ LClampReentry2: ja LClampHigh3 LClampReentry3: - movl %ebp,snext - movl %ecx,tnext + movl %ebp,C(snext) + movl %ecx,C(tnext) - subl s,%ebp - subl t,%ecx + subl C(s),%ebp + subl C(t),%ecx // // set up advancetable @@ -409,19 +409,19 @@ LClampReentry3: LIsZero: addl %edx,%eax // add in sstep // (tstep >> 16) * cachewidth + (sstep >> 16); - movl tfracf,%edx - movl %eax,advancetable+4 // advance base in t + movl C(tfracf),%edx + movl %eax,C(advancetable)+4 // advance base in t addl %ebx,%eax // ((tstep >> 16) + 1) * cachewidth + // (sstep >> 16); shll $13,%ebp // left-justify sstep fractional part - movl %ebp,sstep - movl sfracf,%ebx + movl %ebp,C(sstep) + movl C(sfracf),%ebx shll $13,%ecx // left-justify tstep fractional part - movl %eax,advancetable // advance extra in t - movl %ecx,tstep + movl %eax,C(advancetable) // advance extra in t + movl %ecx,C(tstep) - movl pz,%ecx - movl izi,%ebp + movl C(pz),%ecx + movl C(izi),%ebp cmpw (%ecx),%bp jl Lp1 @@ -431,13 +431,13 @@ LIsZero: movw %bp,(%ecx) movb %al,(%edi) // store first dest pixel Lp1: - addl izistep,%ebp + addl C(izistep),%ebp adcl $0,%ebp - addl tstep,%edx // advance tfrac fractional part by tstep frac + addl C(tstep),%edx // advance tfrac fractional part by tstep frac sbbl %eax,%eax // turn tstep carry into -1 (0 if none) - addl sstep,%ebx // advance sfrac fractional part by sstep frac - adcl advancetable+4(,%eax,4),%esi // point to next source texel + addl C(sstep),%ebx // advance sfrac fractional part by sstep frac + adcl C(advancetable)+4(,%eax,4),%esi // point to next source texel cmpw 2(%ecx),%bp jl Lp2 @@ -447,12 +447,12 @@ Lp1: movw %bp,2(%ecx) movb %al,1(%edi) Lp2: - addl izistep,%ebp + addl C(izistep),%ebp adcl $0,%ebp - addl tstep,%edx + addl C(tstep),%edx sbbl %eax,%eax - addl sstep,%ebx - adcl advancetable+4(,%eax,4),%esi + addl C(sstep),%ebx + adcl C(advancetable)+4(,%eax,4),%esi cmpw 4(%ecx),%bp jl Lp3 @@ -462,12 +462,12 @@ Lp2: movw %bp,4(%ecx) movb %al,2(%edi) Lp3: - addl izistep,%ebp + addl C(izistep),%ebp adcl $0,%ebp - addl tstep,%edx + addl C(tstep),%edx sbbl %eax,%eax - addl sstep,%ebx - adcl advancetable+4(,%eax,4),%esi + addl C(sstep),%ebx + adcl C(advancetable)+4(,%eax,4),%esi cmpw 6(%ecx),%bp jl Lp4 @@ -477,12 +477,12 @@ Lp3: movw %bp,6(%ecx) movb %al,3(%edi) Lp4: - addl izistep,%ebp + addl C(izistep),%ebp adcl $0,%ebp - addl tstep,%edx + addl C(tstep),%edx sbbl %eax,%eax - addl sstep,%ebx - adcl advancetable+4(,%eax,4),%esi + addl C(sstep),%ebx + adcl C(advancetable)+4(,%eax,4),%esi cmpw 8(%ecx),%bp jl Lp5 @@ -492,12 +492,12 @@ Lp4: movw %bp,8(%ecx) movb %al,4(%edi) Lp5: - addl izistep,%ebp + addl C(izistep),%ebp adcl $0,%ebp - addl tstep,%edx + addl C(tstep),%edx sbbl %eax,%eax - addl sstep,%ebx - adcl advancetable+4(,%eax,4),%esi + addl C(sstep),%ebx + adcl C(advancetable)+4(,%eax,4),%esi // // start FDIV for end of next segment in flight, so it can overlap @@ -508,8 +508,8 @@ Lp5: decl %eax jz LFDIVInFlight2 // if only one pixel, no need to start an FDIV - movl %eax,spancountminus1 - fildl spancountminus1 + movl %eax,C(spancountminus1) + fildl C(spancountminus1) flds C(d_zistepu) // _d_zistepu | spancountminus1 fmul %st(1),%st(0) // _d_zistepu*scm1 | scm1 @@ -521,7 +521,7 @@ Lp5: fmuls C(d_sdivzstepu) // _d_sdivzstepu*scm1 | _d_tdivzstepu*scm1 fxch %st(1) // _d_tdivzstepu*scm1 | _d_sdivzstepu*scm1 faddp %st(0),%st(3) // _d_sdivzstepu*scm1 - flds fp_64k // 64k | _d_sdivzstepu*scm1 + flds C(fp_64k) // 64k | _d_sdivzstepu*scm1 fxch %st(1) // _d_sdivzstepu*scm1 | 64k faddp %st(0),%st(4) // 64k @@ -531,13 +531,13 @@ Lp5: .align 4 LSetupNotLast2: - fadds zi8stepu + fadds C(zi8stepu) fxch %st(2) - fadds sdivz8stepu + fadds C(sdivz8stepu) fxch %st(2) - flds tdivz8stepu + flds C(tdivz8stepu) faddp %st(0),%st(2) - flds fp_64k + flds C(fp_64k) fdiv %st(1),%st(0) // z = 1/1/z // this is what we've gone to all this trouble to // overlap @@ -552,12 +552,12 @@ LFDIVInFlight2: movw %bp,10(%ecx) movb %al,5(%edi) Lp6: - addl izistep,%ebp + addl C(izistep),%ebp adcl $0,%ebp - addl tstep,%edx + addl C(tstep),%edx sbbl %eax,%eax - addl sstep,%ebx - adcl advancetable+4(,%eax,4),%esi + addl C(sstep),%ebx + adcl C(advancetable)+4(,%eax,4),%esi cmpw 12(%ecx),%bp jl Lp7 @@ -567,12 +567,12 @@ Lp6: movw %bp,12(%ecx) movb %al,6(%edi) Lp7: - addl izistep,%ebp + addl C(izistep),%ebp adcl $0,%ebp - addl tstep,%edx + addl C(tstep),%edx sbbl %eax,%eax - addl sstep,%ebx - adcl advancetable+4(,%eax,4),%esi + addl C(sstep),%ebx + adcl C(advancetable)+4(,%eax,4),%esi cmpw 14(%ecx),%bp jl Lp8 @@ -582,24 +582,24 @@ Lp7: movw %bp,14(%ecx) movb %al,7(%edi) Lp8: - addl izistep,%ebp + addl C(izistep),%ebp adcl $0,%ebp - addl tstep,%edx + addl C(tstep),%edx sbbl %eax,%eax - addl sstep,%ebx - adcl advancetable+4(,%eax,4),%esi + addl C(sstep),%ebx + adcl C(advancetable)+4(,%eax,4),%esi addl $8,%edi addl $16,%ecx - movl %edx,tfracf - movl snext,%edx - movl %ebx,sfracf - movl tnext,%ebx - movl %edx,s - movl %ebx,t + movl %edx,C(tfracf) + movl C(snext),%edx + movl %ebx,C(sfracf) + movl C(tnext),%ebx + movl %edx,C(s) + movl %ebx,C(t) - movl %ecx,pz - movl %ebp,izi + movl %ecx,C(pz) + movl %ebp,C(izi) popl %ecx // retrieve count @@ -630,14 +630,14 @@ LLastSegment: fxch %st(1) fmul %st(3),%st(0) // t = t/z * z fxch %st(1) - fistpl snext - fistpl tnext + fistpl C(snext) + fistpl C(tnext) movl C(tadjust),%ebx movl C(sadjust),%eax - addl snext,%eax - addl tnext,%ebx + addl C(snext),%eax + addl C(tnext),%ebx movl C(bbextents),%ebp movl C(bbextentt),%edx @@ -647,7 +647,7 @@ LLastSegment: cmpl %ebp,%eax ja LClampHigh4 LClampReentry4: - movl %eax,snext + movl %eax,C(snext) cmpl $2048,%ebx jl LClampLow5 @@ -658,22 +658,22 @@ LClampReentry5: cmpl $1,%ecx // don't bother je LOnlyOneStep // if two pixels in segment, there's only one step, // of the segment length - subl s,%eax - subl t,%ebx + subl C(s),%eax + subl C(t),%ebx addl %eax,%eax // convert to 15.17 format so multiply by 1.31 addl %ebx,%ebx // reciprocal yields 16.48 - imull reciprocal_table-8(,%ecx,4) // sstep = (snext - s) / (spancount-1) + imull C(reciprocal_table)-8(,%ecx,4) // sstep = (snext - s) / (spancount-1) movl %edx,%ebp movl %ebx,%eax - imull reciprocal_table-8(,%ecx,4) // tstep = (tnext - t) / (spancount-1) + imull C(reciprocal_table)-8(,%ecx,4) // tstep = (tnext - t) / (spancount-1) LSetEntryvec: // // set up advancetable // - movl spr8entryvec_table(,%ecx,4),%ebx + movl C(spr8entryvec_table)(,%ecx,4),%ebx movl %edx,%eax pushl %ebx // entry point into code for RET later movl %ebp,%ecx @@ -685,44 +685,44 @@ LSetEntryvec: LIsZeroLast: addl %ecx,%edx // add in sstep // (tstep >> 16) * cachewidth + (sstep >> 16); - movl tfracf,%ecx - movl %edx,advancetable+4 // advance base in t + movl C(tfracf),%ecx + movl %edx,C(advancetable)+4 // advance base in t addl %ebx,%edx // ((tstep >> 16) + 1) * cachewidth + // (sstep >> 16); shll $16,%ebp // left-justify sstep fractional part - movl sfracf,%ebx + movl C(sfracf),%ebx shll $16,%eax // left-justify tstep fractional part - movl %edx,advancetable // advance extra in t + movl %edx,C(advancetable) // advance extra in t - movl %eax,tstep - movl %ebp,sstep + movl %eax,C(tstep) + movl %ebp,C(sstep) movl %ecx,%edx - movl pz,%ecx - movl izi,%ebp + movl C(pz),%ecx + movl C(izi),%ebp ret // jump to the number-of-pixels handler //---------------------------------------- LNoSteps: - movl pz,%ecx + movl C(pz),%ecx subl $7,%edi // adjust for hardwired offset subl $14,%ecx jmp LEndSpan LOnlyOneStep: - subl s,%eax - subl t,%ebx + subl C(s),%eax + subl C(t),%ebx movl %eax,%ebp movl %ebx,%edx jmp LSetEntryvec //---------------------------------------- -.globl Spr8Entry2_8 -Spr8Entry2_8: +.globl C(Spr8Entry2_8) +C(Spr8Entry2_8): subl $6,%edi // adjust for hardwired offsets subl $12,%ecx movb (%esi),%al @@ -730,48 +730,48 @@ Spr8Entry2_8: //---------------------------------------- -.globl Spr8Entry3_8 -Spr8Entry3_8: +.globl C(Spr8Entry3_8) +C(Spr8Entry3_8): subl $5,%edi // adjust for hardwired offsets subl $10,%ecx jmp LLEntry3_8 //---------------------------------------- -.globl Spr8Entry4_8 -Spr8Entry4_8: +.globl C(Spr8Entry4_8) +C(Spr8Entry4_8): subl $4,%edi // adjust for hardwired offsets subl $8,%ecx jmp LLEntry4_8 //---------------------------------------- -.globl Spr8Entry5_8 -Spr8Entry5_8: +.globl C(Spr8Entry5_8) +C(Spr8Entry5_8): subl $3,%edi // adjust for hardwired offsets subl $6,%ecx jmp LLEntry5_8 //---------------------------------------- -.globl Spr8Entry6_8 -Spr8Entry6_8: +.globl C(Spr8Entry6_8) +C(Spr8Entry6_8): subl $2,%edi // adjust for hardwired offsets subl $4,%ecx jmp LLEntry6_8 //---------------------------------------- -.globl Spr8Entry7_8 -Spr8Entry7_8: +.globl C(Spr8Entry7_8) +C(Spr8Entry7_8): decl %edi // adjust for hardwired offsets subl $2,%ecx jmp LLEntry7_8 //---------------------------------------- -.globl Spr8Entry8_8 -Spr8Entry8_8: +.globl C(Spr8Entry8_8) +C(Spr8Entry8_8): cmpw (%ecx),%bp jl Lp9 movb (%esi),%al @@ -780,12 +780,12 @@ Spr8Entry8_8: movw %bp,(%ecx) movb %al,(%edi) Lp9: - addl izistep,%ebp + addl C(izistep),%ebp adcl $0,%ebp - addl tstep,%edx + addl C(tstep),%edx sbbl %eax,%eax - addl sstep,%ebx - adcl advancetable+4(,%eax,4),%esi + addl C(sstep),%ebx + adcl C(advancetable)+4(,%eax,4),%esi LLEntry7_8: cmpw 2(%ecx),%bp jl Lp10 @@ -795,12 +795,12 @@ LLEntry7_8: movw %bp,2(%ecx) movb %al,1(%edi) Lp10: - addl izistep,%ebp + addl C(izistep),%ebp adcl $0,%ebp - addl tstep,%edx + addl C(tstep),%edx sbbl %eax,%eax - addl sstep,%ebx - adcl advancetable+4(,%eax,4),%esi + addl C(sstep),%ebx + adcl C(advancetable)+4(,%eax,4),%esi LLEntry6_8: cmpw 4(%ecx),%bp jl Lp11 @@ -810,12 +810,12 @@ LLEntry6_8: movw %bp,4(%ecx) movb %al,2(%edi) Lp11: - addl izistep,%ebp + addl C(izistep),%ebp adcl $0,%ebp - addl tstep,%edx + addl C(tstep),%edx sbbl %eax,%eax - addl sstep,%ebx - adcl advancetable+4(,%eax,4),%esi + addl C(sstep),%ebx + adcl C(advancetable)+4(,%eax,4),%esi LLEntry5_8: cmpw 6(%ecx),%bp jl Lp12 @@ -825,12 +825,12 @@ LLEntry5_8: movw %bp,6(%ecx) movb %al,3(%edi) Lp12: - addl izistep,%ebp + addl C(izistep),%ebp adcl $0,%ebp - addl tstep,%edx + addl C(tstep),%edx sbbl %eax,%eax - addl sstep,%ebx - adcl advancetable+4(,%eax,4),%esi + addl C(sstep),%ebx + adcl C(advancetable)+4(,%eax,4),%esi LLEntry4_8: cmpw 8(%ecx),%bp jl Lp13 @@ -840,12 +840,12 @@ LLEntry4_8: movw %bp,8(%ecx) movb %al,4(%edi) Lp13: - addl izistep,%ebp + addl C(izistep),%ebp adcl $0,%ebp - addl tstep,%edx + addl C(tstep),%edx sbbl %eax,%eax - addl sstep,%ebx - adcl advancetable+4(,%eax,4),%esi + addl C(sstep),%ebx + adcl C(advancetable)+4(,%eax,4),%esi LLEntry3_8: cmpw 10(%ecx),%bp jl Lp14 @@ -855,12 +855,12 @@ LLEntry3_8: movw %bp,10(%ecx) movb %al,5(%edi) Lp14: - addl izistep,%ebp + addl C(izistep),%ebp adcl $0,%ebp - addl tstep,%edx + addl C(tstep),%edx sbbl %eax,%eax - addl sstep,%ebx - adcl advancetable+4(,%eax,4),%esi + addl C(sstep),%ebx + adcl C(advancetable)+4(,%eax,4),%esi LLEntry2_8: cmpw 12(%ecx),%bp jl Lp15 @@ -870,12 +870,12 @@ LLEntry2_8: movw %bp,12(%ecx) movb %al,6(%edi) Lp15: - addl izistep,%ebp + addl C(izistep),%ebp adcl $0,%ebp - addl tstep,%edx + addl C(tstep),%edx sbbl %eax,%eax - addl sstep,%ebx - adcl advancetable+4(,%eax,4),%esi + addl C(sstep),%ebx + adcl C(advancetable)+4(,%eax,4),%esi LEndSpan: cmpw 14(%ecx),%bp diff --git a/libs/video/renderer/sw/d_varsa.S b/libs/video/renderer/sw/d_varsa.S index d6ac3504b..ece5dc2c1 100644 --- a/libs/video/renderer/sw/d_varsa.S +++ b/libs/video/renderer/sw/d_varsa.S @@ -95,39 +95,39 @@ C(d_zwidth): .long 0 //------------------------------------------------------- // ASM-only variables //------------------------------------------------------- -.globl izi -izi: .long 0 +.globl C(izi) +C(izi): .long 0 -.globl pbase, s, t, sfracf, tfracf, snext, tnext -.globl spancountminus1, zi16stepu, sdivz16stepu, tdivz16stepu -.globl zi8stepu, sdivz8stepu, tdivz8stepu, pz -s: .long 0 -t: .long 0 -snext: .long 0 -tnext: .long 0 -sfracf: .long 0 -tfracf: .long 0 -pbase: .long 0 -zi8stepu: .long 0 -sdivz8stepu: .long 0 -tdivz8stepu: .long 0 -zi16stepu: .long 0 -sdivz16stepu: .long 0 -tdivz16stepu: .long 0 -spancountminus1: .long 0 -pz: .long 0 +.globl C(pbase), C(s), C(t), C(sfracf), C(tfracf), C(snext), C(tnext) +.globl C(spancountminus1), C(zi16stepu), C(sdivz16stepu), C(tdivz16stepu) +.globl C(zi8stepu), C(sdivz8stepu), C(tdivz8stepu), C(pz) +C(s): .long 0 +C(t): .long 0 +C(snext): .long 0 +C(tnext): .long 0 +C(sfracf): .long 0 +C(tfracf): .long 0 +C(pbase): .long 0 +C(zi8stepu): .long 0 +C(sdivz8stepu): .long 0 +C(tdivz8stepu): .long 0 +C(zi16stepu): .long 0 +C(sdivz16stepu): .long 0 +C(tdivz16stepu): .long 0 +C(spancountminus1): .long 0 +C(pz): .long 0 -.globl izistep -izistep: .long 0 +.globl C(izistep) +C(izistep): .long 0 //------------------------------------------------------- // local variables for d_draw16.s //------------------------------------------------------- -.globl reciprocal_table_16 +.globl C(reciprocal_table_16) // 1/2, 1/3, 1/4, 1/5, 1/6, 1/7, 1/8, 1/9, 1/10, 1/11, 1/12, 1/13, // 1/14, and 1/15 in 0.32 form -reciprocal_table_16: .long 0x40000000, 0x2aaaaaaa, 0x20000000 +C(reciprocal_table_16): .long 0x40000000, 0x2aaaaaaa, 0x20000000 .long 0x19999999, 0x15555555, 0x12492492 .long 0x10000000, 0xe38e38e, 0xccccccc, 0xba2e8ba .long 0xaaaaaaa, 0x9d89d89, 0x9249249, 0x8888888 @@ -136,68 +136,70 @@ reciprocal_table_16: .long 0x40000000, 0x2aaaaaaa, 0x20000000 //------------------------------------------------------- // local variables for d_parta.s //------------------------------------------------------- -.globl DP_Count, DP_u, DP_v, DP_32768, DP_Color, DP_Pix, DP_EntryTable -DP_Count: .long 0 -DP_u: .long 0 -DP_v: .long 0 -DP_32768: .single 32768.0 -DP_Color: .long 0 -DP_Pix: .long 0 +.globl C(DP_Count), C(DP_u), C(DP_v), C(DP_32768), C(DP_Color) +.globl C(DP_Pix), C(DP_EntryTable) +C(DP_Count): .long 0 +C(DP_u): .long 0 +C(DP_v): .long 0 +C(DP_32768): .single 32768.0 +C(DP_Color): .long 0 +C(DP_Pix): .long 0 #ifndef NeXT - .extern DP_1x1 - .extern DP_2x2 - .extern DP_3x3 - .extern DP_4x4 + .extern C(DP_1x1) + .extern C(DP_2x2) + .extern C(DP_3x3) + .extern C(DP_4x4) #endif -DP_EntryTable: .long DP_1x1, DP_2x2, DP_3x3, DP_4x4 +C(DP_EntryTable): .long C(DP_1x1), C(DP_2x2), C(DP_3x3), C(DP_4x4) // // advancetable is 8 bytes, but points to the middle of that range so negative // offsets will work // -.globl advancetable, sstep, tstep, pspantemp, counttemp, jumptemp -advancetable: .long 0, 0 -sstep: .long 0 -tstep: .long 0 +.globl C(advancetable), C(sstep), C(tstep), C(pspantemp) +.globl C(counttemp), C(jumptemp) +C(advancetable): .long 0, 0 +C(sstep): .long 0 +C(tstep): .long 0 -pspantemp: .long 0 -counttemp: .long 0 -jumptemp: .long 0 +C(pspantemp): .long 0 +C(counttemp): .long 0 +C(jumptemp): .long 0 // 1/2, 1/3, 1/4, 1/5, 1/6, and 1/7 in 0.32 form -.globl reciprocal_table, entryvec_table -reciprocal_table: .long 0x40000000, 0x2aaaaaaa, 0x20000000 +.globl C(reciprocal_table), C(entryvec_table) +C(reciprocal_table): .long 0x40000000, 0x2aaaaaaa, 0x20000000 .long 0x19999999, 0x15555555, 0x12492492 #ifndef NeXT - .extern Entry2_8 - .extern Entry3_8 - .extern Entry4_8 - .extern Entry5_8 - .extern Entry6_8 - .extern Entry7_8 - .extern Entry8_8 + .extern C(Entry2_8) + .extern C(Entry3_8) + .extern C(Entry4_8) + .extern C(Entry5_8) + .extern C(Entry6_8) + .extern C(Entry7_8) + .extern C(Entry8_8) #endif -entryvec_table: .long 0, Entry2_8, Entry3_8, Entry4_8 - .long Entry5_8, Entry6_8, Entry7_8, Entry8_8 +C(entryvec_table): .long 0, C(Entry2_8), C(Entry3_8), C(Entry4_8) + .long C(Entry5_8), C(Entry6_8), C(Entry7_8), C(Entry8_8) #ifndef NeXT - .extern Spr8Entry2_8 - .extern Spr8Entry3_8 - .extern Spr8Entry4_8 - .extern Spr8Entry5_8 - .extern Spr8Entry6_8 - .extern Spr8Entry7_8 - .extern Spr8Entry8_8 + .extern C(Spr8Entry2_8) + .extern C(Spr8Entry3_8) + .extern C(Spr8Entry4_8) + .extern C(Spr8Entry5_8) + .extern C(Spr8Entry6_8) + .extern C(Spr8Entry7_8) + .extern C(Spr8Entry8_8) #endif -.globl spr8entryvec_table -spr8entryvec_table: .long 0, Spr8Entry2_8, Spr8Entry3_8, Spr8Entry4_8 - .long Spr8Entry5_8, Spr8Entry6_8, Spr8Entry7_8, Spr8Entry8_8 +.globl C(spr8entryvec_table) +C(spr8entryvec_table): .long 0, C(Spr8Entry2_8), C(Spr8Entry3_8), C(Spr8Entry4_8) + .long C(Spr8Entry5_8), C(Spr8Entry6_8), C(Spr8Entry7_8), C(Spr8Entry8_8) #endif // USE_INTEL_ASM diff --git a/libs/video/renderer/sw/fpua.S b/libs/video/renderer/sw/fpua.S index 203ffcd0a..bfe166ee4 100644 --- a/libs/video/renderer/sw/fpua.S +++ b/libs/video/renderer/sw/fpua.S @@ -97,30 +97,30 @@ F_END(unmaskexceptions) .data .align 4 -.globl ceil_cw, single_cw, full_cw, cw, pushed_cw -ceil_cw: .long 0 -single_cw: .long 0 -full_cw: .long 0 -cw: .long 0 -pushed_cw: .long 0 +.globl C(ceil_cw), C(single_cw), C(full_cw), C(cw), C(pushed_cw) +C(ceil_cw): .long 0 +C(single_cw): .long 0 +C(full_cw): .long 0 +C(cw): .long 0 +C(pushed_cw): .long 0 #ifdef PIC -.type ceil_cw,@object -.type single_cw,@object -.type full_cw,@object -.type cw,@object -.type pushed_cw,@object -.size ceil_cw,4 -.size single_cw,4 -.size full_cw,4 -.size cw,4 -.size pushed_cw,4 +.type C(ceil_cw),@object +.type C(single_cw),@object +.type C(full_cw),@object +.type C(cw),@object +.type C(pushed_cw),@object +.size C(ceil_cw),4 +.size C(single_cw),4 +.size C(full_cw),4 +.size C(cw),4 +.size C(pushed_cw),4 #endif .text F_BEGIN(R_LowFPPrecision) got_base(3) - fldcw got_var(single_cw) + fldcw got_var(C(single_cw)) ret F_END(R_LowFPPrecision) @@ -128,7 +128,7 @@ F_END(R_LowFPPrecision) F_BEGIN(R_HighFPPrecision) got_base(4) - fldcw got_var(full_cw) + fldcw got_var(C(full_cw)) ret F_END(R_HighFPPrecision) @@ -136,19 +136,19 @@ F_END(R_HighFPPrecision) F_BEGIN(R_SetFPCW) got_base(7) - fnstcw got_var(cw) - movl got_var(cw),%eax + fnstcw got_var(C(cw)) + movl got_var(C(cw)),%eax andb $0xF0,%ah orb $0x03,%ah // round mode, 64-bit precision - movl %eax,got_var(full_cw) + movl %eax,got_var(C(full_cw)) andb $0xF0,%ah orb $0x0C,%ah // chop mode, single precision - movl %eax,got_var(single_cw) + movl %eax,got_var(C(single_cw)) andb $0xF0,%ah orb $0x08,%ah // ceil mode, single precision - movl %eax,got_var(ceil_cw) + movl %eax,got_var(C(ceil_cw)) ret F_END(R_SetFPCW) diff --git a/libs/video/renderer/sw/sw_raclipa.S b/libs/video/renderer/sw/sw_raclipa.S index 1a094b788..24ab9513e 100644 --- a/libs/video/renderer/sw/sw_raclipa.S +++ b/libs/video/renderer/sw/sw_raclipa.S @@ -68,11 +68,11 @@ C(R_Alias_clip_bottom): popl %eax addl $C(_GLOBAL_OFFSET_TABLE_)-1+[.-.Lpic1],%eax - movl float_point5@GOTOFF(%eax),%edx + movl C(float_point5)@GOTOFF(%eax),%edx movl C(r_refdef)@GOT(%eax),%eax #else leal C(r_refdef),%eax - movl float_point5,%edx + movl C(float_point5),%edx #endif movl rd_aliasvrectbottom(%eax),%eax movl %edx,point5(%esp) @@ -209,11 +209,11 @@ C(R_Alias_clip_top): popl %eax addl $C(_GLOBAL_OFFSET_TABLE_)-1+[.-.Lpic2],%eax - movl float_point5@GOTOFF(%eax),%edx + movl C(float_point5)@GOTOFF(%eax),%edx movl C(r_refdef)@GOT(%eax),%eax #else leal C(r_refdef),%eax - movl float_point5,%edx + movl C(float_point5),%edx #endif movl rd_aliasvrect+4(%eax),%eax movl %edx,point5(%esp) @@ -245,11 +245,11 @@ C(R_Alias_clip_right): popl %eax addl $C(_GLOBAL_OFFSET_TABLE_)-1+[.-.Lpic3],%eax - movl float_point5@GOTOFF(%eax),%edx + movl C(float_point5)@GOTOFF(%eax),%edx movl C(r_refdef)@GOT(%eax),%eax #else leal C(r_refdef),%eax - movl float_point5,%edx + movl C(float_point5),%edx #endif movl rd_aliasvrectright(%eax),%eax movl %edx,point5(%esp) @@ -300,11 +300,11 @@ C(R_Alias_clip_left): popl %eax addl $C(_GLOBAL_OFFSET_TABLE_)-1+[.-.Lpic4],%eax - movl float_point5@GOTOFF(%eax),%edx + movl C(float_point5)@GOTOFF(%eax),%edx movl C(r_refdef)@GOT(%eax),%eax #else leal C(r_refdef),%eax - movl float_point5,%edx + movl C(float_point5),%edx #endif movl rd_aliasvrect+0(%eax),%eax movl %edx,point5(%esp) diff --git a/libs/video/renderer/sw/sw_rdrawa.S b/libs/video/renderer/sw/sw_rdrawa.S index d6ceaf211..8fdde816a 100644 --- a/libs/video/renderer/sw/sw_rdrawa.S +++ b/libs/video/renderer/sw/sw_rdrawa.S @@ -153,7 +153,7 @@ Lemit: // // FIXME: do away with by manually extracting integers from floats? // FIXME: set less often - fldcw r_ceil_cw + fldcw C(r_ceil_cw) // edge_t *edge, *pcheck; // int u_check; @@ -220,7 +220,7 @@ LCalcSecond: // r_ceilv1 = (int)(r_v1 - 2000) + 2000; // ceil(r_v1); fistl C(r_ceilv1) - fldcw r_single_cw // put back normal floating-point state + fldcw C(r_single_cw) // put back normal floating-point state fsts C(r_v1) fxch %st(4) // lzi0 | lzi1 | u1 | v0 | v1 | u0 @@ -398,11 +398,11 @@ LSideDone: // edge->u_step = u_step*0x100000; // edge->u = u*0x100000 + 0xFFFFF; - fmuls fp_1m // u*0x100000 | ustep + fmuls C(fp_1m) // u*0x100000 | ustep fxch %st(1) // ustep | u*0x100000 - fmuls fp_1m // ustep*0x100000 | u*0x100000 + fmuls C(fp_1m) // ustep*0x100000 | u*0x100000 fxch %st(1) // u*0x100000 | ustep*0x100000 - fadds fp_1m_minus_1 // u*0x100000 + 0xFFFFF | ustep*0x100000 + fadds C(fp_1m_minus_1) // u*0x100000 + 0xFFFFF | ustep*0x100000 fxch %st(1) // ustep*0x100000 | u*0x100000 + 0xFFFFF fistpl et_u_step(%edi) // u*0x100000 + 0xFFFFF fistpl et_u(%edi) @@ -784,7 +784,7 @@ LTransformAndProject: LNoClip: - fdivrs float_1 // lzi0 | x | y + fdivrs C(float_1) // lzi0 | x | y fxch %st(1) // x | lzi0 | y // // FIXME: build x/yscale into transform? diff --git a/libs/video/renderer/sw/sw_rvarsa.S b/libs/video/renderer/sw/sw_rvarsa.S index dbdbe0463..ca28a2e26 100644 --- a/libs/video/renderer/sw/sw_rvarsa.S +++ b/libs/video/renderer/sw/sw_rvarsa.S @@ -41,43 +41,43 @@ //------------------------------------------------------- // ASM-only variables //------------------------------------------------------- -.globl float_1, float_particle_z_clip, float_point5 -.globl float_minus_1, float_0 -float_0: .single 0.0 -float_1: .single 1.0 -float_minus_1: .single -1.0 -float_particle_z_clip: .single PARTICLE_Z_CLIP -float_point5: .single 0.5 +.globl C(float_1), C(float_particle_z_clip), C(float_point5) +.globl C(float_minus_1), C(float_0) +C(float_0): .single 0.0 +C(float_1): .single 1.0 +C(float_minus_1): .single -1.0 +C(float_particle_z_clip): .single PARTICLE_Z_CLIP +C(float_point5): .single 0.5 -.globl fp_16, fp_64k, fp_1m, fp_64kx64k -.globl fp_1m_minus_1 -.globl fp_8 -fp_1m: .single 1048576.0 -fp_1m_minus_1: .single 1048575.0 -fp_64k: .single 65536.0 -fp_8: .single 8.0 -fp_16: .single 16.0 -fp_64kx64k: .long 0x4f000000 // (float)0x8000*0x10000 +.globl C(fp_16), C(fp_64k), C(fp_1m), C(fp_64kx64k) +.globl C(fp_1m_minus_1) +.globl C(fp_8) +C(fp_1m): .single 1048576.0 +C(fp_1m_minus_1): .single 1048575.0 +C(fp_64k): .single 65536.0 +C(fp_8): .single 8.0 +C(fp_16): .single 16.0 +C(fp_64kx64k): .long 0x4f000000 // (float)0x8000*0x10000 -.globl FloatZero, Float2ToThe31nd, FloatMinus2ToThe31nd -FloatZero: .long 0 -Float2ToThe31nd: .long 0x4f000000 -FloatMinus2ToThe31nd: .long 0xcf000000 +.globl C(FloatZero), C(Float2ToThe31nd), C(FloatMinus2ToThe31nd) +C(FloatZero): .long 0 +C(Float2ToThe31nd): .long 0x4f000000 +C(FloatMinus2ToThe31nd): .long 0xcf000000 -.globl r_ceil_cw, r_single_cw -r_ceil_cw: .long 0 -r_single_cw: .long 0 +.globl C(r_ceil_cw), C(r_single_cw) +C(r_ceil_cw): .long 0 +C(r_single_cw): .long 0 .globl C(r_bmodelactive) C(r_bmodelactive): .long 0 .global C(R_InitVars) C(R_InitVars): - movl ceil_cw, %eax - movl single_cw, %edx - movl %eax, r_ceil_cw - movl %edx, r_single_cw + movl C(ceil_cw), %eax + movl C(single_cw), %edx + movl %eax, C(r_ceil_cw) + movl %edx, C(r_single_cw) ret #endif // USE_INTEL_ASM From b9401fe7c6eaba77b2226d677712be57d0fcc2ba Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 10 Sep 2011 18:10:51 +0900 Subject: [PATCH 159/334] Fix incomplete removal of old files. --- tools/build_scripts/qf-release | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/build_scripts/qf-release b/tools/build_scripts/qf-release index 58766cf6d..a5771d725 100755 --- a/tools/build_scripts/qf-release +++ b/tools/build_scripts/qf-release @@ -61,7 +61,7 @@ git_url=${git_url:-git://git.quakeforge.net/gitroot/quake/quakeforge} mkdir -p $RELEASE cd $RELEASE if test $no_rm -ne 1; then - rm -rf NEWS quakeforge-* quakeforge_* qfcc_* + rm -rf NEWS quakeforge-* qfcc-* quakeforge_* qfcc_* fi git clone $git_url || true mv quakeforge quakeforge-$ver From 8bab548d1641be5befdceceb6badb2861b1c613e Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 11 Sep 2011 08:04:47 +0900 Subject: [PATCH 160/334] Make the hud type configurable via dirconf. Currently only "id", "hipnotic" and "rogue" are supported (anything else is treated as "id"). Has no effect in quakeworld (good thing too: changing gamedirs is a little broken). --- doc/dirconf.dox | 27 +++++++++++++++++---------- include/QF/quakefs.h | 1 + libs/util/quakefs.c | 27 +++++++++++++++++---------- nq/include/game.h | 2 +- nq/source/game.c | 5 ----- nq/source/sbar.c | 8 ++++---- 6 files changed, 40 insertions(+), 30 deletions(-) diff --git a/doc/dirconf.dox b/doc/dirconf.dox index 6e37df11c..fe614c2a5 100644 --- a/doc/dirconf.dox +++ b/doc/dirconf.dox @@ -16,12 +16,24 @@ Quake = { Inherit = QF; Path = "id1"; GameCode = "progs.dat"; + HudType = "id"; }; QuakeWorld = { Inherit = (Quake); Path = "qw"; SkinPath = "${path}/skins"; GameCode = "qwprogs.dat"; + HudType = "id"; +}; +"Hipnotic" = { + Inherit = (Quake); + Path = "hipnotic"; + HudType = "hipnotic"; +}; +"Rogue" = { + Inherit = (Quake); + Path = "rogue"; + HudType = "rogue"; }; "qw:qw" = { Inherit = (QuakeWorld); @@ -34,20 +46,12 @@ QuakeWorld = { Inherit = (Quake); Path = "$gamedir"; }; -"hipnotic" = { - Inherit = (Quake); - Path = "hipnotic"; -}; "hipnotic:*" = { - Inherit = (hipnotic); + Inherit = (Hipnotic); Path = "$gamedir"; }; -"rogue" = { - Inherit = (Quake); - Path = "rogue"; -}; "rogue:*" = { - Inherit = (rogue); + Inherit = (Rogue); Path = "$gamedir"; }; "abyss" = { @@ -72,6 +76,9 @@ Supported attributes are:
GameCode
The name of the mod progs file. This is relative to the mod directory
+
HudType
+
The name of the hud style. Currently, "id", "hipnotic" and + "rogue" are supported. Has no effect in quakeworld.
SkinPath
Directory to which downloaded skins will be saved. This is relative to the QuakeForge data directory, and thus the default diff --git a/include/QF/quakefs.h b/include/QF/quakefs.h index 11985c23f..e5b3ef3f3 100644 --- a/include/QF/quakefs.h +++ b/include/QF/quakefs.h @@ -57,6 +57,7 @@ typedef struct gamedir_s { const char *gamedir; ///< the actual game dir const char *path; ///< colon separated list of search paths const char *gamecode; ///< name of file to load for gamecode + const char *hudtype; ///< name of the hud type struct { const char *def; ///< directory to which to write other files const char *skins; ///< directory to which to write skins diff --git a/libs/util/quakefs.c b/libs/util/quakefs.c index c25a65fa6..d4431b80a 100644 --- a/libs/util/quakefs.c +++ b/libs/util/quakefs.c @@ -159,12 +159,24 @@ static const char *qfs_default_dirconf = " Inherit = QF;" " Path = \"id1\";" " GameCode = \"progs.dat\";" + " HudType = \"id\";" " };" " QuakeWorld = {" " Inherit = (Quake);" " Path = \"qw\";" " SkinPath = \"${path}/skins\";" " GameCode = \"qwprogs.dat\";" + " HudType = \"id\";" + " };" + " \"Hipnotic\" = {" + " Inherit = (Quake);" + " Path = \"hipnotic\";" + " HudType = \"hipnotic\";" + " };" + " \"Rogue\" = {" + " Inherit = (Quake);" + " Path = \"rogue\";" + " HudType = \"rogue\";" " };" " \"qw:qw\" = {" " Inherit = (QuakeWorld);" @@ -177,20 +189,12 @@ static const char *qfs_default_dirconf = " Inherit = (Quake);" " Path = \"$gamedir\";" " };" - " \"hipnotic\" = {" - " Inherit = (Quake);" - " Path = \"hipnotic\";" - " };" " \"hipnotic:*\" = {" - " Inherit = (hipnotic);" + " Inherit = (Hipnotic);" " Path = \"$gamedir\";" " };" - " \"rogue\" = {" - " Inherit = (Quake);" - " Path = \"rogue\";" - " };" " \"rogue:*\" = {" - " Inherit = (rogue);" + " Inherit = (Rogue);" " Path = \"$gamedir\";" " };" " \"abyss\" = {" @@ -329,6 +333,8 @@ qfs_get_gd_params (plitem_t *gdpl, gamedir_t *gamedir, dstring_t *path, } if (!gamedir->gamecode && (p = PL_ObjectForKey (gdpl, "GameCode"))) gamedir->gamecode = qfs_var_subst (PL_String (p), vars); + if (!gamedir->hudtype && (p = PL_ObjectForKey (gdpl, "HudType"))) + gamedir->hudtype = qfs_var_subst (PL_String (p), vars); if (!gamedir->dir.skins && (p = PL_ObjectForKey (gdpl, "SkinPath"))) gamedir->dir.skins = qfs_var_subst (PL_String (p), vars); if (!gamedir->dir.models && (p = PL_ObjectForKey (gdpl, "ModelPath"))) @@ -553,6 +559,7 @@ qfs_build_gamedir (const char **list) Sys_MaskPrintf (SYS_FS, " gamedir : %s\n", qfs_gamedir->gamedir); Sys_MaskPrintf (SYS_FS, " path : %s\n", qfs_gamedir->path); Sys_MaskPrintf (SYS_FS, " gamecode: %s\n", qfs_gamedir->gamecode); + Sys_MaskPrintf (SYS_FS, " hudtype : %s\n", qfs_gamedir->hudtype); Sys_MaskPrintf (SYS_FS, " def : %s\n", qfs_gamedir->dir.def); Sys_MaskPrintf (SYS_FS, " skins : %s\n", qfs_gamedir->dir.skins); Sys_MaskPrintf (SYS_FS, " models : %s\n", qfs_gamedir->dir.models); diff --git a/nq/include/game.h b/nq/include/game.h index f40aadaf8..ffa96c1e5 100644 --- a/nq/include/game.h +++ b/nq/include/game.h @@ -162,7 +162,7 @@ extern int current_skill; // skill level for currently loaded level (in case // running, this reflects the level actually in use) extern qboolean isDedicated; -extern qboolean abyss, rogue, hipnotic, standard_quake; +extern qboolean standard_quake; extern struct cvar_s *registered; const char *Game_Init (void); diff --git a/nq/source/game.c b/nq/source/game.c index db44eaef7..969583021 100644 --- a/nq/source/game.c +++ b/nq/source/game.c @@ -36,8 +36,6 @@ #include "game.h" qboolean standard_quake = false; -qboolean hipnotic, rogue, abyss; - const char * Game_Init (void) @@ -49,14 +47,11 @@ Game_Init (void) if ((i = COM_CheckParm ("-hipnotic"))) { standard_quake = false; - hipnotic = true; return "hipnotic"; } else if ((i = COM_CheckParm ("-rogue"))) { standard_quake = false; - rogue = true; return "rogue"; } else if ((i = COM_CheckParm ("-abyss"))) { - abyss = true; return "abyss"; } diff --git a/nq/source/sbar.c b/nq/source/sbar.c index 88e8b4050..a7a8a7c23 100644 --- a/nq/source/sbar.c +++ b/nq/source/sbar.c @@ -1611,10 +1611,10 @@ init_views (void) view_insert (con_module->data->console->view, stuff_view, 0); } - if (hipnotic) { + if (!strcmp (qfs_gamedir->hudtype, "hipnotic")) { init_hipnotic_sbar_views (); init_hipnotic_hud_views (); - } else if (rogue) { + } else if (!strcmp (qfs_gamedir->hudtype, "rogue")) { init_rogue_sbar_views (); init_rogue_hud_views (); } else { @@ -1723,7 +1723,7 @@ Sbar_Init (void) sb_scorebar = Draw_PicFromWad ("scorebar"); // MED 01/04/97 added new hipnotic weapons - if (hipnotic) { + if (!strcmp (qfs_gamedir->hudtype, "hipnotic")) { hsb_weapons[0][0] = Draw_PicFromWad ("inv_laser"); hsb_weapons[0][1] = Draw_PicFromWad ("inv_mjolnir"); hsb_weapons[0][2] = Draw_PicFromWad ("inv_gren_prox"); @@ -1753,7 +1753,7 @@ Sbar_Init (void) } // FIXME: MISSIONHUD - if (rogue) { + if (!strcmp (qfs_gamedir->hudtype, "rogue")) { rsb_invbar[0] = Draw_PicFromWad ("r_invbar1"); rsb_invbar[1] = Draw_PicFromWad ("r_invbar2"); From e5add8b4f5a606b9051e1584033f6506e7bbdcf6 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 11 Sep 2011 13:09:24 +0900 Subject: [PATCH 161/334] Use dstring_freeze() to cleanup some code. --- libs/util/quakefs.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/libs/util/quakefs.c b/libs/util/quakefs.c index d4431b80a..9d063a841 100644 --- a/libs/util/quakefs.c +++ b/libs/util/quakefs.c @@ -264,7 +264,6 @@ qfs_var_subst (const char *string, hashtab_t *vars) const char *s = string; const char *e = s; const char *var; - char *t; qfs_var_t *sub; while (1) { @@ -307,9 +306,7 @@ qfs_var_subst (const char *string, hashtab_t *vars) s = e; } } - t = new->str; - free (new); - return t; + return dstring_freeze (new); } static void From 6fb73b5ae89d00a6a600685ec767f14f430d79c4 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 11 Sep 2011 13:10:14 +0900 Subject: [PATCH 162/334] Nuke some mystery code. I have no idea why I did that, but it crept in with the var substitution fix, so I guess it might have been an attempt to fix a bug, but it looks like it was broken anyway. --- libs/util/quakefs.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/libs/util/quakefs.c b/libs/util/quakefs.c index 9d063a841..4206eebc6 100644 --- a/libs/util/quakefs.c +++ b/libs/util/quakefs.c @@ -318,11 +318,8 @@ qfs_get_gd_params (plitem_t *gdpl, gamedir_t *gamedir, dstring_t *path, if ((p = PL_ObjectForKey (gdpl, "Path")) && *(ps = PL_String (p))) { char *str = qfs_var_subst (ps, vars); - char *e = strchr (str, '"'); - if (!e) - e = str + strlen (str); - qfs_set_var (vars, "path", va ("%.*s", (int) (e - str), str)); + qfs_set_var (vars, "path", str); if (path->str[0]) dstring_appendstr (path, ":"); dstring_appendstr (path, str); From f921005a5d1aba667b4ddc5ed2c229b94f8d2007 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 11 Sep 2011 14:55:13 +0900 Subject: [PATCH 163/334] Nuke com.c. It's contents have been moved into game.c and massaged appropriately. --- nq/source/Makefile.am | 2 +- nq/source/com.c | 85 ----------------------------------------- nq/source/game.c | 42 +++++++++++++++++++++ nq/source/host.c | 1 - qw/source/Makefile.am | 2 +- qw/source/cl_main.c | 2 - qw/source/com.c | 88 ------------------------------------------- qw/source/game.c | 36 ++++++++++++++++++ qw/source/sv_main.c | 2 - 9 files changed, 80 insertions(+), 180 deletions(-) delete mode 100644 nq/source/com.c delete mode 100644 qw/source/com.c diff --git a/nq/source/Makefile.am b/nq/source/Makefile.am index daeb49dc3..d304f6271 100644 --- a/nq/source/Makefile.am +++ b/nq/source/Makefile.am @@ -41,7 +41,7 @@ EXTRA_PROGRAMS= nq-fbdev nq-glx nq-mgl nq-sdl nq-sdl32 nq-sgl nq-svga nq-3dfx \ noinst_LIBRARIES= @nq_libs@ EXTRA_LIBRARIES=libnq_client.a libnq_common.a libnq_sdl.a libnq_server.a -libnq_common_a_SOURCES=game.c world.c com.c +libnq_common_a_SOURCES=game.c world.c libnq_sdl_a_SOURCES= sys_sdl.c libnq_sdl_a_CFLAGS= $(SDL_CFLAGS) diff --git a/nq/source/com.c b/nq/source/com.c deleted file mode 100644 index efbb6c1e0..000000000 --- a/nq/source/com.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - com.c - - misc functions used in client and server - - Copyright (C) 1996-1997 Id Software, Inc. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to: - - Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA - -*/ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -static __attribute__ ((used)) const char rcsid[] = - "$Id$"; - -#include "QF/cmd.h" -#include "QF/cvar.h" -#include "QF/qargs.h" -#include "QF/quakefs.h" -#include "QF/sys.h" - -#include "game.h" -#include "server.h" - -cvar_t *registered; -cvar_t *cmdline; -int static_registered = 1; - - -/* - COM_CheckRegistered - - Looks for the pop.txt file and verifies it. - Sets the "registered" cvar. - Immediately exits out if an alternate game was attempted to be started - without being registered. -*/ -static void -COM_CheckRegistered (void) -{ - unsigned short check[128]; - QFile *h; - - QFS_FOpenFile ("gfx/pop.lmp", &h); - static_registered = 0; - - if (h) { - static_registered = 1; - Qread (h, check, sizeof (check)); - Qclose (h); - } - - if (static_registered) { - Cvar_Set (registered, "1"); - Sys_Printf ("Playing registered version.\n"); - } -} - -void -COM_Init (void) -{ - registered = Cvar_Get ("registered", "0", CVAR_NONE, NULL, - "Is the game the registered version. 1 yes 0 no"); - cmdline = Cvar_Get ("cmdline", "0", CVAR_SERVERINFO, Cvar_Info, "None"); - - COM_CheckRegistered (); -} diff --git a/nq/source/game.c b/nq/source/game.c index 969583021..bbbface90 100644 --- a/nq/source/game.c +++ b/nq/source/game.c @@ -30,17 +30,59 @@ # include #endif +#include "QF/cvar.h" #include "QF/qargs.h" #include "QF/quakefs.h" +#include "QF/sys.h" #include "game.h" +#include "server.h" qboolean standard_quake = false; +cvar_t *registered; +cvar_t *cmdline; +int static_registered = 1; + + +/* + Game_CheckRegistered + + Looks for the pop.txt file and verifies it. + Sets the "registered" cvar. + Immediately exits out if an alternate game was attempted to be started + without being registered. +*/ +static void +Game_CheckRegistered (void) +{ + unsigned short check[128]; + QFile *h; + + QFS_FOpenFile ("gfx/pop.lmp", &h); + static_registered = 0; + + if (h) { + static_registered = 1; + Qread (h, check, sizeof (check)); + Qclose (h); + } + + if (static_registered) { + Cvar_Set (registered, "1"); + Sys_Printf ("Playing registered version.\n"); + } +} + const char * Game_Init (void) { int i; + registered = Cvar_Get ("registered", "0", CVAR_NONE, NULL, + "Is the game the registered version. 1 yes 0 no"); + cmdline = Cvar_Get ("cmdline", "0", CVAR_SERVERINFO, Cvar_Info, "None"); + + Game_CheckRegistered (); // FIXME: make this dependant on QF metadata in the mission packs standard_quake = true; diff --git a/nq/source/host.c b/nq/source/host.c index d33e4d95e..74d40d40a 100644 --- a/nq/source/host.c +++ b/nq/source/host.c @@ -957,7 +957,6 @@ Host_Init (void) PR_Init (); V_Init (); - COM_Init (); if (isDedicated) { PI_RegisterPlugins (server_plugin_list); diff --git a/qw/source/Makefile.am b/qw/source/Makefile.am index 6e081b605..15e4e7155 100644 --- a/qw/source/Makefile.am +++ b/qw/source/Makefile.am @@ -44,7 +44,7 @@ EXTRA_LIBRARIES=libqw_client.a libqw_common.a libqw_sdl.a libqw_server.a libqw_common_a_SOURCES=\ - com.c game.c map_cfg.c pmove.c pmovetst.c net_packetlog.c + game.c map_cfg.c pmove.c pmovetst.c net_packetlog.c libqw_sdl_a_SOURCES=cl_sys_sdl.c libqw_sdl_a_CFLAGS=$(SDL_CFLAGS) diff --git a/qw/source/cl_main.c b/qw/source/cl_main.c index b4fbc38b9..a17956306 100644 --- a/qw/source/cl_main.c +++ b/qw/source/cl_main.c @@ -1770,7 +1770,6 @@ Host_Init (void) CL_Skin_Init_Cvars (); CL_Init_Cvars (); CL_Prediction_Init_Cvars (); - COM_Init_Cvars (); Game_Init_Cvars (); IN_Init_Cvars (); Key_Init_Cvars (); @@ -1792,7 +1791,6 @@ Host_Init (void) CL_Cmd_Init (); V_Init (); Game_Init (); - COM_Init (); PI_RegisterPlugins (client_plugin_list); Con_Init ("client"); diff --git a/qw/source/com.c b/qw/source/com.c deleted file mode 100644 index b09970225..000000000 --- a/qw/source/com.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - com.c - - misc functions used in client and server - - Copyright (C) 1996-1997 Id Software, Inc. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to: - - Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA - -*/ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -static __attribute__ ((used)) const char rcsid[] = - "$Id$"; - -#include - -#include "QF/cmd.h" -#include "QF/cvar.h" -#include "QF/qargs.h" -#include "QF/quakefs.h" -#include "QF/sys.h" - -cvar_t *registered; - -int static_registered = 1; // only for startup check, then set - -qboolean com_modified; // set true if using non-id files - -/* - COM_CheckRegistered - - Looks for the pop.txt file and verifies it. - Sets the "registered" cvar. - Immediately exits out if an alternate game was attempted to be started - without being registered. -*/ -static void -COM_CheckRegistered (void) -{ - unsigned short check[128]; - QFile *h; - - QFS_FOpenFile ("gfx/pop.lmp", &h); - static_registered = 0; - - if (h) { - static_registered = 1; - Qread (h, check, sizeof (check)); - Qclose (h); - } - - if (static_registered) { - Cvar_Set (registered, "1"); - Sys_Printf ("Playing registered version.\n"); - } -} - -void -COM_Init (void) -{ - COM_CheckRegistered (); -} - -void -COM_Init_Cvars (void) -{ - registered = Cvar_Get ("registered", "0", CVAR_NONE, NULL, - "Is the game the registered version. 1 yes 0 no"); -} diff --git a/qw/source/game.c b/qw/source/game.c index 83fed6d6a..727bb28fe 100644 --- a/qw/source/game.c +++ b/qw/source/game.c @@ -48,6 +48,39 @@ +cvar_t *registered; +int static_registered = 1; // only for startup check, then set +qboolean com_modified; // set true if using non-id files + +/* + Game_CheckRegistered + + Looks for the pop.txt file and verifies it. + Sets the "registered" cvar. + Immediately exits out if an alternate game was attempted to be started + without being registered. +*/ +static void +Game_CheckRegistered (void) +{ + unsigned short check[128]; + QFile *h; + + QFS_FOpenFile ("gfx/pop.lmp", &h); + static_registered = 0; + + if (h) { + static_registered = 1; + Qread (h, check, sizeof (check)); + Qclose (h); + } + + if (static_registered) { + Cvar_Set (registered, "1"); + Sys_Printf ("Playing registered version.\n"); + } +} + /* SV_Gamedir_f @@ -82,6 +115,9 @@ SV_Gamedir_f (void) void Game_Init (void) { + registered = Cvar_Get ("registered", "0", CVAR_NONE, NULL, + "Is the game the registered version. 1 yes 0 no"); + Game_CheckRegistered (); Cmd_AddCommand ("gamedir", SV_Gamedir_f, "Specifies the directory to be used while playing."); } diff --git a/qw/source/sv_main.c b/qw/source/sv_main.c index b7bd606b0..dc670a072 100644 --- a/qw/source/sv_main.c +++ b/qw/source/sv_main.c @@ -2556,7 +2556,6 @@ SV_Init (void) Sys_SetErrPrintf (SV_Error); Game_Init_Cvars (); - COM_Init_Cvars (); Mod_Init_Cvars (); Netchan_Init_Cvars (); Pmove_Init_Cvars (); @@ -2570,7 +2569,6 @@ SV_Init (void) SV_Sbar_Init (); Game_Init (); - COM_Init (); PR_Init (); SV_Progs_Init (); From a71acc9ae57109db312f31aa4644962d034e1e00 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 11 Sep 2011 14:56:47 +0900 Subject: [PATCH 164/334] Move the essential init code into Sys_Init(). --- hw/source/master.c | 5 ----- libs/audio/test/testsound.c | 5 ----- libs/util/sys.c | 8 ++++++++ nq/source/host.c | 7 ------- qtv/source/qtv.c | 5 ----- qw/source/cl_main.c | 7 ------- qw/source/sv_main.c | 7 ------- tools/bsp2img/bsp2img.c | 6 +----- tools/carne/main.c | 5 +---- tools/qfcc/source/qfprogs.c | 6 +----- tools/qflmp/lmp.c | 6 +----- tools/qwaq/main.c | 6 +----- tools/wad/wad.c | 6 +----- 13 files changed, 14 insertions(+), 65 deletions(-) diff --git a/hw/source/master.c b/hw/source/master.c index a895b779c..6cdcf4e4c 100644 --- a/hw/source/master.c +++ b/hw/source/master.c @@ -525,12 +525,7 @@ main (int argc, const char **argv) Sys_RegisterShutdown (SV_Shutdown); - Cvar_Init_Hash (); - Cmd_Init_Hash (); - Cvar_Init (); - Sys_Init_Cvars (); Sys_Init (); - Cmd_Init (); Cmd_AddCommand ("quit", MST_Quit_f, "Shut down the master server"); Cmd_AddCommand ("clear", SVL_Clear, "Clear the server list"); diff --git a/libs/audio/test/testsound.c b/libs/audio/test/testsound.c index 0dd7333dc..2b26325ed 100644 --- a/libs/audio/test/testsound.c +++ b/libs/audio/test/testsound.c @@ -69,13 +69,8 @@ init (void) testsound_cbuf = Cbuf_New (&id_interp); testsound_args = Cbuf_ArgsNew (); - Cvar_Init_Hash (); - Cmd_Init_Hash (); - Cvar_Init (); - Sys_Init_Cvars (); Sys_Init (); Cvar_Get ("cmd_warncmd", "1", CVAR_NONE, NULL, NULL); - Cmd_Init (); Cmd_StuffCmds (testsound_cbuf); Cbuf_Execute_Sets (testsound_cbuf); diff --git a/libs/util/sys.c b/libs/util/sys.c index 00179f44d..ca98118be 100644 --- a/libs/util/sys.c +++ b/libs/util/sys.c @@ -75,6 +75,7 @@ static __attribute__ ((used)) const char rcsid[] = #include #endif +#include "QF/cmd.h" #include "QF/cvar.h" #include "QF/dstring.h" #include "QF/sys.h" @@ -773,6 +774,13 @@ Sys_Init (void) signal (SIGSEGV, signal_handler); signal (SIGTERM, signal_handler); signal (SIGFPE, signal_handler); + + Cvar_Init_Hash (); + Cmd_Init_Hash (); + Cvar_Init (); + Sys_Init_Cvars (); + + Cmd_Init (); } VISIBLE int diff --git a/nq/source/host.c b/nq/source/host.c index 74d40d40a..438ec9a72 100644 --- a/nq/source/host.c +++ b/nq/source/host.c @@ -898,14 +898,7 @@ Host_Init (void) host_cbuf = Cbuf_New (&id_interp); cmd_source = src_command; - Cvar_Init_Hash (); - Cmd_Init_Hash (); - Cvar_Init (); - Sys_Init_Cvars (); - Sys_Init (); - - Cmd_Init (); GIB_Init (true); // execute +set as early as possible diff --git a/qtv/source/qtv.c b/qtv/source/qtv.c index 077155c87..618fd884e 100644 --- a/qtv/source/qtv.c +++ b/qtv/source/qtv.c @@ -259,13 +259,8 @@ qtv_init (void) Sys_RegisterShutdown (qtv_shutdown); - Cvar_Init_Hash (); - Cmd_Init_Hash (); - Cvar_Init (); - Sys_Init_Cvars (); Sys_Init (); Cvar_Get ("cmd_warncmd", "1", CVAR_NONE, NULL, NULL); - Cmd_Init (); Cmd_StuffCmds (qtv_cbuf); Cbuf_Execute_Sets (qtv_cbuf); diff --git a/qw/source/cl_main.c b/qw/source/cl_main.c index a17956306..8e248a5af 100644 --- a/qw/source/cl_main.c +++ b/qw/source/cl_main.c @@ -1713,14 +1713,7 @@ Host_Init (void) cl_cbuf = Cbuf_New (&id_interp); cl_stbuf = Cbuf_New (&id_interp); - Cvar_Init_Hash (); - Cmd_Init_Hash (); - Cvar_Init (); - Sys_Init_Cvars (); - Sys_Init (); - - Cmd_Init (); GIB_Init (true); // execute +set as early as possible diff --git a/qw/source/sv_main.c b/qw/source/sv_main.c index dc670a072..cc15a03ea 100644 --- a/qw/source/sv_main.c +++ b/qw/source/sv_main.c @@ -2492,16 +2492,9 @@ SV_Init (void) Sys_RegisterShutdown (SV_Shutdown); - Cvar_Init_Hash (); - Cmd_Init_Hash (); - Cvar_Init (); - Sys_Init_Cvars (); - Sys_Init (); Cvar_Get ("cmd_warncmd", "1", CVAR_NONE, NULL, NULL); - - Cmd_Init (); GIB_Init (true); // execute +set as early as possible diff --git a/tools/bsp2img/bsp2img.c b/tools/bsp2img/bsp2img.c index 2d5fe6701..eade1f831 100644 --- a/tools/bsp2img/bsp2img.c +++ b/tools/bsp2img/bsp2img.c @@ -922,11 +922,7 @@ write_pcx (image_t *image) palette[i * 3 + 2] = i; } - Cvar_Init_Hash (); - Cmd_Init_Hash (); - Cvar_Init (); - Sys_Init_Cvars (); - Cmd_Init (); + Sys_Init (); Memory_Init (malloc (MEMSIZE), MEMSIZE); pcx = EncodePCX (image->image, image->width, image->height, diff --git a/tools/carne/main.c b/tools/carne/main.c index 8eb0244b5..3079b8196 100644 --- a/tools/carne/main.c +++ b/tools/carne/main.c @@ -111,10 +111,7 @@ main (int argc, char **argv) int result, i; // Initialize required QF subsystems - Cvar_Init_Hash (); - Cmd_Init_Hash (); - Cmd_Init (); - Cvar_Init (); + Sys_Init (); GIB_Init (false); // No sandbox GIB_Builtin_Add ("exit", Carne_GIB_Exit_f); diff --git a/tools/qfcc/source/qfprogs.c b/tools/qfcc/source/qfprogs.c index 589afa385..f82a1aa69 100644 --- a/tools/qfcc/source/qfprogs.c +++ b/tools/qfcc/source/qfprogs.c @@ -230,11 +230,7 @@ func_find (int st_ofs) static void init_qf (void) { - Cvar_Init_Hash (); - Cmd_Init_Hash (); - Cvar_Init (); - Sys_Init_Cvars (); - Cmd_Init (); + Sys_Init (); Cvar_Get ("pr_debug", va ("%d", verbosity), 0, 0, ""); Cvar_Get ("pr_source_path", source_path, 0, 0, ""); diff --git a/tools/qflmp/lmp.c b/tools/qflmp/lmp.c index d5f30ee50..719f47bec 100644 --- a/tools/qflmp/lmp.c +++ b/tools/qflmp/lmp.c @@ -330,11 +330,7 @@ main (int argc, char **argv) this_program = argv[0]; - Cvar_Init_Hash (); - Cmd_Init_Hash (); - Cvar_Init (); - Sys_Init_Cvars (); - Cmd_Init (); + Sys_Init (); Memory_Init (malloc (MEMSIZE), MEMSIZE); decode_args (argc, argv); diff --git a/tools/qwaq/main.c b/tools/qwaq/main.c index 1b8a5eb46..97bc76841 100644 --- a/tools/qwaq/main.c +++ b/tools/qwaq/main.c @@ -102,12 +102,8 @@ free_progs_mem (progs_t *pr, void *mem) static void init_qf (void) { - Cvar_Init_Hash (); - Cmd_Init_Hash (); + Sys_Init (); //Cvar_Get ("developer", "128", 0, 0, 0); - Cvar_Init (); - Sys_Init_Cvars (); - Cmd_Init (); Memory_Init (malloc (1024 * 1024), 1024 * 1024); diff --git a/tools/wad/wad.c b/tools/wad/wad.c index 4fba912e4..6ff78d8ec 100644 --- a/tools/wad/wad.c +++ b/tools/wad/wad.c @@ -388,11 +388,7 @@ main (int argc, char **argv) int i;//, j, rehash = 0; lumpinfo_t *pf; - Cvar_Init_Hash (); - Cmd_Init_Hash (); - Cvar_Init (); - Sys_Init_Cvars (); - Cmd_Init (); + Sys_Init (); Memory_Init (malloc (MEMSIZE), MEMSIZE); this_program = argv[0]; From d9ab3a1f542ae8eeb83d21d636c85ddaf013bf83 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 11 Sep 2011 14:47:56 +0900 Subject: [PATCH 165/334] Move the config file/command line parsing into qargs.c I don't like the COM prefix, but it will do for now. --- include/QF/qargs.h | 9 +++++--- libs/audio/test/testsound.c | 23 +------------------ libs/util/qargs.c | 44 +++++++++++++++++++++++++++++++++++-- nq/source/host.c | 30 +------------------------ qtv/source/qtv.c | 23 +------------------ qw/source/cl_main.c | 30 +------------------------ qw/source/sv_main.c | 32 ++------------------------- 7 files changed, 54 insertions(+), 137 deletions(-) diff --git a/include/QF/qargs.h b/include/QF/qargs.h index 9765268c2..e564310d7 100644 --- a/include/QF/qargs.h +++ b/include/QF/qargs.h @@ -37,9 +37,11 @@ #include "QF/qtypes.h" -extern int com_argc; -extern const char **com_argv; -extern const char *com_cmdline; +extern int com_argc; +extern const char **com_argv; +extern const char *com_cmdline; +extern struct cvar_s *fs_globalcfg; +extern struct cvar_s *fs_usercfg; int COM_CheckParm (const char *parm); void COM_AddParm (const char *parm); @@ -47,6 +49,7 @@ void COM_AddParm (const char *parm); void COM_Init (void); void COM_Init_Cvars (void); void COM_InitArgv (int argc, const char **argv); +void COM_ParseConfig (void); //@} diff --git a/libs/audio/test/testsound.c b/libs/audio/test/testsound.c index 2b26325ed..5bb3e1f0f 100644 --- a/libs/audio/test/testsound.c +++ b/libs/audio/test/testsound.c @@ -59,8 +59,6 @@ HWND mainwindow; cbuf_t *testsound_cbuf; cbuf_args_t *testsound_args; -static cvar_t *fs_globalcfg; -static cvar_t *fs_usercfg; static void @@ -70,28 +68,9 @@ init (void) testsound_args = Cbuf_ArgsNew (); Sys_Init (); + COM_ParseConfig (); Cvar_Get ("cmd_warncmd", "1", CVAR_NONE, NULL, NULL); - Cmd_StuffCmds (testsound_cbuf); - Cbuf_Execute_Sets (testsound_cbuf); - - fs_globalcfg = Cvar_Get ("fs_globalcfg", FS_GLOBALCFG, - CVAR_ROM, 0, "global configuration file"); - Cmd_Exec_File (testsound_cbuf, fs_globalcfg->string, 0); - Cbuf_Execute_Sets (testsound_cbuf); - - // execute +set again to override the config file - Cmd_StuffCmds (testsound_cbuf); - Cbuf_Execute_Sets (testsound_cbuf); - fs_usercfg = Cvar_Get ("fs_usercfg", FS_USERCFG, - CVAR_ROM, 0, "user configuration file"); - Cmd_Exec_File (testsound_cbuf, fs_usercfg->string, 0); - Cbuf_Execute_Sets (testsound_cbuf); - - // execute +set again to override the config file - Cmd_StuffCmds (testsound_cbuf); - Cbuf_Execute_Sets (testsound_cbuf); - Memory_Init (malloc (MEMSIZE), MEMSIZE); QFS_Init ("qw"); diff --git a/libs/util/qargs.c b/libs/util/qargs.c index b1cffca31..e12bfd4a7 100644 --- a/libs/util/qargs.c +++ b/libs/util/qargs.c @@ -30,8 +30,7 @@ # include "config.h" #endif -static __attribute__ ((used)) const char rcsid[] = - "$Id$"; +static __attribute__ ((used)) const char rcsid[] = "$Id$"; #ifdef HAVE_STRING_H # include @@ -46,10 +45,15 @@ static __attribute__ ((used)) const char rcsid[] = #include "QF/cmd.h" #include "QF/crc.h" +#include "QF/cvar.h" +#include "QF/idparse.h" #include "QF/qargs.h" #include "QF/qtypes.h" #include "QF/sys.h" +cvar_t *fs_globalcfg; +cvar_t *fs_usercfg; + static const char **largv; static const char *argvdummy = " "; @@ -147,3 +151,39 @@ COM_AddParm (const char *parm) { largv[com_argc++] = parm; } + +void +COM_ParseConfig (void) +{ + cbuf_t *cbuf; + + cbuf = Cbuf_New (&id_interp); + + // execute +set as early as possible + Cmd_StuffCmds (cbuf); + Cbuf_Execute_Sets (cbuf); + + // execute the global configuration file if it exists + // would have been nice if Cmd_Exec_f could have been used, but it + // reads from only within the quake file system, and changing that is + // probably Not A Good Thing (tm). + fs_globalcfg = Cvar_Get ("fs_globalcfg", FS_GLOBALCFG, CVAR_ROM, NULL, + "global configuration file"); + Cmd_Exec_File (cbuf, fs_globalcfg->string, 0); + Cbuf_Execute_Sets (cbuf); + + // execute +set again to override the config file + Cmd_StuffCmds (cbuf); + Cbuf_Execute_Sets (cbuf); + + fs_usercfg = Cvar_Get ("fs_usercfg", FS_USERCFG, CVAR_ROM, NULL, + "user configuration file"); + Cmd_Exec_File (cbuf, fs_usercfg->string, 0); + Cbuf_Execute_Sets (cbuf); + + // execute +set again to override the config file + Cmd_StuffCmds (cbuf); + Cbuf_Execute_Sets (cbuf); + + Cbuf_Delete (cbuf); +} diff --git a/nq/source/host.c b/nq/source/host.c index 438ec9a72..db7d30d7f 100644 --- a/nq/source/host.c +++ b/nq/source/host.c @@ -109,9 +109,6 @@ jmp_buf host_abortserver; byte *host_basepal; -cvar_t *fs_globalcfg; -cvar_t *fs_usercfg; - cvar_t *host_mem_size; cvar_t *host_framerate; @@ -900,32 +897,7 @@ Host_Init (void) Sys_Init (); GIB_Init (true); - - // execute +set as early as possible - Cmd_StuffCmds (host_cbuf); - Cbuf_Execute_Sets (host_cbuf); - - // execute the global configuration file if it exists - // would have been nice if Cmd_Exec_f could have been used, but it - // reads only from within the quake file system, and changing that is - // probably Not A Good Thing (tm). - fs_globalcfg = Cvar_Get ("fs_globalcfg", FS_GLOBALCFG, - CVAR_ROM, NULL, "global configuration file"); - Cmd_Exec_File (host_cbuf, fs_globalcfg->string, 0); - Cbuf_Execute_Sets (host_cbuf); - - // execute +set again to override the config file - Cmd_StuffCmds (host_cbuf); - Cbuf_Execute_Sets (host_cbuf); - - fs_usercfg = Cvar_Get ("fs_usercfg", FS_USERCFG, CVAR_ROM, NULL, - "user configuration file"); - Cmd_Exec_File (host_cbuf, fs_usercfg->string, 0); - Cbuf_Execute_Sets (host_cbuf); - - // execute +set again to override the config file - Cmd_StuffCmds (host_cbuf); - Cbuf_Execute_Sets (host_cbuf); + COM_ParseConfig (); CL_Init_Memory (); diff --git a/qtv/source/qtv.c b/qtv/source/qtv.c index 618fd884e..eb32e9e9b 100644 --- a/qtv/source/qtv.c +++ b/qtv/source/qtv.c @@ -84,8 +84,6 @@ cbuf_args_t *qtv_args; static cvar_t *qtv_console_plugin; static cvar_t *qtv_port; static cvar_t *qtv_mem_size; -static cvar_t *fs_globalcfg; -static cvar_t *fs_usercfg; redirect_t qtv_redirected; client_t *qtv_redirect_client; @@ -260,28 +258,9 @@ qtv_init (void) Sys_RegisterShutdown (qtv_shutdown); Sys_Init (); + COM_ParseConfig (); Cvar_Get ("cmd_warncmd", "1", CVAR_NONE, NULL, NULL); - Cmd_StuffCmds (qtv_cbuf); - Cbuf_Execute_Sets (qtv_cbuf); - - fs_globalcfg = Cvar_Get ("fs_globalcfg", FS_GLOBALCFG, - CVAR_ROM, 0, "global configuration file"); - Cmd_Exec_File (qtv_cbuf, fs_globalcfg->string, 0); - Cbuf_Execute_Sets (qtv_cbuf); - - // execute +set again to override the config file - Cmd_StuffCmds (qtv_cbuf); - Cbuf_Execute_Sets (qtv_cbuf); - fs_usercfg = Cvar_Get ("fs_usercfg", FS_USERCFG, - CVAR_ROM, 0, "user configuration file"); - Cmd_Exec_File (qtv_cbuf, fs_usercfg->string, 0); - Cbuf_Execute_Sets (qtv_cbuf); - - // execute +set again to override the config file - Cmd_StuffCmds (qtv_cbuf); - Cbuf_Execute_Sets (qtv_cbuf); - qtv_memory_init (); QFS_Init ("qw"); diff --git a/qw/source/cl_main.c b/qw/source/cl_main.c index 8e248a5af..c931db4a8 100644 --- a/qw/source/cl_main.c +++ b/qw/source/cl_main.c @@ -127,9 +127,6 @@ qboolean noclip_anglehack; // remnant from old quake cbuf_t *cl_cbuf; cbuf_t *cl_stbuf; -cvar_t *fs_globalcfg; -cvar_t *fs_usercfg; - cvar_t *cl_mem_size; cvar_t *rcon_password; @@ -1715,32 +1712,7 @@ Host_Init (void) Sys_Init (); GIB_Init (true); - - // execute +set as early as possible - Cmd_StuffCmds (cl_cbuf); - Cbuf_Execute_Sets (cl_cbuf); - - // execute the global configuration file if it exists - // would have been nice if Cmd_Exec_f could have been used, but it - // reads from only within the quake file system, and changing that is - // probably Not A Good Thing (tm). - fs_globalcfg = Cvar_Get ("fs_globalcfg", FS_GLOBALCFG, CVAR_ROM, NULL, - "global configuration file"); - Cmd_Exec_File (cl_cbuf, fs_globalcfg->string, 0); - Cbuf_Execute_Sets (cl_cbuf); - - // execute +set again to override the config file - Cmd_StuffCmds (cl_cbuf); - Cbuf_Execute_Sets (cl_cbuf); - - fs_usercfg = Cvar_Get ("fs_usercfg", FS_USERCFG, CVAR_ROM, NULL, - "user configuration file"); - Cmd_Exec_File (cl_cbuf, fs_usercfg->string, 0); - Cbuf_Execute_Sets (cl_cbuf); - - // execute +set again to override the config file - Cmd_StuffCmds (cl_cbuf); - Cbuf_Execute_Sets (cl_cbuf); + COM_ParseConfig (); CL_Init_Memory (); diff --git a/qw/source/sv_main.c b/qw/source/sv_main.c index cc15a03ea..e8ee03162 100644 --- a/qw/source/sv_main.c +++ b/qw/source/sv_main.c @@ -123,9 +123,6 @@ qboolean rcon_from_user; double netdosexpire[DOSFLOODCMDS] = { 1, 1, 2, 0.9, 1, 5 }; double netdosvalues[DOSFLOODCMDS] = { 12, 1, 3, 1, 1, 1 }; -cvar_t *fs_globalcfg; -cvar_t *fs_usercfg; - cvar_t *sv_mem_size; cvar_t *sv_console_plugin; @@ -2493,39 +2490,14 @@ SV_Init (void) Sys_RegisterShutdown (SV_Shutdown); Sys_Init (); + GIB_Init (true); + COM_ParseConfig (); Cvar_Get ("cmd_warncmd", "1", CVAR_NONE, NULL, NULL); - GIB_Init (true); - - // execute +set as early as possible - Cmd_StuffCmds (sv_cbuf); - Cbuf_Execute_Sets (sv_cbuf); // snax: Init experimental object system and run a test //Object_Init(); - // execute the global configuration file if it exists - // would have been nice if Cmd_Exec_f could have been used, but it - // reads from only within the quake file system, and changing that is - // probably Not A Good Thing (tm). - fs_globalcfg = Cvar_Get ("fs_globalcfg", FS_GLOBALCFG, - CVAR_ROM, 0, "global configuration file"); - Cmd_Exec_File (sv_cbuf, fs_globalcfg->string, 0); - Cbuf_Execute_Sets (sv_cbuf); - - // execute +set again to override the config file - Cmd_StuffCmds (sv_cbuf); - Cbuf_Execute_Sets (sv_cbuf); - - fs_usercfg = Cvar_Get ("fs_usercfg", FS_USERCFG, - CVAR_ROM, 0, "user configuration file"); - Cmd_Exec_File (sv_cbuf, fs_usercfg->string, 0); - Cbuf_Execute_Sets (sv_cbuf); - - // execute +set again to override the config file - Cmd_StuffCmds (sv_cbuf); - Cbuf_Execute_Sets (sv_cbuf); - SV_Init_Memory (); QFS_GamedirCallback (gamedir_f); From cb9a30e949abe5ab5e47f2f3323ef6e1fa397c82 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 11 Sep 2011 15:40:36 +0900 Subject: [PATCH 166/334] Fix registered game detection. registered detection needs qfs to be initted, but qfs needs game to be inited... so move the qfs init into game init before the registered check. --- nq/include/game.h | 2 +- nq/source/game.c | 23 ++++++++++++----------- nq/source/host.c | 5 +---- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/nq/include/game.h b/nq/include/game.h index ffa96c1e5..711468716 100644 --- a/nq/include/game.h +++ b/nq/include/game.h @@ -165,6 +165,6 @@ extern qboolean isDedicated; extern qboolean standard_quake; extern struct cvar_s *registered; -const char *Game_Init (void); +void Game_Init (void); #endif // __game_h diff --git a/nq/source/game.c b/nq/source/game.c index bbbface90..1b96bb528 100644 --- a/nq/source/game.c +++ b/nq/source/game.c @@ -74,28 +74,29 @@ Game_CheckRegistered (void) } } -const char * +void Game_Init (void) { - int i; - registered = Cvar_Get ("registered", "0", CVAR_NONE, NULL, - "Is the game the registered version. 1 yes 0 no"); - cmdline = Cvar_Get ("cmdline", "0", CVAR_SERVERINFO, Cvar_Info, "None"); - - Game_CheckRegistered (); + int i; + const char *game = "nq"; // FIXME: make this dependant on QF metadata in the mission packs standard_quake = true; if ((i = COM_CheckParm ("-hipnotic"))) { standard_quake = false; - return "hipnotic"; + game = "hipnotic"; } else if ((i = COM_CheckParm ("-rogue"))) { standard_quake = false; - return "rogue"; + game = "rogue"; } else if ((i = COM_CheckParm ("-abyss"))) { - return "abyss"; + game = "abyss"; } + QFS_Init (game); - return "nq"; + registered = Cvar_Get ("registered", "0", CVAR_NONE, NULL, + "Is the game the registered version. 1 yes 0 no"); + cmdline = Cvar_Get ("cmdline", "0", CVAR_SERVERINFO, Cvar_Info, "None"); + + Game_CheckRegistered (); } diff --git a/nq/source/host.c b/nq/source/host.c index db7d30d7f..a37a23cda 100644 --- a/nq/source/host.c +++ b/nq/source/host.c @@ -888,8 +888,6 @@ CL_Init_Memory (void) void Host_Init (void) { - const char *mp; - Sys_Printf ("Host_Init\n"); host_cbuf = Cbuf_New (&id_interp); @@ -901,8 +899,7 @@ Host_Init (void) CL_Init_Memory (); - mp = Game_Init (); - QFS_Init (mp); + Game_Init (); PI_Init (); Chase_Init_Cvars (); From e7f845ece18a2dacaeb1c47cf62b433df896e39e Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 11 Sep 2011 17:07:41 +0900 Subject: [PATCH 167/334] Fix the accidentally broken model precaching. This fixes the explodebox bug reported by scar3crow (thanks!), caused by a subtle difference between nq and qw precaching (nasty). --- nq/source/sv_pr_cmds.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/nq/source/sv_pr_cmds.c b/nq/source/sv_pr_cmds.c index 852a92ea7..acc3afcec 100644 --- a/nq/source/sv_pr_cmds.c +++ b/nq/source/sv_pr_cmds.c @@ -756,7 +756,7 @@ PR_CheckEmptyString (progs_t *pr, const char *s) PR_RunError (pr, "Bad string"); } -static void +static int do_precache (progs_t *pr, const char **cache, int max, const char *name, const char *func) { @@ -782,10 +782,10 @@ do_precache (progs_t *pr, const char **cache, int max, const char *name, strcpy (c, s); cache[i] = c; // blah, const Sys_MaskPrintf (SYS_DEV, "%s: %3d %s\n", func, i, s); - return; + return i; } if (!strcmp (cache[i], s)) - return; + return i; } PR_RunError (pr, "%s: overflow", func); } @@ -814,8 +814,11 @@ PF_precache_sound (progs_t *pr) static void PF_precache_model (progs_t *pr) { - do_precache (pr, sv.model_precache, MAX_MODELS, P_GSTRING (pr, 0), - "precache_model"); + int ind; + const char *mod = P_GSTRING (pr, 0); + ind = do_precache (pr, sv.model_precache, MAX_MODELS, mod, + "precache_model"); + sv.models[ind] = Mod_ForName (mod, true); R_INT (pr) = P_INT (pr, 0); } From 3de5575def4442046b65104d98c213362fa34925 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 11 Sep 2011 17:13:20 +0900 Subject: [PATCH 168/334] Move the menu files into the QF directory for win32. --- tools/build_scripts/qf-release | 2 +- tools/build_scripts/qf-win32.py | 20 ++++++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/tools/build_scripts/qf-release b/tools/build_scripts/qf-release index a5771d725..0ec8d4a50 100755 --- a/tools/build_scripts/qf-release +++ b/tools/build_scripts/qf-release @@ -113,7 +113,7 @@ if test $do_win32 -eq 1; then ../tools/cross/cross-make.sh $QFSMP \ prefix=${qf_win32_dir} \ exec_prefix=${qf_win32_dir} \ - pkgdatadir=${qf_win32_dir} \ + pkgdatadir=${qf_win32_dir}/QF \ man1dir=${qf_win32_dir} \ install $MINGW/bin/strip --strip-unneeded "$qf_win32"/bin/*.exe diff --git a/tools/build_scripts/qf-win32.py b/tools/build_scripts/qf-win32.py index 0edef3153..fa160b9e8 100755 --- a/tools/build_scripts/qf-win32.py +++ b/tools/build_scripts/qf-win32.py @@ -31,8 +31,9 @@ client_wgl = [ dir + "bin", dir + "bin/nq-wgl.exe", dir + "bin/qw-client-wgl.exe", - dir + "menu.dat.gz", - dir + "menu.plist", + dir + "QF", + dir + "QF/menu.dat.gz", + dir + "QF/menu.plist", ] client_sgl = [ @@ -40,8 +41,9 @@ client_sgl = [ dir + "bin", dir + "bin/nq-sgl.exe", dir + "bin/qw-client-sgl.exe", - dir + "menu.dat.gz", - dir + "menu.plist", + dir + "QF", + dir + "QF/menu.dat.gz", + dir + "QF/menu.plist", ] client_sdl = [ @@ -49,8 +51,9 @@ client_sdl = [ dir + "bin", dir + "bin/nq-sdl.exe", dir + "bin/qw-client-sdl.exe", - dir + "menu.dat.gz", - dir + "menu.plist", + dir + "QF", + dir + "QF/menu.dat.gz", + dir + "QF/menu.plist", ] client_sdl32 = [ @@ -58,8 +61,9 @@ client_sdl32 = [ dir + "bin", dir + "bin/nq-sdl32.exe", dir + "bin/qw-client-sdl32.exe", - dir + "menu.dat.gz", - dir + "menu.plist", + dir + "QF", + dir + "QF/menu.dat.gz", + dir + "QF/menu.plist", ] tools = [ From 5029fde3e1ebb5db248fc9ca0cbb9f2190c7dc91 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 11 Sep 2011 17:49:24 +0900 Subject: [PATCH 169/334] Fix the bogus frags on death. I'd missed some casts in the MSG_ReadShort change. --- nq/source/cl_parse.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nq/source/cl_parse.c b/nq/source/cl_parse.c index b2d65bac0..6088860ec 100644 --- a/nq/source/cl_parse.c +++ b/nq/source/cl_parse.c @@ -764,7 +764,7 @@ CL_ParseClientdata (void) cl.viewent.lerpflags |= LERP_RESETANIM; } - i = MSG_ReadShort (net_message); + i = (short) MSG_ReadShort (net_message); if (cl.stats[STAT_HEALTH] != i) { cl.stats[STAT_HEALTH] = i; Sbar_Changed (); @@ -1151,7 +1151,7 @@ CL_ParseServerMessage (void) red = MSG_ReadByte (net_message) / 255.0; green = MSG_ReadByte (net_message) / 255.0; blue = MSG_ReadByte (net_message) / 255.0; - time = MSG_ReadShort (net_message) / 100.0; + time = (short) MSG_ReadShort (net_message) / 100.0; time = max (0.0, time); Fog_Update (density, red, green, blue, time); } From 9d025e0058b243c4b1637aa06abc62b6096d8dd2 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 14 Sep 2011 19:33:51 +0900 Subject: [PATCH 170/334] Begin working on an mdl import/export plugin for blender. This is only preliminary at this stage: o No export yet. o Only the first frame is converte4d. o Skins are not yet converted --- .gitignore | 1 + tools/qfmdl/__init__.py | 94 ++++++++++++++++++++ tools/qfmdl/import_mdl.py | 178 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 273 insertions(+) create mode 100644 tools/qfmdl/__init__.py create mode 100644 tools/qfmdl/import_mdl.py diff --git a/.gitignore b/.gitignore index 7de7a36b9..bfaa7c6ae 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ *.a *.o *~ +__pycache__/ autom4te.cache/ .deps/ .libs/ diff --git a/tools/qfmdl/__init__.py b/tools/qfmdl/__init__.py new file mode 100644 index 000000000..599f58648 --- /dev/null +++ b/tools/qfmdl/__init__.py @@ -0,0 +1,94 @@ +# vim:ts=4:et +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +# copied from io_scene_obj + +# + +bl_info = { + "name": "Quake MDL format", + "author": "Bill Currie", + "blender": (2, 5, 7), + "api": 35622, + "location": "File > Import-Export", + "description": "Import-Export Quake MDL (version 6) files. (.mdl)", + "warning": "not even alpha", + "wiki_url": "", + "tracker_url": "", +# "support": 'OFFICIAL', + "category": "Import-Export"} + +# To support reload properly, try to access a package var, if it's there, +# reload everything +if "bpy" in locals(): + import imp + if "import_mdl" in locals(): + imp.reload(import_mdl) + #if "export_mdl" in locals(): + # imp.reload(export_mdl) + + +import bpy +from bpy.props import BoolProperty, FloatProperty, StringProperty, EnumProperty +from bpy_extras.io_utils import ExportHelper, ImportHelper, path_reference_mode, axis_conversion + + +class ImportMDL6(bpy.types.Operator, ImportHelper): + '''Load a Quake MDL (v6) File''' + bl_idname = "import_mesh.quake_mdl_v6" + bl_label = "Import MDL" + + def execute(self, context): + from . import import_mdl + keywords = self.as_keywords () + return import_mdl.import_mdl(self, context, **keywords) + +class ExportMDL6(bpy.types.Operator, ExportHelper): + '''Save a Quake MDL (v6) File''' + + bl_idname = "export_mesh.quake_mdl_v6" + bl_label = 'Export MDL' + + def execute(self, context): + return export_mdl.export_mdl(self, context, **keywords) + + +def menu_func_import(self, context): + self.layout.operator(ImportMDL6.bl_idname, text="Quake MDL (.mdl)") + + +def menu_func_export(self, context): + self.layout.operator(ExportMDL6.bl_idname, text="Quake MDL (.mdl)") + + +def register(): + bpy.utils.register_module(__name__) + + bpy.types.INFO_MT_file_import.append(menu_func_import) + bpy.types.INFO_MT_file_export.append(menu_func_export) + + +def unregister(): + bpy.utils.unregister_module(__name__) + + bpy.types.INFO_MT_file_import.remove(menu_func_import) + bpy.types.INFO_MT_file_export.remove(menu_func_export) + +if __name__ == "__main__": + register() diff --git a/tools/qfmdl/import_mdl.py b/tools/qfmdl/import_mdl.py new file mode 100644 index 000000000..52af85944 --- /dev/null +++ b/tools/qfmdl/import_mdl.py @@ -0,0 +1,178 @@ +# vim:ts=4:et +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +# + +from struct import unpack +from pprint import pprint + +import bpy +from bpy_extras.object_utils import object_data_add +from mathutils import Vector,Matrix + +class MDL: + pass +class stvert: + pass +class tri: + pass +class frame: + pass +class vert: + pass + +def load_mdl(filepath): + data = open(filepath, "rb").read() + m = unpack("<4s i 3f 3f f 3f i i i i i i i i f", data[:84]) + data = data[84:] + mdl = MDL() + mdl.ident = m[0] + mdl.version = m[1] + mdl.scale = Vector(m[2:5]) + mdl.scale_origin = Vector(m[5:8]) + mdl.boundingradius = m[8] + mdl.eyeposition = Vector(m[9:12]) + mdl.numskins = m[12] + mdl.skinwidth = m[13] + mdl.skinheight = m[14] + mdl.numverts = m[15] + mdl.numtris = m[16] + mdl.numframes = m[17] + mdl.synctype = m[18] + mdl.flags = m[19] + mdl.size = m[20] + # read in the skin data + size = mdl.skinwidth * mdl.skinheight + mdl.skins = [] + for i in range(mdl.numskins): + skintype = unpack (" Date: Thu, 15 Sep 2011 11:29:54 +0900 Subject: [PATCH 171/334] Load the skins into blender images. Skin groups are not yet supported (skipped). --- tools/qfmdl/import_mdl.py | 50 ++++++-- tools/qfmdl/quakepal.py | 258 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 298 insertions(+), 10 deletions(-) create mode 100644 tools/qfmdl/quakepal.py diff --git a/tools/qfmdl/import_mdl.py b/tools/qfmdl/import_mdl.py index 52af85944..1d4ab496f 100644 --- a/tools/qfmdl/import_mdl.py +++ b/tools/qfmdl/import_mdl.py @@ -26,8 +26,12 @@ import bpy from bpy_extras.object_utils import object_data_add from mathutils import Vector,Matrix +from . import quakepal + class MDL: pass +class skin: + pass class stvert: pass class tri: @@ -42,6 +46,8 @@ def load_mdl(filepath): m = unpack("<4s i 3f 3f f 3f i i i i i i i i f", data[:84]) data = data[84:] mdl = MDL() + mdl.name = filepath.split('/')[-1] + mdl.name = mdl.name.split('.')[0] mdl.ident = m[0] mdl.version = m[1] mdl.scale = Vector(m[2:5]) @@ -61,22 +67,27 @@ def load_mdl(filepath): size = mdl.skinwidth * mdl.skinheight mdl.skins = [] for i in range(mdl.numskins): - skintype = unpack (" Date: Thu, 15 Sep 2011 13:21:08 +0900 Subject: [PATCH 172/334] Build the uv layout. --- tools/qfmdl/import_mdl.py | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/tools/qfmdl/import_mdl.py b/tools/qfmdl/import_mdl.py index 1d4ab496f..30a882b96 100644 --- a/tools/qfmdl/import_mdl.py +++ b/tools/qfmdl/import_mdl.py @@ -156,12 +156,11 @@ def load_mdl(filepath): mdl.frames.append(f) return mdl -def make_mesh(mdl, framenum, subframenum=0): +def make_verts(mdl, framenum, subframenum=0): frame = mdl.frames[framenum] if frame.type: frame = frame.frames[subframenum] verts = [] - faces = [] s = mdl.scale o = mdl.scale_origin m = Matrix(((s.x, 0, 0, 0), @@ -170,9 +169,25 @@ def make_mesh(mdl, framenum, subframenum=0): (o.x,o.y,o.z, 1))) for v in frame.verts: verts.append(Vector(v.r) * m) - for t in mdl.tris: - faces.append (t.verts) - return verts, faces + return verts + +def make_faces(mdl): + faces = [] + uvs = [] + for tri in mdl.tris: + faces.append (tri.verts) + sts = [] + for v in tri.verts: + stv = mdl.stverts[v] + s = stv.s + t = stv.t + if stv.onseam and not tri.facesfront: + s += mdl.skinwidth / 2 + # quake textures are top to bottom, but blender images + # are bottom to top + sts.append((s * 1.0 / mdl.skinwidth, 1 - t * 1.0 / mdl.skinheight)) + uvs.append(sts) + return faces, uvs def load_skins(mdl): for i in range(mdl.numskins): @@ -196,13 +211,22 @@ def load_skins(mdl): def import_mdl(operator, context, filepath): mdl = load_mdl(filepath) - verts, faces = make_mesh (mdl, 0) + bpy.context.user_preferences.edit.use_global_undo = False + + faces, uvs = make_faces (mdl) + verts = make_verts (mdl, 0) load_skins (mdl) mesh = bpy.data.meshes.new(mdl.name) mesh.from_pydata(verts, [], faces) + uvlay = mesh.uv_textures.new() + for i, f in enumerate(uvlay.data): + mdl_uv = uvs[i] + for j, uv in enumerate(f.uv): + uv[0], uv[1] = mdl_uv[j] mesh.update() object_data_add(context, mesh, operator=None) + bpy.context.user_preferences.edit.use_global_undo = True return 'FINISHED' From 11f37298bea0bf53a8da83c07446e83f5454dc0a Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 15 Sep 2011 17:23:40 +0900 Subject: [PATCH 173/334] Reveres the face windings. Blender's vertex order and quake's vertex order seem to be opposed. --- tools/qfmdl/import_mdl.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/qfmdl/import_mdl.py b/tools/qfmdl/import_mdl.py index 30a882b96..ec9d5f80b 100644 --- a/tools/qfmdl/import_mdl.py +++ b/tools/qfmdl/import_mdl.py @@ -175,7 +175,9 @@ def make_faces(mdl): faces = [] uvs = [] for tri in mdl.tris: - faces.append (tri.verts) + tv = tri.verts + tv = tv[2], tv[1], tv[0] # flip the normal by reversing the winding + faces.append (tv) sts = [] for v in tri.verts: stv = mdl.stverts[v] @@ -186,6 +188,7 @@ def make_faces(mdl): # quake textures are top to bottom, but blender images # are bottom to top sts.append((s * 1.0 / mdl.skinwidth, 1 - t * 1.0 / mdl.skinheight)) + sts = sts[2], sts[1], sts[0] # to match face vert reversal uvs.append(sts) return faces, uvs From f8e1e3d4ec18994146405c4e95105855130d2c56 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 15 Sep 2011 19:18:31 +0900 Subject: [PATCH 174/334] Fix incorrect bracket/parens --- tools/qfmdl/import_mdl.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/qfmdl/import_mdl.py b/tools/qfmdl/import_mdl.py index ec9d5f80b..d27a1506b 100644 --- a/tools/qfmdl/import_mdl.py +++ b/tools/qfmdl/import_mdl.py @@ -87,7 +87,7 @@ def load_mdl(filepath): ss.type = 0 ss.pixels = data[:size] data = data[size:] - s.skins.append[ss] + s.skins.append(ss) #read in the st verts (uv map) mdl.stverts = [] for i in range(mdl.numverts): From 7489d5646be96e388210e22470496916e45318c5 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 15 Sep 2011 19:19:21 +0900 Subject: [PATCH 175/334] Convert all skins. Skin groups are now partially supported. --- tools/qfmdl/import_mdl.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/tools/qfmdl/import_mdl.py b/tools/qfmdl/import_mdl.py index d27a1506b..5fb1ee182 100644 --- a/tools/qfmdl/import_mdl.py +++ b/tools/qfmdl/import_mdl.py @@ -193,13 +193,11 @@ def make_faces(mdl): return faces, uvs def load_skins(mdl): - for i in range(mdl.numskins): - if mdl.skins[i].type: - continue #skin groups not yet supported - img = bpy.data.images.new("%s_%d" % (mdl.name, i), - mdl.skinwidth, mdl.skinheight) + def load_skin(skin, name): + img = bpy.data.images.new(name, mdl.skinwidth, mdl.skinheight) + mdl.images.append(img) p = [0.0] * mdl.skinwidth * mdl.skinheight * 4 - d = mdl.skins[i].pixels + d = skin.pixels for j in range(mdl.skinheight): for k in range(mdl.skinwidth): c = quakepal.palette[d[j * mdl.skinwidth + k]] @@ -212,6 +210,15 @@ def load_skins(mdl): p[l + 3] = 1.0 img.pixels[:] = p[:] + mdl.images=[] + for i in range(mdl.numskins): + if mdl.skins[i].type: + for j in range(mdl.skins[i].numskins): + load_skin (mdl.skins[i].skins[j], + "%s_%d_%d" % (mdl.name, i, j)) + else: + load_skin (mdl.skins[i], "%s_%d" % (mdl.name, i)) + def import_mdl(operator, context, filepath): mdl = load_mdl(filepath) From 257fefca38f5308d6f2ac0ed6d423120aa96255e Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 15 Sep 2011 19:52:18 +0900 Subject: [PATCH 176/334] Link the first skin to the imported object. The texture doesn't display properly in 3d space in texture mode yet. --- tools/qfmdl/import_mdl.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tools/qfmdl/import_mdl.py b/tools/qfmdl/import_mdl.py index 5fb1ee182..46fe9372c 100644 --- a/tools/qfmdl/import_mdl.py +++ b/tools/qfmdl/import_mdl.py @@ -234,8 +234,25 @@ def import_mdl(operator, context, filepath): mdl_uv = uvs[i] for j, uv in enumerate(f.uv): uv[0], uv[1] = mdl_uv[j] + + mat = bpy.data.materials.new(mdl.name) + mat.diffuse_color = (1,1,1) + mat.use_raytrace = False + tex = bpy.data.textures.new(mdl.name, 'IMAGE') + tex.extension = 'CLIP' + tex.use_preview_alpha = True + tex.image = mdl.images[0] # use the first skin for now + mat.texture_slots.add() + ts = mat.texture_slots[0] + ts.texture = tex + ts.use_map_alpha = True + ts.texture_coords = 'UV' mesh.update() object_data_add(context, mesh, operator=None) + act = bpy.context.active_object + if not act.material_slots: + bpy.ops.object.material_slot_add() + act.material_slots[0].material = mat bpy.context.user_preferences.edit.use_global_undo = True return 'FINISHED' From 320f6132635320f6e284603eb412d223e1271fd3 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 15 Sep 2011 20:39:26 +0900 Subject: [PATCH 177/334] Give the uvlayer texture a name. --- tools/qfmdl/import_mdl.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/qfmdl/import_mdl.py b/tools/qfmdl/import_mdl.py index 46fe9372c..1bf6ca1ae 100644 --- a/tools/qfmdl/import_mdl.py +++ b/tools/qfmdl/import_mdl.py @@ -229,7 +229,7 @@ def import_mdl(operator, context, filepath): load_skins (mdl) mesh = bpy.data.meshes.new(mdl.name) mesh.from_pydata(verts, [], faces) - uvlay = mesh.uv_textures.new() + uvlay = mesh.uv_textures.new(mdl.name) for i, f in enumerate(uvlay.data): mdl_uv = uvs[i] for j, uv in enumerate(f.uv): From 41213f2c30eb647eca4b705c755993e1d4b953e3 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 15 Sep 2011 22:45:23 +0900 Subject: [PATCH 178/334] Make the skin show in blender's 3d view. Much thanks to ideasman_42 for showing me which code I needed to grok to get it working. --- tools/qfmdl/import_mdl.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/qfmdl/import_mdl.py b/tools/qfmdl/import_mdl.py index 1bf6ca1ae..616ca9909 100644 --- a/tools/qfmdl/import_mdl.py +++ b/tools/qfmdl/import_mdl.py @@ -227,6 +227,7 @@ def import_mdl(operator, context, filepath): faces, uvs = make_faces (mdl) verts = make_verts (mdl, 0) load_skins (mdl) + img = mdl.images[0] # use the first skin for now mesh = bpy.data.meshes.new(mdl.name) mesh.from_pydata(verts, [], faces) uvlay = mesh.uv_textures.new(mdl.name) @@ -234,14 +235,15 @@ def import_mdl(operator, context, filepath): mdl_uv = uvs[i] for j, uv in enumerate(f.uv): uv[0], uv[1] = mdl_uv[j] - + f.image = img + f.use_image = True mat = bpy.data.materials.new(mdl.name) mat.diffuse_color = (1,1,1) mat.use_raytrace = False tex = bpy.data.textures.new(mdl.name, 'IMAGE') tex.extension = 'CLIP' tex.use_preview_alpha = True - tex.image = mdl.images[0] # use the first skin for now + tex.image = img mat.texture_slots.add() ts = mat.texture_slots[0] ts.texture = tex From de24fa99a826161b6df2b6532d8f49d6cc21d19a Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 16 Sep 2011 17:57:07 +0900 Subject: [PATCH 179/334] Break out the skin/material setup code. --- tools/qfmdl/import_mdl.py | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/tools/qfmdl/import_mdl.py b/tools/qfmdl/import_mdl.py index 616ca9909..6f36276e2 100644 --- a/tools/qfmdl/import_mdl.py +++ b/tools/qfmdl/import_mdl.py @@ -219,17 +219,9 @@ def load_skins(mdl): else: load_skin (mdl.skins[i], "%s_%d" % (mdl.name, i)) -def import_mdl(operator, context, filepath): - mdl = load_mdl(filepath) - - bpy.context.user_preferences.edit.use_global_undo = False - - faces, uvs = make_faces (mdl) - verts = make_verts (mdl, 0) +def setup_skins (mdl, mesh, uvs): load_skins (mdl) img = mdl.images[0] # use the first skin for now - mesh = bpy.data.meshes.new(mdl.name) - mesh.from_pydata(verts, [], faces) uvlay = mesh.uv_textures.new(mdl.name) for i, f in enumerate(uvlay.data): mdl_uv = uvs[i] @@ -249,13 +241,23 @@ def import_mdl(operator, context, filepath): ts.texture = tex ts.use_map_alpha = True ts.texture_coords = 'UV' - mesh.update() - object_data_add(context, mesh, operator=None) act = bpy.context.active_object if not act.material_slots: bpy.ops.object.material_slot_add() act.material_slots[0].material = mat +def import_mdl(operator, context, filepath): + bpy.context.user_preferences.edit.use_global_undo = False + + mdl = load_mdl(filepath) + faces, uvs = make_faces (mdl) + verts = make_verts (mdl, 0) + mesh = bpy.data.meshes.new(mdl.name) + mesh.from_pydata(verts, [], faces) + object_data_add(context, mesh, operator=None) + setup_skins (mdl, mesh, uvs) + mesh.update() + bpy.context.user_preferences.edit.use_global_undo = True return 'FINISHED' From b0af18478bea448cf695446d8133830a103ea4ca Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 16 Sep 2011 19:14:31 +0900 Subject: [PATCH 180/334] Be a little more direct in object linking and materal adding. --- tools/qfmdl/import_mdl.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/tools/qfmdl/import_mdl.py b/tools/qfmdl/import_mdl.py index 6f36276e2..01f95d1c5 100644 --- a/tools/qfmdl/import_mdl.py +++ b/tools/qfmdl/import_mdl.py @@ -241,20 +241,23 @@ def setup_skins (mdl, mesh, uvs): ts.texture = tex ts.use_map_alpha = True ts.texture_coords = 'UV' - act = bpy.context.active_object - if not act.material_slots: - bpy.ops.object.material_slot_add() - act.material_slots[0].material = mat + mesh.materials.append(mat) def import_mdl(operator, context, filepath): bpy.context.user_preferences.edit.use_global_undo = False + for obj in bpy.context.scene.objects: + obj.select = False + mdl = load_mdl(filepath) faces, uvs = make_faces (mdl) verts = make_verts (mdl, 0) mesh = bpy.data.meshes.new(mdl.name) mesh.from_pydata(verts, [], faces) - object_data_add(context, mesh, operator=None) + obj = bpy.data.objects.new(mdl.name, mesh) + bpy.context.scene.objects.link(obj) + bpy.context.scene.objects.active = obj + obj.select = True setup_skins (mdl, mesh, uvs) mesh.update() From f7de55ed5e7bfeead6eb213305074a73cdd520c2 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 16 Sep 2011 20:59:39 +0900 Subject: [PATCH 181/334] Create a shape key for every frame and subframe. Shammy has no frame groups :(. Need to find a model with groups. --- tools/qfmdl/import_mdl.py | 50 ++++++++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/tools/qfmdl/import_mdl.py b/tools/qfmdl/import_mdl.py index 01f95d1c5..3b46dcb0c 100644 --- a/tools/qfmdl/import_mdl.py +++ b/tools/qfmdl/import_mdl.py @@ -219,10 +219,10 @@ def load_skins(mdl): else: load_skin (mdl.skins[i], "%s_%d" % (mdl.name, i)) -def setup_skins (mdl, mesh, uvs): +def setup_skins (mdl, uvs): load_skins (mdl) img = mdl.images[0] # use the first skin for now - uvlay = mesh.uv_textures.new(mdl.name) + uvlay = mdl.mesh.uv_textures.new(mdl.name) for i, f in enumerate(uvlay.data): mdl_uv = uvs[i] for j, uv in enumerate(f.uv): @@ -241,7 +241,25 @@ def setup_skins (mdl, mesh, uvs): ts.texture = tex ts.use_map_alpha = True ts.texture_coords = 'UV' - mesh.materials.append(mat) + mdl.mesh.materials.append(mat) + +def make_shape_key(mdl, framenum, subframenum=0): + frame = mdl.frames[framenum] + name = "%s_%d" % (mdl.name, framenum) + if frame.type: + frame = frame.frames[subframenum] + name = "%s_%d_%d" % (mdl.name, framenum, subframenum) + if frame.name: + name = frame.name.decode('ascii','ignore') + frame.key = mdl.obj.shape_key_add(name) + s = mdl.scale + o = mdl.scale_origin + m = Matrix(((s.x, 0, 0, 0), + ( 0,s.y, 0, 0), + ( 0, 0,s.z, 0), + (o.x,o.y,o.z, 1))) + for i, v in enumerate(frame.verts): + frame.key.data[i].co = Vector(v.r) * m def import_mdl(operator, context, filepath): bpy.context.user_preferences.edit.use_global_undo = False @@ -252,14 +270,24 @@ def import_mdl(operator, context, filepath): mdl = load_mdl(filepath) faces, uvs = make_faces (mdl) verts = make_verts (mdl, 0) - mesh = bpy.data.meshes.new(mdl.name) - mesh.from_pydata(verts, [], faces) - obj = bpy.data.objects.new(mdl.name, mesh) - bpy.context.scene.objects.link(obj) - bpy.context.scene.objects.active = obj - obj.select = True - setup_skins (mdl, mesh, uvs) - mesh.update() + mdl.mesh = bpy.data.meshes.new(mdl.name) + mdl.mesh.from_pydata(verts, [], faces) + mdl.obj = bpy.data.objects.new(mdl.name, mdl.mesh) + bpy.context.scene.objects.link(mdl.obj) + bpy.context.scene.objects.active = mdl.obj + mdl.obj.select = True + setup_skins (mdl, uvs) + + if mdl.numframes > 1 or mdl.frames[0].type: + for i in range(mdl.numframes): + frame = mdl.frames[i] + if frame.type: + for j in range(frame.numframes): + make_shape_key(mdl, i, j) + else: + make_shape_key(mdl, i) + + mdl.mesh.update() bpy.context.user_preferences.edit.use_global_undo = True return 'FINISHED' From 644f4db9d16bb148c5fb475f0464e45c6086c86d Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 17 Sep 2011 09:05:07 +0900 Subject: [PATCH 182/334] Add support for v3 (qtest) mdl files. Finally, I can see the dragon in all its... glory? --- tools/qfmdl/import_mdl.py | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/tools/qfmdl/import_mdl.py b/tools/qfmdl/import_mdl.py index 3b46dcb0c..d90b1bab1 100644 --- a/tools/qfmdl/import_mdl.py +++ b/tools/qfmdl/import_mdl.py @@ -43,8 +43,8 @@ class vert: def load_mdl(filepath): data = open(filepath, "rb").read() - m = unpack("<4s i 3f 3f f 3f i i i i i i i i f", data[:84]) - data = data[84:] + m = unpack("<4s i 3f 3f f 3f i i i i i i i", data[:76]) + data = data[76:] mdl = MDL() mdl.name = filepath.split('/')[-1] mdl.name = mdl.name.split('.')[0] @@ -61,8 +61,13 @@ def load_mdl(filepath): mdl.numtris = m[16] mdl.numframes = m[17] mdl.synctype = m[18] - mdl.flags = m[19] - mdl.size = m[20] + mdl.flags = 0 + mdl.size = 1.0 # random number ;) + if mdl.version == 6: + m = (" Date: Sat, 17 Sep 2011 23:13:21 +0900 Subject: [PATCH 183/334] Create actions for frames and frame groups. Simple frames get a one key action, groups get an action with a key per subframe. --- tools/qfmdl/import_mdl.py | 103 ++++++++++++++++++++++++++++++++------ 1 file changed, 88 insertions(+), 15 deletions(-) diff --git a/tools/qfmdl/import_mdl.py b/tools/qfmdl/import_mdl.py index d90b1bab1..b93675c53 100644 --- a/tools/qfmdl/import_mdl.py +++ b/tools/qfmdl/import_mdl.py @@ -118,15 +118,15 @@ def load_mdl(filepath): if mdl.version == 6: x = unpack("<3B B 3B B 16s", data[:24]) data = data[24:] - name = x[8] + name = x[8].decode('ascii','ignore') else: x = unpack("<3B B 3B B", data[:8]) data = data[8:] - name = b"" + name = "" f.mins = x[0:3] f.maxs = x[4:7] - if b"\0" in name: - name = name[:name.index(b"\0")] + if "\0" in name: + name = name[:name.index("\0")] f.name = name f.verts = [] for j in range(mdl.numverts): @@ -148,11 +148,21 @@ def load_mdl(filepath): g.frames = [] for k in range(g.numframes): f = frame() + if mdl.version == 6: + x = unpack("<3B B 3B B 16s", data[:24]) + data = data[24:] + name = x[8].decode('ascii','ignore') + else: + x = unpack("<3B B 3B B", data[:8]) + data = data[8:] + name = "" x = unpack("<3B B 3B B 16s", data[:24]) data = data[24:] f.mins = x[0:3] f.maxs = x[4:7] - f.name = x[8] + if "\0" in name: + name = name[:name.index("\0")] + f.name = name f.verts = [] for j in range(mdl.numverts): x = unpack("<3B B", data[:4]) @@ -260,8 +270,10 @@ def make_shape_key(mdl, framenum, subframenum=0): frame = frame.frames[subframenum] name = "%s_%d_%d" % (mdl.name, framenum, subframenum) if frame.name: - name = frame.name.decode('ascii','ignore') + name = frame.name frame.key = mdl.obj.shape_key_add(name) + frame.key.value = 0.0 + mdl.keys.append (frame.key) s = mdl.scale o = mdl.scale_origin m = Matrix(((s.x, 0, 0, 0), @@ -271,6 +283,74 @@ def make_shape_key(mdl, framenum, subframenum=0): for i, v in enumerate(frame.verts): frame.key.data[i].co = Vector(v.r) * m +def build_shape_keys(mdl): + mdl.keys = [] + mdl.obj.shape_key_add("Basis") # FIXME do I want this? + for i in range(mdl.numframes): + frame = mdl.frames[i] + if frame.type: + for j in range(frame.numframes): + make_shape_key(mdl, i, j) + else: + make_shape_key(mdl, i) + +""" +fc.keyframe_points.add(3) +fc.keyframe_points[0].co=10.0,0.0 +fc.keyframe_points[1].co=20.0,1.0 +fc.keyframe_points[2].co=30.0,0.0 +fc.keyframe_points[2].co=30.2,0.0 +""" +def set_keys(fck, current, f, m): + c = 1 + if f > 1: + c += 1 + if f > 2: + c += 1 + if f < m: + c += 1 + if f < m - 1: + c += 1 + for k in fck: + k[1].keyframe_points.add(c) + kp = k[1].keyframe_points + i = 0 + if f > 2: + kp[i].co = 1.0,0.0 + i += 1 + x = f * 1.0 + if f > 1: + kp[i].co = x - 1.0,0.0 + i += 1 + if k[0] == current: + y = 1.0 + else: + y = 0.0 + kp[i].co = x,y + i += 1 + if f < m: + kp[i].co = x + 1.0,0.0 + i += 1 + if f < m - 1: + kp[i].co = m * 1.0,0.0 + +def build_actions(mdl): + sk = mdl.mesh.shape_keys + for i in range(mdl.numframes): + frame = mdl.frames[i] + sk.animation_data_create() + sk.animation_data.action = bpy.data.actions.new(frame.name) + act=sk.animation_data.action + fck = [] + for k in mdl.keys: + dp = """key_blocks["%s"].value""" % k.name + fck.append((k, act.fcurves.new(data_path=dp))) + if frame.type: + for j in range(frame.numframes): + set_keys (fck, frame.frames[i].key, j + 1, frame.numframes) + else: + set_keys (fck, frame.key, 1, 1) + def import_mdl(operator, context, filepath): bpy.context.user_preferences.edit.use_global_undo = False @@ -287,18 +367,11 @@ def import_mdl(operator, context, filepath): bpy.context.scene.objects.active = mdl.obj mdl.obj.select = True setup_skins (mdl, uvs) - if mdl.numframes > 1 or mdl.frames[0].type: - for i in range(mdl.numframes): - frame = mdl.frames[i] - if frame.type: - for j in range(frame.numframes): - make_shape_key(mdl, i, j) - else: - make_shape_key(mdl, i) + build_shape_keys(mdl) + build_actions(mdl) mdl.mesh.update() bpy.context.user_preferences.edit.use_global_undo = True return 'FINISHED' - From ad8afec84c5e36749474f5573447558c19d7a635 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 17 Sep 2011 23:41:35 +0900 Subject: [PATCH 184/334] Merge multiple frames into a single frame group. But only if they seem to be related (ie, the frame name is the same up to the number). This will later become optional, but it allows me to test some of the frame group code. --- tools/qfmdl/import_mdl.py | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/tools/qfmdl/import_mdl.py b/tools/qfmdl/import_mdl.py index b93675c53..046cb0900 100644 --- a/tools/qfmdl/import_mdl.py +++ b/tools/qfmdl/import_mdl.py @@ -347,10 +347,39 @@ def build_actions(mdl): fck.append((k, act.fcurves.new(data_path=dp))) if frame.type: for j in range(frame.numframes): - set_keys (fck, frame.frames[i].key, j + 1, frame.numframes) + set_keys (fck, frame.frames[j].key, j + 1, frame.numframes) else: set_keys (fck, frame.key, 1, 1) +def get_base(name): + i = 0 + while name[i] not in "0123456789": + i += 1 + return name[:i] + +def merge_frames(mdl): + i = 0 + while i < mdl.numframes: + if mdl.frames[i].type: + i += 1 + continue + base = get_base(mdl.frames[i].name) + j = i + 1 + while j < mdl.numframes: + if mdl.frames[j].type: + break + if get_base(mdl.frames[j].name) != base: + break + j += 1 + f = frame() + f.name = base + f.numframes = j - i + f.type = 1 + f.frames = mdl.frames[i:j] + mdl.frames[i:j] = [f] + mdl.numframes -= f.numframes - 1 + i += 1 + def import_mdl(operator, context, filepath): bpy.context.user_preferences.edit.use_global_undo = False @@ -367,6 +396,7 @@ def import_mdl(operator, context, filepath): bpy.context.scene.objects.active = mdl.obj mdl.obj.select = True setup_skins (mdl, uvs) + merge_frames(mdl) if mdl.numframes > 1 or mdl.frames[0].type: build_shape_keys(mdl) build_actions(mdl) From dbb1df70b5f3f76431fb30bcdd2972ae5c24a30f Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 18 Sep 2011 09:18:49 +0900 Subject: [PATCH 185/334] Fix frame merging for mdlv3 files. v3 files have no name fields in the frames, so we need to store the generated name. --- tools/qfmdl/import_mdl.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/qfmdl/import_mdl.py b/tools/qfmdl/import_mdl.py index 046cb0900..2b44afd09 100644 --- a/tools/qfmdl/import_mdl.py +++ b/tools/qfmdl/import_mdl.py @@ -271,6 +271,8 @@ def make_shape_key(mdl, framenum, subframenum=0): name = "%s_%d_%d" % (mdl.name, framenum, subframenum) if frame.name: name = frame.name + else: + frame.name = name frame.key = mdl.obj.shape_key_add(name) frame.key.value = 0.0 mdl.keys.append (frame.key) @@ -353,7 +355,7 @@ def build_actions(mdl): def get_base(name): i = 0 - while name[i] not in "0123456789": + while i < len(name) and name[i] not in "0123456789": i += 1 return name[:i] @@ -396,9 +398,9 @@ def import_mdl(operator, context, filepath): bpy.context.scene.objects.active = mdl.obj mdl.obj.select = True setup_skins (mdl, uvs) - merge_frames(mdl) if mdl.numframes > 1 or mdl.frames[0].type: build_shape_keys(mdl) + merge_frames(mdl) build_actions(mdl) mdl.mesh.update() From b57e098e93785f86d4f5d5e4ef8ca315c03b32dc Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 18 Sep 2011 09:58:59 +0900 Subject: [PATCH 186/334] Rewrite the frame group to action conversion. Now it works :) Mostly :/ Need to figure out how to "finalize" the action. Also, blender occasionally loses my skin texture :( --- tools/qfmdl/import_mdl.py | 68 +++++++++++++-------------------------- 1 file changed, 23 insertions(+), 45 deletions(-) diff --git a/tools/qfmdl/import_mdl.py b/tools/qfmdl/import_mdl.py index 2b44afd09..7dc7e723e 100644 --- a/tools/qfmdl/import_mdl.py +++ b/tools/qfmdl/import_mdl.py @@ -296,45 +296,14 @@ def build_shape_keys(mdl): else: make_shape_key(mdl, i) -""" -fc.keyframe_points.add(3) -fc.keyframe_points[0].co=10.0,0.0 -fc.keyframe_points[1].co=20.0,1.0 -fc.keyframe_points[2].co=30.0,0.0 -fc.keyframe_points[2].co=30.2,0.0 -""" -def set_keys(fck, current, f, m): - c = 1 - if f > 1: - c += 1 - if f > 2: - c += 1 - if f < m: - c += 1 - if f < m - 1: - c += 1 - for k in fck: - k[1].keyframe_points.add(c) - kp = k[1].keyframe_points - i = 0 - if f > 2: - kp[i].co = 1.0,0.0 - i += 1 - x = f * 1.0 - if f > 1: - kp[i].co = x - 1.0,0.0 - i += 1 - if k[0] == current: - y = 1.0 - else: - y = 0.0 - kp[i].co = x,y - i += 1 - if f < m: - kp[i].co = x + 1.0,0.0 - i += 1 - if f < m - 1: - kp[i].co = m * 1.0,0.0 +def set_keys(act, data): + for d in data: + key, co = d + dp = """key_blocks["%s"].value""" % key.name + fc = act.fcurves.new(data_path = dp) + fc.keyframe_points.add(len(co)) + for i in range(len(co)): + fc.keyframe_points[i].co = co[i] def build_actions(mdl): sk = mdl.mesh.shape_keys @@ -343,15 +312,24 @@ def build_actions(mdl): sk.animation_data_create() sk.animation_data.action = bpy.data.actions.new(frame.name) act=sk.animation_data.action - fck = [] - for k in mdl.keys: - dp = """key_blocks["%s"].value""" % k.name - fck.append((k, act.fcurves.new(data_path=dp))) + data = [] if frame.type: for j in range(frame.numframes): - set_keys (fck, frame.frames[j].key, j + 1, frame.numframes) + co = [] + if j > 1: + co.append ((1.0, 0.0)) + if j > 0: + co.append ((j * 1.0, 0.0)) + co.append (((j + 1) * 1.0, 1.0)) + if j < frame.numframes - 2: + co.append (((j + 2) * 1.0, 0.0)) + if j < frame.numframes - 1: + co.append ((frame.numframes * 1.0, 0.0)) + pprint (co) + data.append((frame.frames[j].key, co)) else: - set_keys (fck, frame.key, 1, 1) + data.append((frame.key, [(1.0, 1.0)])) + set_keys (act, data) def get_base(name): i = 0 From 94ac2fa675e155c1bfc55f62f8329955d93f9930 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 18 Sep 2011 10:37:28 +0900 Subject: [PATCH 187/334] Remove a debug print --- tools/qfmdl/import_mdl.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/qfmdl/import_mdl.py b/tools/qfmdl/import_mdl.py index 7dc7e723e..227e4e45e 100644 --- a/tools/qfmdl/import_mdl.py +++ b/tools/qfmdl/import_mdl.py @@ -325,7 +325,6 @@ def build_actions(mdl): co.append (((j + 2) * 1.0, 0.0)) if j < frame.numframes - 1: co.append ((frame.numframes * 1.0, 0.0)) - pprint (co) data.append((frame.frames[j].key, co)) else: data.append((frame.key, [(1.0, 1.0)])) From c65522b5cf428f16b9983bf607fbba6fde535443 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 18 Sep 2011 15:37:17 +0900 Subject: [PATCH 188/334] Add key frames for all shape keys. --- tools/qfmdl/import_mdl.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tools/qfmdl/import_mdl.py b/tools/qfmdl/import_mdl.py index 227e4e45e..14f345f91 100644 --- a/tools/qfmdl/import_mdl.py +++ b/tools/qfmdl/import_mdl.py @@ -313,6 +313,7 @@ def build_actions(mdl): sk.animation_data.action = bpy.data.actions.new(frame.name) act=sk.animation_data.action data = [] + other_keys = mdl.keys[:] if frame.type: for j in range(frame.numframes): co = [] @@ -326,8 +327,18 @@ def build_actions(mdl): if j < frame.numframes - 1: co.append ((frame.numframes * 1.0, 0.0)) data.append((frame.frames[j].key, co)) + if frame.frames[j].key in other_keys: + del(other_keys[other_keys.index(frame.frames[j].key)]) + co = [(1.0, 0.0), (frame.numframes * 1.0, 0.0)] + for k in other_keys: + data.append((k, co)) else: data.append((frame.key, [(1.0, 1.0)])) + if frame.key in other_keys: + del(other_keys[other_keys.index(frame.key)]) + co = [(1.0, 0.0)] + for k in other_keys: + data.append((k, co)) set_keys (act, data) def get_base(name): From d90fd4cee9f4208aefc60fa1624d91d0b50ca7bb Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 18 Sep 2011 18:49:16 +0900 Subject: [PATCH 189/334] Fix a mistake found by a debug build of blender. --- tools/qfmdl/import_mdl.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/qfmdl/import_mdl.py b/tools/qfmdl/import_mdl.py index 14f345f91..81bc7ca30 100644 --- a/tools/qfmdl/import_mdl.py +++ b/tools/qfmdl/import_mdl.py @@ -394,4 +394,4 @@ def import_mdl(operator, context, filepath): mdl.mesh.update() bpy.context.user_preferences.edit.use_global_undo = True - return 'FINISHED' + return {'FINISHED'} From a32e45d2d503337ecabfad5da0fab3793140ee7b Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 20 Sep 2011 12:44:37 +0900 Subject: [PATCH 190/334] Refactor the import code. This should make things a little more maintainable. --- tools/qfmdl/import_mdl.py | 342 ++++++++++++++++++++------------------ 1 file changed, 176 insertions(+), 166 deletions(-) diff --git a/tools/qfmdl/import_mdl.py b/tools/qfmdl/import_mdl.py index 81bc7ca30..39d7adcc6 100644 --- a/tools/qfmdl/import_mdl.py +++ b/tools/qfmdl/import_mdl.py @@ -29,152 +29,160 @@ from mathutils import Vector,Matrix from . import quakepal class MDL: - pass -class skin: - pass -class stvert: - pass -class tri: - pass -class frame: - pass -class vert: - pass + class Skin: + def __init__(self): + pass + def read(self, mdl, sub=0): + self.width, self.height = mdl.skinwidth, mdl.skinheight + if sub: + self.type = 0 + self.read_pixels(mdl) + return self + self.type = mdl.read_int() + if self.type: + # skin group + num = mdl.read_int() + self.times = mdl.read_float(num) + self.skins = [] + for i in range(num): + self.skins.append(MDL.Skin().read(mdl, 1)) + num -= 1 + return self + self.read_pixels(mdl) + return self -def load_mdl(filepath): - data = open(filepath, "rb").read() - m = unpack("<4s i 3f 3f f 3f i i i i i i i", data[:76]) - data = data[76:] - mdl = MDL() - mdl.name = filepath.split('/')[-1] - mdl.name = mdl.name.split('.')[0] - mdl.ident = m[0] - mdl.version = m[1] - mdl.scale = Vector(m[2:5]) - mdl.scale_origin = Vector(m[5:8]) - mdl.boundingradius = m[8] - mdl.eyeposition = Vector(m[9:12]) - mdl.numskins = m[12] - mdl.skinwidth = m[13] - mdl.skinheight = m[14] - mdl.numverts = m[15] - mdl.numtris = m[16] - mdl.numframes = m[17] - mdl.synctype = m[18] - mdl.flags = 0 - mdl.size = 1.0 # random number ;) - if mdl.version == 6: - m = (" 1: co.append ((1.0, 0.0)) if j > 0: co.append ((j * 1.0, 0.0)) co.append (((j + 1) * 1.0, 1.0)) - if j < frame.numframes - 2: + if j < len(frame.frames) - 2: co.append (((j + 2) * 1.0, 0.0)) - if j < frame.numframes - 1: - co.append ((frame.numframes * 1.0, 0.0)) - data.append((frame.frames[j].key, co)) - if frame.frames[j].key in other_keys: - del(other_keys[other_keys.index(frame.frames[j].key)]) - co = [(1.0, 0.0), (frame.numframes * 1.0, 0.0)] + if j < len(frame.frames) - 1: + co.append ((len(frame.frames) * 1.0, 0.0)) + data.append((subframe.key, co)) + if subframe.key in other_keys: + del(other_keys[other_keys.index(subframe.key)]) + co = [(1.0, 0.0), (len(frame.frames) * 1.0, 0.0)] for k in other_keys: data.append((k, co)) else: @@ -349,25 +358,23 @@ def get_base(name): def merge_frames(mdl): i = 0 - while i < mdl.numframes: + while i < len(mdl.frames): if mdl.frames[i].type: i += 1 continue base = get_base(mdl.frames[i].name) j = i + 1 - while j < mdl.numframes: + while j < len(mdl.frames): if mdl.frames[j].type: break if get_base(mdl.frames[j].name) != base: break j += 1 - f = frame() + f = MDL.Frame() f.name = base - f.numframes = j - i f.type = 1 f.frames = mdl.frames[i:j] mdl.frames[i:j] = [f] - mdl.numframes -= f.numframes - 1 i += 1 def import_mdl(operator, context, filepath): @@ -376,7 +383,10 @@ def import_mdl(operator, context, filepath): for obj in bpy.context.scene.objects: obj.select = False - mdl = load_mdl(filepath) + mdl = MDL() + if not mdl.read(filepath): + #FIXME report? + return {'CANCELED'} faces, uvs = make_faces (mdl) verts = make_verts (mdl, 0) mdl.mesh = bpy.data.meshes.new(mdl.name) @@ -386,7 +396,7 @@ def import_mdl(operator, context, filepath): bpy.context.scene.objects.active = mdl.obj mdl.obj.select = True setup_skins (mdl, uvs) - if mdl.numframes > 1 or mdl.frames[0].type: + if len(mdl.frames) > 1 or mdl.frames[0].type: build_shape_keys(mdl) merge_frames(mdl) build_actions(mdl) From 9a4e5aef53315245b304fc82979af16ec8f0a3ab Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 20 Sep 2011 13:33:41 +0900 Subject: [PATCH 191/334] Read strings as strings rather than bytes. --- tools/qfmdl/import_mdl.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/tools/qfmdl/import_mdl.py b/tools/qfmdl/import_mdl.py index 39d7adcc6..49411fe9b 100644 --- a/tools/qfmdl/import_mdl.py +++ b/tools/qfmdl/import_mdl.py @@ -53,7 +53,7 @@ class MDL: def read_pixels(self, mdl): size = self.width * self.height - self.pixels = mdl.read_string(size) + self.pixels = mdl.read_bytes(size) class STVert: def __init__(self): @@ -142,9 +142,16 @@ class MDL: return data[0] return data - def read_string(self, size): + def read_bytes(self, size): return self.file.read(size) + def read_string(self, size): + data = self.file.read(size) + s = "" + for c in data: + s = s + chr(c) + return s + def __init__(self): pass def read(self, filepath): @@ -153,7 +160,7 @@ class MDL: self.name = self.name.split('.')[0] self.ident = self.read_string(4) self.version = self.read_int() - if self.ident not in [b"IDPO", b"MD16"] or self.version not in [3, 6]: + if self.ident not in ["IDPO", "MD16"] or self.version not in [3, 6]: return None self.scale = Vector(self.read_float(3)) self.scale_origin = Vector(self.read_float(3)) From 67ba9129ed90f4da681711d9784ee6ce1892b55c Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 20 Sep 2011 13:34:12 +0900 Subject: [PATCH 192/334] Report bad mdl files. --- tools/qfmdl/import_mdl.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/qfmdl/import_mdl.py b/tools/qfmdl/import_mdl.py index 49411fe9b..bdf8ee514 100644 --- a/tools/qfmdl/import_mdl.py +++ b/tools/qfmdl/import_mdl.py @@ -392,8 +392,9 @@ def import_mdl(operator, context, filepath): mdl = MDL() if not mdl.read(filepath): - #FIXME report? - return {'CANCELED'} + operator.report({'ERROR'}, + "Unrecognized format: %s %d" % (mdl.ident, mdl.version)) + return {'CANCELLED'} faces, uvs = make_faces (mdl) verts = make_verts (mdl, 0) mdl.mesh = bpy.data.meshes.new(mdl.name) From b00e865d4c2f8bea0a91a02b8283da31efcf466a Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 20 Sep 2011 18:58:45 +0900 Subject: [PATCH 193/334] Make the importer work in both 2.58 and svn blender. --- tools/qfmdl/import_mdl.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/tools/qfmdl/import_mdl.py b/tools/qfmdl/import_mdl.py index bdf8ee514..693695bd0 100644 --- a/tools/qfmdl/import_mdl.py +++ b/tools/qfmdl/import_mdl.py @@ -203,8 +203,10 @@ def make_verts(mdl, framenum, subframenum=0): ( 0, 0,s.z, 0), (o.x,o.y,o.z, 1))) for v in frame.verts: - verts.append(Vector(v.r) * m) - #verts.append(m * Vector(v.r)) + try: #FIXME + verts.append(Vector(v.r) * m) + except ValueError: + verts.append(m * Vector(v.r)) return verts def make_faces(mdl): @@ -245,7 +247,8 @@ def load_skins(mdl): p[l + 2] = c[2] / 255.0 p[l + 3] = 1.0 img.pixels[:] = p[:] - #img.pack(True) + if hasattr(img, "pack"): + img.pack(True) mdl.images=[] for i, skin in enumerate(mdl.skins): @@ -299,8 +302,10 @@ def make_shape_key(mdl, framenum, subframenum=0): ( 0, 0,s.z, 0), (o.x,o.y,o.z, 1))) for i, v in enumerate(frame.verts): - frame.key.data[i].co = Vector(v.r) * m - #frame.key.data[i].co = m * Vector(v.r) + try: #FIXME + frame.key.data[i].co = Vector(v.r) * m + except ValueError: + frame.key.data[i].co = m * Vector(v.r) def build_shape_keys(mdl): mdl.keys = [] @@ -404,6 +409,10 @@ def import_mdl(operator, context, filepath): bpy.context.scene.objects.active = mdl.obj mdl.obj.select = True setup_skins (mdl, uvs) + if mdl.images and not hasattr(mdl.images[0], "pack"): + operator.report({'WARNING'}, + "Unable to pack skins. They must be packed by hand." + +" Some may have been lost") if len(mdl.frames) > 1 or mdl.frames[0].type: build_shape_keys(mdl) merge_frames(mdl) From af4a91accf7239663e31f51232d5d9a9a4a5388e Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 20 Sep 2011 19:32:49 +0900 Subject: [PATCH 194/334] Do a tiny bit of cleanup. --- tools/qfmdl/import_mdl.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tools/qfmdl/import_mdl.py b/tools/qfmdl/import_mdl.py index 693695bd0..8a06d640d 100644 --- a/tools/qfmdl/import_mdl.py +++ b/tools/qfmdl/import_mdl.py @@ -309,7 +309,7 @@ def make_shape_key(mdl, framenum, subframenum=0): def build_shape_keys(mdl): mdl.keys = [] - mdl.obj.shape_key_add("Basis") # FIXME do I want this? + mdl.obj.shape_key_add("Basis") for i, frame in enumerate(mdl.frames): frame = mdl.frames[i] if frame.type: @@ -362,13 +362,13 @@ def build_actions(mdl): data.append((k, co)) set_keys (act, data) -def get_base(name): - i = 0 - while i < len(name) and name[i] not in "0123456789": - i += 1 - return name[:i] - def merge_frames(mdl): + def get_base(name): + i = 0 + while i < len(name) and name[i] not in "0123456789": + i += 1 + return name[:i] + i = 0 while i < len(mdl.frames): if mdl.frames[i].type: From 4b9a4219281b1ffe4d52b33e2a8b7eb1603768f2 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 21 Sep 2011 12:34:09 +0900 Subject: [PATCH 195/334] Split out the MDL class. I will need it for the exporter. --- tools/qfmdl/import_mdl.py | 168 +--------------------------------- tools/qfmdl/mdl.py | 187 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 189 insertions(+), 166 deletions(-) create mode 100644 tools/qfmdl/mdl.py diff --git a/tools/qfmdl/import_mdl.py b/tools/qfmdl/import_mdl.py index 8a06d640d..807fcd9aa 100644 --- a/tools/qfmdl/import_mdl.py +++ b/tools/qfmdl/import_mdl.py @@ -19,177 +19,13 @@ # -from struct import unpack -from pprint import pprint - import bpy from bpy_extras.object_utils import object_data_add from mathutils import Vector,Matrix from . import quakepal - -class MDL: - class Skin: - def __init__(self): - pass - def read(self, mdl, sub=0): - self.width, self.height = mdl.skinwidth, mdl.skinheight - if sub: - self.type = 0 - self.read_pixels(mdl) - return self - self.type = mdl.read_int() - if self.type: - # skin group - num = mdl.read_int() - self.times = mdl.read_float(num) - self.skins = [] - for i in range(num): - self.skins.append(MDL.Skin().read(mdl, 1)) - num -= 1 - return self - self.read_pixels(mdl) - return self - - def read_pixels(self, mdl): - size = self.width * self.height - self.pixels = mdl.read_bytes(size) - - class STVert: - def __init__(self): - pass - def read(self, mdl): - self.onseam = mdl.read_int() - self.s, self.t = mdl.read_int(2) - return self - - class Tri: - def __init__(self): - pass - def read(self, mdl): - self.facesfront = mdl.read_int() - self.verts = mdl.read_int(3) - return self - - class Frame: - def __init__(self): - pass - def read(self, mdl, numverts, sub=0): - if sub: - self.type = 0 - else: - self.type = mdl.read_int() - if self.type: - num = mdl.read_int() - self.read_bounds(mdl) - self.times = mdl.read_float(num) - self.frames = [] - for i in range(num): - self.frames.append(MDL.Frame().read(mdl, numverts, 1)) - return self - self.read_bounds(mdl) - self.read_name(mdl) - self.read_verts(mdl, numverts) - return self - - def read_name(self, mdl): - if mdl.version == 6: - name = mdl.read_string(16) - else: - name = "" - if "\0" in name: - name = name[:name.index("\0")] - self.name = name - - def read_bounds(self, mdl): - self.mins = mdl.read_byte(4)[:3] #discard normal index - self.maxs = mdl.read_byte(4)[:3] #discard normal index - - def read_verts(self, mdl, num): - self.verts = [] - for i in range(num): - self.verts.append(MDL.Vert().read(mdl)) - - class Vert: - def __init__(self): - pass - def read(self, mdl): - self.r = mdl.read_byte(3) - self.ni = mdl.read_byte() - return self - - def read_byte(self, count=1): - size = 1 * count - data = self.file.read(size) - data = unpack("<%dB" % count, data) - if count == 1: - return data[0] - return data - - def read_int(self, count=1): - size = 4 * count - data = self.file.read(size) - data = unpack("<%di" % count, data) - if count == 1: - return data[0] - return data - - def read_float(self, count=1): - size = 4 * count - data = self.file.read(size) - data = unpack("<%df" % count, data) - if count == 1: - return data[0] - return data - - def read_bytes(self, size): - return self.file.read(size) - - def read_string(self, size): - data = self.file.read(size) - s = "" - for c in data: - s = s + chr(c) - return s - - def __init__(self): - pass - def read(self, filepath): - self.file = open(filepath, "rb") - self.name = filepath.split('/')[-1] - self.name = self.name.split('.')[0] - self.ident = self.read_string(4) - self.version = self.read_int() - if self.ident not in ["IDPO", "MD16"] or self.version not in [3, 6]: - return None - self.scale = Vector(self.read_float(3)) - self.scale_origin = Vector(self.read_float(3)) - self.boundingradius = self.read_float() - self.eyeposition = Vector(self.read_float(3)) - numskins = self.read_int() - self.skinwidth, self.skinheight = self.read_int(2) - numverts, numtris, numframes = self.read_int(3) - self.synctype = self.read_int() - if self.version == 6: - self.flags = self.read_int() - self.size = self.read_float() - # read in the skin data - self.skins = [] - for i in range(numskins): - self.skins.append(MDL.Skin().read(self)) - #read in the st verts (uv map) - self.stverts = [] - for i in range(numverts): - self.stverts.append (MDL.STVert().read(self)) - #read in the tris - self.tris = [] - for i in range(numtris): - self.tris.append(MDL.Tri().read(self)) - #read in the frames - self.frames = [] - for i in range(numframes): - self.frames.append(MDL.Frame().read(self, numverts)) - return self +from . import mdl +MDL = mdl.MDL def make_verts(mdl, framenum, subframenum=0): frame = mdl.frames[framenum] diff --git a/tools/qfmdl/mdl.py b/tools/qfmdl/mdl.py new file mode 100644 index 000000000..4711715ea --- /dev/null +++ b/tools/qfmdl/mdl.py @@ -0,0 +1,187 @@ +# vim:ts=4:et +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +# + +from struct import unpack + +from mathutils import Vector + +class MDL: + class Skin: + def __init__(self): + pass + def read(self, mdl, sub=0): + self.width, self.height = mdl.skinwidth, mdl.skinheight + if sub: + self.type = 0 + self.read_pixels(mdl) + return self + self.type = mdl.read_int() + if self.type: + # skin group + num = mdl.read_int() + self.times = mdl.read_float(num) + self.skins = [] + for i in range(num): + self.skins.append(MDL.Skin().read(mdl, 1)) + num -= 1 + return self + self.read_pixels(mdl) + return self + + def read_pixels(self, mdl): + size = self.width * self.height + self.pixels = mdl.read_bytes(size) + + class STVert: + def __init__(self): + pass + def read(self, mdl): + self.onseam = mdl.read_int() + self.s, self.t = mdl.read_int(2) + return self + + class Tri: + def __init__(self): + pass + def read(self, mdl): + self.facesfront = mdl.read_int() + self.verts = mdl.read_int(3) + return self + + class Frame: + def __init__(self): + pass + def read(self, mdl, numverts, sub=0): + if sub: + self.type = 0 + else: + self.type = mdl.read_int() + if self.type: + num = mdl.read_int() + self.read_bounds(mdl) + self.times = mdl.read_float(num) + self.frames = [] + for i in range(num): + self.frames.append(MDL.Frame().read(mdl, numverts, 1)) + return self + self.read_bounds(mdl) + self.read_name(mdl) + self.read_verts(mdl, numverts) + return self + + def read_name(self, mdl): + if mdl.version == 6: + name = mdl.read_string(16) + else: + name = "" + if "\0" in name: + name = name[:name.index("\0")] + self.name = name + + def read_bounds(self, mdl): + self.mins = mdl.read_byte(4)[:3] #discard normal index + self.maxs = mdl.read_byte(4)[:3] #discard normal index + + def read_verts(self, mdl, num): + self.verts = [] + for i in range(num): + self.verts.append(MDL.Vert().read(mdl)) + + class Vert: + def __init__(self): + pass + def read(self, mdl): + self.r = mdl.read_byte(3) + self.ni = mdl.read_byte() + return self + + def read_byte(self, count=1): + size = 1 * count + data = self.file.read(size) + data = unpack("<%dB" % count, data) + if count == 1: + return data[0] + return data + + def read_int(self, count=1): + size = 4 * count + data = self.file.read(size) + data = unpack("<%di" % count, data) + if count == 1: + return data[0] + return data + + def read_float(self, count=1): + size = 4 * count + data = self.file.read(size) + data = unpack("<%df" % count, data) + if count == 1: + return data[0] + return data + + def read_bytes(self, size): + return self.file.read(size) + + def read_string(self, size): + data = self.file.read(size) + s = "" + for c in data: + s = s + chr(c) + return s + + def __init__(self): + pass + def read(self, filepath): + self.file = open(filepath, "rb") + self.name = filepath.split('/')[-1] + self.name = self.name.split('.')[0] + self.ident = self.read_string(4) + self.version = self.read_int() + if self.ident not in ["IDPO", "MD16"] or self.version not in [3, 6]: + return None + self.scale = Vector(self.read_float(3)) + self.scale_origin = Vector(self.read_float(3)) + self.boundingradius = self.read_float() + self.eyeposition = Vector(self.read_float(3)) + numskins = self.read_int() + self.skinwidth, self.skinheight = self.read_int(2) + numverts, numtris, numframes = self.read_int(3) + self.synctype = self.read_int() + if self.version == 6: + self.flags = self.read_int() + self.size = self.read_float() + # read in the skin data + self.skins = [] + for i in range(numskins): + self.skins.append(MDL.Skin().read(self)) + #read in the st verts (uv map) + self.stverts = [] + for i in range(numverts): + self.stverts.append (MDL.STVert().read(self)) + #read in the tris + self.tris = [] + for i in range(numtris): + self.tris.append(MDL.Tri().read(self)) + #read in the frames + self.frames = [] + for i in range(numframes): + self.frames.append(MDL.Frame().read(self, numverts)) + return self From 2ca39e7f7570c9549496e7d1563e689e9b76a8f1 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 21 Sep 2011 17:37:32 +0900 Subject: [PATCH 196/334] Start working on the exporter. --- tools/qfmdl/__init__.py | 8 +++++++- tools/qfmdl/export_mdl.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 tools/qfmdl/export_mdl.py diff --git a/tools/qfmdl/__init__.py b/tools/qfmdl/__init__.py index 599f58648..1fc18fc39 100644 --- a/tools/qfmdl/__init__.py +++ b/tools/qfmdl/__init__.py @@ -54,6 +54,8 @@ class ImportMDL6(bpy.types.Operator, ImportHelper): bl_idname = "import_mesh.quake_mdl_v6" bl_label = "Import MDL" + filename_ext = ".mdl" + def execute(self, context): from . import import_mdl keywords = self.as_keywords () @@ -63,9 +65,13 @@ class ExportMDL6(bpy.types.Operator, ExportHelper): '''Save a Quake MDL (v6) File''' bl_idname = "export_mesh.quake_mdl_v6" - bl_label = 'Export MDL' + bl_label = "Export MDL" + + filename_ext = ".mdl" def execute(self, context): + from . import export_mdl + keywords = self.as_keywords () return export_mdl.export_mdl(self, context, **keywords) diff --git a/tools/qfmdl/export_mdl.py b/tools/qfmdl/export_mdl.py new file mode 100644 index 000000000..ddc209dfa --- /dev/null +++ b/tools/qfmdl/export_mdl.py @@ -0,0 +1,31 @@ +# vim:ts=4:et +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +# + +import bpy +from bpy_extras.object_utils import object_data_add +from mathutils import Vector,Matrix + +from . import quakepal +from . import mdl +MDL = mdl.MDL + +def export_mdl(operator, context, filepath): + return {'FINISHED'} From 84f65a0171e7aa7c13790208972ae7d87875d52e Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 21 Sep 2011 18:23:45 +0900 Subject: [PATCH 197/334] Get the "front end" working nicely. Proper enable/disable of export, file filtering and no exceptions :) --- tools/qfmdl/__init__.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tools/qfmdl/__init__.py b/tools/qfmdl/__init__.py index 1fc18fc39..6d100de1f 100644 --- a/tools/qfmdl/__init__.py +++ b/tools/qfmdl/__init__.py @@ -55,10 +55,11 @@ class ImportMDL6(bpy.types.Operator, ImportHelper): bl_label = "Import MDL" filename_ext = ".mdl" + filter_glob = StringProperty(default="*.mdl", options={'HIDDEN'}) def execute(self, context): from . import import_mdl - keywords = self.as_keywords () + keywords = self.as_keywords (ignore=("filter_glob",)) return import_mdl.import_mdl(self, context, **keywords) class ExportMDL6(bpy.types.Operator, ExportHelper): @@ -68,10 +69,16 @@ class ExportMDL6(bpy.types.Operator, ExportHelper): bl_label = "Export MDL" filename_ext = ".mdl" + filter_glob = StringProperty(default="*.mdl", options={'HIDDEN'}) + + @classmethod + def poll(cls, context): + return (context.active_object != None + and type(context.active_object.data) == bpy.types.Mesh) def execute(self, context): from . import export_mdl - keywords = self.as_keywords () + keywords = self.as_keywords (ignore=("check_existing", "filter_glob")) return export_mdl.export_mdl(self, context, **keywords) From c3b358f470d6e2861c630e159035867d80262781 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 21 Sep 2011 19:13:01 +0900 Subject: [PATCH 198/334] Clean up the intra-package import lines. --- tools/qfmdl/export_mdl.py | 5 ++--- tools/qfmdl/import_mdl.py | 7 +++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/tools/qfmdl/export_mdl.py b/tools/qfmdl/export_mdl.py index ddc209dfa..7ff6b989c 100644 --- a/tools/qfmdl/export_mdl.py +++ b/tools/qfmdl/export_mdl.py @@ -23,9 +23,8 @@ import bpy from bpy_extras.object_utils import object_data_add from mathutils import Vector,Matrix -from . import quakepal -from . import mdl -MDL = mdl.MDL +from .quakepal import palette +from .mdl import MDL def export_mdl(operator, context, filepath): return {'FINISHED'} diff --git a/tools/qfmdl/import_mdl.py b/tools/qfmdl/import_mdl.py index 807fcd9aa..c59d3acb2 100644 --- a/tools/qfmdl/import_mdl.py +++ b/tools/qfmdl/import_mdl.py @@ -23,9 +23,8 @@ import bpy from bpy_extras.object_utils import object_data_add from mathutils import Vector,Matrix -from . import quakepal -from . import mdl -MDL = mdl.MDL +from .quakepal import palette +from .mdl import MDL def make_verts(mdl, framenum, subframenum=0): frame = mdl.frames[framenum] @@ -74,7 +73,7 @@ def load_skins(mdl): d = skin.pixels for j in range(mdl.skinheight): for k in range(mdl.skinwidth): - c = quakepal.palette[d[j * mdl.skinwidth + k]] + c = palette[d[j * mdl.skinwidth + k]] # quake textures are top to bottom, but blender images # are bottom to top l = ((mdl.skinheight - 1 - j) * mdl.skinwidth + k) * 4 From 57aa19bd44ed1020b58004ea889e680863d3becc Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 21 Sep 2011 20:18:23 +0900 Subject: [PATCH 199/334] Rename qfmdl to io_mesh_qfmdl. This fits in better with the blender addon naming scheme. --- tools/{qfmdl => io_mesh_qfmdl}/__init__.py | 0 tools/{qfmdl => io_mesh_qfmdl}/export_mdl.py | 0 tools/{qfmdl => io_mesh_qfmdl}/import_mdl.py | 0 tools/{qfmdl => io_mesh_qfmdl}/mdl.py | 0 tools/{qfmdl => io_mesh_qfmdl}/quakepal.py | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename tools/{qfmdl => io_mesh_qfmdl}/__init__.py (100%) rename tools/{qfmdl => io_mesh_qfmdl}/export_mdl.py (100%) rename tools/{qfmdl => io_mesh_qfmdl}/import_mdl.py (100%) rename tools/{qfmdl => io_mesh_qfmdl}/mdl.py (100%) rename tools/{qfmdl => io_mesh_qfmdl}/quakepal.py (100%) diff --git a/tools/qfmdl/__init__.py b/tools/io_mesh_qfmdl/__init__.py similarity index 100% rename from tools/qfmdl/__init__.py rename to tools/io_mesh_qfmdl/__init__.py diff --git a/tools/qfmdl/export_mdl.py b/tools/io_mesh_qfmdl/export_mdl.py similarity index 100% rename from tools/qfmdl/export_mdl.py rename to tools/io_mesh_qfmdl/export_mdl.py diff --git a/tools/qfmdl/import_mdl.py b/tools/io_mesh_qfmdl/import_mdl.py similarity index 100% rename from tools/qfmdl/import_mdl.py rename to tools/io_mesh_qfmdl/import_mdl.py diff --git a/tools/qfmdl/mdl.py b/tools/io_mesh_qfmdl/mdl.py similarity index 100% rename from tools/qfmdl/mdl.py rename to tools/io_mesh_qfmdl/mdl.py diff --git a/tools/qfmdl/quakepal.py b/tools/io_mesh_qfmdl/quakepal.py similarity index 100% rename from tools/qfmdl/quakepal.py rename to tools/io_mesh_qfmdl/quakepal.py From ba4ccaf81639c77e52e2a1c69861b33ddf5ef081 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 21 Sep 2011 22:34:23 +0900 Subject: [PATCH 200/334] Check that all faces are triangles. --- tools/io_mesh_qfmdl/export_mdl.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tools/io_mesh_qfmdl/export_mdl.py b/tools/io_mesh_qfmdl/export_mdl.py index 7ff6b989c..9e4ce24b9 100644 --- a/tools/io_mesh_qfmdl/export_mdl.py +++ b/tools/io_mesh_qfmdl/export_mdl.py @@ -27,4 +27,22 @@ from .quakepal import palette from .mdl import MDL def export_mdl(operator, context, filepath): + obj = context.active_object + mesh = obj.data + faces_ok = True + save_select = [] + for f in mesh.faces: + save_select.append(f.select) + f.select = False + if len(f.vertices) > 3: + f.select = True + faces_ok = False + if not faces_ok: + mesh.update() + operator.report({'ERROR'}, + "Mesh has faces with more than 3 vertices.") + return {'CANCELLED'} + #reset selection to what it was before the check. + for f, s in map(lambda x,y: (x, y), mesh.faces, save_select): + f.select = s return {'FINISHED'} From a58f9582b0966fdb0bf682d60c7d3f8696d3c3bc Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 22 Sep 2011 00:58:57 +0900 Subject: [PATCH 201/334] Try to write out the skin. Something's not working as all I get is a black texture, but the basics (MDL writing) seem to be ok. --- tools/io_mesh_qfmdl/export_mdl.py | 49 ++++++++++++++++++++++- tools/io_mesh_qfmdl/mdl.py | 66 ++++++++++++++++++++++++++++++- 2 files changed, 113 insertions(+), 2 deletions(-) diff --git a/tools/io_mesh_qfmdl/export_mdl.py b/tools/io_mesh_qfmdl/export_mdl.py index 9e4ce24b9..fe09c18d0 100644 --- a/tools/io_mesh_qfmdl/export_mdl.py +++ b/tools/io_mesh_qfmdl/export_mdl.py @@ -43,6 +43,53 @@ def export_mdl(operator, context, filepath): "Mesh has faces with more than 3 vertices.") return {'CANCELLED'} #reset selection to what it was before the check. - for f, s in map(lambda x,y: (x, y), mesh.faces, save_select): + for f, s in map(lambda x, y: (x, y), mesh.faces, save_select): f.select = s + mdl = MDL() + mdl.name = obj.name + mdl.ident = "IDPO" #only 8 bit for now + mdl.version = 6 #write only version 6 (nothing usable uses 3) + mdl.scale = (1.0, 1.0, 1.0) #FIXME + mdl.scale_origin = (0.0, 0.0, 0.0) #FIXME + mdl.boundingradius = 1.0 #FIXME + mdl.eyeposition = (0.0, 0.0, 0.0) #FIXME + mdl.synctype = 0 #FIXME config (right default?) + mdl.flags = 0 #FIXME config + mdl.size = 0 #FIXME ??? + mdl.skins = [] + mdl.stverts = [] + mdl.tris = [] + mdl.frames = [] + if (not mesh.uv_textures or not mesh.uv_textures[0].data + or not mesh.uv_textures[0].data[0].image): + mdl.skinwidth = mdl.skinheight = 4 + skin = MDL.Skin() + skin.type = 0 + skin.pixels = bytes(mdl.skinwidth * mdl.skinheight) # black skin + else: + image = mesh.uv_textures[0].data[0].image + mdl.skinwidth, mdl.skinheight = image.size + skin = MDL.Skin() + skin.type = 0 + skin.pixels = bytearray(mdl.skinwidth * mdl.skinheight) # preallocate + for y in range(mdl.skinheight): + for x in range(mdl.skinwidth): + oi = y * mdl.skinwidth + x + # quake textures are top to bottom, but blender images + # are bottom to top + ii = ((mdl.skinheight - 1 - y) * mdl.skinwidth + x) * 4 + rgb = image.pixels[ii : ii + 3] # ignore alpha + rgb = map(lambda x: int(x * 255 + 0.5), rgb) + best = (3*256*256, -1) + for i, p in enumerate(palette): + if i > 255: # should never happen + break + r = 0 + for x in map (lambda a, b: (a - b) ** 2, rgb, p): + r += x + if r < best[0]: + best = (r, i) + skin.pixels[i] = best[1] + mdl.skins.append(skin) + mdl.write (filepath) return {'FINISHED'} diff --git a/tools/io_mesh_qfmdl/mdl.py b/tools/io_mesh_qfmdl/mdl.py index 4711715ea..3c6c929d2 100644 --- a/tools/io_mesh_qfmdl/mdl.py +++ b/tools/io_mesh_qfmdl/mdl.py @@ -19,7 +19,7 @@ # -from struct import unpack +from struct import unpack, pack from mathutils import Vector @@ -45,6 +45,15 @@ class MDL: return self self.read_pixels(mdl) return self + def write(self, mdl, sub=9): + if not sub: + mdl.write_int(self.type) + if self.type: + mdl.write_float(self.times) + for subskin in self.skins: + subskin.write(mdl, 1) + return + mdl.write_bytes(self.pixels) def read_pixels(self, mdl): size = self.width * self.height @@ -147,6 +156,32 @@ class MDL: s = s + chr(c) return s + def write_byte(self, data): + if not hasattr(data, "__len__"): + data = (data,) + self.file.write(pack(("<%dB" % len(data)), *data)) + + def write_int(self, data): + if not hasattr(data, "__len__"): + data = (data,) + self.file.write(pack(("<%di" % len(data)), *data)) + + def write_float(self, data): + if not hasattr(data, "__len__"): + data = (data,) + self.file.write(pack(("<%df" % len(data)), *data)) + + def write_bytes(self, data, size=-1): + if size == -1: + size = len(data) + self.file.write(data[:size]) + if size > len(data): + self.file.write(bytes(size - len(data))) + + def write_string(self, data, size=-1): + data = data.encode() + self.write_bytes(data, size) + def __init__(self): pass def read(self, filepath): @@ -185,3 +220,32 @@ class MDL: for i in range(numframes): self.frames.append(MDL.Frame().read(self, numverts)) return self + + def write (self, filepath): + self.file = open(filepath, "wb") + self.write_string (self.ident, 4) + self.write_int (self.version) + self.write_float (self.scale) + self.write_float (self.scale_origin) + self.write_float (self.boundingradius) + self.write_float (self.eyeposition) + self.write_int (len(self.skins)) + self.write_int ((self.skinwidth, self.skinheight)) + self.write_int (len(self.stverts)) + self.write_int (len(self.tris)) + self.write_int (len(self.frames)) + self.write_int (self.synctype) + self.write_int (self.flags) + self.write_float (self.size) + # write out the skin data + for skin in self.skins: + skin.write(self) + #write out the st verts (uv map) + for stvert in self.stverts: + stvert.write(self) + #write out the tris + for tri in self.tris: + tri.write(self) + #write out the frames + for frame in self.frames: + frame.write(self) From e35dd29a2def898f8877c2d7e49a88eab6966df3 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 22 Sep 2011 01:03:50 +0900 Subject: [PATCH 202/334] Don't use Vector in mdl.py This will make testing of the MDL class a little easier (independent of Blender). --- tools/io_mesh_qfmdl/import_mdl.py | 8 ++++---- tools/io_mesh_qfmdl/mdl.py | 8 +++----- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/tools/io_mesh_qfmdl/import_mdl.py b/tools/io_mesh_qfmdl/import_mdl.py index c59d3acb2..90e57dc4b 100644 --- a/tools/io_mesh_qfmdl/import_mdl.py +++ b/tools/io_mesh_qfmdl/import_mdl.py @@ -31,8 +31,8 @@ def make_verts(mdl, framenum, subframenum=0): if frame.type: frame = frame.frames[subframenum] verts = [] - s = mdl.scale - o = mdl.scale_origin + s = Vector(mdl.scale) + o = Vector(mdl.scale_origin) m = Matrix(((s.x, 0, 0, 0), ( 0,s.y, 0, 0), ( 0, 0,s.z, 0), @@ -130,8 +130,8 @@ def make_shape_key(mdl, framenum, subframenum=0): frame.key = mdl.obj.shape_key_add(name) frame.key.value = 0.0 mdl.keys.append (frame.key) - s = mdl.scale - o = mdl.scale_origin + s = Vector(mdl.scale) + o = Vector(mdl.scale_origin) m = Matrix(((s.x, 0, 0, 0), ( 0,s.y, 0, 0), ( 0, 0,s.z, 0), diff --git a/tools/io_mesh_qfmdl/mdl.py b/tools/io_mesh_qfmdl/mdl.py index 3c6c929d2..0150fc384 100644 --- a/tools/io_mesh_qfmdl/mdl.py +++ b/tools/io_mesh_qfmdl/mdl.py @@ -21,8 +21,6 @@ from struct import unpack, pack -from mathutils import Vector - class MDL: class Skin: def __init__(self): @@ -192,10 +190,10 @@ class MDL: self.version = self.read_int() if self.ident not in ["IDPO", "MD16"] or self.version not in [3, 6]: return None - self.scale = Vector(self.read_float(3)) - self.scale_origin = Vector(self.read_float(3)) + self.scale = self.read_float(3) + self.scale_origin = self.read_float(3) self.boundingradius = self.read_float() - self.eyeposition = Vector(self.read_float(3)) + self.eyeposition = self.read_float(3) numskins = self.read_int() self.skinwidth, self.skinheight = self.read_int(2) numverts, numtris, numframes = self.read_int(3) From 40f46f2ea3d9212fb38cef5ce74542ba5fd5ed43 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 22 Sep 2011 11:36:45 +0900 Subject: [PATCH 203/334] Complete mdl writing. Except for the normal index in the frame bounds (and potentially frame names with junk after the terminating nul), the output is identical to the input for: mdl=MDL().read("invisibl.mdl") mdl.write("test.mdl") --- tools/io_mesh_qfmdl/mdl.py | 42 +++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/tools/io_mesh_qfmdl/mdl.py b/tools/io_mesh_qfmdl/mdl.py index 0150fc384..9e760d961 100644 --- a/tools/io_mesh_qfmdl/mdl.py +++ b/tools/io_mesh_qfmdl/mdl.py @@ -43,7 +43,7 @@ class MDL: return self self.read_pixels(mdl) return self - def write(self, mdl, sub=9): + def write(self, mdl, sub=0): if not sub: mdl.write_int(self.type) if self.type: @@ -52,7 +52,6 @@ class MDL: subskin.write(mdl, 1) return mdl.write_bytes(self.pixels) - def read_pixels(self, mdl): size = self.width * self.height self.pixels = mdl.read_bytes(size) @@ -64,6 +63,9 @@ class MDL: self.onseam = mdl.read_int() self.s, self.t = mdl.read_int(2) return self + def write(self, mdl): + mdl.write_int(self.onseam) + mdl.write_int((self.s, self.t)) class Tri: def __init__(self): @@ -72,6 +74,9 @@ class MDL: self.facesfront = mdl.read_int() self.verts = mdl.read_int(3) return self + def write(self, mdl): + mdl.write_int(self.facesfront) + mdl.write_int(self.verts) class Frame: def __init__(self): @@ -93,7 +98,19 @@ class MDL: self.read_name(mdl) self.read_verts(mdl, numverts) return self - + def write(self, mdl, sub=0): + if not sub: + mdl.write_int(self.type) + if self.type: + mdl.write_int(len(self.frames)) + self.write_bounds(mdl) + mdl.write_float(self.times) + for frame in self.frames: + frame.write(mdl, 1) + return + self.write_bounds(mdl) + self.write_name(mdl) + self.write_verts(mdl) def read_name(self, mdl): if mdl.version == 6: name = mdl.read_string(16) @@ -102,15 +119,22 @@ class MDL: if "\0" in name: name = name[:name.index("\0")] self.name = name - + def write_name(self, mdl): + if mdl.version == 6: + mdl.write_string(self.name, 16) def read_bounds(self, mdl): self.mins = mdl.read_byte(4)[:3] #discard normal index self.maxs = mdl.read_byte(4)[:3] #discard normal index - + def write_bounds(self, mdl): + mdl.write_byte(self.mins + (0,)) + mdl.write_byte(self.maxs + (0,)) def read_verts(self, mdl, num): self.verts = [] for i in range(num): self.verts.append(MDL.Vert().read(mdl)) + def write_verts(self, mdl): + for vert in self.verts: + vert.write(mdl) class Vert: def __init__(self): @@ -119,6 +143,9 @@ class MDL: self.r = mdl.read_byte(3) self.ni = mdl.read_byte() return self + def write(self, mdl): + mdl.write_byte(self.r) + mdl.write_byte(self.ni) def read_byte(self, count=1): size = 1 * count @@ -233,8 +260,9 @@ class MDL: self.write_int (len(self.tris)) self.write_int (len(self.frames)) self.write_int (self.synctype) - self.write_int (self.flags) - self.write_float (self.size) + if self.version == 6: + self.write_int (self.flags) + self.write_float (self.size) # write out the skin data for skin in self.skins: skin.write(self) From 4a3731652eb15eb85c49be5db59bb5062c1e5a6e Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 22 Sep 2011 14:08:10 +0900 Subject: [PATCH 204/334] Fix the exported skin conversion. I must remember to test language features in python 3 :P --- tools/io_mesh_qfmdl/export_mdl.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/io_mesh_qfmdl/export_mdl.py b/tools/io_mesh_qfmdl/export_mdl.py index fe09c18d0..cbdea618b 100644 --- a/tools/io_mesh_qfmdl/export_mdl.py +++ b/tools/io_mesh_qfmdl/export_mdl.py @@ -74,12 +74,12 @@ def export_mdl(operator, context, filepath): skin.pixels = bytearray(mdl.skinwidth * mdl.skinheight) # preallocate for y in range(mdl.skinheight): for x in range(mdl.skinwidth): - oi = y * mdl.skinwidth + x + outind = y * mdl.skinwidth + x # quake textures are top to bottom, but blender images # are bottom to top - ii = ((mdl.skinheight - 1 - y) * mdl.skinwidth + x) * 4 - rgb = image.pixels[ii : ii + 3] # ignore alpha - rgb = map(lambda x: int(x * 255 + 0.5), rgb) + inind = ((mdl.skinheight - 1 - y) * mdl.skinwidth + x) * 4 + rgb = image.pixels[inind : inind + 3] # ignore alpha + rgb = tuple(map(lambda x: int(x * 255 + 0.5), rgb)) best = (3*256*256, -1) for i, p in enumerate(palette): if i > 255: # should never happen @@ -89,7 +89,7 @@ def export_mdl(operator, context, filepath): r += x if r < best[0]: best = (r, i) - skin.pixels[i] = best[1] + skin.pixels[outind] = best[1] mdl.skins.append(skin) mdl.write (filepath) return {'FINISHED'} From 8bec9cb203e5d0691122e6dc5abf24d1b058df8c Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 23 Sep 2011 13:00:46 +0900 Subject: [PATCH 205/334] Clean up export_mdl() a little. --- tools/io_mesh_qfmdl/export_mdl.py | 42 +++++++++++++++---------------- tools/io_mesh_qfmdl/mdl.py | 16 +++++++++++- 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/tools/io_mesh_qfmdl/export_mdl.py b/tools/io_mesh_qfmdl/export_mdl.py index cbdea618b..40fa2921d 100644 --- a/tools/io_mesh_qfmdl/export_mdl.py +++ b/tools/io_mesh_qfmdl/export_mdl.py @@ -26,9 +26,10 @@ from mathutils import Vector,Matrix from .quakepal import palette from .mdl import MDL -def export_mdl(operator, context, filepath): - obj = context.active_object - mesh = obj.data +def check_faces(mesh): + #Check that all faces are tris because mdl does not support anything else. + #Because the diagonal on which a quad is split can make a big difference, + #quad to tri conversion will not be done automatically. faces_ok = True save_select = [] for f in mesh.faces: @@ -39,27 +40,14 @@ def export_mdl(operator, context, filepath): faces_ok = False if not faces_ok: mesh.update() - operator.report({'ERROR'}, - "Mesh has faces with more than 3 vertices.") - return {'CANCELLED'} + return False #reset selection to what it was before the check. for f, s in map(lambda x, y: (x, y), mesh.faces, save_select): f.select = s - mdl = MDL() - mdl.name = obj.name - mdl.ident = "IDPO" #only 8 bit for now - mdl.version = 6 #write only version 6 (nothing usable uses 3) - mdl.scale = (1.0, 1.0, 1.0) #FIXME - mdl.scale_origin = (0.0, 0.0, 0.0) #FIXME - mdl.boundingradius = 1.0 #FIXME - mdl.eyeposition = (0.0, 0.0, 0.0) #FIXME - mdl.synctype = 0 #FIXME config (right default?) - mdl.flags = 0 #FIXME config - mdl.size = 0 #FIXME ??? - mdl.skins = [] - mdl.stverts = [] - mdl.tris = [] - mdl.frames = [] + mesh.update() + return True + +def make_skin(mdl, mesh): if (not mesh.uv_textures or not mesh.uv_textures[0].data or not mesh.uv_textures[0].data[0].image): mdl.skinwidth = mdl.skinheight = 4 @@ -91,5 +79,15 @@ def export_mdl(operator, context, filepath): best = (r, i) skin.pixels[outind] = best[1] mdl.skins.append(skin) - mdl.write (filepath) + +def export_mdl(operator, context, filepath): + obj = context.active_object + mesh = obj.data + if not check_faces (mesh): + operator.report({'ERROR'}, + "Mesh has faces with more than 3 vertices.") + return {'CANCELLED'} + mdl = MDL(obj.name) + make_skin(mdl, mesh) + mdl.write(filepath) return {'FINISHED'} diff --git a/tools/io_mesh_qfmdl/mdl.py b/tools/io_mesh_qfmdl/mdl.py index 9e760d961..41f4ac44c 100644 --- a/tools/io_mesh_qfmdl/mdl.py +++ b/tools/io_mesh_qfmdl/mdl.py @@ -207,7 +207,21 @@ class MDL: data = data.encode() self.write_bytes(data, size) - def __init__(self): + def __init__(self, name = "mdl"): + self.name = name + self.ident = "IDPO" #only 8 bit for now + self.version = 6 #write only version 6 (nothing usable uses 3) + self.scale = (1.0, 1.0, 1.0) #FIXME + self.scale_origin = (0.0, 0.0, 0.0) #FIXME + self.boundingradius = 1.0 #FIXME + self.eyeposition = (0.0, 0.0, 0.0) #FIXME + self.synctype = 0 #FIXME config (right default?) + self.flags = 0 #FIXME config + self.size = 0 #FIXME ??? + self.skins = [] + self.stverts = [] + self.tris = [] + self.frames = [] pass def read(self, filepath): self.file = open(filepath, "rb") From 8ccb07d959ea66451fcd449f68a5ed1dd9dc46fa Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 23 Sep 2011 19:00:39 +0900 Subject: [PATCH 206/334] Make the MDL classes a little more usable. This really eased the writing of the exporter :) --- tools/io_mesh_qfmdl/mdl.py | 53 ++++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 5 deletions(-) diff --git a/tools/io_mesh_qfmdl/mdl.py b/tools/io_mesh_qfmdl/mdl.py index 41f4ac44c..3f520b5b6 100644 --- a/tools/io_mesh_qfmdl/mdl.py +++ b/tools/io_mesh_qfmdl/mdl.py @@ -57,7 +57,11 @@ class MDL: self.pixels = mdl.read_bytes(size) class STVert: - def __init__(self): + def __init__(self, st=None, onseam=False): + if not st: + st = (0, 0) + self.onseam = onseam + self.s, self.t = st pass def read(self, mdl): self.onseam = mdl.read_int() @@ -68,8 +72,11 @@ class MDL: mdl.write_int((self.s, self.t)) class Tri: - def __init__(self): - pass + def __init__(self, verts=None, facesfront=True): + if not verts: + verts = (0, 0, 0) + self.facesfront = facesfront + self.verts = verts def read(self, mdl): self.facesfront = mdl.read_int() self.verts = mdl.read_int(3) @@ -80,7 +87,36 @@ class MDL: class Frame: def __init__(self): - pass + self.type = 0 + self.name = "" + self.mins = [0, 0, 0] + self.maxs = [0, 0, 0] + self.verts = [] + self.frames = [] + self.times = [] + def add_vert(self, vert): + self.verts.append(vert) + for i, v in enumerate(vert.r): + self.mins[i] = min(self.mins[i], v) + self.maxs[i] = max(self.maxs[i], v) + def add_frame(self, frame, time): + self.type = 1 + self.frames.append(frame) + self.times.append(time) + for i in range(3): + self.mins[i] = min(self.mins[i], frame.mins[i]) + self.maxs[i] = max(self.maxs[i], frame.maxs[i]) + def scale(self, mdl): + self.mins = tuple(map(lambda x, s, t: int((x - t) / s), + self.mins, mdl.scale, mdl.scale_origin)) + self.maxs = tuple(map(lambda x, s, t: int((x - t) / s), + self.maxs, mdl.scale, mdl.scale_origin)) + if self.type: + for subframe in self.frames: + subframe.scale(mdl) + else: + for vert in self.verts: + vert.scale(mdl) def read(self, mdl, numverts, sub=0): if sub: self.type = 0 @@ -137,7 +173,11 @@ class MDL: vert.write(mdl) class Vert: - def __init__(self): + def __init__(self, r=None, ni=0): + if not r: + r = (0, 0, 0) + self.r = r + self.ni = ni pass def read(self, mdl): self.r = mdl.read_byte(3) @@ -146,6 +186,9 @@ class MDL: def write(self, mdl): mdl.write_byte(self.r) mdl.write_byte(self.ni) + def scale(self, mdl): + self.r = tuple(map(lambda x, s, t: int((x - t) / s), + self.r, mdl.scale, mdl.scale_origin)) def read_byte(self, count=1): size = 1 * count From a80eef8bc496f96ee5e9a097ef31648299474994 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 23 Sep 2011 19:01:31 +0900 Subject: [PATCH 207/334] Get the exporter mostly working. There seems to be some problems with the UVs, only one frame is exported, and various model params don't get set (eye position, size, bounding radius, synctype, flags), but the size and shape look right in qf :). --- tools/io_mesh_qfmdl/export_mdl.py | 64 ++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/tools/io_mesh_qfmdl/export_mdl.py b/tools/io_mesh_qfmdl/export_mdl.py index 40fa2921d..2aa8e712e 100644 --- a/tools/io_mesh_qfmdl/export_mdl.py +++ b/tools/io_mesh_qfmdl/export_mdl.py @@ -80,14 +80,76 @@ def make_skin(mdl, mesh): skin.pixels[outind] = best[1] mdl.skins.append(skin) +def build_tris(mesh): + # mdl files have a 1:1 relationship between stverts and 3d verts. + # a bit sucky, but it does allow faces to take less memory + # + # modelgen's algorithm for generating UVs is very efficient in that no + # vertices are duplicated (thanks to the onseam flag), but it can result + # in fairly nasty UV layouts, and worse: the artist has no control over + # the layout. However, there seems to be nothing in the mdl format + # preventing the use of duplicate 3d vertices to allow complete freedom + # of the UV layout. + uvfaces = mesh.uv_textures[0].data + stverts = [] + tris = [] + vertmap = [] # map mdl vert num to blender vert num (for 3d verts) + uvdict = {} + for face, uvface in map(lambda a,b: (a,b), mesh.faces, uvfaces): + fv = tuple(face.vertices) + uv = tuple(uvface.uv) + tv = [] + for v, u in map(lambda a,b: (a,b), fv, uv): + k = tuple(u) + if k not in uvdict: + uvdict[k] = len(stverts) + vertmap.append(v) + stverts.append(u) + tv.append(uvdict[k]) + # blender's and quake's vertex order seem to be opposed + tv.reverse() + tris.append(MDL.Tri(tv)) + return tris, stverts, vertmap + +def convert_stverts(mdl, stverts): + for i, st in enumerate (stverts): + s, t = st + s = int (s * mdl.skinwidth + 0.5) + t = int (t * mdl.skinheight + 0.5) + # ensure st is within the skin + s = ((s % mdl.skinwidth) + mdl.skinwidth) % mdl.skinwidth + t = ((t % mdl.skinheight) + mdl.skinheight) % mdl.skinheight + stverts[i] = MDL.STVert ((s, t)) + +def make_frame(mesh, vertmap): + frame = MDL.Frame() + for v in vertmap: + vert = MDL.Vert(tuple(mesh.vertices[v].co)) + frame.add_vert(vert) + return frame + +def scale_verts(mdl): + tf = MDL.Frame() + for f in mdl.frames: + tf.add_frame(f, 0.0) # let the frame class do the dirty work for us + size = Vector(tf.maxs) - Vector(tf.mins) + mdl.scale_origin = tf.mins + mdl.scale = tuple(map(lambda x: x / 255.0, size)) + for f in mdl.frames: + f.scale(mdl) + def export_mdl(operator, context, filepath): obj = context.active_object - mesh = obj.data + mesh = obj.to_mesh (context.scene, True, 'PREVIEW') #wysiwyg? if not check_faces (mesh): operator.report({'ERROR'}, "Mesh has faces with more than 3 vertices.") return {'CANCELLED'} mdl = MDL(obj.name) make_skin(mdl, mesh) + mdl.tris, mdl.stverts, vertmap = build_tris(mesh) + convert_stverts (mdl, mdl.stverts) + mdl.frames.append(make_frame(mesh, vertmap)) + scale_verts(mdl) mdl.write(filepath) return {'FINISHED'} From a1d9e752cd2f304e6a01c0407acef34dae17944e Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 23 Sep 2011 19:58:26 +0900 Subject: [PATCH 208/334] Fix the messed up UVs. I had forgotten to invert the t axis. --- tools/io_mesh_qfmdl/export_mdl.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/io_mesh_qfmdl/export_mdl.py b/tools/io_mesh_qfmdl/export_mdl.py index 2aa8e712e..7c0793da0 100644 --- a/tools/io_mesh_qfmdl/export_mdl.py +++ b/tools/io_mesh_qfmdl/export_mdl.py @@ -114,8 +114,10 @@ def build_tris(mesh): def convert_stverts(mdl, stverts): for i, st in enumerate (stverts): s, t = st + # quake textures are top to bottom, but blender images + # are bottom to top s = int (s * mdl.skinwidth + 0.5) - t = int (t * mdl.skinheight + 0.5) + t = int ((1 - t) * mdl.skinheight + 0.5) # ensure st is within the skin s = ((s % mdl.skinwidth) + mdl.skinwidth) % mdl.skinwidth t = ((t % mdl.skinheight) + mdl.skinheight) % mdl.skinheight From bd840726c2fe46c86790c6e190e7dc3bc4cf15eb Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 24 Sep 2011 09:00:14 +0900 Subject: [PATCH 209/334] Fix the mangled faces. I /did/ see the warning about vertex index 0 in the obj importer script, but I didn't take it seriously enough. This fixes both the twisted texture on a couple of faces, and the truly mangled tris when exporting (using invisibl.mdl for testing). --- tools/io_mesh_qfmdl/export_mdl.py | 9 +++++---- tools/io_mesh_qfmdl/import_mdl.py | 14 ++++++++++---- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/tools/io_mesh_qfmdl/export_mdl.py b/tools/io_mesh_qfmdl/export_mdl.py index 7c0793da0..0d6b61a89 100644 --- a/tools/io_mesh_qfmdl/export_mdl.py +++ b/tools/io_mesh_qfmdl/export_mdl.py @@ -96,8 +96,11 @@ def build_tris(mesh): vertmap = [] # map mdl vert num to blender vert num (for 3d verts) uvdict = {} for face, uvface in map(lambda a,b: (a,b), mesh.faces, uvfaces): - fv = tuple(face.vertices) - uv = tuple(uvface.uv) + fv = list(face.vertices) + uv = list(uvface.uv) + # blender's and quake's vertex order seem to be opposed + fv.reverse() + uv.reverse() tv = [] for v, u in map(lambda a,b: (a,b), fv, uv): k = tuple(u) @@ -106,8 +109,6 @@ def build_tris(mesh): vertmap.append(v) stverts.append(u) tv.append(uvdict[k]) - # blender's and quake's vertex order seem to be opposed - tv.reverse() tris.append(MDL.Tri(tv)) return tris, stverts, vertmap diff --git a/tools/io_mesh_qfmdl/import_mdl.py b/tools/io_mesh_qfmdl/import_mdl.py index 90e57dc4b..1049c729b 100644 --- a/tools/io_mesh_qfmdl/import_mdl.py +++ b/tools/io_mesh_qfmdl/import_mdl.py @@ -48,9 +48,7 @@ def make_faces(mdl): faces = [] uvs = [] for tri in mdl.tris: - tv = tri.verts - tv = tv[2], tv[1], tv[0] # flip the normal by reversing the winding - faces.append (tv) + tv = list(tri.verts) sts = [] for v in tri.verts: stv = mdl.stverts[v] @@ -61,7 +59,15 @@ def make_faces(mdl): # quake textures are top to bottom, but blender images # are bottom to top sts.append((s * 1.0 / mdl.skinwidth, 1 - t * 1.0 / mdl.skinheight)) - sts = sts[2], sts[1], sts[0] # to match face vert reversal + # blender's and quake's vertex order seem to be opposed + tv.reverse() + sts.reverse() + # annoyingly, blender can't have 0 in the final vertex, so rotate the + # face vertices and uvs + if not tv[2]: + tv = [tv[2]] + tv[:2] + sts = [sts[2]] + sts[:2] + faces.append (tv) uvs.append(sts) return faces, uvs From 3b33d8dadeee09e9cd4b42f35a03264aab6b3347 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 24 Sep 2011 11:43:06 +0900 Subject: [PATCH 210/334] Make the basis shape key active on import. Blender must have an active shape key before shape key animation will work. This fixes the models being locked to the first frame until a shape key is selected via the UI. --- tools/io_mesh_qfmdl/import_mdl.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/io_mesh_qfmdl/import_mdl.py b/tools/io_mesh_qfmdl/import_mdl.py index 1049c729b..48c2b6690 100644 --- a/tools/io_mesh_qfmdl/import_mdl.py +++ b/tools/io_mesh_qfmdl/import_mdl.py @@ -151,6 +151,7 @@ def make_shape_key(mdl, framenum, subframenum=0): def build_shape_keys(mdl): mdl.keys = [] mdl.obj.shape_key_add("Basis") + mdl.obj.active_shape_key_index = 0 for i, frame in enumerate(mdl.frames): frame = mdl.frames[i] if frame.type: From 07b5db64c6ec454a54766e716091bafe8193b4bc Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 24 Sep 2011 13:03:18 +0900 Subject: [PATCH 211/334] Calculate the bounding radius. The calculated radius is a smidge (0.05) smaller than the original (invisibl.mdl), but I think that's due to the difference in source data: id used the original models, I'm using their output. --- tools/io_mesh_qfmdl/export_mdl.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/io_mesh_qfmdl/export_mdl.py b/tools/io_mesh_qfmdl/export_mdl.py index 0d6b61a89..d51e5dedc 100644 --- a/tools/io_mesh_qfmdl/export_mdl.py +++ b/tools/io_mesh_qfmdl/export_mdl.py @@ -136,6 +136,8 @@ def scale_verts(mdl): for f in mdl.frames: tf.add_frame(f, 0.0) # let the frame class do the dirty work for us size = Vector(tf.maxs) - Vector(tf.mins) + rsqr = tuple(map(lambda a, b: max(abs(a), abs(b)) ** 2, tf.mins, tf.maxs)) + mdl.boundingradius = (rsqr[0] + rsqr[1] + rsqr[2]) ** 0.5 mdl.scale_origin = tf.mins mdl.scale = tuple(map(lambda x: x / 255.0, size)) for f in mdl.frames: From 50795b82398bca52271282cbade2a9f0d0865654 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 24 Sep 2011 13:18:23 +0900 Subject: [PATCH 212/334] Calculate the model "size". The size is actually the average area in quake units of the mesh's triangles. Again, my results are slightly smaller (0.025). With this, all calculable fields are set. Only eye position, flags and synctype remain. --- tools/io_mesh_qfmdl/export_mdl.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tools/io_mesh_qfmdl/export_mdl.py b/tools/io_mesh_qfmdl/export_mdl.py index d51e5dedc..b8b2759cf 100644 --- a/tools/io_mesh_qfmdl/export_mdl.py +++ b/tools/io_mesh_qfmdl/export_mdl.py @@ -143,6 +143,19 @@ def scale_verts(mdl): for f in mdl.frames: f.scale(mdl) +def calc_average_area(mdl): + frame = mdl.frames[0] + if frame.type: + frame = frame.frames[0] + totalarea = 0.0 + for tri in mdl.tris: + verts = tuple(map(lambda i: frame.verts[i], tri.verts)) + a = Vector(verts[0].r) - Vector(verts[1].r) + b = Vector(verts[2].r) - Vector(verts[1].r) + c = a.cross(b) + totalarea += (c * c) ** 0.5 / 2.0 + return totalarea / len(mdl.tris) + def export_mdl(operator, context, filepath): obj = context.active_object mesh = obj.to_mesh (context.scene, True, 'PREVIEW') #wysiwyg? @@ -155,6 +168,7 @@ def export_mdl(operator, context, filepath): mdl.tris, mdl.stverts, vertmap = build_tris(mesh) convert_stverts (mdl, mdl.stverts) mdl.frames.append(make_frame(mesh, vertmap)) + mdl.size = calc_average_area(mdl) scale_verts(mdl) mdl.write(filepath) return {'FINISHED'} From 2e2484250c90924be87524445365eb1de8692515 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 24 Sep 2011 21:31:02 +0900 Subject: [PATCH 213/334] Add some notes about modelgen's commands. --- tools/qfmodelgen/source/modelgen.txt | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 tools/qfmodelgen/source/modelgen.txt diff --git a/tools/qfmodelgen/source/modelgen.txt b/tools/qfmodelgen/source/modelgen.txt new file mode 100644 index 000000000..116867603 --- /dev/null +++ b/tools/qfmodelgen/source/modelgen.txt @@ -0,0 +1,25 @@ +$modelname #output name +$base #basis model +$cd #source path base +$sync +$origin #model origin offset +$eyeposition #self explanatory :) +$scale #scale factor +$flags NUM #entity effects + 1 EF_ROCKET + 2 EF_GRENADE + 4 EF_GIB + 8 EF_ROTATE + 16 EF_TRACER + 32 EF_ZOMGIB + 64 EF_TRACER2 + 128 EF_TRACER3 + 4096 EF_GLOWTRAIL (qf ext? nehahra?) +$frame + #frame grabbing +$skin [interval=0.1] #skin grabbing +$framegroupstart #auto-animated frames + $frame [interval] + $framegroupend +$skingroupstart #auto-animated skins + $skin + $skingroupend From 1277c17cd94344f89b08224e6abb1833cdec4f31 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 25 Sep 2011 20:50:32 +0900 Subject: [PATCH 214/334] Give the 24-8 bit converter a massive speedup. The biggest part of the speedup is reading from blender's image only once (it seems that every read does so from GL rather than memory: ouch). Also, cache the results for each color. --- tools/io_mesh_qfmdl/export_mdl.py | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/tools/io_mesh_qfmdl/export_mdl.py b/tools/io_mesh_qfmdl/export_mdl.py index b8b2759cf..1938aea25 100644 --- a/tools/io_mesh_qfmdl/export_mdl.py +++ b/tools/io_mesh_qfmdl/export_mdl.py @@ -60,24 +60,28 @@ def make_skin(mdl, mesh): skin = MDL.Skin() skin.type = 0 skin.pixels = bytearray(mdl.skinwidth * mdl.skinheight) # preallocate + cache = {} + pixels = image.pixels[:] for y in range(mdl.skinheight): for x in range(mdl.skinwidth): outind = y * mdl.skinwidth + x # quake textures are top to bottom, but blender images # are bottom to top inind = ((mdl.skinheight - 1 - y) * mdl.skinwidth + x) * 4 - rgb = image.pixels[inind : inind + 3] # ignore alpha + rgb = pixels[inind : inind + 3] # ignore alpha rgb = tuple(map(lambda x: int(x * 255 + 0.5), rgb)) - best = (3*256*256, -1) - for i, p in enumerate(palette): - if i > 255: # should never happen - break - r = 0 - for x in map (lambda a, b: (a - b) ** 2, rgb, p): - r += x - if r < best[0]: - best = (r, i) - skin.pixels[outind] = best[1] + if rgb not in cache: + best = (3*256*256, -1) + for i, p in enumerate(palette): + if i > 255: # should never happen + break + r = 0 + for x in map (lambda a, b: (a - b) ** 2, rgb, p): + r += x + if r < best[0]: + best = (r, i) + cache[rgb] = best[1] + skin.pixels[outind] = cache[rgb] mdl.skins.append(skin) def build_tris(mesh): From 521f482806c2d0d3b019535fba2a0733b9e6c468 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 25 Sep 2011 20:52:28 +0900 Subject: [PATCH 215/334] Fix an off-by-one error that caused uvs to wrap. --- tools/io_mesh_qfmdl/export_mdl.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/io_mesh_qfmdl/export_mdl.py b/tools/io_mesh_qfmdl/export_mdl.py index 1938aea25..deda8707a 100644 --- a/tools/io_mesh_qfmdl/export_mdl.py +++ b/tools/io_mesh_qfmdl/export_mdl.py @@ -121,8 +121,8 @@ def convert_stverts(mdl, stverts): s, t = st # quake textures are top to bottom, but blender images # are bottom to top - s = int (s * mdl.skinwidth + 0.5) - t = int ((1 - t) * mdl.skinheight + 0.5) + s = int (s * (mdl.skinwidth - 1) + 0.5) + t = int ((1 - t) * (mdl.skinheight - 1) + 0.5) # ensure st is within the skin s = ((s % mdl.skinwidth) + mdl.skinwidth) % mdl.skinwidth t = ((t % mdl.skinheight) + mdl.skinheight) % mdl.skinheight From 683adf1850c1859f544ee0c2e782973c9190ff06 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 26 Sep 2011 10:50:45 +0900 Subject: [PATCH 216/334] Print the name and texture number for model skins. Use SYS_GLT (1024) for gl texture debugging. --- include/QF/sys.h | 1 + libs/models/alias/gl_model_alias.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/include/QF/sys.h b/include/QF/sys.h index e4663c9cb..295291c66 100644 --- a/include/QF/sys.h +++ b/include/QF/sys.h @@ -87,6 +87,7 @@ void Sys_MaskPrintf (int mask, const char *fmt, ...) __attribute__((format(print #define SYS_RUA_OBJ (1|128) #define SYS_RUA_MSG (1|256) #define SYS_SND (1|512) +#define SYS_GLT (1|1024) int Sys_CheckInput (int idle, int net_socket); const char *Sys_ConsoleInput (void); diff --git a/libs/models/alias/gl_model_alias.c b/libs/models/alias/gl_model_alias.c index 482daee97..4fb8b37a0 100644 --- a/libs/models/alias/gl_model_alias.c +++ b/libs/models/alias/gl_model_alias.c @@ -102,7 +102,7 @@ Mod_FloodFillSkin (byte * skin, int skinwidth, int skinheight) } // can't fill to filled color or transparent color (used as visited marker) if ((fillcolor == filledcolor) || (fillcolor == 255)) { - Sys_MaskPrintf (SYS_DEV, "not filling skin from %d to %d\n", + Sys_MaskPrintf (SYS_GLT, "not filling skin from %d to %d\n", fillcolor, filledcolor); return; } @@ -160,6 +160,7 @@ Mod_LoadSkin (byte * skin, int skinsize, int snum, int gnum, qboolean group, } fb_texnum = Mod_Fullbright (pskin, pheader->mdl.skinwidth, pheader->mdl.skinheight, name); + Sys_MaskPrintf (SYS_GLT, "%s %d\n", name, fb_texnum); } if (group) { snprintf (name, sizeof (name), "%s_%i_%i", modname, snum, @@ -169,6 +170,7 @@ Mod_LoadSkin (byte * skin, int skinsize, int snum, int gnum, qboolean group, } texnum = GL_LoadTexture (name, pheader->mdl.skinwidth, pheader->mdl.skinheight, pskin, true, false, 1); + Sys_MaskPrintf (SYS_GLT, "%s %d\n", name, texnum); skindesc->texnum = texnum; skindesc->fb_texnum = fb_texnum; loadmodel->hasfullbrights = fb_texnum; From baf9b7c1817a825a7583e64fbf7529ad9981cfeb Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 26 Sep 2011 18:52:59 +0900 Subject: [PATCH 217/334] Make the test nodes a little easier to read. --- libs/models/test/testclip.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index ab644ae0b..3d4b29574 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -14,8 +14,8 @@ #endif mclipnode_t clipnodes0[] = { - { 0, { 1, -1}}, - { 1, {-1, -2}}, + { 0, { 1, CONTENTS_EMPTY}}, + { 1, {CONTENTS_EMPTY, CONTENTS_SOLID}}, }; mplane_t planes0[] = { @@ -33,9 +33,9 @@ hull_t hull0 = { }; mclipnode_t clipnodes1[] = { - { 0, { 1, -2}}, - { 1, { 2, -2}}, - { 2, {-2, -1}}, + { 0, { 1, CONTENTS_SOLID}}, + { 1, { 2, CONTENTS_SOLID}}, + { 2, {CONTENTS_SOLID, CONTENTS_EMPTY}}, }; mplane_t planes1[] = { @@ -54,9 +54,9 @@ hull_t hull1 = { }; mclipnode_t clipnodes2[] = { - { 0, { 2, 1}}, - { 1, {-2, -2}}, - { 2, {-2, -1}}, + { 0, { 2, 1}}, + { 1, {CONTENTS_SOLID, CONTENTS_SOLID}}, + { 2, {CONTENTS_SOLID, CONTENTS_EMPTY}}, }; mplane_t planes2[] = { From ae0dc6f06b87d0b1cff120bcf2ada3730c0dbffb Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 26 Sep 2011 19:19:11 +0900 Subject: [PATCH 218/334] Disable the "shouldn't happen" code. It causes the tests to fail, and doesn't affect the problem I'm currently facing. --- libs/models/test/trace-id.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/models/test/trace-id.c b/libs/models/test/trace-id.c index 2e9898423..32d3d2d08 100644 --- a/libs/models/test/trace-id.c +++ b/libs/models/test/trace-id.c @@ -123,7 +123,7 @@ qboolean SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, con VectorSubtract (vec3_origin, plane->normal, trace->plane.normal); trace->plane.dist = -plane->dist; } - +#if 0 while (SV_HullPointContents (hull, hull->firstclipnode, mid) == CONTENTS_SOLID) { // shouldn't really happen, but does occasionally @@ -139,7 +139,7 @@ qboolean SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, con for (i=0 ; i<3 ; i++) mid[i] = p1[i] + frac*(p2[i] - p1[i]); } - +#endif trace->fraction = midf; VectorCopy (mid, trace->endpos); From 800e8cb3dae0795455d18fd4d703cb428d9c8988 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 26 Sep 2011 19:20:02 +0900 Subject: [PATCH 219/334] Make the id trace code more readily usable in the engine. --- libs/models/test/trace-id.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/libs/models/test/trace-id.c b/libs/models/test/trace-id.c index 32d3d2d08..41b482d70 100644 --- a/libs/models/test/trace-id.c +++ b/libs/models/test/trace-id.c @@ -1,4 +1,8 @@ -int SV_HullPointContents (hull_t *hull, int num, const vec3_t p) +#include "QF/sys.h" +#include "world.h" + +static int +HullPointContents (hull_t *hull, int num, const vec3_t p) { float d; mclipnode_t *node; @@ -7,7 +11,7 @@ int SV_HullPointContents (hull_t *hull, int num, const vec3_t p) while (num >= 0) { if (num < hull->firstclipnode || num > hull->lastclipnode) - Sys_Error ("SV_HullPointContents: bad node number"); + Sys_Error ("HullPointContents: bad node number"); node = hull->clipnodes + num; plane = hull->planes + node->planenum; @@ -30,7 +34,8 @@ int SV_HullPointContents (hull_t *hull, int num, const vec3_t p) #define DIST_EPSILON (0.03125) #endif -qboolean SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, const vec3_t p1, const vec3_t p2, trace_t *trace) +static qboolean +SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, const vec3_t p1, const vec3_t p2, trace_t *trace) { mclipnode_t *node; mplane_t *plane; @@ -102,7 +107,7 @@ qboolean SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, con if (!SV_RecursiveHullCheck (hull, node->children[side], p1f, midf, p1, mid, trace) ) return false; - if (SV_HullPointContents (hull, node->children[side^1], mid) + if (HullPointContents (hull, node->children[side^1], mid) != CONTENTS_SOLID) // go past the node return SV_RecursiveHullCheck (hull, node->children[side^1], midf, p2f, mid, p2, trace); @@ -124,7 +129,7 @@ qboolean SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, con trace->plane.dist = -plane->dist; } #if 0 - while (SV_HullPointContents (hull, hull->firstclipnode, mid) + while (HullPointContents (hull, hull->firstclipnode, mid) == CONTENTS_SOLID) { // shouldn't really happen, but does occasionally frac -= 0.1; From aa6b7ef7e8030757b9495c950ccbd714ebd9685d Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 26 Sep 2011 21:02:54 +0900 Subject: [PATCH 220/334] Add some water based tests. Unfortunatly, they haven't uncovered the bug. --- libs/models/test/testclip.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index 3d4b29574..27bd1839a 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -74,6 +74,27 @@ hull_t hull2 = { {0, 0, 0}, }; +mclipnode_t clipnodes3[] = { + { 0, { 2, 1}}, + { 1, {CONTENTS_SOLID, CONTENTS_EMPTY}}, + { 2, {CONTENTS_SOLID, CONTENTS_WATER}}, +}; + +mplane_t planes3[] = { + {{1, 0, 0}, 32, 0, 0}, + {{1, 0, 0}, -32, 0, 0}, + {{1, 0, 0}, 48, 0, 0}, +}; + +hull_t hull3 = { + clipnodes3, + planes3, + 0, + 2, + {0, 0, 0}, + {0, 0, 0}, +}; + typedef struct { vec3_t extents; } box_t; @@ -106,6 +127,11 @@ test_t tests[] = { {0, &point, &hull2, { 0, 0, 0}, { 40, 0, 0}, { 1, 0, 1, 1, 0}}, {0, &point, &hull2, { 40, 0, 0}, {-88, 0, 0}, {0.0625, 0, 0, 1, 0}}, {0, &point, &hull2, { 0, 0, 0}, { 64, 0, 0}, { 0.75, 0, 1, 1, 0}}, + + {0, &point, &hull3, {-64, 0, 0}, { 64, 0, 0}, { 0.25, 0, 0, 1, 0}}, + {0, &point, &hull3, { 0, 0, 0}, { 40, 0, 0}, { 1, 0, 1, 0, 1}}, + {0, &point, &hull3, { 40, 0, 0}, {-88, 0, 0}, {0.0625, 0, 0, 0, 1}}, + {0, &point, &hull3, { 0, 0, 0}, { 64, 0, 0}, { 0.75, 0, 1, 0, 1}}, }; #define num_tests (sizeof (tests) / sizeof (tests[0])) From a7482570b6d44b67266b58893f63b68790396ff5 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 27 Sep 2011 12:30:21 +0900 Subject: [PATCH 221/334] Document the geometry in the tests. --- libs/models/test/testclip.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index 27bd1839a..b42c971cd 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -13,6 +13,13 @@ # include "../trace.c" #endif + +// 0,0 +// |\ . +// |s\ . +// |ss\ . +// 0 1 + mclipnode_t clipnodes0[] = { { 0, { 1, CONTENTS_EMPTY}}, { 1, {CONTENTS_EMPTY, CONTENTS_SOLID}}, @@ -32,6 +39,11 @@ hull_t hull0 = { {0, 0, 0}, }; +// -32 32 48 +// sss|sss| |sss +// sss|sss| |sss +// 0 1 2 + mclipnode_t clipnodes1[] = { { 0, { 1, CONTENTS_SOLID}}, { 1, { 2, CONTENTS_SOLID}}, @@ -53,6 +65,11 @@ hull_t hull1 = { {0, 0, 0}, }; +// -32 32 48 +// sss|sss| |sss +// sss|sss| |sss +// 1 0 2 + mclipnode_t clipnodes2[] = { { 0, { 2, 1}}, { 1, {CONTENTS_SOLID, CONTENTS_SOLID}}, @@ -74,6 +91,11 @@ hull_t hull2 = { {0, 0, 0}, }; +// -32 32 48 +// sss| |www|sss +// sss| |www|sss +// 1 0 2 + mclipnode_t clipnodes3[] = { { 0, { 2, 1}}, { 1, {CONTENTS_SOLID, CONTENTS_EMPTY}}, From 9daa0b7bde0d5b076b00f9709c28d8a2dcd48dcb Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 27 Sep 2011 12:33:50 +0900 Subject: [PATCH 222/334] Rename the empty and solid flags, and use them correctly. seen_empty and seen_solid much better reflect their meanings, and also use them correctly (eg, visiting an empty node does not clear seen_solid). Hipnotic's bobbing water is still broken, though. --- libs/models/trace.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/libs/models/trace.c b/libs/models/trace.c index fbff60d7c..c78c566c5 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -95,7 +95,7 @@ MOD_TraceLine (hull_t *hull, int num, vec_t start_dist, end_dist, frac; vec3_t start, end, dist; int side; - qboolean empty, solid; + qboolean seen_empty, seen_solid; tracestack_t *tstack; tracestack_t tracestack[256]; mclipnode_t *node; @@ -105,8 +105,8 @@ MOD_TraceLine (hull_t *hull, int num, VectorCopy (end_point, end); tstack = tracestack; - empty = 0; - solid = 0; + seen_empty = 0; + seen_solid = 0; split_plane = 0; trace->allsolid = false; @@ -118,23 +118,22 @@ MOD_TraceLine (hull_t *hull, int num, while (1) { while (num < 0) { if (num == CONTENTS_SOLID) { - if (!empty && !solid) { + if (!seen_empty && !seen_solid) { // this is the first leaf visited, thus the start leaf - trace->startsolid = solid = true; - } else if (solid) { + trace->startsolid = seen_solid = true; + } else if (!seen_empty && seen_solid) { // if crossing from one solid leaf to another, treat the // whole trace as solid (this is what id does) trace->allsolid = true; return; - } else if (empty) { + } else { // crossing from an empty leaf to a solid leaf: the trace // has collided. calc_impact (trace, start_point, end_point, split_plane); return; } } else { - empty = true; - solid = false; + seen_empty = true; if (num == CONTENTS_EMPTY) trace->inopen = true; else From 32ff639bf3a5a861964d6b27277c638b909aa279 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 27 Sep 2011 13:00:19 +0900 Subject: [PATCH 223/334] Add an old qf version of trace.c This version is broken (it's the one "fixed" by commit 981622f9), but it does behave correctly for hipnotic's bobbing water. The question is, why? --- libs/models/test/trace-qf-bad.c | 191 ++++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 libs/models/test/trace-qf-bad.c diff --git a/libs/models/test/trace-qf-bad.c b/libs/models/test/trace-qf-bad.c new file mode 100644 index 000000000..b60b3456a --- /dev/null +++ b/libs/models/test/trace-qf-bad.c @@ -0,0 +1,191 @@ +/* + trace.c + + BSP line tracing + + Copyright (C) 2004 Bill Currie + + Author: Bill Currie + Date: 2004/9/25 + + 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: + + Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA + +*/ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +static __attribute__ ((used)) const char rcsid[] = + "$Id$"; + +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif + +#include "QF/model.h" +#include "QF/sys.h" + +#include "compat.h" +#include "world.h" + +/* LINE TESTING IN HULLS */ + +// 1/32 epsilon to keep floating point happy +#ifndef DIST_EPSILON +#define DIST_EPSILON (0.03125) +#endif + +typedef struct { + vec3_t end; + int side; + int num; + mplane_t *plane; +} tracestack_t; + +static inline void +calc_impact (trace_t *trace, const vec3_t start, const vec3_t end, + mplane_t *plane) +{ + vec_t t1, t2, frac; + vec3_t dist; + + t1 = PlaneDiff (start, plane); + t2 = PlaneDiff (end, plane); + + if (t1 < 0) { + frac = (t1 + DIST_EPSILON) / (t1 - t2); + // invert plane paramterers + VectorNegate (plane->normal, trace->plane.normal); + trace->plane.dist = -plane->dist; + } else { + frac = (t1 - DIST_EPSILON) / (t1 - t2); + VectorCopy (plane->normal, trace->plane.normal); + trace->plane.dist = plane->dist; + } + frac = bound (0, frac, 1); + trace->fraction = frac; + VectorSubtract (end, start, dist); + VectorMultAdd (start, frac, dist, trace->endpos); +} + +VISIBLE void +MOD_TraceLine (hull_t *hull, int num, + const vec3_t start_point, const vec3_t end_point, + trace_t *trace) +{ + vec_t start_dist, end_dist, frac; + vec3_t start, end, dist; + int side, empty, solid; + tracestack_t *tstack; + tracestack_t tracestack[256]; + mclipnode_t *node; + mplane_t *plane, *split_plane; + + VectorCopy (start_point, start); + VectorCopy (end_point, end); + + tstack = tracestack; + empty = 0; + solid = 0; + split_plane = 0; + + while (1) { + while (num < 0) { + if (!solid && num != CONTENTS_SOLID) { + empty = 1; + if (num == CONTENTS_EMPTY) + trace->inopen = true; + else + trace->inwater = true; + } else if (!empty && num == CONTENTS_SOLID) { + solid = 1; + } else if (solid && num != CONTENTS_SOLID) { + //FIXME not sure what I want + //made it out of the solid and into open space, continue + //on as if we were always in empty space + empty = 1; + solid = 0; + trace->startsolid = 1; + if (num == CONTENTS_EMPTY) + trace->inopen = true; + else + trace->inwater = true; + } else if (empty/* || solid*/) {//FIXME not sure what I want + // DONE! + trace->allsolid = solid & (num == CONTENTS_SOLID); + trace->startsolid = solid; + calc_impact (trace, start_point, end_point, split_plane); + return; + } + + // pop up the stack for a back side + if (tstack-- == tracestack) { + // we've finished. + trace->allsolid = solid & (num == CONTENTS_SOLID); + trace->startsolid = solid; + return; + } + + // set the hit point for this plane + VectorCopy (end, start); + + // go down the back side + VectorCopy (tstack->end, end); + side = tstack->side; + split_plane = tstack->plane; + + num = hull->clipnodes[tstack->num].children[side ^ 1]; + } + + node = hull->clipnodes + num; + plane = hull->planes + node->planenum; + + start_dist = PlaneDiff (start, plane); + end_dist = PlaneDiff (end, plane); + + if (start_dist >= 0 && end_dist >= 0) { + // entirely in front of the plane + num = node->children[0]; + continue; + } + if (start_dist < 0 && end_dist < 0) { + // entirely behind the plane + num = node->children[1]; + continue; + } + + side = start_dist < 0; + frac = start_dist / (start_dist - end_dist); + frac = bound (0, frac, 1); + + tstack->num = num; + tstack->side = side; + tstack->plane = plane; + VectorCopy (end, tstack->end); + tstack++; + + VectorSubtract (end, start, dist); + VectorMultAdd (start, frac, dist, end); + + num = node->children[side]; + } +} From e23ee07b6f11e835d3988399ac0f1aa62ab94ae1 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 27 Sep 2011 15:38:28 +0900 Subject: [PATCH 224/334] Ensure id's trace is properly initialized. --- libs/models/test/trace-id.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libs/models/test/trace-id.c b/libs/models/test/trace-id.c index 41b482d70..cedc4c7ed 100644 --- a/libs/models/test/trace-id.c +++ b/libs/models/test/trace-id.c @@ -156,5 +156,7 @@ MOD_TraceLine (hull_t *hull, int num, const vec3_t start_point, const vec3_t end_point, trace_t *trace) { + trace->fraction = 1; + trace->allsolid = true; SV_RecursiveHullCheck (hull, num, 0, 1, start_point, end_point, trace); } From 3e74aa530392808290ba10bb707e531fccc3b38f Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 27 Sep 2011 17:09:04 +0900 Subject: [PATCH 225/334] Add trace-qf-bad.c to Makefile.am and testclip.c. --- libs/models/test/Makefile.am | 2 +- libs/models/test/testclip.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/libs/models/test/Makefile.am b/libs/models/test/Makefile.am index 31670db4e..66525bb42 100644 --- a/libs/models/test/Makefile.am +++ b/libs/models/test/Makefile.am @@ -3,7 +3,7 @@ AUTOMAKE_OPTIONS= foreign INCLUDES= -I$(srcdir) -I$(top_srcdir)/include check_PROGRAMS=testclip -EXTRA_DIST= trace-id.c +EXTRA_DIST= trace-id.c trace-qf-bad.c testclip_SOURCES=testclip.c testclip_LDADD= $(top_builddir)/libs/models/libQFmodels.la $(top_builddir)/libs/util/libQFutil.la diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index b42c971cd..d14351a6f 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -9,6 +9,8 @@ #ifdef TEST_ID # include "trace-id.c" +#elif defined(TEST_QF_BAD) +# include "trace-qf-bad.c" #else # include "../trace.c" #endif From 9c6693d567f88c1b282979b9189decf2b25d007c Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 27 Sep 2011 17:11:57 +0900 Subject: [PATCH 226/334] Correct hull3 and its tests. I'd gotten the solid/empty parts backwards. --- libs/models/test/testclip.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index d14351a6f..f56a0176e 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -100,7 +100,7 @@ hull_t hull2 = { mclipnode_t clipnodes3[] = { { 0, { 2, 1}}, - { 1, {CONTENTS_SOLID, CONTENTS_EMPTY}}, + { 1, {CONTENTS_EMPTY, CONTENTS_SOLID}}, { 2, {CONTENTS_SOLID, CONTENTS_WATER}}, }; @@ -152,10 +152,10 @@ test_t tests[] = { {0, &point, &hull2, { 40, 0, 0}, {-88, 0, 0}, {0.0625, 0, 0, 1, 0}}, {0, &point, &hull2, { 0, 0, 0}, { 64, 0, 0}, { 0.75, 0, 1, 1, 0}}, - {0, &point, &hull3, {-64, 0, 0}, { 64, 0, 0}, { 0.25, 0, 0, 1, 0}}, - {0, &point, &hull3, { 0, 0, 0}, { 40, 0, 0}, { 1, 0, 1, 0, 1}}, - {0, &point, &hull3, { 40, 0, 0}, {-88, 0, 0}, {0.0625, 0, 0, 0, 1}}, - {0, &point, &hull3, { 0, 0, 0}, { 64, 0, 0}, { 0.75, 0, 1, 0, 1}}, + {0, &point, &hull3, {-64, 0, 0}, { 64, 0, 0}, { 0.875, 0, 1, 1, 1}}, + {0, &point, &hull3, { 0, 0, 0}, { 40, 0, 0}, { 1, 0, 0, 1, 1}}, + {0, &point, &hull3, { 40, 0, 0}, {-88, 0, 0}, {0.5625, 0, 0, 1, 1}}, + {0, &point, &hull3, { 0, 0, 0}, { 64, 0, 0}, { 0.75, 0, 0, 1, 1}}, }; #define num_tests (sizeof (tests) / sizeof (tests[0])) From a356ce6572953270245773556015d346d56ed8cf Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 27 Sep 2011 17:14:42 +0900 Subject: [PATCH 227/334] Assume the trace will be allsolid. Rather than setting allsolid when the trace fails to leave solid space, clear it when the trace enters non-solid space. This is necessary because the trace might visit only one node and thus the failure to leave solid space will not be detected. This fixes the problem with hipnotic's bobbing water. --- libs/models/test/testclip.c | 5 +++++ libs/models/trace.c | 10 ++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index f56a0176e..5992d3563 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -146,6 +146,8 @@ test_t tests[] = { {0, &point, &hull1, { 0, 0, 0}, { 40, 0, 0}, { 1, 0, 1, 1, 0}}, {0, &point, &hull1, { 40, 0, 0}, {-88, 0, 0}, {0.0625, 0, 0, 1, 0}}, {0, &point, &hull1, { 0, 0, 0}, { 64, 0, 0}, { 0.75, 0, 1, 1, 0}}, + {0, &point, &hull1, { 0, 0, 0}, { 0, 8, 0}, { 1, 1, 1, 0, 0}}, + {0, &point, &hull1, { 40, 0, 0}, { 40, 8, 0}, { 1, 0, 0, 1, 0}}, {0, &point, &hull2, {-64, 0, 0}, { 64, 0, 0}, { 1, 1, 1, 0, 0}}, {0, &point, &hull2, { 0, 0, 0}, { 40, 0, 0}, { 1, 0, 1, 1, 0}}, @@ -156,6 +158,9 @@ test_t tests[] = { {0, &point, &hull3, { 0, 0, 0}, { 40, 0, 0}, { 1, 0, 0, 1, 1}}, {0, &point, &hull3, { 40, 0, 0}, {-88, 0, 0}, {0.5625, 0, 0, 1, 1}}, {0, &point, &hull3, { 0, 0, 0}, { 64, 0, 0}, { 0.75, 0, 0, 1, 1}}, + {0, &point, &hull3, { 0, 0, 0}, { 0, 8, 0}, { 1, 0, 0, 1, 0}}, + {0, &point, &hull3, { 40, 0, 0}, { 40, 8, 0}, { 1, 0, 0, 0, 1}}, + {0, &point, &hull3, { 0, 0, 0}, { 40, 0, 0}, { 1, 0, 0, 1, 1}}, }; #define num_tests (sizeof (tests) / sizeof (tests[0])) diff --git a/libs/models/trace.c b/libs/models/trace.c index c78c566c5..1cb02d00a 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -109,7 +109,7 @@ MOD_TraceLine (hull_t *hull, int num, seen_solid = 0; split_plane = 0; - trace->allsolid = false; + trace->allsolid = true; trace->startsolid = false; trace->inopen = false; trace->inwater = false; @@ -122,9 +122,10 @@ MOD_TraceLine (hull_t *hull, int num, // this is the first leaf visited, thus the start leaf trace->startsolid = seen_solid = true; } else if (!seen_empty && seen_solid) { - // if crossing from one solid leaf to another, treat the - // whole trace as solid (this is what id does) - trace->allsolid = true; + // If crossing from one solid leaf to another, treat the + // whole trace as solid (this is what id does). + // However, since allsolid is initialized to true, no need + // to do anything. return; } else { // crossing from an empty leaf to a solid leaf: the trace @@ -134,6 +135,7 @@ MOD_TraceLine (hull_t *hull, int num, } } else { seen_empty = true; + trace->allsolid = false; if (num == CONTENTS_EMPTY) trace->inopen = true; else From 3b8ab404a06533c170401afd0eece397b0222fbd Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 28 Sep 2011 07:41:20 +0900 Subject: [PATCH 228/334] Add the ability to save the extra model parameters. The params are eye position, flags and synctype. Provision is made for reading them from a text block on export, but nothing is done other than retrieving the text block. --- tools/io_mesh_qfmdl/export_mdl.py | 4 ++++ tools/io_mesh_qfmdl/import_mdl.py | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/tools/io_mesh_qfmdl/export_mdl.py b/tools/io_mesh_qfmdl/export_mdl.py index deda8707a..87f526deb 100644 --- a/tools/io_mesh_qfmdl/export_mdl.py +++ b/tools/io_mesh_qfmdl/export_mdl.py @@ -168,6 +168,10 @@ def export_mdl(operator, context, filepath): "Mesh has faces with more than 3 vertices.") return {'CANCELLED'} mdl = MDL(obj.name) + #FIXME this should be configurable + #FIXME use it + if mdl.name in bpy.data.texts: + mdl.script = bpy.data.texts[mdl.name].as_string() make_skin(mdl, mesh) mdl.tris, mdl.stverts, vertmap = build_tris(mesh) convert_stverts (mdl, mdl.stverts) diff --git a/tools/io_mesh_qfmdl/import_mdl.py b/tools/io_mesh_qfmdl/import_mdl.py index 48c2b6690..53d4379c2 100644 --- a/tools/io_mesh_qfmdl/import_mdl.py +++ b/tools/io_mesh_qfmdl/import_mdl.py @@ -231,6 +231,15 @@ def merge_frames(mdl): mdl.frames[i:j] = [f] i += 1 +def write_text(mdl): + string = "$eyeposition %g %g %g\n" % mdl.eyeposition + string += "$flags %d\n" % mdl.flags + if mdl.synctype: + string += "$sync\n" + txt = bpy.data.texts.new(mdl.name) + txt.from_string(string) + return txt.name + def import_mdl(operator, context, filepath): bpy.context.user_preferences.edit.use_global_undo = False @@ -260,6 +269,9 @@ def import_mdl(operator, context, filepath): merge_frames(mdl) build_actions(mdl) + operator.report({'INFO'}, + "Extra settings saved in the %s text block." % write_text(mdl)) + mdl.mesh.update() bpy.context.user_preferences.edit.use_global_undo = True From 940476dce1440b622e203934c58f2ba299c5fc7a Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 12 Jun 2011 17:03:51 +0900 Subject: [PATCH 229/334] Do some renaming to make things a little clearer. --- libs/models/test/testclip.c | 92 ++++++++++++++++++++++--------------- 1 file changed, 54 insertions(+), 38 deletions(-) diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index 5992d3563..a29c57888 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -15,26 +15,25 @@ # include "../trace.c" #endif - // 0,0 // |\ . // |s\ . // |ss\ . // 0 1 -mclipnode_t clipnodes0[] = { +mclipnode_t clipnodes_simple_wedge[] = { { 0, { 1, CONTENTS_EMPTY}}, { 1, {CONTENTS_EMPTY, CONTENTS_SOLID}}, }; -mplane_t planes0[] = { +mplane_t planes_simple_wedge[] = { {{1, 0, 0}, 0, 0, 0}, // 0 {{0.8, 0, 0.6}, 0, 4, 0}, // 1 }; -hull_t hull0 = { - clipnodes0, - planes0, +hull_t hull_simple_wedge = { + clipnodes_simple_wedge, + planes_simple_wedge, 0, 1, {0, 0, 0}, @@ -46,21 +45,21 @@ hull_t hull0 = { // sss|sss| |sss // 0 1 2 -mclipnode_t clipnodes1[] = { +mclipnode_t clipnodes_tpp1[] = { { 0, { 1, CONTENTS_SOLID}}, { 1, { 2, CONTENTS_SOLID}}, { 2, {CONTENTS_SOLID, CONTENTS_EMPTY}}, }; -mplane_t planes1[] = { +mplane_t planes_tpp1[] = { {{1, 0, 0}, -32, 0, 0}, {{1, 0, 0}, 32, 0, 0}, {{1, 0, 0}, 48, 0, 0}, }; -hull_t hull1 = { - clipnodes1, - planes1, +hull_t hull_tpp1 = { + clipnodes_tpp1, + planes_tpp1, 0, 2, {0, 0, 0}, @@ -72,21 +71,21 @@ hull_t hull1 = { // sss|sss| |sss // 1 0 2 -mclipnode_t clipnodes2[] = { +mclipnode_t clipnodes_tpp2[] = { { 0, { 2, 1}}, { 1, {CONTENTS_SOLID, CONTENTS_SOLID}}, { 2, {CONTENTS_SOLID, CONTENTS_EMPTY}}, }; -mplane_t planes2[] = { +mplane_t planes_tpp2[] = { {{1, 0, 0}, 32, 0, 0}, {{1, 0, 0}, -32, 0, 0}, {{1, 0, 0}, 48, 0, 0}, }; -hull_t hull2 = { - clipnodes2, - planes2, +hull_t hull_tpp2 = { + clipnodes_tpp2, + planes_tpp2, 0, 2, {0, 0, 0}, @@ -98,21 +97,21 @@ hull_t hull2 = { // sss| |www|sss // 1 0 2 -mclipnode_t clipnodes3[] = { +mclipnode_t clipnodes_tppw[] = { { 0, { 2, 1}}, { 1, {CONTENTS_EMPTY, CONTENTS_SOLID}}, { 2, {CONTENTS_SOLID, CONTENTS_WATER}}, }; -mplane_t planes3[] = { +mplane_t planes_tppw[] = { {{1, 0, 0}, 32, 0, 0}, {{1, 0, 0}, -32, 0, 0}, {{1, 0, 0}, 48, 0, 0}, }; -hull_t hull3 = { - clipnodes3, - planes3, +hull_t hull_tppw = { + clipnodes_tppw, + planes_tppw, 0, 2, {0, 0, 0}, @@ -142,25 +141,42 @@ box_t point = { {0, 0, 0} }; box_t player = { {16, 16, 28} }; test_t tests[] = { - {0, &point, &hull1, {-64, 0, 0}, { 64, 0, 0}, { 1, 1, 1, 0, 0}}, - {0, &point, &hull1, { 0, 0, 0}, { 40, 0, 0}, { 1, 0, 1, 1, 0}}, - {0, &point, &hull1, { 40, 0, 0}, {-88, 0, 0}, {0.0625, 0, 0, 1, 0}}, - {0, &point, &hull1, { 0, 0, 0}, { 64, 0, 0}, { 0.75, 0, 1, 1, 0}}, - {0, &point, &hull1, { 0, 0, 0}, { 0, 8, 0}, { 1, 1, 1, 0, 0}}, - {0, &point, &hull1, { 40, 0, 0}, { 40, 8, 0}, { 1, 0, 0, 1, 0}}, + {"Point, Three parallel planes 1", &point, &hull_tpp1, + {-64, 0, 0}, { 64, 0, 0}, { 1, 1, 1, 0, 0}}, + {"Point, Three parallel planes 1", &point, &hull_tpp1, + { 0, 0, 0}, { 40, 0, 0}, { 1, 0, 1, 1, 0}}, + {"Point, Three parallel planes 1", &point, &hull_tpp1, + { 40, 0, 0}, {-88, 0, 0}, {0.0625, 0, 0, 1, 0}}, + {"Point, Three parallel planes 1", &point, &hull_tpp1, + { 0, 0, 0}, { 64, 0, 0}, { 0.75, 0, 1, 1, 0}}, + {"Point, Three parallel planes 1", &point, &hull_tpp1, + { 0, 0, 0}, { 0, 8, 0}, { 1, 1, 1, 0, 0}}, + {"Point, Three parallel planes 1", &point, &hull_tpp1, + { 40, 0, 0}, { 40, 8, 0}, { 1, 0, 0, 1, 0}}, - {0, &point, &hull2, {-64, 0, 0}, { 64, 0, 0}, { 1, 1, 1, 0, 0}}, - {0, &point, &hull2, { 0, 0, 0}, { 40, 0, 0}, { 1, 0, 1, 1, 0}}, - {0, &point, &hull2, { 40, 0, 0}, {-88, 0, 0}, {0.0625, 0, 0, 1, 0}}, - {0, &point, &hull2, { 0, 0, 0}, { 64, 0, 0}, { 0.75, 0, 1, 1, 0}}, + {"Point, Three parallel planes 2", &point, &hull_tpp2, + {-64, 0, 0}, { 64, 0, 0}, { 1, 1, 1, 0, 0}}, + {"Point, Three parallel planes 2", &point, &hull_tpp2, + { 0, 0, 0}, { 40, 0, 0}, { 1, 0, 1, 1, 0}}, + {"Point, Three parallel planes 2", &point, &hull_tpp2, + { 40, 0, 0}, {-88, 0, 0}, {0.0625, 0, 0, 1, 0}}, + {"Point, Three parallel planes 2", &point, &hull_tpp2, + { 0, 0, 0}, { 64, 0, 0}, { 0.75, 0, 1, 1, 0}}, - {0, &point, &hull3, {-64, 0, 0}, { 64, 0, 0}, { 0.875, 0, 1, 1, 1}}, - {0, &point, &hull3, { 0, 0, 0}, { 40, 0, 0}, { 1, 0, 0, 1, 1}}, - {0, &point, &hull3, { 40, 0, 0}, {-88, 0, 0}, {0.5625, 0, 0, 1, 1}}, - {0, &point, &hull3, { 0, 0, 0}, { 64, 0, 0}, { 0.75, 0, 0, 1, 1}}, - {0, &point, &hull3, { 0, 0, 0}, { 0, 8, 0}, { 1, 0, 0, 1, 0}}, - {0, &point, &hull3, { 40, 0, 0}, { 40, 8, 0}, { 1, 0, 0, 0, 1}}, - {0, &point, &hull3, { 0, 0, 0}, { 40, 0, 0}, { 1, 0, 0, 1, 1}}, + {"Point, Three parallel planes with water", &point, &hull_tppw, + {-64, 0, 0}, { 64, 0, 0}, { 0.875, 0, 1, 1, 1}}, + {"Point, Three parallel planes with water", &point, &hull_tppw, + { 0, 0, 0}, { 40, 0, 0}, { 1, 0, 0, 1, 1}}, + {"Point, Three parallel planes with water", &point, &hull_tppw, + { 40, 0, 0}, {-88, 0, 0}, {0.5625, 0, 0, 1, 1}}, + {"Point, Three parallel planes with water", &point, &hull_tppw, + { 0, 0, 0}, { 64, 0, 0}, { 0.75, 0, 0, 1, 1}}, + {"Point, Three parallel planes with water", &point, &hull_tppw, + { 0, 0, 0}, { 0, 8, 0}, { 1, 0, 0, 1, 0}}, + {"Point, Three parallel planes with water", &point, &hull_tppw, + { 40, 0, 0}, { 40, 8, 0}, { 1, 0, 0, 0, 1}}, + {"Point, Three parallel planes with water", &point, &hull_tppw, + { 0, 0, 0}, { 40, 0, 0}, { 1, 0, 0, 1, 1}}, }; #define num_tests (sizeof (tests) / sizeof (tests[0])) From 6b62b850a7769663be9af96c532c0f55876e500c Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 5 Oct 2011 20:43:40 +0900 Subject: [PATCH 230/334] Add an option to omit the mipmap from extracted textures. This is at the request of Spirit (quaddicted). Great idea. --- tools/wad/wad.c | 44 +++++++++++++++++++++++++++----------------- tools/wad/wad.h | 1 + 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/tools/wad/wad.c b/tools/wad/wad.c index 6ff78d8ec..1c672112b 100644 --- a/tools/wad/wad.c +++ b/tools/wad/wad.c @@ -74,6 +74,7 @@ static const struct option long_options[] = { {"pad", no_argument, 0, 'p'}, {"quiet", no_argument, 0, 'q'}, {"verbose", no_argument, 0, 'v'}, + {"nomip", no_argument, 0, 256}, {NULL, 0, NULL, 0}, }; @@ -94,6 +95,7 @@ usage (int status) printf ("Options:\n" " -f, --file ARCHIVE Use ARCHIVE for archive filename\n" " -p, --pad Pad file space to a 32-bit boundary\n" + " --nomip Do not output mipmaps with textures\n" " -q, --quiet Inhibit usual output\n" " -v, --verbose Display more output than usual\n"); exit (status); @@ -148,6 +150,9 @@ decode_args (int argc, char **argv) case 'v': // increase verbosity options.verbosity++; break; + case 256: + options.nomip = 1; + break; default: usage (1); } @@ -328,24 +333,29 @@ wad_extract (wad_t *wad, lumpinfo_t *pf) image = calloc (1, miptex->width * miptex->height * 3 / 2); memcpy (image, buffer + miptex->offsets[0], miptex->width * miptex->height); - for (u = 0; u < miptex->height * 1 / 2; u++) { - i = miptex->height + u; - memcpy (image + i * miptex->width, - buffer + miptex->offsets[1] + u * miptex->width / 2, - miptex->width / 2); - if (u >= miptex->height * 1 / 4) - continue; - memcpy (image + i * miptex->width + miptex->width / 2, - buffer + miptex->offsets[2] + u * miptex->width / 4, - miptex->width / 4); - if (u >= miptex->height * 1 / 8) - continue; - memcpy (image + i * miptex->width + miptex->width * 3 / 4, - buffer + miptex->offsets[2] + u * miptex->width / 8, - miptex->width / 8); + if (!options.nomip) { + for (u = 0; u < miptex->height * 1 / 2; u++) { + i = miptex->height + u; + memcpy (image + i * miptex->width, + buffer + miptex->offsets[1] + u * miptex->width / 2, + miptex->width / 2); + if (u >= miptex->height * 1 / 4) + continue; + memcpy (image + i * miptex->width + miptex->width / 2, + buffer + miptex->offsets[2] + u * miptex->width / 4, + miptex->width / 4); + if (u >= miptex->height * 1 / 8) + continue; + memcpy (image + i * miptex->width + miptex->width * 3 / 4, + buffer + miptex->offsets[2] + u * miptex->width / 8, + miptex->width / 8); + } + pcx = EncodePCX (image, miptex->width, miptex->height * 3 / 2, + miptex->width, default_palette, false, &len); + } else { + pcx = EncodePCX (image, miptex->width, miptex->height, + miptex->width, default_palette, false, &len); } - pcx = EncodePCX (image, miptex->width, miptex->height * 3 /2, - miptex->width, default_palette, false, &len); free (image); free (buffer); if (Qwrite (file, pcx, len) != len) { diff --git a/tools/wad/wad.h b/tools/wad/wad.h index 7b5d4c054..f82297dd2 100644 --- a/tools/wad/wad.h +++ b/tools/wad/wad.h @@ -49,6 +49,7 @@ typedef struct { int verbosity; // 0=silent qboolean compress; // for the future qboolean pad; // pad area of files to 4-byte boundary + qboolean nomip; // exclude mipmaps from output textures. char *wadfile; // wad file to read/write/test } options_t; From 2457837b37d1dbe8e1aef6b4d2b2d12fa1dc805d Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 12 Nov 2011 12:17:45 +0900 Subject: [PATCH 231/334] Make some improvements to the winding docs. --- tools/qfbsp/include/winding.h | 20 +++++++++++++++----- tools/qfbsp/source/winding.c | 2 ++ 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/tools/qfbsp/include/winding.h b/tools/qfbsp/include/winding.h index 4faae3552..3bae9415e 100644 --- a/tools/qfbsp/include/winding.h +++ b/tools/qfbsp/include/winding.h @@ -33,21 +33,27 @@ struct plane_s; typedef struct winding_s { - int numpoints; - vec3_t points[8]; // variable sized + int numpoints; ///< The number of points in the winding + vec3_t points[3]; ///< variable sized, never less than 3 } winding_t; /** Create a very large four-point winding with all point on the plane. - The winding will be a box with aligned with the axes of the plane. + The winding will be a box with aligned with the axes of the plane. The + order of yhe points is clockwise when viewed from the front side of + the plane. - \param p The plane for which to create the winding. + In terms of s and t, the axes of the plane will be such that t (up) is + the projection of either the z-axis or the x-axis (whichever is + "closer"), and s is to the right (n = s cross t). + + \param p The plane on which to create the winding. \return The new winding. \note It is the caller's responsibiltiy to free the new winding. */ winding_t *BaseWindingForPlane (const struct plane_s *p); -/** Create a new, empty winding with. +/** Create a new, empty winding with space for the specified number of points. \param points The number of points for which to leave space. \return The new winding. @@ -71,6 +77,8 @@ winding_t *CopyWinding (const winding_t *w); /** Create a new winding with the reverse points of the given winding. + This is useful when a winding for the back side of a plane is required. + \param w The winding to copy. \return The new winding. \note It is the caller's responsibiltiy to free the new winding. @@ -82,6 +90,8 @@ winding_t *CopyWindingReverse (const winding_t *w); The new winding will be the part of the input winding that is on the front side of the plane. + The direction of the winding is preserved. + \note It is the caller's responsibiltiy to free the new winding. \note The input winding will be freed. diff --git a/tools/qfbsp/source/winding.c b/tools/qfbsp/source/winding.c index 1ec35c96b..90849b168 100644 --- a/tools/qfbsp/source/winding.c +++ b/tools/qfbsp/source/winding.c @@ -153,6 +153,7 @@ ClipWinding (winding_t *in, plane_t *split, qboolean keepon) counts[0] = counts[1] = counts[2] = 0; + // +1 for duplicating the first point sides = alloca ((in->numpoints + 1) * sizeof (int)); dists = alloca ((in->numpoints + 1) * sizeof (vec_t)); @@ -170,6 +171,7 @@ ClipWinding (winding_t *in, plane_t *split, qboolean keepon) } counts[sides[i]]++; } + // duplicate the first point sides[i] = sides[0]; dists[i] = dists[0]; From 6d2b92125afcd78112448cc5174de5af3e0eb45b Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 15 Nov 2011 13:47:05 +0900 Subject: [PATCH 232/334] Make nva a little more memory efficient. --- libs/util/va.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libs/util/va.c b/libs/util/va.c index 7da7a775f..361b7a092 100644 --- a/libs/util/va.c +++ b/libs/util/va.c @@ -70,14 +70,13 @@ VISIBLE char * nva (const char *fmt, ...) { va_list args; - static dstring_t *string; + dstring_t *string; - if (!string) - string = dstring_new (); + string = dstring_new (); va_start (args, fmt); dvsprintf (string, fmt, args); va_end (args); - return strdup (string->str); + return dstring_freeze (string); } From ea02f3cd44b426c4ba88b663994a5387c366864b Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 15 Nov 2011 17:36:55 +0900 Subject: [PATCH 233/334] Fix a missed byteswap when loading qfo files. --- tools/qfcc/source/obj_file.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/qfcc/source/obj_file.c b/tools/qfcc/source/obj_file.c index 67fdfee27..cecb75458 100644 --- a/tools/qfcc/source/obj_file.c +++ b/tools/qfcc/source/obj_file.c @@ -555,6 +555,7 @@ qfo_read (QFile *file) qfo->funcs[i].code = LittleLong (qfo->funcs[i].code); qfo->funcs[i].def = LittleLong (qfo->funcs[i].def); qfo->funcs[i].locals_space = LittleLong (qfo->funcs[i].locals_space); + qfo->funcs[i].line_info = LittleLong (qfo->funcs[i].line_info); qfo->funcs[i].relocs = LittleLong (qfo->funcs[i].relocs); qfo->funcs[i].num_relocs = LittleLong (qfo->funcs[i].num_relocs); } From 268e732b90ca56c9d976cd19b2461424c7e3338b Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 28 Nov 2011 09:36:09 +0900 Subject: [PATCH 234/334] Add a Quat_t union. It isn't used yet, but it might make messing with quaternions a little easier. --- include/QF/qtypes.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/QF/qtypes.h b/include/QF/qtypes.h index a5a92cd45..ed4255634 100644 --- a/include/QF/qtypes.h +++ b/include/QF/qtypes.h @@ -72,6 +72,13 @@ typedef vec_t vec3_t[3]; ///< A 3D vector (used for Euler angles and motion vect typedef vec_t vec4_t[4]; typedef vec_t quat_t[4]; ///< A quaternion. typedef vec_t vec5_t[5]; +typedef union { + struct { + vec_t s; + vec3_t v; + } sv; + quat_t q; +} Quat_t; typedef int fixed4_t; typedef int fixed8_t; typedef int fixed16_t; From b4da9241f64f1aeba27c87b2eddfec4d559de8ac Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 2 Oct 2011 21:06:56 +0900 Subject: [PATCH 235/334] Make a fresh start on box clipping. I even have a failing test to fix :) --- libs/models/test/testclip.c | 33 +++++++++++++++++++++++++++++++++ libs/models/trace.c | 21 ++++++++++++++++++--- 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index a29c57888..d4dfd4734 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -118,6 +118,33 @@ hull_t hull_tppw = { {0, 0, 0}, }; +// 2 +// eee|eee +// 0,32+--- 1 +// eee|sss +// ---+--- 0 +// ss0,0ss +mclipnode_t clipnodes_step1[] = { + { 0, { 1, CONTENTS_SOLID}}, + { 1, {CONTENTS_EMPTY, 2}}, + { 2, {CONTENTS_SOLID, CONTENTS_EMPTY}}, +}; + +mplane_t planes_step1[] = { + {{0, 0, 1}, 0, 2, 0}, + {{0, 0, 1}, 32, 2, 0}, + {{1, 0, 0}, 0, 0, 0}, +}; + +hull_t hull_step1 = { + clipnodes_step1, + planes_step1, + 0, + 2, + {0, 0, 0}, + {0, 0, 0}, +}; + typedef struct { vec3_t extents; } box_t; @@ -138,6 +165,7 @@ typedef struct { } test_t; box_t point = { {0, 0, 0} }; +box_t box = { {8, 8, 8} }; box_t player = { {16, 16, 28} }; test_t tests[] = { @@ -177,6 +205,11 @@ test_t tests[] = { { 40, 0, 0}, { 40, 8, 0}, { 1, 0, 0, 0, 1}}, {"Point, Three parallel planes with water", &point, &hull_tppw, { 0, 0, 0}, { 40, 0, 0}, { 1, 0, 0, 1, 1}}, + + {"Point, Step 1", &point, &hull_step1, + { -16, 0, 8}, {16, 0, 24}, { 0.5, 0, 0, 1, 0}}, + {"Box, Step 1", &box, &hull_step1, + { -16, 0, 8}, {16, 0, 24}, { 0.25, 0, 0, 1, 0}}, }; #define num_tests (sizeof (tests) / sizeof (tests[0])) diff --git a/libs/models/trace.c b/libs/models/trace.c index 1cb02d00a..ded4eab41 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -61,6 +61,20 @@ typedef struct { mplane_t *plane; } tracestack_t; +static inline float +calc_offset (trace_t *trace, mplane_t *plane) +{ + if (trace->isbox) { + if (plane->type < 3) + return trace->extents[plane->type]; + else + return (fabs (trace->extents[0] * plane->normal[0]) + + fabs (trace->extents[1] * plane->normal[1]) + + fabs (trace->extents[2] * plane->normal[2])); + } + return 0; +} + static inline void calc_impact (trace_t *trace, const vec3_t start, const vec3_t end, mplane_t *plane) @@ -92,7 +106,7 @@ MOD_TraceLine (hull_t *hull, int num, const vec3_t start_point, const vec3_t end_point, trace_t *trace) { - vec_t start_dist, end_dist, frac; + vec_t start_dist, end_dist, frac, offset; vec3_t start, end, dist; int side; qboolean seen_empty, seen_solid; @@ -164,13 +178,14 @@ MOD_TraceLine (hull_t *hull, int num, start_dist = PlaneDiff (start, plane); end_dist = PlaneDiff (end, plane); + offset = calc_offset (trace, plane); - if (start_dist >= 0 && end_dist >= 0) { + if (start_dist >= offset && end_dist >= offset) { // entirely in front of the plane num = node->children[0]; continue; } - if (start_dist < 0 && end_dist < 0) { + if (start_dist < offset && end_dist < offset) { // entirely behind the plane num = node->children[1]; continue; From 03abb3b27d0778bff5159da4f8ae45702c3aac1d Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 6 Oct 2011 20:09:10 +0900 Subject: [PATCH 236/334] Add support for ellipsoids. Not that boxes work yet, but the fix is the same. --- include/world.h | 8 +++++++- libs/models/test/testclip.c | 2 +- libs/models/trace.c | 29 +++++++++++++++++++++-------- nq/source/world.c | 5 +++-- qw/source/world.c | 5 +++-- 5 files changed, 35 insertions(+), 14 deletions(-) diff --git a/include/world.h b/include/world.h index b9b274dd5..5744b8f71 100644 --- a/include/world.h +++ b/include/world.h @@ -39,13 +39,19 @@ typedef struct vec_t dist; } plane_t; +typedef enum { + tr_point, + tr_box, + tr_ellipsoid, +} trace_e; + typedef struct trace_s { qboolean allsolid; // if true, plane is not valid qboolean startsolid; // if true, the initial point was in a solid area qboolean inopen, inwater; float fraction; // time completed, 1.0 = didn't hit anything vec3_t extents; // 1/2 size of traced box - qboolean isbox; // box or point + trace_e type; // type of trace to perform vec3_t endpos; // final position plane_t plane; // surface normal at impact struct edict_s *ent; // entity the surface is on diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index d4dfd4734..ef0266073 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -228,7 +228,7 @@ do_trace (box_t *box, hull_t *hull, vec3_t start, vec3_t end) trace.inwater = false; trace.fraction = 1; VectorCopy (box->extents, trace.extents); - trace.isbox = true; + trace.type = tr_box; VectorCopy (end, trace.endpos); MOD_TraceLine (hull, 0, start, end, &trace); return trace; diff --git a/libs/models/trace.c b/libs/models/trace.c index ded4eab41..92e28755f 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -64,15 +64,28 @@ typedef struct { static inline float calc_offset (trace_t *trace, mplane_t *plane) { - if (trace->isbox) { - if (plane->type < 3) - return trace->extents[plane->type]; - else - return (fabs (trace->extents[0] * plane->normal[0]) - + fabs (trace->extents[1] * plane->normal[1]) - + fabs (trace->extents[2] * plane->normal[2])); + vec_t d = 0; + vec3_t Rn; + + switch (trace->type) { + case tr_point: + break; + case tr_box: + if (plane->type < 3) + d = trace->extents[plane->type]; + else + d = (fabs (trace->extents[0] * plane->normal[0]) + + fabs (trace->extents[1] * plane->normal[1]) + + fabs (trace->extents[2] * plane->normal[2])); + break; + case tr_ellipsoid: + VectorSet (trace->extents[0] * plane->normal[0], + trace->extents[1] * plane->normal[1], + trace->extents[2] * plane->normal[2], Rn); + d = sqrt(DotProduct (Rn, Rn)); //FIXME no sqrt + break; } - return 0; + return d; } static inline void diff --git a/nq/source/world.c b/nq/source/world.c index 2ae9aa700..7c49f979d 100644 --- a/nq/source/world.c +++ b/nq/source/world.c @@ -614,12 +614,13 @@ SV_ClipMoveToEntity (edict_t *touched, const vec3_t start, trace.fraction = 1; trace.allsolid = true; - trace.isbox = 0; + trace.type = tr_point; VectorCopy (end, trace.endpos); // get the clipping hull hull = SV_HullForEntity (touched, mins, maxs, - trace.isbox ? trace.extents : 0, offset); + trace.type != tr_point ? trace.extents : 0, + offset); VectorSubtract (start, offset, start_l); VectorSubtract (end, offset, end_l); diff --git a/qw/source/world.c b/qw/source/world.c index 2ae9aa700..7c49f979d 100644 --- a/qw/source/world.c +++ b/qw/source/world.c @@ -614,12 +614,13 @@ SV_ClipMoveToEntity (edict_t *touched, const vec3_t start, trace.fraction = 1; trace.allsolid = true; - trace.isbox = 0; + trace.type = tr_point; VectorCopy (end, trace.endpos); // get the clipping hull hull = SV_HullForEntity (touched, mins, maxs, - trace.isbox ? trace.extents : 0, offset); + trace.type != tr_point ? trace.extents : 0, + offset); VectorSubtract (start, offset, start_l); VectorSubtract (end, offset, end_l); From 9d6329803286c44d26b3a426fb45ec98ea25a489 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 12 Nov 2011 16:36:07 +0900 Subject: [PATCH 237/334] Tweak a fixme comment. The code is potentially slow, especially on big maps, but I haven't noticed any issues yet. --- libs/models/brush/model_brush.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/models/brush/model_brush.c b/libs/models/brush/model_brush.c index aba444a10..5a4439625 100644 --- a/libs/models/brush/model_brush.c +++ b/libs/models/brush/model_brush.c @@ -128,7 +128,7 @@ Mod_LeafPVS (mleaf_t *leaf, model_t *model) // BRUSHMODEL LOADING ========================================================= -//FIXME SLOW! +//FIXME SLOW! However, it doesn't seem to be a big issue. Leave alone? static void mod_unique_miptex_name (texture_t **textures, texture_t *tx, int ind) { From 9984a2e87a5d21927c5e303c93cc9c46183e4301 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 12 Nov 2011 17:21:37 +0900 Subject: [PATCH 238/334] Fix some missing usages of offset. This fixes my one failing box clip test. Now I need to find more broken cases. At least now, they should be real tests. --- libs/models/trace.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/libs/models/trace.c b/libs/models/trace.c index 92e28755f..f6ec82f05 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -92,19 +92,20 @@ static inline void calc_impact (trace_t *trace, const vec3_t start, const vec3_t end, mplane_t *plane) { - vec_t t1, t2, frac; + vec_t t1, t2, frac, offset; vec3_t dist; t1 = PlaneDiff (start, plane); t2 = PlaneDiff (end, plane); + offset = calc_offset (trace, plane); if (t1 < 0) { - frac = (t1 + DIST_EPSILON) / (t1 - t2); + frac = (t1 + offset + DIST_EPSILON) / (t1 - t2); // invert plane paramterers VectorNegate (plane->normal, trace->plane.normal); trace->plane.dist = -plane->dist; } else { - frac = (t1 - DIST_EPSILON) / (t1 - t2); + frac = (t1 - offset - DIST_EPSILON) / (t1 - t2); VectorCopy (plane->normal, trace->plane.normal); trace->plane.dist = plane->dist; } @@ -207,7 +208,10 @@ MOD_TraceLine (hull_t *hull, int num, // cross the plane side = start_dist < 0; - frac = start_dist / (start_dist - end_dist); + if (side) + frac = (start_dist + offset) / (start_dist - end_dist); + else + frac = (start_dist - offset) / (start_dist - end_dist); frac = bound (0, frac, 1); tstack->num = num; From b82d9f5894976fb77786686504aebbbae2eb265b Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 12 Nov 2011 18:12:56 +0900 Subject: [PATCH 239/334] Another test, another bug. Fix an incorrect test using offset (forgot to negate). --- libs/models/test/testclip.c | 2 ++ libs/models/trace.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index ef0266073..3351273b8 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -210,6 +210,8 @@ test_t tests[] = { { -16, 0, 8}, {16, 0, 24}, { 0.5, 0, 0, 1, 0}}, {"Box, Step 1", &box, &hull_step1, { -16, 0, 8}, {16, 0, 24}, { 0.25, 0, 0, 1, 0}}, + {"Box, Step 1", &box, &hull_step1, + { -16, 0, 8}, {16, 0, 40}, { 0.25, 0, 0, 1, 0}}, }; #define num_tests (sizeof (tests) / sizeof (tests[0])) diff --git a/libs/models/trace.c b/libs/models/trace.c index f6ec82f05..54fa77842 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -199,7 +199,7 @@ MOD_TraceLine (hull_t *hull, int num, num = node->children[0]; continue; } - if (start_dist < offset && end_dist < offset) { + if (start_dist < -offset && end_dist < -offset) { // entirely behind the plane num = node->children[1]; continue; From fa6390a46a89e45cca47857cca2d912fadea86e5 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 12 Nov 2011 18:53:05 +0900 Subject: [PATCH 240/334] Correct the sign for the shift in frac. However, this is not entirely correct as the new start point when testing the other side of the plane also needs to be calculated. --- libs/models/test/testclip.c | 5 +++++ libs/models/trace.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index 3351273b8..34cf5715e 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -212,6 +212,11 @@ test_t tests[] = { { -16, 0, 8}, {16, 0, 24}, { 0.25, 0, 0, 1, 0}}, {"Box, Step 1", &box, &hull_step1, { -16, 0, 8}, {16, 0, 40}, { 0.25, 0, 0, 1, 0}}, + {"Box, Step 1", &box, &hull_step1, + { -16, 0, 8}, {16, 0, 135}, { 0.25, 0, 0, 1, 0}}, + // 136 is a corner case caused by back/front side issues and 0 + {"Box, Step 1", &box, &hull_step1, + { -16, 0, 8}, {16, 0, 137}, { 1, 0, 0, 1, 0}}, }; #define num_tests (sizeof (tests) / sizeof (tests[0])) diff --git a/libs/models/trace.c b/libs/models/trace.c index 54fa77842..6e2dac36a 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -209,9 +209,9 @@ MOD_TraceLine (hull_t *hull, int num, side = start_dist < 0; if (side) - frac = (start_dist + offset) / (start_dist - end_dist); - else frac = (start_dist - offset) / (start_dist - end_dist); + else + frac = (start_dist + offset) / (start_dist - end_dist); frac = bound (0, frac, 1); tstack->num = num; From 8cc320b7ef09495c704525b0ee0f8bd67bde24e4 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 12 Nov 2011 20:42:44 +0900 Subject: [PATCH 241/334] Move the start point to the near side of the crossed plane. I'm not sure the end point needs to be moved at all, but I'll leave it alone for now. I have a couple of failing test cases that seem to be caused by not handling moves where the box is always cut by the plane. --- libs/models/test/testclip.c | 44 +++++++++++++++++++++++++++++++++++++ libs/models/trace.c | 17 +++++++------- 2 files changed, 53 insertions(+), 8 deletions(-) diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index 34cf5715e..ea07463cc 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -145,6 +145,37 @@ hull_t hull_step1 = { {0, 0, 0}, }; +// 2 +// eee|eee +// 0,32+--- 1 +// eee|sss +// ---+--- 0 +// ss0,0ss +mclipnode_t clipnodes_covered_step[] = { + { 0, { 1, CONTENTS_SOLID}}, + { 1, { 3, 2}}, + { 2, {CONTENTS_SOLID, CONTENTS_EMPTY}}, + { 3, {CONTENTS_EMPTY, 4}}, + { 4, {CONTENTS_SOLID, CONTENTS_EMPTY}}, +}; + +mplane_t planes_covered_step[] = { + {{0, 0, 1}, 0, 2, 0}, + {{0, 0, 1}, 32, 2, 0}, + {{1, 0, 0}, 0, 0, 0}, + {{1, 0, 0}, -20, 0, 0}, + {{0, 0, 1}, 40, 2, 0}, +}; + +hull_t hull_covered_step = { + clipnodes_covered_step, + planes_covered_step, + 0, + 4, + {0, 0, 0}, + {0, 0, 0}, +}; + typedef struct { vec3_t extents; } box_t; @@ -217,6 +248,19 @@ test_t tests[] = { // 136 is a corner case caused by back/front side issues and 0 {"Box, Step 1", &box, &hull_step1, { -16, 0, 8}, {16, 0, 137}, { 1, 0, 0, 1, 0}}, + + {"Point, Covered Step", &point, &hull_covered_step, + { -24, 0, 8}, {-24, 0, 72}, { 0.5, 0, 0, 1, 0}}, + {"Box, Covered Step", &box, &hull_covered_step, + { -32, 0, 8}, {-32, 0, 72}, { 0.375, 0, 0, 1, 0}}, + {"Box, Covered Step", &box, &hull_covered_step, + { -24, 0, 8}, {-24, 0, 72}, { 0.375, 0, 0, 1, 0}}, + {"Box, Covered Step", &box, &hull_covered_step, + { -24, 0, 8}, {8, 0, 72}, { 0.375, 0, 0, 1, 0}}, +// {"Box, Covered Step", &box, &hull_covered_step, +// { -16, 0, 8}, {0, 0, 72}, { 1, 0, 0, 1, 0}}, + {"Box, Covered Step", &box, &hull_covered_step, + { -8, 0, 40}, {8, 0, 72}, { 1, 0, 0, 1, 0}}, }; #define num_tests (sizeof (tests) / sizeof (tests[0])) diff --git a/libs/models/trace.c b/libs/models/trace.c index 6e2dac36a..6fcb20eaf 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -55,6 +55,7 @@ static __attribute__ ((used)) const char rcsid[] = #endif typedef struct { + vec3_t start; vec3_t end; int side; int num; @@ -120,7 +121,7 @@ MOD_TraceLine (hull_t *hull, int num, const vec3_t start_point, const vec3_t end_point, trace_t *trace) { - vec_t start_dist, end_dist, frac, offset; + vec_t start_dist, end_dist, frac[2], offset; vec3_t start, end, dist; int side; qboolean seen_empty, seen_solid; @@ -177,7 +178,7 @@ MOD_TraceLine (hull_t *hull, int num, } // set the hit point for this plane - VectorCopy (end, start); + VectorCopy (end, tstack->start); // go down the back side VectorCopy (tstack->end, end); @@ -208,11 +209,10 @@ MOD_TraceLine (hull_t *hull, int num, // cross the plane side = start_dist < 0; - if (side) - frac = (start_dist - offset) / (start_dist - end_dist); - else - frac = (start_dist + offset) / (start_dist - end_dist); - frac = bound (0, frac, 1); + frac[0] = (start_dist + offset) / (start_dist - end_dist); + frac[1] = (start_dist - offset) / (start_dist - end_dist); + frac[0] = bound (0, frac[0], 1); + frac[1] = bound (0, frac[1], 1); tstack->num = num; tstack->side = side; @@ -221,7 +221,8 @@ MOD_TraceLine (hull_t *hull, int num, tstack++; VectorSubtract (end, start, dist); - VectorMultAdd (start, frac, dist, end); + VectorMultAdd (start, frac[side], dist, end); + VectorMultAdd (start, frac[side ^ 1], dist, tstack->start); num = node->children[side]; } From 0cf5dec5bb6ac6f3d1760a2cb641c7ecf87bbdc8 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 12 Nov 2011 21:30:45 +0900 Subject: [PATCH 242/334] Fix the covered step tests. However, there is still a problem with moves where the box is always cut by the plane: both sides need to be tested (done), but when the first side checked allows longer motion than the second, but still collides, only the first side is checked. The shorter motion is required. --- libs/models/test/testclip.c | 71 ++++++++++++++++++++++++++++++++++--- libs/models/trace.c | 17 ++++++--- 2 files changed, 79 insertions(+), 9 deletions(-) diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index ea07463cc..3cab3011c 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -145,10 +145,66 @@ hull_t hull_step1 = { {0, 0, 0}, }; -// 2 +// 0 // eee|eee // 0,32+--- 1 // eee|sss +// ---+sss 2 +// ss0,0ss +mclipnode_t clipnodes_step2[] = { + { 0, { 1, 2}}, + { 1, {CONTENTS_EMPTY, CONTENTS_SOLID}}, + { 2, {CONTENTS_EMPTY, CONTENTS_SOLID}}, +}; + +mplane_t planes_step2[] = { + {{1, 0, 0}, 0, 0, 0}, + {{0, 0, 1}, 32, 2, 0}, + {{0, 0, 1}, 0, 2, 0}, +}; + +hull_t hull_step2 = { + clipnodes_step2, + planes_step2, + 0, + 2, + {0, 0, 0}, + {0, 0, 0}, +}; + +// 0 +// eee|eee +// 2---+0,32 +// sss|eee +// sss+--- 1 +// ss0,0ss +mclipnode_t clipnodes_step3[] = { + { 0, { 1, 2}}, + { 1, {CONTENTS_EMPTY, CONTENTS_SOLID}}, + { 2, {CONTENTS_EMPTY, CONTENTS_SOLID}}, +}; + +mplane_t planes_step3[] = { + {{1, 0, 0}, 0, 0, 0}, + {{0, 0, 1}, 0, 2, 0}, + {{0, 0, 1}, 32, 2, 0}, +}; + +hull_t hull_step3 = { + clipnodes_step3, + planes_step3, + 0, + 2, + {0, 0, 0}, + {0, 0, 0}, +}; + +// 3 2 +// s|e|eee +// 4-+e|-20,40 +// e|e|eee +// 0,32+--- 1 +// eee|sss // ---+--- 0 // ss0,0ss mclipnode_t clipnodes_covered_step[] = { @@ -256,11 +312,18 @@ test_t tests[] = { {"Box, Covered Step", &box, &hull_covered_step, { -24, 0, 8}, {-24, 0, 72}, { 0.375, 0, 0, 1, 0}}, {"Box, Covered Step", &box, &hull_covered_step, - { -24, 0, 8}, {8, 0, 72}, { 0.375, 0, 0, 1, 0}}, -// {"Box, Covered Step", &box, &hull_covered_step, -// { -16, 0, 8}, {0, 0, 72}, { 1, 0, 0, 1, 0}}, + { -25, 0, 8}, {7, 0, 72}, { 0.375, 0, 0, 1, 0}}, + {"Box, Covered Step", &box, &hull_covered_step, + { -8, 0, 40}, {-16, 0, 40}, { 0.5, 0, 0, 1, 0}}, + {"Box, Covered Step", &box, &hull_covered_step, + { -17, 0, 8}, {-1, 0, 72}, { 1, 0, 0, 1, 0}}, {"Box, Covered Step", &box, &hull_covered_step, { -8, 0, 40}, {8, 0, 72}, { 1, 0, 0, 1, 0}}, + + {"Box, Step 2", &box, &hull_step2, + { 0, 0, 64}, {0, 0, 0}, { 0.375, 0, 0, 1, 0}}, + {"Box, Step 3", &box, &hull_step3, + { 0, 0, 64}, {0, 0, 0}, { 0.375, 0, 0, 1, 0}}, }; #define num_tests (sizeof (tests) / sizeof (tests[0])) diff --git a/libs/models/trace.c b/libs/models/trace.c index 6fcb20eaf..16e7e5944 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -208,11 +208,18 @@ MOD_TraceLine (hull_t *hull, int num, // cross the plane - side = start_dist < 0; - frac[0] = (start_dist + offset) / (start_dist - end_dist); - frac[1] = (start_dist - offset) / (start_dist - end_dist); - frac[0] = bound (0, frac[0], 1); - frac[1] = bound (0, frac[1], 1); + if (start_dist < offset && end_dist < offset + && start_dist >= -offset && end_dist >= end_dist) { + side = 0; + frac[0] = 1; + frac[1] = 0; + } else { + side = start_dist < offset; + frac[0] = (start_dist + offset) / (start_dist - end_dist); + frac[1] = (start_dist - offset) / (start_dist - end_dist); + frac[0] = bound (0, frac[0], 1); + frac[1] = bound (0, frac[1], 1); + } tstack->num = num; tstack->side = side; From a943cdf2c4da37ccbbd0e7ee7669fde0fbc3e9a0 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 13 Nov 2011 08:48:44 +0900 Subject: [PATCH 243/334] Handle dual collisions. When the trace collides with something on both sides of a plane, the nearer collision is required. The code now correctly checks both sides and keeps the nearer collision. --- libs/models/trace.c | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/libs/models/trace.c b/libs/models/trace.c index 16e7e5944..7d2269d13 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -103,17 +103,23 @@ calc_impact (trace_t *trace, const vec3_t start, const vec3_t end, if (t1 < 0) { frac = (t1 + offset + DIST_EPSILON) / (t1 - t2); // invert plane paramterers - VectorNegate (plane->normal, trace->plane.normal); - trace->plane.dist = -plane->dist; } else { frac = (t1 - offset - DIST_EPSILON) / (t1 - t2); - VectorCopy (plane->normal, trace->plane.normal); - trace->plane.dist = plane->dist; } frac = bound (0, frac, 1); - trace->fraction = frac; - VectorSubtract (end, start, dist); - VectorMultAdd (start, frac, dist, trace->endpos); + if (frac < trace->fraction) { + trace->fraction = frac; + VectorSubtract (end, start, dist); + VectorMultAdd (start, frac, dist, trace->endpos); + if (t1 < 0) { + // invert plane paramterers + VectorNegate (plane->normal, trace->plane.normal); + trace->plane.dist = -plane->dist; + } else { + VectorCopy (plane->normal, trace->plane.normal); + trace->plane.dist = plane->dist; + } + } } VISIBLE void @@ -160,7 +166,8 @@ MOD_TraceLine (hull_t *hull, int num, // crossing from an empty leaf to a solid leaf: the trace // has collided. calc_impact (trace, start_point, end_point, split_plane); - return; + if (trace->type == tr_point) + return; } } else { seen_empty = true; @@ -172,6 +179,7 @@ MOD_TraceLine (hull_t *hull, int num, } // pop up the stack for a back side + // FIXME detect early out from collisions if (tstack-- == tracestack) { // we've finished. return; @@ -208,13 +216,19 @@ MOD_TraceLine (hull_t *hull, int num, // cross the plane - if (start_dist < offset && end_dist < offset - && start_dist >= -offset && end_dist >= end_dist) { + if (start_dist == end_dist) { + // avoid division by zero (non-point clip only) + // since we need to check both sides anyway, it doesn't matter + // which side we start with, so long as the fractions are + // correct. side = 0; frac[0] = 1; frac[1] = 0; } else { - side = start_dist < offset; + // if either start or end have the box straddling the plane, then + // frac will be appropriately clipped to 0 and 1, otherwise, frac + // will be inside that range + side = start_dist < end_dist; frac[0] = (start_dist + offset) / (start_dist - end_dist); frac[1] = (start_dist - offset) / (start_dist - end_dist); frac[0] = bound (0, frac[0], 1); From 7a1faee46042c0698d65654a909f17d69084167a Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 13 Nov 2011 10:13:10 +0900 Subject: [PATCH 244/334] Bail out when the trace advances past the nearest collision. --- libs/models/trace.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/libs/models/trace.c b/libs/models/trace.c index 7d2269d13..c7d371f7d 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -57,6 +57,7 @@ static __attribute__ ((used)) const char rcsid[] = typedef struct { vec3_t start; vec3_t end; + vec_t start_frac; int side; int num; mplane_t *plane; @@ -179,11 +180,12 @@ MOD_TraceLine (hull_t *hull, int num, } // pop up the stack for a back side - // FIXME detect early out from collisions - if (tstack-- == tracestack) { - // we've finished. - return; - } + do { + if (tstack-- == tracestack) { + // we've finished. + return; + } + } while (tstack->start_frac > trace->fraction); // set the hit point for this plane VectorCopy (end, tstack->start); @@ -244,6 +246,7 @@ MOD_TraceLine (hull_t *hull, int num, VectorSubtract (end, start, dist); VectorMultAdd (start, frac[side], dist, end); VectorMultAdd (start, frac[side ^ 1], dist, tstack->start); + tstack->start_frac = frac[side ^ 1]; num = node->children[side]; } From 2f23cfa4d0403f4599f7ca5ee004b99e7cbec45c Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 14 Nov 2011 09:26:31 +0900 Subject: [PATCH 245/334] Add a new (failing) test case. This one demonstrates the need for more information in the bsp tree (surface polygons). When the box collides with a corner where one side is flat and the other angled, but there's a partition plane cutting the two, the box can instead collide with the angled side before it hits the corner. --- libs/models/test/testclip.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index 3cab3011c..338c7eae7 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -232,6 +232,33 @@ hull_t hull_covered_step = { {0, 0, 0}, }; +// 0 +// eee|eee +// eee+--- 1 +// ee/0,0s +// 2 ssss +mclipnode_t clipnodes_ramp[] = { + { 0, { 1, 2}}, + { 1, {CONTENTS_EMPTY, CONTENTS_SOLID}}, + { 2, {CONTENTS_EMPTY, CONTENTS_SOLID}}, +}; + +mplane_t planes_ramp[] = { + {{ 1, 0, 0}, 0, 0, 0}, + {{ 0, 0, 1}, 0, 2, 0}, + {{-0.6, 0, 0.8}, 0, 4, 0}, +}; + +hull_t hull_ramp = { + clipnodes_ramp, + planes_ramp, + 0, + 2, + {0, 0, 0}, + {0, 0, 0}, +}; + + typedef struct { vec3_t extents; } box_t; @@ -324,6 +351,9 @@ test_t tests[] = { { 0, 0, 64}, {0, 0, 0}, { 0.375, 0, 0, 1, 0}}, {"Box, Step 3", &box, &hull_step3, { 0, 0, 64}, {0, 0, 0}, { 0.375, 0, 0, 1, 0}}, + + {"Box, Ramp", &box, &hull_ramp, + { 0, 0, 16}, {0, 0, 0}, { 0.5, 0, 0, 1, 0}}, }; #define num_tests (sizeof (tests) / sizeof (tests[0])) From 91e65b6c80a75c2e080646ae627c112808c00fa9 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 14 Nov 2011 11:18:22 +0900 Subject: [PATCH 246/334] Rename mplane_t to plane_t and clean up the mess. I got rather tired of there being multiple definitions of mostly compatible plane types (and I need a common type anyway). dplane_t still exists for now because I want to be careful when messing with the actual bsp format. --- include/QF/mathlib.h | 4 ++-- include/QF/model.h | 8 ++++---- include/QF/qtypes.h | 4 ++-- include/r_local.h | 4 ++-- include/world.h | 8 +------- libs/models/brush/model_brush.c | 4 ++-- libs/models/clip_hull.c | 6 +++--- libs/models/trace.c | 8 ++++---- libs/util/mathlib.c | 6 +++--- libs/video/renderer/gl/gl_rmain.c | 4 ++-- libs/video/renderer/gl/gl_rsurf.c | 4 ++-- libs/video/renderer/r_efrag.c | 2 +- libs/video/renderer/r_light.c | 16 ++++++++-------- libs/video/renderer/sw/sw_rbsp.c | 10 +++++----- libs/video/renderer/sw/sw_rdraw.c | 8 ++++---- libs/video/renderer/sw/sw_rmain.c | 2 +- libs/video/renderer/sw/sw_rmisc.c | 2 +- libs/video/renderer/sw32/sw32_rbsp.c | 10 +++++----- libs/video/renderer/sw32/sw32_rdraw.c | 8 ++++---- libs/video/renderer/sw32/sw32_rmain.c | 2 +- libs/video/renderer/sw32/sw32_rmisc.c | 2 +- nq/source/sv_main.c | 2 +- nq/source/world.c | 8 ++++---- qw/source/pmovetst.c | 8 ++++---- qw/source/sv_ents.c | 2 +- qw/source/world.c | 8 ++++---- tools/qfbsp/include/bsp5.h | 6 ------ tools/qfvis/include/vis.h | 5 ----- 28 files changed, 72 insertions(+), 89 deletions(-) diff --git a/include/QF/mathlib.h b/include/QF/mathlib.h index 7fbf0e828..894a36eb9 100644 --- a/include/QF/mathlib.h +++ b/include/QF/mathlib.h @@ -249,7 +249,7 @@ void AngleVectors (const vec3_t angles, vec3_t forward, vec3_t right, void AngleQuat (const vec3_t angles, quat_t q); void VectorVectors (const vec3_t forward, vec3_t right, vec3_t up); int BoxOnPlaneSide (const vec3_t emins, const vec3_t emaxs, - struct mplane_s *plane); + struct plane_s *plane); float anglemod (float a); void RotatePointAroundVector (vec3_t dst, const vec3_t axis, @@ -288,7 +288,7 @@ void QuatToMatrix (const quat_t q, vec_t *m, int homogenous, int vertical); VectorNegate ((sp)->normal, (dp)->normal); \ } while (0) -extern mplane_t * const frustum; +extern plane_t * const frustum; extern inline qboolean R_CullBox (const vec3_t mins, const vec3_t maxs); extern inline qboolean R_CullSphere (const vec3_t origin, const float radius); extern inline float VectorNormalize (vec3_t v); // returns vector length diff --git a/include/QF/model.h b/include/QF/model.h index 86c098c02..c0493f4d3 100644 --- a/include/QF/model.h +++ b/include/QF/model.h @@ -122,7 +122,7 @@ typedef struct glpoly_s { typedef struct msurface_s { int visframe; // should be drawn when node is crossed - mplane_t *plane; + plane_t *plane; int flags; int firstedge; // look up in model->surfedges[], negative numbers @@ -162,7 +162,7 @@ typedef struct mnode_s { struct mnode_s *parent; // node specific - mplane_t *plane; + plane_t *plane; struct mnode_s *children[2]; unsigned short firstsurface; @@ -197,7 +197,7 @@ typedef struct mclipnode_s { typedef struct hull_s { mclipnode_t *clipnodes; - mplane_t *planes; + plane_t *planes; int firstclipnode; int lastclipnode; vec3_t clip_mins; @@ -357,7 +357,7 @@ typedef struct model_s { dmodel_t *submodels; int numplanes; - mplane_t *planes; + plane_t *planes; int numleafs; // number of visible leafs, not counting 0 mleaf_t *leafs; diff --git a/include/QF/qtypes.h b/include/QF/qtypes.h index ed4255634..8402a5bd9 100644 --- a/include/QF/qtypes.h +++ b/include/QF/qtypes.h @@ -89,12 +89,12 @@ typedef int fixed16_t; // plane_t structure // !!! if this is changed, it must be changed in asm_i386.h too !!! -typedef struct mplane_s { +typedef struct plane_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; +} plane_t; #endif // __qtypes_h diff --git a/include/r_local.h b/include/r_local.h index b0bee6519..7dc6e7af0 100644 --- a/include/r_local.h +++ b/include/r_local.h @@ -128,7 +128,7 @@ void R_RenderWorld (void); //============================================================================= -extern mplane_t screenedge[4]; +extern plane_t screenedge[4]; extern vec3_t r_origin; @@ -158,7 +158,7 @@ void R_DrawSprite (void); void R_RenderFace (msurface_t *fa, int clipflags); void R_RenderPoly (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_TransformPlane (plane_t *p, float *normal, float *dist); void R_TransformFrustum (void); void R_SetSkyFrame (void); void R_DrawSurfaceBlock (void); diff --git a/include/world.h b/include/world.h index 5744b8f71..d3f1a5b08 100644 --- a/include/world.h +++ b/include/world.h @@ -33,12 +33,6 @@ #include "QF/mathlib.h" #include "QF/model.h" -typedef struct -{ - vec3_t normal; - vec_t dist; -} plane_t; - typedef enum { tr_point, tr_box, @@ -77,7 +71,7 @@ extern areanode_t sv_areanodes[AREA_NODES]; void SV_FreeAllEdictLeafs (void); -void SV_InitHull (hull_t *hull, mclipnode_t *clipnodes, mplane_t *planes); +void SV_InitHull (hull_t *hull, mclipnode_t *clipnodes, plane_t *planes); void SV_ClearWorld (void); // called after the world model has been loaded, before linking any entities diff --git a/libs/models/brush/model_brush.c b/libs/models/brush/model_brush.c index 5a4439625..954c3bc86 100644 --- a/libs/models/brush/model_brush.c +++ b/libs/models/brush/model_brush.c @@ -63,7 +63,7 @@ Mod_PointInLeaf (const vec3_t p, model_t *model) { float d; mnode_t *node; - mplane_t *plane; + plane_t *plane; if (!model || !model->nodes) Sys_Error ("Mod_PointInLeaf: bad model"); @@ -837,7 +837,7 @@ Mod_LoadPlanes (bsp_t *bsp) { dplane_t *in; int bits, count, i, j; - mplane_t *out; + plane_t *out; in = bsp->planes; count = bsp->numplanes; diff --git a/libs/models/clip_hull.c b/libs/models/clip_hull.c index 6161c6d38..c0b7ddf63 100644 --- a/libs/models/clip_hull.c +++ b/libs/models/clip_hull.c @@ -47,7 +47,7 @@ MOD_Alloc_Hull (int nodes, int planes) int size, i; size = sizeof (hull_t); - size += sizeof (mclipnode_t) * nodes + sizeof (mplane_t) * planes; + size += sizeof (mclipnode_t) * nodes + sizeof (plane_t) * planes; size *= MAX_MAP_HULLS; size += sizeof (clip_hull_t); @@ -58,11 +58,11 @@ MOD_Alloc_Hull (int nodes, int planes) for (i = 1; i < MAX_MAP_HULLS; i++) ch->hulls[i] = &ch->hulls[i - 1][1]; ch->hulls[0]->clipnodes = (mclipnode_t *) &ch->hulls[i - 1][1]; - ch->hulls[0]->planes = (mplane_t *) &ch->hulls[0]->clipnodes[nodes]; + ch->hulls[0]->planes = (plane_t *) &ch->hulls[0]->clipnodes[nodes]; for (i = 1; i < MAX_MAP_HULLS; i++) { ch->hulls[i]->clipnodes = (mclipnode_t *) &ch->hulls[i - 1]->planes[planes]; - ch->hulls[i]->planes = (mplane_t *) &ch->hulls[i]->clipnodes[nodes]; + ch->hulls[i]->planes = (plane_t *) &ch->hulls[i]->clipnodes[nodes]; } return ch; } diff --git a/libs/models/trace.c b/libs/models/trace.c index c7d371f7d..671d7a22d 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -60,11 +60,11 @@ typedef struct { vec_t start_frac; int side; int num; - mplane_t *plane; + plane_t *plane; } tracestack_t; static inline float -calc_offset (trace_t *trace, mplane_t *plane) +calc_offset (trace_t *trace, plane_t *plane) { vec_t d = 0; vec3_t Rn; @@ -92,7 +92,7 @@ calc_offset (trace_t *trace, mplane_t *plane) static inline void calc_impact (trace_t *trace, const vec3_t start, const vec3_t end, - mplane_t *plane) + plane_t *plane) { vec_t t1, t2, frac, offset; vec3_t dist; @@ -135,7 +135,7 @@ MOD_TraceLine (hull_t *hull, int num, tracestack_t *tstack; tracestack_t tracestack[256]; mclipnode_t *node; - mplane_t *plane, *split_plane; + plane_t *plane, *split_plane; VectorCopy (start_point, start); VectorCopy (end_point, end); diff --git a/libs/util/mathlib.c b/libs/util/mathlib.c index 8e4871ec1..dab28b628 100644 --- a/libs/util/mathlib.c +++ b/libs/util/mathlib.c @@ -48,8 +48,8 @@ static __attribute__ ((used)) const char rcsid[] = #include "QF/sys.h" VISIBLE int nanmask = 255 << 23; -static mplane_t _frustum[4]; -VISIBLE mplane_t *const frustum = _frustum; +static plane_t _frustum[4]; +VISIBLE plane_t *const frustum = _frustum; static vec3_t _vec3_origin = { 0, 0, 0 }; VISIBLE const vec_t * const vec3_origin = _vec3_origin; static vec3_t _quat_origin = { 0, 0, 0 }; @@ -269,7 +269,7 @@ BOPS_Error (void) Returns 1, 2, or 1 + 2 */ VISIBLE int -BoxOnPlaneSide (const vec3_t emins, const vec3_t emaxs, mplane_t *p) +BoxOnPlaneSide (const vec3_t emins, const vec3_t emaxs, plane_t *p) { float dist1, dist2; int sides; diff --git a/libs/video/renderer/gl/gl_rmain.c b/libs/video/renderer/gl/gl_rmain.c index 3242ac1d8..b419a1f6d 100644 --- a/libs/video/renderer/gl/gl_rmain.c +++ b/libs/video/renderer/gl/gl_rmain.c @@ -83,7 +83,7 @@ qboolean envmap; // true during envmap command capture int mirrortexturenum; // quake texturenum, not gltexturenum qboolean mirror; -mplane_t *mirror_plane; +plane_t *mirror_plane; // view origin VISIBLE vec3_t vup; @@ -360,7 +360,7 @@ R_DrawViewModel (void) } static inline int -SignbitsForPlane (mplane_t *out) +SignbitsForPlane (plane_t *out) { int bits, j; diff --git a/libs/video/renderer/gl/gl_rsurf.c b/libs/video/renderer/gl/gl_rsurf.c index 2d65780f5..cd6b6400d 100644 --- a/libs/video/renderer/gl/gl_rsurf.c +++ b/libs/video/renderer/gl/gl_rsurf.c @@ -370,7 +370,7 @@ R_DrawBrushModel (entity_t *e) int i; unsigned int k; model_t *model; - mplane_t *pplane; + plane_t *pplane; msurface_t *psurf; qboolean rotated; vec3_t mins, maxs; @@ -571,7 +571,7 @@ static inline int get_side (mnode_t *node) { // find which side of the node we are on - mplane_t *plane = node->plane; + plane_t *plane = node->plane; if (plane->type < 3) return (modelorg[plane->type] - plane->dist) < 0; diff --git a/libs/video/renderer/r_efrag.c b/libs/video/renderer/r_efrag.c index fb4a0f354..82912370c 100644 --- a/libs/video/renderer/r_efrag.c +++ b/libs/video/renderer/r_efrag.c @@ -125,7 +125,7 @@ static void R_SplitEntityOnNode (mnode_t *node) { efrag_t *ef; - mplane_t *splitplane; + plane_t *splitplane; mleaf_t *leaf; int sides; diff --git a/libs/video/renderer/r_light.c b/libs/video/renderer/r_light.c index 601d10550..8a9e844db 100644 --- a/libs/video/renderer/r_light.c +++ b/libs/video/renderer/r_light.c @@ -152,7 +152,7 @@ R_RecursiveMarkLights (const vec3_t lightorigin, dlight_t *light, int bit, { int i; float ndist, maxdist; - mplane_t *splitplane; + plane_t *splitplane; msurface_t *surf; //XXX mvertex_t *vertices; @@ -276,7 +276,7 @@ R_PushDlights (const vec3_t entorigin) /* LIGHT SAMPLING */ -mplane_t *lightplane; +plane_t *lightplane; vec3_t lightspot; static int @@ -345,12 +345,12 @@ calc_lighting_3 (msurface_t *surf, int ds, int dt) static int RecursiveLightPoint (mnode_t *node, const vec3_t start, const vec3_t end) { - int i, r, s, t, ds, dt, side; - float front, back, frac; - mplane_t *plane; - msurface_t *surf; - mtexinfo_t *tex; - vec3_t mid; + int i, r, s, t, ds, dt, side; + float front, back, frac; + plane_t *plane; + msurface_t *surf; + mtexinfo_t *tex; + vec3_t mid; loop: if (node->contents < 0) return -1; // didn't hit anything diff --git a/libs/video/renderer/sw/sw_rbsp.c b/libs/video/renderer/sw/sw_rbsp.c index ede228fa3..a60b93694 100644 --- a/libs/video/renderer/sw/sw_rbsp.c +++ b/libs/video/renderer/sw/sw_rbsp.c @@ -155,7 +155,7 @@ R_RecursiveClipBPoly (bedge_t *pedges, mnode_t *pnode, msurface_t *psurf) bedge_t *psideedges[2], *pnextedge, *ptedge; int i, side, lastside; float dist, frac, lastdist; - mplane_t *splitplane, tplane; + plane_t *splitplane, tplane; mvertex_t *pvert, *plastvert, *ptvert; mnode_t *pn; @@ -301,7 +301,7 @@ R_DrawSolidClippedSubmodelPolygons (model_t *pmodel) vec_t dot; msurface_t *psurf; int numsurfaces; - mplane_t *pplane; + plane_t *pplane; mvertex_t bverts[MAX_BMODEL_VERTS]; bedge_t bedges[MAX_BMODEL_EDGES], *pbedge; medge_t *pedge, *pedges; @@ -370,7 +370,7 @@ R_DrawSubmodelPolygons (model_t *pmodel, int clipflags) vec_t dot; msurface_t *psurf; int numsurfaces; - mplane_t *pplane; + plane_t *pplane; // FIXME: use bounding-box-based frustum clipping info? @@ -409,7 +409,7 @@ static inline int get_side (mnode_t *node) { // find which side of the node we are on - mplane_t *plane = node->plane; + plane_t *plane = node->plane; if (plane->type < 3) return (modelorg[plane->type] - plane->dist) < 0; @@ -560,7 +560,7 @@ R_RecursiveWorldNode (mnode_t *node, int clipflags) { int i, c, side, *pindex; vec3_t acceptpt, rejectpt; - mplane_t *plane; + plane_t *plane; msurface_t *surf; mleaf_t *pleaf; double d, dot; diff --git a/libs/video/renderer/sw/sw_rdraw.c b/libs/video/renderer/sw/sw_rdraw.c index 59f0206b0..fb17fe4c0 100644 --- a/libs/video/renderer/sw/sw_rdraw.c +++ b/libs/video/renderer/sw/sw_rdraw.c @@ -353,7 +353,7 @@ R_RenderFace (msurface_t *fa, int clipflags) { int i, lindex; unsigned int mask; - mplane_t *pplane; + plane_t *pplane; float distinv; vec3_t p_normal; medge_t *pedges, tedge; @@ -519,7 +519,7 @@ R_RenderBmodelFace (bedge_t *pedges, msurface_t *psurf) { int i; unsigned int mask; - mplane_t *pplane; + plane_t *pplane; float distinv; vec3_t p_normal; medge_t tedge; @@ -623,7 +623,7 @@ R_RenderPoly (msurface_t *fa, int clipflags) vec3_t local, transformed; clipplane_t *pclip; medge_t *pedges; - mplane_t *pplane; + plane_t *pplane; mvertex_t verts[2][100]; // FIXME: do real number polyvert_t pverts[100]; // FIXME: do real number, safely int vertpage, newverts, newpage, lastvert; @@ -787,7 +787,7 @@ R_ZDrawSubmodelPolys (model_t *pmodel) int i, numsurfaces; msurface_t *psurf; float dot; - mplane_t *pplane; + plane_t *pplane; psurf = &pmodel->surfaces[pmodel->firstmodelsurface]; numsurfaces = pmodel->nummodelsurfaces; diff --git a/libs/video/renderer/sw/sw_rmain.c b/libs/video/renderer/sw/sw_rmain.c index 1d280a4a4..6c7f6e568 100644 --- a/libs/video/renderer/sw/sw_rmain.c +++ b/libs/video/renderer/sw/sw_rmain.c @@ -116,7 +116,7 @@ float screenAspect; float verticalFieldOfView; float xOrigin, yOrigin; -mplane_t screenedge[4]; +plane_t screenedge[4]; // refresh flags int r_framecount = 1; // so frame counts initialized to 0 don't match diff --git a/libs/video/renderer/sw/sw_rmisc.c b/libs/video/renderer/sw/sw_rmisc.c index a4bd3145b..e22a9c6b7 100644 --- a/libs/video/renderer/sw/sw_rmisc.c +++ b/libs/video/renderer/sw/sw_rmisc.c @@ -175,7 +175,7 @@ TransformVector (const vec3_t in, vec3_t out) #endif void -R_TransformPlane (mplane_t *p, float *normal, float *dist) +R_TransformPlane (plane_t *p, float *normal, float *dist) { float d; diff --git a/libs/video/renderer/sw32/sw32_rbsp.c b/libs/video/renderer/sw32/sw32_rbsp.c index ce3ef050b..28511e491 100644 --- a/libs/video/renderer/sw32/sw32_rbsp.c +++ b/libs/video/renderer/sw32/sw32_rbsp.c @@ -155,7 +155,7 @@ R_RecursiveClipBPoly (bedge_t *pedges, mnode_t *pnode, msurface_t *psurf) bedge_t *psideedges[2], *pnextedge, *ptedge; int i, side, lastside; float dist, frac, lastdist; - mplane_t *splitplane, tplane; + plane_t *splitplane, tplane; mvertex_t *pvert, *plastvert, *ptvert; mnode_t *pn; @@ -301,7 +301,7 @@ R_DrawSolidClippedSubmodelPolygons (model_t *pmodel) vec_t dot; msurface_t *psurf; int numsurfaces; - mplane_t *pplane; + plane_t *pplane; mvertex_t bverts[MAX_BMODEL_VERTS]; bedge_t bedges[MAX_BMODEL_EDGES], *pbedge; medge_t *pedge, *pedges; @@ -370,7 +370,7 @@ R_DrawSubmodelPolygons (model_t *pmodel, int clipflags) vec_t dot; msurface_t *psurf; int numsurfaces; - mplane_t *pplane; + plane_t *pplane; // FIXME: use bounding-box-based frustum clipping info? @@ -409,7 +409,7 @@ static inline int get_side (mnode_t *node) { // find which side of the node we are on - mplane_t *plane = node->plane; + plane_t *plane = node->plane; if (plane->type < 3) return (modelorg[plane->type] - plane->dist) < 0; @@ -560,7 +560,7 @@ R_RecursiveWorldNode (mnode_t *node, int clipflags) { int i, c, side, *pindex; vec3_t acceptpt, rejectpt; - mplane_t *plane; + plane_t *plane; msurface_t *surf; mleaf_t *pleaf; double d, dot; diff --git a/libs/video/renderer/sw32/sw32_rdraw.c b/libs/video/renderer/sw32/sw32_rdraw.c index fd1ca5f1e..08335ea4c 100644 --- a/libs/video/renderer/sw32/sw32_rdraw.c +++ b/libs/video/renderer/sw32/sw32_rdraw.c @@ -346,7 +346,7 @@ R_RenderFace (msurface_t *fa, int clipflags) { int i, lindex; unsigned int mask; - mplane_t *pplane; + plane_t *pplane; float distinv; vec3_t p_normal; medge_t *pedges, tedge; @@ -513,7 +513,7 @@ R_RenderBmodelFace (bedge_t *pedges, msurface_t *psurf) { int i; unsigned int mask; - mplane_t *pplane; + plane_t *pplane; float distinv; vec3_t p_normal; medge_t tedge; @@ -618,7 +618,7 @@ R_RenderPoly (msurface_t *fa, int clipflags) vec3_t local, transformed; clipplane_t *pclip; medge_t *pedges; - mplane_t *pplane; + plane_t *pplane; mvertex_t verts[2][100]; // FIXME: do real number polyvert_t pverts[100]; // FIXME: do real number, safely int vertpage, newverts, newpage, lastvert; @@ -782,7 +782,7 @@ R_ZDrawSubmodelPolys (model_t *pmodel) int i, numsurfaces; msurface_t *psurf; float dot; - mplane_t *pplane; + plane_t *pplane; psurf = &pmodel->surfaces[pmodel->firstmodelsurface]; numsurfaces = pmodel->nummodelsurfaces; diff --git a/libs/video/renderer/sw32/sw32_rmain.c b/libs/video/renderer/sw32/sw32_rmain.c index e78d64c59..afa0ca1c1 100644 --- a/libs/video/renderer/sw32/sw32_rmain.c +++ b/libs/video/renderer/sw32/sw32_rmain.c @@ -110,7 +110,7 @@ float screenAspect; float verticalFieldOfView; float xOrigin, yOrigin; -mplane_t screenedge[4]; +plane_t screenedge[4]; // refresh flags VISIBLE int r_framecount = 1; // so frame counts initialized to 0 don't match diff --git a/libs/video/renderer/sw32/sw32_rmisc.c b/libs/video/renderer/sw32/sw32_rmisc.c index 14933f4a2..62dd30318 100644 --- a/libs/video/renderer/sw32/sw32_rmisc.c +++ b/libs/video/renderer/sw32/sw32_rmisc.c @@ -169,7 +169,7 @@ TransformVector (const vec3_t in, vec3_t out) } void -R_TransformPlane (mplane_t *p, float *normal, float *dist) +R_TransformPlane (plane_t *p, float *normal, float *dist) { float d; diff --git a/nq/source/sv_main.c b/nq/source/sv_main.c index e6f230e39..389c9bd1a 100644 --- a/nq/source/sv_main.c +++ b/nq/source/sv_main.c @@ -390,7 +390,7 @@ SV_AddToFatPVS (vec3_t org, mnode_t *node) int i; float d; byte *pvs; - mplane_t *plane; + plane_t *plane; while (1) { // if this is a leaf, accumulate the pvs bits diff --git a/nq/source/world.c b/nq/source/world.c index 7c49f979d..518824a6e 100644 --- a/nq/source/world.c +++ b/nq/source/world.c @@ -136,7 +136,7 @@ typedef struct { static hull_t box_hull; static mclipnode_t box_clipnodes[6]; -static mplane_t box_planes[6]; +static plane_t box_planes[6]; /* @@ -146,7 +146,7 @@ static mplane_t box_planes[6]; can just be stored out and get a proper hull_t structure. */ void -SV_InitHull (hull_t *hull, mclipnode_t *clipnodes, mplane_t *planes) +SV_InitHull (hull_t *hull, mclipnode_t *clipnodes, plane_t *planes) { int side, i; @@ -412,7 +412,7 @@ SV_FindTouchedLeafs (edict_t *ent, mnode_t *node) { int sides; mleaf_t *leaf; - mplane_t *splitplane; + plane_t *splitplane; edict_leaf_t *edict_leaf; if (node->contents == CONTENTS_SOLID) @@ -531,7 +531,7 @@ SV_HullPointContents (hull_t *hull, int num, const vec3_t p) { float d; mclipnode_t *node; - mplane_t *plane; + plane_t *plane; while (num >= 0) { //if (num < hull->firstclipnode || num > hull->lastclipnode) diff --git a/qw/source/pmovetst.c b/qw/source/pmovetst.c index 57b9444b7..9ee69cf45 100644 --- a/qw/source/pmovetst.c +++ b/qw/source/pmovetst.c @@ -49,7 +49,7 @@ static __attribute__ ((used)) const char rcsid[] = static hull_t box_hull; static mclipnode_t box_clipnodes[6]; -static mplane_t box_planes[6]; +static plane_t box_planes[6]; /* @@ -107,9 +107,9 @@ PM_HullForBox (const vec3_t mins, const vec3_t maxs) inline int PM_HullPointContents (hull_t *hull, int num, const vec3_t p) { - float d; + float d; mclipnode_t *node; - mplane_t *plane; + plane_t *plane; while (num >= 0) { node = hull->clipnodes + num; @@ -135,7 +135,7 @@ PM_PointContents (const vec3_t p) int num; mclipnode_t *node; hull_t *hull; - mplane_t *plane; + plane_t *plane; hull = &pmove.physents[0].model->hulls[0]; diff --git a/qw/source/sv_ents.c b/qw/source/sv_ents.c index 60355bdf9..f94c8a853 100644 --- a/qw/source/sv_ents.c +++ b/qw/source/sv_ents.c @@ -66,7 +66,7 @@ SV_AddToFatPVS (vec3_t org, mnode_t *node) byte *pvs; int i; float d; - mplane_t *plane; + plane_t *plane; while (1) { // if this is a leaf, accumulate the pvs bits diff --git a/qw/source/world.c b/qw/source/world.c index 7c49f979d..518824a6e 100644 --- a/qw/source/world.c +++ b/qw/source/world.c @@ -136,7 +136,7 @@ typedef struct { static hull_t box_hull; static mclipnode_t box_clipnodes[6]; -static mplane_t box_planes[6]; +static plane_t box_planes[6]; /* @@ -146,7 +146,7 @@ static mplane_t box_planes[6]; can just be stored out and get a proper hull_t structure. */ void -SV_InitHull (hull_t *hull, mclipnode_t *clipnodes, mplane_t *planes) +SV_InitHull (hull_t *hull, mclipnode_t *clipnodes, plane_t *planes) { int side, i; @@ -412,7 +412,7 @@ SV_FindTouchedLeafs (edict_t *ent, mnode_t *node) { int sides; mleaf_t *leaf; - mplane_t *splitplane; + plane_t *splitplane; edict_leaf_t *edict_leaf; if (node->contents == CONTENTS_SOLID) @@ -531,7 +531,7 @@ SV_HullPointContents (hull_t *hull, int num, const vec3_t p) { float d; mclipnode_t *node; - mplane_t *plane; + plane_t *plane; while (num >= 0) { //if (num < hull->firstclipnode || num > hull->lastclipnode) diff --git a/tools/qfbsp/include/bsp5.h b/tools/qfbsp/include/bsp5.h index 78d73398a..5230ed550 100644 --- a/tools/qfbsp/include/bsp5.h +++ b/tools/qfbsp/include/bsp5.h @@ -34,12 +34,6 @@ */ //@{ -typedef struct plane_s { - vec3_t normal; - vec_t dist; - int type; -} plane_t; - #define MAX_THREADS 4 #define ON_EPSILON 0.05 diff --git a/tools/qfvis/include/vis.h b/tools/qfvis/include/vis.h index 226691e9d..c365907b8 100644 --- a/tools/qfvis/include/vis.h +++ b/tools/qfvis/include/vis.h @@ -51,11 +51,6 @@ extern pthread_mutex_t *my_mutex; #define MAX_POINTS_ON_WINDING 64 #define MAX_PORTALS_ON_CLUSTER 128 -typedef struct { - vec3_t normal; - float dist; -} plane_t; - typedef struct { qboolean original; // don't free, it's part of the portal int numpoints; From 853bf13d9e1aef6fe544990b1f89a39ceb3820d2 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 14 Nov 2011 15:46:39 +0900 Subject: [PATCH 247/334] Move the winding code into libQFmodels. --- config.d/build_control.m4 | 2 +- include/QF/Makefile.am | 2 +- {tools/qfbsp/include => include/QF}/winding.h | 11 ++++++----- libs/models/Makefile.am | 2 +- libs/models/test/testclip.c | 18 +++++++++--------- {tools/qfbsp/source => libs/models}/winding.c | 11 ++++++----- tools/qfbsp/include/Makefile.am | 2 +- tools/qfbsp/include/bsp5.h | 2 +- tools/qfbsp/source/Makefile.am | 3 +-- tools/qfbsp/source/brush.c | 1 - tools/qfbsp/source/csg4.c | 1 - tools/qfbsp/source/merge.c | 1 - tools/qfbsp/source/outside.c | 1 - tools/qfbsp/source/portals.c | 1 - tools/qfbsp/source/readbsp.c | 1 - tools/qfbsp/source/region.c | 1 - tools/qfbsp/source/solidbsp.c | 1 - tools/qfbsp/source/surfaces.c | 1 - tools/qfbsp/source/tjunc.c | 1 - 19 files changed, 27 insertions(+), 36 deletions(-) rename {tools/qfbsp/include => include/QF}/winding.h (96%) rename {tools/qfbsp/source => libs/models}/winding.c (97%) diff --git a/config.d/build_control.m4 b/config.d/build_control.m4 index 8f4953a95..8105ba438 100644 --- a/config.d/build_control.m4 +++ b/config.d/build_control.m4 @@ -527,7 +527,7 @@ QF_DEPS(BSP2IMG, ) QF_DEPS(QFBSP, [-I$(top_srcdir)/tools/qfbsp/include], - [$(top_builddir)/libs/util/libQFutil.la], + [$(top_builddir)/libs/util/libQFutil.la $(top_builddir)/libs/models/libQFmodels.la], [$(WIN32_LIBS)], ) QF_DEPS(QFCC, diff --git a/include/QF/Makefile.am b/include/QF/Makefile.am index 8998e8a4d..451faf023 100644 --- a/include/QF/Makefile.am +++ b/include/QF/Makefile.am @@ -9,7 +9,7 @@ nobase_pkginclude_HEADERS = \ qargs.h qdefs.h qendian.h qfplist.h qtypes.h quakefs.h quakeio.h render.h \ riff.h ruamoko.h screen.h script.h sizebuf.h skin.h sound.h spritegn.h \ sys.h teamplay.h tga.h uint32.h va.h ver_check.h vid.h view.h wad.h \ - wadfile.h zone.h \ + wadfile.h winding.h zone.h \ \ GL/ati.h GL/defines.h GL/extensions.h GL/funcs.h GL/qf_explosions.h \ GL/qf_funcs_list.h GL/qf_lightmap.h GL/qf_noisetextures.h \ diff --git a/tools/qfbsp/include/winding.h b/include/QF/winding.h similarity index 96% rename from tools/qfbsp/include/winding.h rename to include/QF/winding.h index 3bae9415e..f1a779003 100644 --- a/tools/qfbsp/include/winding.h +++ b/include/QF/winding.h @@ -20,18 +20,19 @@ $Id$ */ -#ifndef qfbsp_winding_h -#define qfbsp_winding_h +#ifndef __QF_winding_h +#define __QF_winding_h #include "QF/mathlib.h" -/** \defgroup qfbsp_winding Winding Manipulation - \ingroup qfbsp +/** \defgroup winding Winding Manipulation */ //@{ struct plane_s; +#define ON_EPSILON 0.05 + typedef struct winding_s { int numpoints; ///< The number of points in the winding vec3_t points[3]; ///< variable sized, never less than 3 @@ -130,4 +131,4 @@ void DivideWinding (winding_t *in, struct plane_s *split, //@} -#endif//qfbsp_winding_h +#endif//__QF_winding_h diff --git a/libs/models/Makefile.am b/libs/models/Makefile.am index e11fb0b2b..134b59909 100644 --- a/libs/models/Makefile.am +++ b/libs/models/Makefile.am @@ -7,7 +7,7 @@ INCLUDES= -I$(top_srcdir)/include lib_LTLIBRARIES= libQFmodels.la @VID_MODEL_TARGETS@ EXTRA_LTLIBRARIES= libQFmodels_gl.la libQFmodels_sw.la -models_sources = clip_hull.c model.c trace.c +models_sources = clip_hull.c model.c trace.c winding.c libQFmodels_la_LDFLAGS= -version-info $(QUAKE_LIBRARY_VERSION_INFO) -no-undefined libQFmodels_la_LIBADD= brush/libbrush.la $(top_builddir)/libs/util/libQFutil.la diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index 338c7eae7..97e5e282a 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -26,7 +26,7 @@ mclipnode_t clipnodes_simple_wedge[] = { { 1, {CONTENTS_EMPTY, CONTENTS_SOLID}}, }; -mplane_t planes_simple_wedge[] = { +plane_t planes_simple_wedge[] = { {{1, 0, 0}, 0, 0, 0}, // 0 {{0.8, 0, 0.6}, 0, 4, 0}, // 1 }; @@ -51,7 +51,7 @@ mclipnode_t clipnodes_tpp1[] = { { 2, {CONTENTS_SOLID, CONTENTS_EMPTY}}, }; -mplane_t planes_tpp1[] = { +plane_t planes_tpp1[] = { {{1, 0, 0}, -32, 0, 0}, {{1, 0, 0}, 32, 0, 0}, {{1, 0, 0}, 48, 0, 0}, @@ -77,7 +77,7 @@ mclipnode_t clipnodes_tpp2[] = { { 2, {CONTENTS_SOLID, CONTENTS_EMPTY}}, }; -mplane_t planes_tpp2[] = { +plane_t planes_tpp2[] = { {{1, 0, 0}, 32, 0, 0}, {{1, 0, 0}, -32, 0, 0}, {{1, 0, 0}, 48, 0, 0}, @@ -103,7 +103,7 @@ mclipnode_t clipnodes_tppw[] = { { 2, {CONTENTS_SOLID, CONTENTS_WATER}}, }; -mplane_t planes_tppw[] = { +plane_t planes_tppw[] = { {{1, 0, 0}, 32, 0, 0}, {{1, 0, 0}, -32, 0, 0}, {{1, 0, 0}, 48, 0, 0}, @@ -130,7 +130,7 @@ mclipnode_t clipnodes_step1[] = { { 2, {CONTENTS_SOLID, CONTENTS_EMPTY}}, }; -mplane_t planes_step1[] = { +plane_t planes_step1[] = { {{0, 0, 1}, 0, 2, 0}, {{0, 0, 1}, 32, 2, 0}, {{1, 0, 0}, 0, 0, 0}, @@ -157,7 +157,7 @@ mclipnode_t clipnodes_step2[] = { { 2, {CONTENTS_EMPTY, CONTENTS_SOLID}}, }; -mplane_t planes_step2[] = { +plane_t planes_step2[] = { {{1, 0, 0}, 0, 0, 0}, {{0, 0, 1}, 32, 2, 0}, {{0, 0, 1}, 0, 2, 0}, @@ -184,7 +184,7 @@ mclipnode_t clipnodes_step3[] = { { 2, {CONTENTS_EMPTY, CONTENTS_SOLID}}, }; -mplane_t planes_step3[] = { +plane_t planes_step3[] = { {{1, 0, 0}, 0, 0, 0}, {{0, 0, 1}, 0, 2, 0}, {{0, 0, 1}, 32, 2, 0}, @@ -215,7 +215,7 @@ mclipnode_t clipnodes_covered_step[] = { { 4, {CONTENTS_SOLID, CONTENTS_EMPTY}}, }; -mplane_t planes_covered_step[] = { +plane_t planes_covered_step[] = { {{0, 0, 1}, 0, 2, 0}, {{0, 0, 1}, 32, 2, 0}, {{1, 0, 0}, 0, 0, 0}, @@ -243,7 +243,7 @@ mclipnode_t clipnodes_ramp[] = { { 2, {CONTENTS_EMPTY, CONTENTS_SOLID}}, }; -mplane_t planes_ramp[] = { +plane_t planes_ramp[] = { {{ 1, 0, 0}, 0, 0, 0}, {{ 0, 0, 1}, 0, 2, 0}, {{-0.6, 0, 0.8}, 0, 4, 0}, diff --git a/tools/qfbsp/source/winding.c b/libs/models/winding.c similarity index 97% rename from tools/qfbsp/source/winding.c rename to libs/models/winding.c index 90849b168..c5b06cb3a 100644 --- a/tools/qfbsp/source/winding.c +++ b/libs/models/winding.c @@ -37,8 +37,9 @@ static __attribute__ ((used)) const char rcsid[] = #include "QF/sys.h" -#include "bsp5.h" -#include "winding.h" +#include "QF/winding.h" + +#define BOGUS (8e6) /** \addtogroup qfbsp_winding */ @@ -56,7 +57,7 @@ BaseWindingForPlane (const plane_t *p) // find the major axis - max = -BOGUS_RANGE; + max = -BOGUS; x = -1; for (i = 0; i < 3; i++) { v = fabs (p->normal[i]); @@ -87,8 +88,8 @@ BaseWindingForPlane (const plane_t *p) CrossProduct (vup, p->normal, vright); - VectorScale (vup, BOGUS_RANGE, vup); - VectorScale (vright, BOGUS_RANGE, vright); + VectorScale (vup, BOGUS, vup); + VectorScale (vright, BOGUS, vright); // project a really big axis aligned box onto the plane w = NewWinding (4); diff --git a/tools/qfbsp/include/Makefile.am b/tools/qfbsp/include/Makefile.am index 527651177..d4ab30d4e 100644 --- a/tools/qfbsp/include/Makefile.am +++ b/tools/qfbsp/include/Makefile.am @@ -2,4 +2,4 @@ AUTOMAKE_OPTIONS= foreign EXTRA_DIST= brush.h bsp5.h csg4.h draw.h map.h merge.h options.h outside.h \ portals.h readbsp.h region.h solidbsp.h surfaces.h tjunc.h \ - winding.h writebsp.h + writebsp.h diff --git a/tools/qfbsp/include/bsp5.h b/tools/qfbsp/include/bsp5.h index 5230ed550..30a924d7d 100644 --- a/tools/qfbsp/include/bsp5.h +++ b/tools/qfbsp/include/bsp5.h @@ -28,6 +28,7 @@ #include "QF/mathlib.h" #include "QF/bspfile.h" +#include "QF/winding.h" /** \defgroup qfbsp_general General functions \ingroup qfbsp @@ -36,7 +37,6 @@ #define MAX_THREADS 4 -#define ON_EPSILON 0.05 #define BOGUS_RANGE 18000 // the exact bounding box of the brushes is expanded some for the headnode diff --git a/tools/qfbsp/source/Makefile.am b/tools/qfbsp/source/Makefile.am index 2bd7b6fee..9e4172541 100644 --- a/tools/qfbsp/source/Makefile.am +++ b/tools/qfbsp/source/Makefile.am @@ -17,8 +17,7 @@ EXTRA_PROGRAMS= qfbsp qfbsp_SOURCES= \ brush.c csg4.c map.c merge.c nodraw.c options.c outside.c portals.c \ - qfbsp.c readbsp.c region.c solidbsp.c surfaces.c tjunc.c winding.c \ - writebsp.c + qfbsp.c readbsp.c region.c solidbsp.c surfaces.c tjunc.c writebsp.c qfbsp_LDADD= $(QFBSP_LIBS) qfbsp_DEPENDENCIES= $(QFBSP_DEPS) diff --git a/tools/qfbsp/source/brush.c b/tools/qfbsp/source/brush.c index f3dbfd89a..f27c253b8 100644 --- a/tools/qfbsp/source/brush.c +++ b/tools/qfbsp/source/brush.c @@ -37,7 +37,6 @@ #include "draw.h" #include "options.h" #include "surfaces.h" -#include "winding.h" /** \addtogroup qfbsp_brush */ diff --git a/tools/qfbsp/source/csg4.c b/tools/qfbsp/source/csg4.c index 0de15cd58..bbb63fd0c 100644 --- a/tools/qfbsp/source/csg4.c +++ b/tools/qfbsp/source/csg4.c @@ -37,7 +37,6 @@ static __attribute__ ((used)) const char rcsid[] = #include "merge.h" #include "solidbsp.h" #include "surfaces.h" -#include "winding.h" /** \addtogroup qfbsp_csg4 */ diff --git a/tools/qfbsp/source/merge.c b/tools/qfbsp/source/merge.c index 91a21e8f5..c3c6c04e1 100644 --- a/tools/qfbsp/source/merge.c +++ b/tools/qfbsp/source/merge.c @@ -32,7 +32,6 @@ static __attribute__ ((used)) const char rcsid[] = #include "draw.h" #include "merge.h" #include "surfaces.h" -#include "winding.h" /** \addtogroup qfbsp_merge */ diff --git a/tools/qfbsp/source/outside.c b/tools/qfbsp/source/outside.c index 08ea2e8d8..3de085e7b 100644 --- a/tools/qfbsp/source/outside.c +++ b/tools/qfbsp/source/outside.c @@ -31,7 +31,6 @@ static __attribute__ ((used)) const char rcsid[] = #include "options.h" #include "portals.h" #include "outside.h" -#include "winding.h" /** \addtogroup qfbsp_outside */ diff --git a/tools/qfbsp/source/portals.c b/tools/qfbsp/source/portals.c index e6f068044..b4c54a971 100644 --- a/tools/qfbsp/source/portals.c +++ b/tools/qfbsp/source/portals.c @@ -36,7 +36,6 @@ static __attribute__ ((used)) const char rcsid[] = #include "draw.h" #include "options.h" #include "portals.h" -#include "winding.h" /** \addtogroup qfbsp_portals */ diff --git a/tools/qfbsp/source/readbsp.c b/tools/qfbsp/source/readbsp.c index 7beea980a..9578af25c 100644 --- a/tools/qfbsp/source/readbsp.c +++ b/tools/qfbsp/source/readbsp.c @@ -56,7 +56,6 @@ static __attribute__ ((used)) const char rcsid[] = #include "options.h" #include "portals.h" #include "readbsp.h" -#include "winding.h" /** \addtogroup qfbsp_readbsp */ diff --git a/tools/qfbsp/source/region.c b/tools/qfbsp/source/region.c index 243b0cfd8..52487aeb2 100644 --- a/tools/qfbsp/source/region.c +++ b/tools/qfbsp/source/region.c @@ -35,7 +35,6 @@ static __attribute__ ((used)) const char rcsid[] = #include "bsp5.h" #include "region.h" #include "surfaces.h" -#include "winding.h" /** \addtogroup qfbsp_region */ diff --git a/tools/qfbsp/source/solidbsp.c b/tools/qfbsp/source/solidbsp.c index d0ff65c96..365f9d0e8 100644 --- a/tools/qfbsp/source/solidbsp.c +++ b/tools/qfbsp/source/solidbsp.c @@ -37,7 +37,6 @@ static __attribute__ ((used)) const char rcsid[] = #include "draw.h" #include "solidbsp.h" #include "surfaces.h" -#include "winding.h" /** \addtogroup qfbsp_solidbsp */ diff --git a/tools/qfbsp/source/surfaces.c b/tools/qfbsp/source/surfaces.c index 95970ae3e..0879ff416 100644 --- a/tools/qfbsp/source/surfaces.c +++ b/tools/qfbsp/source/surfaces.c @@ -36,7 +36,6 @@ static __attribute__ ((used)) const char rcsid[] = #include "options.h" #include "region.h" #include "surfaces.h" -#include "winding.h" /** \addtogroup qfbsp_surface */ diff --git a/tools/qfbsp/source/tjunc.c b/tools/qfbsp/source/tjunc.c index 0a831d609..9f33159df 100644 --- a/tools/qfbsp/source/tjunc.c +++ b/tools/qfbsp/source/tjunc.c @@ -35,7 +35,6 @@ static __attribute__ ((used)) const char rcsid[] = #include "brush.h" #include "bsp5.h" #include "options.h" -#include "winding.h" #include "tjunc.h" /** \addtogroup qfbsp_tjunc From d61cb25a4479263088f3027c5957827db68d6079 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 15 Nov 2011 12:57:08 +0900 Subject: [PATCH 248/334] Add code to rebuild the bsp brushes. Names and locations of declarations are still up in the air, but things seem to be working assuming my test code is correct. --- include/QF/model.h | 1 + include/world.h | 18 ++++ libs/models/Makefile.am | 2 +- libs/models/portal.c | 181 ++++++++++++++++++++++++++++++++++++ libs/models/test/testclip.c | 164 +++++++++++++++++++++++++------- 5 files changed, 333 insertions(+), 33 deletions(-) create mode 100644 libs/models/portal.c diff --git a/include/QF/model.h b/include/QF/model.h index c0493f4d3..e5fa57602 100644 --- a/include/QF/model.h +++ b/include/QF/model.h @@ -202,6 +202,7 @@ typedef struct hull_s { int lastclipnode; vec3_t clip_mins; vec3_t clip_maxs; + struct nodeleaf_s *nodeleafs; } hull_t; // SPRITE MODELS ============================================================== diff --git a/include/world.h b/include/world.h index d3f1a5b08..0b9bf1b06 100644 --- a/include/world.h +++ b/include/world.h @@ -118,4 +118,22 @@ hull_t *SV_HullForEntity (struct edict_s *ent, const vec3_t mins, void MOD_TraceLine (hull_t *hull, int num, const vec3_t start, const vec3_t end, trace_t *trace); +typedef struct clipport_s { + int planenum; + struct clipport_s *next[2]; ///< front, back + struct clipleaf_s *leafs[2]; ///< front, back + struct winding_s *winding; +} clipport_t; + +typedef struct clipleaf_s { + clipport_t *portals; + int contents; +} clipleaf_t; + +typedef struct nodeleaf_s { + clipleaf_t *leafs[2]; ///< front, back. If null, node's child is a node +} nodeleaf_t; + +nodeleaf_t *MOD_BuildBrushes (hull_t *hull); + #endif // __world_h diff --git a/libs/models/Makefile.am b/libs/models/Makefile.am index 134b59909..acc54aef4 100644 --- a/libs/models/Makefile.am +++ b/libs/models/Makefile.am @@ -7,7 +7,7 @@ INCLUDES= -I$(top_srcdir)/include lib_LTLIBRARIES= libQFmodels.la @VID_MODEL_TARGETS@ EXTRA_LTLIBRARIES= libQFmodels_gl.la libQFmodels_sw.la -models_sources = clip_hull.c model.c trace.c winding.c +models_sources = clip_hull.c model.c portal.c trace.c winding.c libQFmodels_la_LDFLAGS= -version-info $(QUAKE_LIBRARY_VERSION_INFO) -no-undefined libQFmodels_la_LIBADD= brush/libbrush.la $(top_builddir)/libs/util/libQFutil.la diff --git a/libs/models/portal.c b/libs/models/portal.c new file mode 100644 index 000000000..21678d5ce --- /dev/null +++ b/libs/models/portal.c @@ -0,0 +1,181 @@ +/* + #FILENAME# + + #DESCRIPTION# + + Copyright (C) 2011 Bill Currie + + Author: Bill Currie + Date: 2011/11/14 + + 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: + + Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA + +*/ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +static __attribute__ ((used)) const char rcsid[] = "$Id$"; + +#include +#ifdef HAVE_STRING_H +#include +#endif +#ifdef HAVE_STRINGS_H +#include +#endif +#include + +#include "QF/model.h" +#include "QF/winding.h" + +#include "world.h" + +static clipleaf_t * +alloc_leaf (void) +{ + return calloc (1, sizeof (clipleaf_t)); +} + +static clipport_t * +alloc_portal (void) +{ + return calloc (1, sizeof (clipport_t)); +} + +static void +remove_portal (clipport_t *portal, clipleaf_t *leaf) +{ + clipport_t **p; + int side; + + for (p = &leaf->portals; *p; p = &(*p)->next[side]) { + side = (*p)->leafs[1] == leaf; + if (*p == portal) { + *p = portal->next[side]; + portal->next[side] = 0; + break; + } + } +} + +static void +add_portal (clipport_t *portal, clipleaf_t *front, clipleaf_t *back) +{ + portal->leafs[0] = front; + portal->next[0] = front->portals; + front->portals = portal; + + portal->leafs[1] = back; + portal->next[1] = back->portals; + back->portals = portal; +} + +static clipleaf_t * +carve_leaf (hull_t *hull, nodeleaf_t *nodeleafs, clipleaf_t *leaf, int num) +{ + mclipnode_t *node; + plane_t *plane; + winding_t *winding, *fw, *bw; + clipport_t *portal; + clipport_t *new_portal; + clipport_t *next_portal; + clipleaf_t *other_leaf; + clipleaf_t *new_leaf; + plane_t clipplane; + int side; + + if (num < 0) { + // we've hit a leaf. all done + leaf->contents = num; + return leaf; + } + node = hull->clipnodes + num; + plane = hull->planes + node->planenum; + + winding = BaseWindingForPlane (plane); + for (portal = leaf->portals; portal; portal = portal->next[side]) { + clipplane = hull->planes[portal->planenum]; + side = (portal->leafs[1] == leaf); + if (side) + PlaneFlip (&clipplane, &clipplane); + winding = ClipWinding (winding, &clipplane, true); + } + new_leaf = alloc_leaf (); + portal = leaf->portals; + leaf->portals = 0; + for (; portal; portal = next_portal) { + side = (portal->leafs[1] == leaf); + next_portal = portal->next[side]; + other_leaf = portal->leafs[!side]; + remove_portal (portal, other_leaf); + + DivideWinding (portal->winding, plane, &fw, &bw); + if (!fw) { + if (side) + add_portal (portal, other_leaf, new_leaf); + else + add_portal (portal, new_leaf, other_leaf); + continue; + } + if (!bw) { + if (side) + add_portal (portal, other_leaf, leaf); + else + add_portal (portal, leaf, other_leaf); + continue; + } + new_portal = alloc_portal (); + new_portal->planenum = portal->planenum; + new_portal->winding = bw; + FreeWinding (portal->winding); + portal->winding = fw; + + if (side) { + add_portal (portal, other_leaf, leaf); + add_portal (new_portal, other_leaf, new_leaf); + } else { + add_portal (portal, leaf, other_leaf); + add_portal (new_portal, new_leaf, other_leaf); + } + } + new_portal = alloc_portal (); + new_portal->planenum = node->planenum; + new_portal->winding = winding; + add_portal (new_portal, leaf, new_leaf); + + nodeleafs[num].leafs[0] = carve_leaf (hull, nodeleafs, leaf, + node->children[0]); + nodeleafs[num].leafs[1] = carve_leaf (hull, nodeleafs, new_leaf, + node->children[1]); + return 0; +} + +nodeleaf_t * +MOD_BuildBrushes (hull_t *hull) +{ + int numnodes = hull->lastclipnode + 1; + nodeleaf_t *nodeleafs; + clipleaf_t *root; // this will be carved into all the actual leafs + + nodeleafs = calloc (numnodes, sizeof (nodeleaf_t)); + root = alloc_leaf (); + carve_leaf (hull, nodeleafs, root, hull->firstclipnode); + return nodeleafs; +} diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index 97e5e282a..cbfeb4e34 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -275,6 +275,7 @@ typedef struct { qboolean startsolid; qboolean inopen; qboolean inwater; + int num_portals; } expect; } test_t; @@ -284,76 +285,76 @@ box_t player = { {16, 16, 28} }; test_t tests[] = { {"Point, Three parallel planes 1", &point, &hull_tpp1, - {-64, 0, 0}, { 64, 0, 0}, { 1, 1, 1, 0, 0}}, + {-64, 0, 0}, { 64, 0, 0}, { 1, 1, 1, 0, 0, 3}}, {"Point, Three parallel planes 1", &point, &hull_tpp1, - { 0, 0, 0}, { 40, 0, 0}, { 1, 0, 1, 1, 0}}, + { 0, 0, 0}, { 40, 0, 0}, { 1, 0, 1, 1, 0, 3}}, {"Point, Three parallel planes 1", &point, &hull_tpp1, - { 40, 0, 0}, {-88, 0, 0}, {0.0625, 0, 0, 1, 0}}, + { 40, 0, 0}, {-88, 0, 0}, {0.0625, 0, 0, 1, 0, 3}}, {"Point, Three parallel planes 1", &point, &hull_tpp1, - { 0, 0, 0}, { 64, 0, 0}, { 0.75, 0, 1, 1, 0}}, + { 0, 0, 0}, { 64, 0, 0}, { 0.75, 0, 1, 1, 0, 3}}, {"Point, Three parallel planes 1", &point, &hull_tpp1, - { 0, 0, 0}, { 0, 8, 0}, { 1, 1, 1, 0, 0}}, + { 0, 0, 0}, { 0, 8, 0}, { 1, 1, 1, 0, 0, 3}}, {"Point, Three parallel planes 1", &point, &hull_tpp1, - { 40, 0, 0}, { 40, 8, 0}, { 1, 0, 0, 1, 0}}, + { 40, 0, 0}, { 40, 8, 0}, { 1, 0, 0, 1, 0, 3}}, {"Point, Three parallel planes 2", &point, &hull_tpp2, - {-64, 0, 0}, { 64, 0, 0}, { 1, 1, 1, 0, 0}}, + {-64, 0, 0}, { 64, 0, 0}, { 1, 1, 1, 0, 0, 3}}, {"Point, Three parallel planes 2", &point, &hull_tpp2, - { 0, 0, 0}, { 40, 0, 0}, { 1, 0, 1, 1, 0}}, + { 0, 0, 0}, { 40, 0, 0}, { 1, 0, 1, 1, 0, 3}}, {"Point, Three parallel planes 2", &point, &hull_tpp2, - { 40, 0, 0}, {-88, 0, 0}, {0.0625, 0, 0, 1, 0}}, + { 40, 0, 0}, {-88, 0, 0}, {0.0625, 0, 0, 1, 0, 3}}, {"Point, Three parallel planes 2", &point, &hull_tpp2, - { 0, 0, 0}, { 64, 0, 0}, { 0.75, 0, 1, 1, 0}}, + { 0, 0, 0}, { 64, 0, 0}, { 0.75, 0, 1, 1, 0, 3}}, {"Point, Three parallel planes with water", &point, &hull_tppw, - {-64, 0, 0}, { 64, 0, 0}, { 0.875, 0, 1, 1, 1}}, + {-64, 0, 0}, { 64, 0, 0}, { 0.875, 0, 1, 1, 1, 3}}, {"Point, Three parallel planes with water", &point, &hull_tppw, - { 0, 0, 0}, { 40, 0, 0}, { 1, 0, 0, 1, 1}}, + { 0, 0, 0}, { 40, 0, 0}, { 1, 0, 0, 1, 1, 3}}, {"Point, Three parallel planes with water", &point, &hull_tppw, - { 40, 0, 0}, {-88, 0, 0}, {0.5625, 0, 0, 1, 1}}, + { 40, 0, 0}, {-88, 0, 0}, {0.5625, 0, 0, 1, 1, 3}}, {"Point, Three parallel planes with water", &point, &hull_tppw, - { 0, 0, 0}, { 64, 0, 0}, { 0.75, 0, 0, 1, 1}}, + { 0, 0, 0}, { 64, 0, 0}, { 0.75, 0, 0, 1, 1, 3}}, {"Point, Three parallel planes with water", &point, &hull_tppw, - { 0, 0, 0}, { 0, 8, 0}, { 1, 0, 0, 1, 0}}, + { 0, 0, 0}, { 0, 8, 0}, { 1, 0, 0, 1, 0, 3}}, {"Point, Three parallel planes with water", &point, &hull_tppw, - { 40, 0, 0}, { 40, 8, 0}, { 1, 0, 0, 0, 1}}, + { 40, 0, 0}, { 40, 8, 0}, { 1, 0, 0, 0, 1, 3}}, {"Point, Three parallel planes with water", &point, &hull_tppw, - { 0, 0, 0}, { 40, 0, 0}, { 1, 0, 0, 1, 1}}, + { 0, 0, 0}, { 40, 0, 0}, { 1, 0, 0, 1, 1, 3}}, {"Point, Step 1", &point, &hull_step1, - { -16, 0, 8}, {16, 0, 24}, { 0.5, 0, 0, 1, 0}}, + { -16, 0, 8}, {16, 0, 24}, { 0.5, 0, 0, 1, 0, 5}}, {"Box, Step 1", &box, &hull_step1, - { -16, 0, 8}, {16, 0, 24}, { 0.25, 0, 0, 1, 0}}, + { -16, 0, 8}, {16, 0, 24}, { 0.25, 0, 0, 1, 0, 5}}, {"Box, Step 1", &box, &hull_step1, - { -16, 0, 8}, {16, 0, 40}, { 0.25, 0, 0, 1, 0}}, + { -16, 0, 8}, {16, 0, 40}, { 0.25, 0, 0, 1, 0, 5}}, {"Box, Step 1", &box, &hull_step1, - { -16, 0, 8}, {16, 0, 135}, { 0.25, 0, 0, 1, 0}}, + { -16, 0, 8}, {16, 0, 135}, { 0.25, 0, 0, 1, 0, 5}}, // 136 is a corner case caused by back/front side issues and 0 {"Box, Step 1", &box, &hull_step1, - { -16, 0, 8}, {16, 0, 137}, { 1, 0, 0, 1, 0}}, + { -16, 0, 8}, {16, 0, 137}, { 1, 0, 0, 1, 0, 5}}, {"Point, Covered Step", &point, &hull_covered_step, - { -24, 0, 8}, {-24, 0, 72}, { 0.5, 0, 0, 1, 0}}, + { -24, 0, 8}, {-24, 0, 72}, { 0.5, 0, 0, 1, 0, 9}}, {"Box, Covered Step", &box, &hull_covered_step, - { -32, 0, 8}, {-32, 0, 72}, { 0.375, 0, 0, 1, 0}}, + { -32, 0, 8}, {-32, 0, 72}, { 0.375, 0, 0, 1, 0, 9}}, {"Box, Covered Step", &box, &hull_covered_step, - { -24, 0, 8}, {-24, 0, 72}, { 0.375, 0, 0, 1, 0}}, + { -24, 0, 8}, {-24, 0, 72}, { 0.375, 0, 0, 1, 0, 9}}, {"Box, Covered Step", &box, &hull_covered_step, - { -25, 0, 8}, {7, 0, 72}, { 0.375, 0, 0, 1, 0}}, + { -25, 0, 8}, {7, 0, 72}, { 0.375, 0, 0, 1, 0, 9}}, {"Box, Covered Step", &box, &hull_covered_step, - { -8, 0, 40}, {-16, 0, 40}, { 0.5, 0, 0, 1, 0}}, + { -8, 0, 40}, {-16, 0, 40}, { 0.5, 0, 0, 1, 0, 9}}, {"Box, Covered Step", &box, &hull_covered_step, - { -17, 0, 8}, {-1, 0, 72}, { 1, 0, 0, 1, 0}}, + { -17, 0, 8}, {-1, 0, 72}, { 1, 0, 0, 1, 0, 9}}, {"Box, Covered Step", &box, &hull_covered_step, - { -8, 0, 40}, {8, 0, 72}, { 1, 0, 0, 1, 0}}, + { -8, 0, 40}, {8, 0, 72}, { 1, 0, 0, 1, 0, 9}}, {"Box, Step 2", &box, &hull_step2, - { 0, 0, 64}, {0, 0, 0}, { 0.375, 0, 0, 1, 0}}, + { 0, 0, 64}, {0, 0, 0}, { 0.375, 0, 0, 1, 0, 5}}, {"Box, Step 3", &box, &hull_step3, - { 0, 0, 64}, {0, 0, 0}, { 0.375, 0, 0, 1, 0}}, + { 0, 0, 64}, {0, 0, 0}, { 0.375, 0, 0, 1, 0, 5}}, {"Box, Ramp", &box, &hull_ramp, - { 0, 0, 16}, {0, 0, 0}, { 0.5, 0, 0, 1, 0}}, + { 0, 0, 16}, {0, 0, 0}, { 0.5, 0, 0, 1, 0, 4}}, }; #define num_tests (sizeof (tests) / sizeof (tests[0])) @@ -378,6 +379,30 @@ do_trace (box_t *box, hull_t *hull, vec3_t start, vec3_t end) return trace; } +typedef struct portlist_s { + struct portlist_s *next; + clipport_t *portal; +} portlist_t; + +static portlist_t * +collect_portals (clipport_t *portal, portlist_t *portal_list) +{ + portlist_t *p; + + if (!portal) + return portal_list; + for (p = portal_list; p; p = p->next) + if (p->portal == portal) + return portal_list; + p = malloc (sizeof (portlist_t)); + p->portal = portal; + p->next = portal_list; + portal_list = p; + portal_list = collect_portals (portal->next[0], portal_list); + portal_list = collect_portals (portal->next[1], portal_list); + return portal_list; +} + static int run_test (test_t *test) { @@ -387,6 +412,81 @@ run_test (test_t *test) char *expect; char *got; static int output = 0; + portlist_t *portal_list = 0; + + if (!test->hull->nodeleafs) { + hull_t *hull = test->hull; + int i, j; + portlist_t *p; + clipport_t *portal; + clipleaf_t *leaf; + int side; + + hull->nodeleafs = MOD_BuildBrushes (hull); + for (i = hull->firstclipnode; i <= hull->lastclipnode; i++) { + for (j = 0; j < 2; j++) { + if (((hull->clipnodes[i].children[j] >= 0) + != (!hull->nodeleafs[i].leafs[j])) + || (hull->nodeleafs[i].leafs[j] + && (hull->nodeleafs[i].leafs[j]->contents + != hull->clipnodes[i].children[j]))) { + printf ("bad nodeleaf %d %d\n", i, j); + res = 1; + } + } + if (hull->nodeleafs[i].leafs[0] + && (hull->nodeleafs[i].leafs[0] + == hull->nodeleafs[i].leafs[1])) { + printf ("bad nodeleaf %d %d\n", i, j); + res = 1; + } + } + if (res) + goto nodeleaf_bail; + for (i = hull->firstclipnode; i <= hull->lastclipnode; i++) { + for (j = 0; j < 2; j++) { + leaf = hull->nodeleafs[i].leafs[j]; + if (!leaf) + continue; + portal_list = collect_portals (leaf->portals, portal_list); + } + } + for (i = 0, p = portal_list; p; i++, p = p->next) + ; + if (i != test->expect.num_portals) { + res = 1; + printf ("bad portal count: %d %d\n", test->expect.num_portals, i); + goto nodeleaf_bail; + } + for (p = portal_list; p; p = p->next) { + for (j = 0; j < 2; j++) { + int found = 0; + + leaf = p->portal->leafs[j]; + for (portal = leaf->portals; portal; + portal = portal->next[side]) { + //printf("%p %d %p %p %p\n", p, j, leaf, portal, p->portal); + side = portal->leafs[1] == leaf; + if (!side && portal->leafs[0] != leaf) { + printf ("mislinked portal\n"); + res = 1; + } + if (portal == p->portal) + found = 1; + } + if (!found) { + printf ("portal unreachable from leaf\n"); + res = 1; + } + } + } + } +nodeleaf_bail: + while (portal_list) { + portlist_t *t = portal_list; + portal_list = portal_list->next; + free (t); + } VectorSubtract (test->end, test->start, end); VectorMultAdd (test->start, test->expect.frac, end, end); From e41da2f57937fb4605f98c5c6f4b6932360879ed Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 15 Nov 2011 13:26:13 +0900 Subject: [PATCH 249/334] Store the start fraction and position in the right stack slot. Oops. Yay, valgrind. --- libs/models/trace.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libs/models/trace.c b/libs/models/trace.c index 671d7a22d..5f7be88b2 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -237,16 +237,17 @@ MOD_TraceLine (hull_t *hull, int num, frac[1] = bound (0, frac[1], 1); } + VectorSubtract (end, start, dist); + tstack->num = num; tstack->side = side; tstack->plane = plane; VectorCopy (end, tstack->end); - tstack++; - - VectorSubtract (end, start, dist); - VectorMultAdd (start, frac[side], dist, end); VectorMultAdd (start, frac[side ^ 1], dist, tstack->start); tstack->start_frac = frac[side ^ 1]; + tstack++; + + VectorMultAdd (start, frac[side], dist, end); num = node->children[side]; } From 662c04dfdc66188973b46cc2aa295100832c11d9 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 15 Nov 2011 20:21:08 +0900 Subject: [PATCH 250/334] Add a function to obtain the unit vectors of a winding's edges. --- include/QF/winding.h | 9 +++++++++ libs/models/winding.c | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/include/QF/winding.h b/include/QF/winding.h index f1a779003..ca116dc20 100644 --- a/include/QF/winding.h +++ b/include/QF/winding.h @@ -86,6 +86,15 @@ winding_t *CopyWinding (const winding_t *w); */ winding_t *CopyWindingReverse (const winding_t *w); +/** Create a new "winding" that holds the unit vectors of the edges of the + given winding. + + \param w The winding to convert. + \return The "winding" holding the unit vectors. + \note It is the caller's responsibiltiy to free the new winding. +*/ +winding_t *WindingVectors (const winding_t *w); + /** Clip the winding to the plain. The new winding will be the part of the input winding that is on the diff --git a/libs/models/winding.c b/libs/models/winding.c index c5b06cb3a..e75be9731 100644 --- a/libs/models/winding.c +++ b/libs/models/winding.c @@ -140,6 +140,24 @@ CopyWindingReverse (const winding_t *w) return c; } +winding_t * +WindingVectors (const winding_t *w) +{ + int i; + size_t size; + winding_t *c; + + size = (size_t) (uintptr_t) &((winding_t *) 0)->points[w->numpoints]; + c = malloc (size); + c->numpoints = w->numpoints; + for (i = 0; i < w->numpoints; i++) { + VectorSubtract (w->points[(i + 1) % w->numpoints], w->points[i], + c->points[i]); + VectorNormalize (c->points[i]); + } + return c; +} + winding_t * ClipWinding (winding_t *in, plane_t *split, qboolean keepon) { From 297275e3de7baed90bc2c9e6c26f55349202cd29 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 15 Nov 2011 20:21:49 +0900 Subject: [PATCH 251/334] Create edge information for the portals. --- include/world.h | 1 + libs/models/portal.c | 16 ++++++++++++++++ libs/models/test/testclip.c | 10 ++++++++-- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/include/world.h b/include/world.h index 0b9bf1b06..81d053833 100644 --- a/include/world.h +++ b/include/world.h @@ -123,6 +123,7 @@ typedef struct clipport_s { struct clipport_s *next[2]; ///< front, back struct clipleaf_s *leafs[2]; ///< front, back struct winding_s *winding; + struct winding_s *edges; ///< unit vectors along edges } clipport_t; typedef struct clipleaf_s { diff --git a/libs/models/portal.c b/libs/models/portal.c index 21678d5ce..f6d312ff9 100644 --- a/libs/models/portal.c +++ b/libs/models/portal.c @@ -171,11 +171,27 @@ nodeleaf_t * MOD_BuildBrushes (hull_t *hull) { int numnodes = hull->lastclipnode + 1; + int i, j, side; nodeleaf_t *nodeleafs; clipleaf_t *root; // this will be carved into all the actual leafs nodeleafs = calloc (numnodes, sizeof (nodeleaf_t)); root = alloc_leaf (); carve_leaf (hull, nodeleafs, root, hull->firstclipnode); + for (i = 0; i < numnodes; i++) { + for (j = 0; j < 2; j++) { + clipleaf_t *leaf = nodeleafs[i].leafs[j]; + clipport_t *p; + + if (!leaf) + continue; + for (p = leaf->portals; p; p = p->next[side]) { + side = p->leafs[1] == leaf; + if (p->edges) + continue; + p->edges = WindingVectors (p->winding); + } + } + } return nodeleafs; } diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index cbfeb4e34..c9b89276d 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -451,8 +451,14 @@ run_test (test_t *test) portal_list = collect_portals (leaf->portals, portal_list); } } - for (i = 0, p = portal_list; p; i++, p = p->next) - ; + for (i = 0, p = portal_list; p; i++, p = p->next) { + if (!p->portal->winding || !p->portal->edges) { + res = 1; + printf ("portal with missing vertex/edge information\n"); + } + } + if (res) + goto nodeleaf_bail; if (i != test->expect.num_portals) { res = 1; printf ("bad portal count: %d %d\n", test->expect.num_portals, i); From fd5aee1d5e99fb2a436a84b656cdacd64dc84613 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 20 Nov 2011 09:33:57 +0900 Subject: [PATCH 252/334] Use the portals to check leaf validity. If the trace hits a portal on the plane that brought us to the leaf, then we actually are in the leaf (otherwise, we shouldn't be here and thus should ignore the leaf). At least, that's my thinking. Many point tests fail (but they're really using box clipping with a zero sized box) and two box tests fail. --- libs/models/trace.c | 79 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 72 insertions(+), 7 deletions(-) diff --git a/libs/models/trace.c b/libs/models/trace.c index 5f7be88b2..4dddb0984 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -43,6 +43,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "QF/model.h" #include "QF/sys.h" +#include "QF/winding.h" #include "compat.h" #include "world.h" @@ -90,6 +91,48 @@ calc_offset (trace_t *trace, plane_t *plane) return d; } +static int +check_in_leaf (hull_t *hull, trace_t *trace, clipleaf_t *leaf, plane_t *plane, + const vec3_t vel, const vec3_t org) +{ + clipport_t *portal; + int side; + int miss = 0; + int i; + int planenum; + plane_t cutplane; + vec_t offset, dist, v_n; + vec_t *point, *edge; + + planenum = plane - hull->planes; + cutplane.type = 3; // generic plane + v_n = DotProduct (vel, plane->normal); + + for (portal = leaf->portals; portal; portal = portal->next[side]) { + side = portal->leafs[1] == leaf; + if (portal->planenum != planenum) + continue; + for (i = 0; !miss && i < portal->winding->numpoints; i++) { + point = portal->winding->points[i]; + edge = portal->edges->points[i]; + // so long as the plane distance and offset are calculated using + // the same normal vector, the normal vector length does not + // matter. + CrossProduct (vel, edge, cutplane.normal); + cutplane.dist = DotProduct (vel, point); + dist = PlaneDiff (org, &cutplane); + offset = calc_offset (trace, &cutplane); + if (v_n >= 0) + miss = dist >= offset; + else + miss = dist <= -offset; + } + if (!miss) + return 1; + } + return 0; +} + static inline void calc_impact (trace_t *trace, const vec3_t start, const vec3_t end, plane_t *plane) @@ -129,21 +172,26 @@ MOD_TraceLine (hull_t *hull, int num, trace_t *trace) { vec_t start_dist, end_dist, frac[2], offset; - vec3_t start, end, dist; + vec3_t start, end, dist, vel; int side; qboolean seen_empty, seen_solid; tracestack_t *tstack; tracestack_t tracestack[256]; mclipnode_t *node; plane_t *plane, *split_plane; + clipleaf_t *leaf; VectorCopy (start_point, start); VectorCopy (end_point, end); + VectorSubtract (end, start, vel); + VectorNormalize (vel); tstack = tracestack; seen_empty = 0; seen_solid = 0; split_plane = 0; + leaf = 0; + plane = 0; trace->allsolid = true; trace->startsolid = false; @@ -153,7 +201,14 @@ MOD_TraceLine (hull_t *hull, int num, while (1) { while (num < 0) { - if (num == CONTENTS_SOLID) { + // it's not possible to not be in the leaf when doing a point trace + // if leaf is null, assume we're in the leaf + // if plane is null, the trace did not cross the last node plane + int in_leaf = (trace->type == tr_point || !leaf || !plane + || check_in_leaf (hull, trace, leaf, + plane, + vel, start)); + if (in_leaf && num == CONTENTS_SOLID) { if (!seen_empty && !seen_solid) { // this is the first leaf visited, thus the start leaf trace->startsolid = seen_solid = true; @@ -170,7 +225,7 @@ MOD_TraceLine (hull_t *hull, int num, if (trace->type == tr_point) return; } - } else { + } else if (in_leaf) { seen_empty = true; trace->allsolid = false; if (num == CONTENTS_EMPTY) @@ -195,6 +250,7 @@ MOD_TraceLine (hull_t *hull, int num, side = tstack->side; split_plane = tstack->plane; + leaf = hull->nodeleafs[tstack->num].leafs[side ^ 1]; num = hull->clipnodes[tstack->num].children[side ^ 1]; } @@ -207,11 +263,17 @@ MOD_TraceLine (hull_t *hull, int num, if (start_dist >= offset && end_dist >= offset) { // entirely in front of the plane + plane = 0; + leaf = hull->nodeleafs[num].leafs[0]; num = node->children[0]; continue; } + //FIXME non-zero offset lets the object touch the plane but still be + //behind the plane if (start_dist < -offset && end_dist < -offset) { // entirely behind the plane + plane = 0; + leaf = hull->nodeleafs[num].leafs[1]; num = node->children[1]; continue; } @@ -220,17 +282,19 @@ MOD_TraceLine (hull_t *hull, int num, if (start_dist == end_dist) { // avoid division by zero (non-point clip only) - // since we need to check both sides anyway, it doesn't matter - // which side we start with, so long as the fractions are - // correct. + // since neither side is forward and we need to check both sides + // anyway, it doesn't matter which side we start with, so long as + // the fractions are correct. side = 0; frac[0] = 1; frac[1] = 0; } else { + // choose the side such that we are always moving forward through + // the map + side = start_dist < end_dist; // if either start or end have the box straddling the plane, then // frac will be appropriately clipped to 0 and 1, otherwise, frac // will be inside that range - side = start_dist < end_dist; frac[0] = (start_dist + offset) / (start_dist - end_dist); frac[1] = (start_dist - offset) / (start_dist - end_dist); frac[0] = bound (0, frac[0], 1); @@ -249,6 +313,7 @@ MOD_TraceLine (hull_t *hull, int num, VectorMultAdd (start, frac[side], dist, end); + leaf = hull->nodeleafs[num].leafs[side]; num = node->children[side]; } } From cde0bbb807daf18627dccd996bc56095408159b3 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 20 Nov 2011 12:02:56 +0900 Subject: [PATCH 253/334] For now, don't use box clipping for point traces. Until I figure out how I want to handle zero sized boxes, don't test them. --- libs/models/test/testclip.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index c9b89276d..264b57ec7 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -373,7 +373,8 @@ do_trace (box_t *box, hull_t *hull, vec3_t start, vec3_t end) trace.inwater = false; trace.fraction = 1; VectorCopy (box->extents, trace.extents); - trace.type = tr_box; + // FIXME specify tract type in test spec + trace.type = box == &point ? tr_point : tr_box; VectorCopy (end, trace.endpos); MOD_TraceLine (hull, 0, start, end, &trace); return trace; From 7b59eaf0cd88c3c2e388189972a4d791ceb913bf Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 20 Nov 2011 14:14:42 +0900 Subject: [PATCH 254/334] Use the correct vector for the plane distance. Oops :) --- libs/models/trace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/models/trace.c b/libs/models/trace.c index 4dddb0984..aa3a684a9 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -119,7 +119,7 @@ check_in_leaf (hull_t *hull, trace_t *trace, clipleaf_t *leaf, plane_t *plane, // the same normal vector, the normal vector length does not // matter. CrossProduct (vel, edge, cutplane.normal); - cutplane.dist = DotProduct (vel, point); + cutplane.dist = DotProduct (cutplane.normal, point); dist = PlaneDiff (org, &cutplane); offset = calc_offset (trace, &cutplane); if (v_n >= 0) From e3d8394b7a5ef7c270b9500e7f28277c77c2258a Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 20 Nov 2011 14:18:05 +0900 Subject: [PATCH 255/334] Use the split_plane for the in-leaf test. This seems to work better (all previously working tests pass again), but the target test is still broken. --- libs/models/trace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/models/trace.c b/libs/models/trace.c index aa3a684a9..bef5947a6 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -204,9 +204,9 @@ MOD_TraceLine (hull_t *hull, int num, // it's not possible to not be in the leaf when doing a point trace // if leaf is null, assume we're in the leaf // if plane is null, the trace did not cross the last node plane - int in_leaf = (trace->type == tr_point || !leaf || !plane + int in_leaf = (trace->type == tr_point || !leaf || !split_plane || check_in_leaf (hull, trace, leaf, - plane, + split_plane, vel, start)); if (in_leaf && num == CONTENTS_SOLID) { if (!seen_empty && !seen_solid) { From 73b93ffd74bebea1e576bf4a44e7aa1316c7f1ad Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 20 Nov 2011 14:56:07 +0900 Subject: [PATCH 256/334] Clean up the in_leaf test line. --- libs/models/trace.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libs/models/trace.c b/libs/models/trace.c index bef5947a6..8b953e73c 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -204,10 +204,10 @@ MOD_TraceLine (hull_t *hull, int num, // it's not possible to not be in the leaf when doing a point trace // if leaf is null, assume we're in the leaf // if plane is null, the trace did not cross the last node plane - int in_leaf = (trace->type == tr_point || !leaf || !split_plane - || check_in_leaf (hull, trace, leaf, - split_plane, - vel, start)); + int in_leaf = 1; + if (trace->type != tr_point && leaf && split_plane) + in_leaf = check_in_leaf (hull, trace, leaf, split_plane, + vel, start); if (in_leaf && num == CONTENTS_SOLID) { if (!seen_empty && !seen_solid) { // this is the first leaf visited, thus the start leaf From 4044f9d8e2aaa54ffad668cb77560b975eea893e Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 20 Nov 2011 20:11:44 +0900 Subject: [PATCH 257/334] Shrink the default winding size. The minimum number of points on a valid winding is 3, and the most common will be 4 (especially useful for static structures). --- include/QF/winding.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/QF/winding.h b/include/QF/winding.h index ca116dc20..0696aa678 100644 --- a/include/QF/winding.h +++ b/include/QF/winding.h @@ -35,7 +35,7 @@ struct plane_s; typedef struct winding_s { int numpoints; ///< The number of points in the winding - vec3_t points[3]; ///< variable sized, never less than 3 + vec3_t points[4]; ///< variable sized, never less than 3 } winding_t; /** Create a very large four-point winding with all point on the plane. From 3a386293fc42e7e73d33fca1dba50aee051684a9 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 26 Nov 2011 11:31:15 +0900 Subject: [PATCH 258/334] Add Vector3Scale macro. Vector3Scale individually scales the components of one vector by the components of another vector. --- include/QF/mathlib.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/QF/mathlib.h b/include/QF/mathlib.h index 894a36eb9..387c54991 100644 --- a/include/QF/mathlib.h +++ b/include/QF/mathlib.h @@ -95,6 +95,12 @@ extern const vec_t * const quat_origin; (c)[1] = (a)[1] * (b); \ (c)[2] = (a)[2] * (b); \ } while (0) +#define Vector3Scale(a,b,c) \ + do { \ + (c)[0] = (a)[0] * (b)[0]; \ + (c)[1] = (a)[1] * (b)[1]; \ + (c)[2] = (a)[2] * (b)[2]; \ + } while (0) #define VectorCompare(x, y) \ (((x)[0] == (y)[0]) && ((x)[1] == (y)[1]) && ((x)[2] == (y)[2])) From 750b5ba0edea3f10fb4245be9a881ee2976b89ca Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 27 Nov 2011 14:19:05 +0900 Subject: [PATCH 259/334] Be a little more lenient with float comparisons. Unfortunately, Pythagorus and binary don't play well together, so rounding errors are inevetible when testing with a slope. However, 1e-6 seems to be a good epsilon (printf's %g hides it nicely :). --- libs/models/test/testclip.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index 264b57ec7..8efc58344 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -15,6 +15,13 @@ # include "../trace.c" #endif +#define FloatCompare(a, b) (fabs (a - b) < 1e-6) +#undef VectorCompare +#define VectorCompare(x, y) \ + (FloatCompare (x[0], y[0]) && FloatCompare (x[1], y[1]) \ + && FloatCompare (x[2], y[2])) + + // 0,0 // |\ . // |s\ . @@ -515,7 +522,7 @@ nodeleaf_bail: trace.allsolid, trace.startsolid, trace.inopen, trace.inwater); if (VectorCompare (end, trace.endpos) - && test->expect.frac == trace.fraction + && FloatCompare (test->expect.frac, trace.fraction) && test->expect.allsolid == trace.allsolid && test->expect.startsolid == trace.startsolid && test->expect.inopen == trace.inopen From 174f381125bfaeecfe79698721985015e271f462 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 27 Nov 2011 14:22:32 +0900 Subject: [PATCH 260/334] Add some more tests for the ramp. These tests pass, but show the basic polygon testing working (just not the collision handling and thus fraction determination). --- libs/models/test/testclip.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index 8efc58344..f0f1b154f 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -362,6 +362,10 @@ test_t tests[] = { {"Box, Ramp", &box, &hull_ramp, { 0, 0, 16}, {0, 0, 0}, { 0.5, 0, 0, 1, 0, 4}}, + {"Box, Ramp", &box, &hull_ramp, + {-16, 0, 8}, {16, 0, 8}, { 1, 0, 0, 1, 0, 4}}, + {"Box, Ramp", &box, &hull_ramp, + {-16, 0, 5}, {16, 0, 5}, { 0.125, 0, 0, 1, 0, 4}}, }; #define num_tests (sizeof (tests) / sizeof (tests[0])) From 5ee552ea5ba69b945a2e34c034b0bd4a51dddf2f Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 27 Nov 2011 17:41:32 +0900 Subject: [PATCH 261/334] Don't normalize the portal edge vectors. This simplifies the collision handling code. --- include/QF/winding.h | 5 +++-- libs/models/portal.c | 2 +- libs/models/winding.c | 5 +++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/include/QF/winding.h b/include/QF/winding.h index 0696aa678..a467b2daa 100644 --- a/include/QF/winding.h +++ b/include/QF/winding.h @@ -90,10 +90,11 @@ winding_t *CopyWindingReverse (const winding_t *w); given winding. \param w The winding to convert. - \return The "winding" holding the unit vectors. + \param unit If true, normalize the vectors. + \return The "winding" holding the (unit) vectors. \note It is the caller's responsibiltiy to free the new winding. */ -winding_t *WindingVectors (const winding_t *w); +winding_t *WindingVectors (const winding_t *w, int unit); /** Clip the winding to the plain. diff --git a/libs/models/portal.c b/libs/models/portal.c index f6d312ff9..d7170b0d1 100644 --- a/libs/models/portal.c +++ b/libs/models/portal.c @@ -189,7 +189,7 @@ MOD_BuildBrushes (hull_t *hull) side = p->leafs[1] == leaf; if (p->edges) continue; - p->edges = WindingVectors (p->winding); + p->edges = WindingVectors (p->winding, 0); } } } diff --git a/libs/models/winding.c b/libs/models/winding.c index e75be9731..455707a36 100644 --- a/libs/models/winding.c +++ b/libs/models/winding.c @@ -141,7 +141,7 @@ CopyWindingReverse (const winding_t *w) } winding_t * -WindingVectors (const winding_t *w) +WindingVectors (const winding_t *w, int unit) { int i; size_t size; @@ -153,7 +153,8 @@ WindingVectors (const winding_t *w) for (i = 0; i < w->numpoints; i++) { VectorSubtract (w->points[(i + 1) % w->numpoints], w->points[i], c->points[i]); - VectorNormalize (c->points[i]); + if (unit) + VectorNormalize (c->points[i]); } return c; } From 8fc99566abaa55b1271f2be716769aa1337aceb6 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 27 Nov 2011 18:50:57 +0900 Subject: [PATCH 262/334] Add code to clip the motion of the box to the leaf's portals. Unfortunately, something is broken (all box tests fail due to 0 fraction). --- libs/models/trace.c | 277 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 274 insertions(+), 3 deletions(-) diff --git a/libs/models/trace.c b/libs/models/trace.c index 8b953e73c..238b9381e 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -133,9 +133,232 @@ check_in_leaf (hull_t *hull, trace_t *trace, clipleaf_t *leaf, plane_t *plane, return 0; } +typedef struct { + plane_t planes[3]; + winding_t points[3]; + winding_t edges[3]; + clipport_t portals[3]; +} clipbox_t; + +/** Initialize the clipbox representing the faces that might hit the portal. + + When a box is moving, at most three of its faces might hit the portal. + Those faces all face such that the dot product of their normal and the + box's velocity is positive (ie, n.v > 0). When the motion is in an axial + plane, only two faces might hit. For axial motion, only one face. + + The faces are set up such that the first point of each winding is the + leading corner of the box, and the edges are set up such that testing + only the first three edges of each winding covers all nine edges (ie, + the forth edge of one face is the reverse of the first edge of the next + face). + + The windings are clockwise when looking down the face's normal (ie, when + looking at the front of the face). +*/ +static void +init_box (const trace_t *trace, clipbox_t *box, const vec3_t vel) +{ + vec3_t p; + int u[3]; + int i, j, k; + vec_t s[2] = {1, -1}; + + //FIXME rotated box + for (i = 0; i < 3; i++) + u[i] = (vel[i] >= 0 ? 1 : -1); + Vector3Scale (u, trace->extents, p); + for (i = 0; i < 3; i++) { + box->portals[i].planenum = i; + box->portals[i].next[0] = 0; + box->portals[i].next[0] = 0; + box->portals[i].leafs[0] = 0; + box->portals[i].leafs[0] = 0; + box->portals[i].winding = &box->points[i]; + box->portals[i].edges = &box->edges[i]; + + VectorZero (box->planes[i].normal); + box->planes[i].normal[i] = u[i]; + box->planes[i].dist = DotProduct (p, box->planes[i].normal); + box->planes[i].type = i; + + box->points[i].numpoints = 4; + box->edges[i].numpoints = 4; + VectorCopy (u, box->points[i].points[0]); + VectorZero (box->edges[i].points[0]); + j = (i + (u[0]*u[1]*u[2] + 3) / 2) % 3; + box->edges[i].points[0][j] = -u[j]; + for (j = 1; j < 4; j++) { + box->points[i].points[j][i] = box->points[i].points[j - 1][i]; + box->edges[i].points[j][i] = box->edges[i].points[j - 1][i]; + for (k = 0; k < 2; k++) { + int a, b; + a = (i + 1 + k) % 3; + b = (i + 2 - k) % 3; + box->points[i].points[j][a] + = s[k] * u[i] * box->points[i].points[j - 1][b]; + box->edges[i].points[j][a] + = s[k] * u[i] * box->edges[i].points[j - 1][b]; + } + Vector3Scale (box->points[i].points[j - 1], trace->extents, + box->points[i].points[j - 1]); + } + Vector3Scale (box->points[i].points[3], trace->extents, + box->points[i].points[3]); + } +} + +static vec_t +edge_portal_dist (const plane_t *plane, const clipport_t *portal, + const vec3_t p1, const vec3_t p2, const vec3_t vel) +{ + int i; + winding_t *winding = portal->winding; + winding_t *edges = portal->edges; + + // check for edge point hitting portal face + { + vec_t t1, t2, vn; + + vn = DotProduct (vel, plane->normal); + t1 = PlaneDiff (p1, plane); + t2 = PlaneDiff (p2, plane); + // ensure p1 is the closest point to the plane + if ((0 < t1 && t1 > t2) + || (0 > t1 && t1 < t2)) { + // p2 is closer to the plane, so swap the points and times + const vec_t *r = p2; + vec_t t = t2; + t2 = t1; t1 = t; + p2 = p1; p1 = r; + } + if (vn * t1 > 0) { + // the edge is travelling away from the portal's plane + return 1; + } + // if t1 * t2 < 0, the points straddle the portal's plane and the + // nearest point test can be skipped + if (vn && t1 * t2 > 0) { //FIXME epsilon + vec3_t x, c; + vec3_t imp; + + if (t1 >= vn) { + // the edge doesn't make it as far as the portal's plane + return 1; + } + VectorMultSub (p1, t1 / vn, vel, imp); + for (i = 0; i < winding->numpoints; i++) { + VectorSubtract (imp, winding->points[i], x); + CrossProduct (x, edges->points[i], c); + if (DotProduct (c, plane->normal) >= 0) + break; // miss + } + if (i == winding->numpoints) { + // the closer end of the edge hit the portal, so t1/vn is the + // fraction + return t1 / vn; + } + // the closer end of the edge missed the portal, check the farther + // end, but only with this portal edge. + VectorMultSub (p2, t2 / vn, vel, imp); + VectorSubtract (imp, winding->points[i], x); + CrossProduct (x, edges->points[i], c); + if (DotProduct (c, plane->normal) >= 0) { + // both impacts are on the outside of this portal edge, so the + // edge being tested misses the portal + return 1; + } + // the two impact points are on both sides of a portal edge, so the + // edge being tested might hit a portal edge rather than the portal + // face + } + } + { + vec3_t e; + vec_t frac = 1.0; + vec_t ee; + plane_t ep; + + // set up the plane through which the edge travels + VectorSubtract (p2, p1, e); + ee = DotProduct (e, e); + CrossProduct (e, vel, ep.normal); + ep.dist = DotProduct (p1, ep.normal); + for (i = 0; i < winding->numpoints; i++) { + vec_t t, te, vn; + const vec_t *r = winding->points[i]; + const vec_t *v = edges->points[i]; + vec3_t x, y, z; + + vn = DotProduct (v, ep.normal); + if (!vn) // FIXME epsilon + continue; // portal edge is parallel to the plane + t = PlaneDiff (r, &ep); + if (t < 0 || t > vn) + continue; // portal edge does not reach the plane + // impact point of portal edge with the plane + VectorMultSub (r, t / vn, v, x); + // project the impact point back to the edge along the velocity + VectorSubtract (x, p1, y); + t = DotProduct (y, vel) / DotProduct (vel, vel); + VectorMultSub (x, t, vel, y); + if (t >= frac) + continue; // this is not the nearest edge pair + // check projected impact point's position along the edge + VectorSubtract (y, p1, z); + te = DotProduct (z, e); + if (te < 0 || te > ee) + continue; // the edge misses the portal edge + // the edges hit, and they are the closes edge pair so far + frac = t; + } + return frac; + } +} + +static vec_t +box_portal_dist (const hull_t *hull, const clipport_t *portal, + const clipbox_t *box, const vec3_t start, const vec3_t vel) +{ + vec3_t nvel; + plane_t *plane = hull->planes + portal->planenum; + int i, j; + vec_t frac, t; + vec3_t p1, p2; + + for (i = 0; i < 3; i++) { + // all faces on box have 4 points (and edges), but we need test only + // three on each face + for (j = 0; j < 3; j++) { + VectorAdd (box->points->points[j], start, p1); + VectorAdd (box->points->points[j + 1], start, p2); + t = edge_portal_dist (plane, portal, p1, p2, vel); + if (t < frac) + frac = t; + } + } + + VectorNegate (vel, nvel); + for (i = 0; i < portal->winding->numpoints; i++) { + j = i + 1; + if (j >= portal->winding->numpoints) + j -= portal->winding->numpoints; + VectorSubtract (portal->winding->points[i], start, p1); + VectorSubtract (portal->winding->points[j], start, p2); + for (j = 0; j < 3; j++) { + const clipport_t *p = &box->portals[j]; + t = edge_portal_dist (box->planes + p->planenum, p, p1, p2, nvel); + if (t < frac) + frac = t; + } + } + return frac; +} + static inline void -calc_impact (trace_t *trace, const vec3_t start, const vec3_t end, - plane_t *plane) +calc_impact (hull_t *hull, trace_t *trace, + const vec3_t start, const vec3_t end, + clipleaf_t *leaf, plane_t *plane) { vec_t t1, t2, frac, offset; vec3_t dist; @@ -151,6 +374,53 @@ calc_impact (trace_t *trace, const vec3_t start, const vec3_t end, frac = (t1 - offset - DIST_EPSILON) / (t1 - t2); } frac = bound (0, frac, 1); + + if (leaf && trace->type != tr_point) { + int i; + int side; + int planenum; + clipport_t *portal; + vec3_t impact; + clipbox_t box; + + planenum = plane - hull->planes; + + VectorSubtract (end, start, dist); + VectorMultAdd (start, frac, dist, impact); + if (DotProduct (dist, plane->normal) > 0) + VectorMultAdd (impact, offset, plane->normal, impact); + else + VectorMultSub (impact, offset, plane->normal, impact); + + init_box (trace, &box, dist); + + for (portal = leaf->portals; portal; portal = portal->next[side]) { + side = portal->leafs[1] == leaf; + if (portal->planenum != planenum) + continue; + for (i = 0; i < portal->winding->numpoints; i++) { + vec3_t r, s; + VectorSubtract (impact, portal->winding->points[i], r); + CrossProduct (r, portal->edges->points[i], s); + if (DotProduct (s, plane->normal) <= 0) + continue; // "hit" + break; // "miss"; + } + if (i == portal->winding->numpoints) + goto finish_impact; // impact with the face of the polygon + } + for (portal = leaf->portals; portal; portal = portal->next[side]) { + vec_t t; + + side = portal->leafs[1] == leaf; + if (portal->planenum != planenum) + continue; + t = box_portal_dist (hull, portal, &box, start, dist); + if (t < frac) + frac = t; + } + } +finish_impact: if (frac < trace->fraction) { trace->fraction = frac; VectorSubtract (end, start, dist); @@ -221,7 +491,8 @@ MOD_TraceLine (hull_t *hull, int num, } else { // crossing from an empty leaf to a solid leaf: the trace // has collided. - calc_impact (trace, start_point, end_point, split_plane); + calc_impact (hull, trace, start_point, end_point, leaf, + split_plane); if (trace->type == tr_point) return; } From a1da8ecdd0c7bc48697e0d05b0871685b7334849 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 27 Nov 2011 19:38:03 +0900 Subject: [PATCH 263/334] Fix some silly errors that broke most of the box tests. Uninitialized variables and crossed signs. Oops :/ --- libs/models/trace.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/libs/models/trace.c b/libs/models/trace.c index 238b9381e..2e8bc831d 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -242,28 +242,29 @@ edge_portal_dist (const plane_t *plane, const clipport_t *portal, vec3_t x, c; vec3_t imp; - if (t1 >= vn) { + t1 /= -vn; + if (t1 >= 1) { // the edge doesn't make it as far as the portal's plane return 1; } - VectorMultSub (p1, t1 / vn, vel, imp); + VectorMultSub (p1, t1, vel, imp); for (i = 0; i < winding->numpoints; i++) { VectorSubtract (imp, winding->points[i], x); CrossProduct (x, edges->points[i], c); - if (DotProduct (c, plane->normal) >= 0) + if (DotProduct (c, plane->normal) < 0) break; // miss } if (i == winding->numpoints) { - // the closer end of the edge hit the portal, so t1/vn is the + // the closer end of the edge hit the portal, so t1 is the // fraction - return t1 / vn; + return t1; } // the closer end of the edge missed the portal, check the farther // end, but only with this portal edge. VectorMultSub (p2, t2 / vn, vel, imp); VectorSubtract (imp, winding->points[i], x); CrossProduct (x, edges->points[i], c); - if (DotProduct (c, plane->normal) >= 0) { + if (DotProduct (c, plane->normal) < 0) { // both impacts are on the outside of this portal edge, so the // edge being tested misses the portal return 1; @@ -284,6 +285,7 @@ edge_portal_dist (const plane_t *plane, const clipport_t *portal, ee = DotProduct (e, e); CrossProduct (e, vel, ep.normal); ep.dist = DotProduct (p1, ep.normal); + ep.type = 3; for (i = 0; i < winding->numpoints; i++) { vec_t t, te, vn; const vec_t *r = winding->points[i]; @@ -326,6 +328,7 @@ box_portal_dist (const hull_t *hull, const clipport_t *portal, vec_t frac, t; vec3_t p1, p2; + frac = 1.0; for (i = 0; i < 3; i++) { // all faces on box have 4 points (and edges), but we need test only // three on each face @@ -402,7 +405,7 @@ calc_impact (hull_t *hull, trace_t *trace, vec3_t r, s; VectorSubtract (impact, portal->winding->points[i], r); CrossProduct (r, portal->edges->points[i], s); - if (DotProduct (s, plane->normal) <= 0) + if (DotProduct (s, plane->normal) > 0) continue; // "hit" break; // "miss"; } From 2abff680894e9594c8b5d84633a5e601c1e79f7a Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 27 Nov 2011 21:04:08 +0900 Subject: [PATCH 264/334] Fix some more silly bugs. The target test now works, but some others have broken due to getting negative fractions. --- libs/models/trace.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/libs/models/trace.c b/libs/models/trace.c index 2e8bc831d..67beebc1a 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -295,11 +295,11 @@ edge_portal_dist (const plane_t *plane, const clipport_t *portal, vn = DotProduct (v, ep.normal); if (!vn) // FIXME epsilon continue; // portal edge is parallel to the plane - t = PlaneDiff (r, &ep); - if (t < 0 || t > vn) + t = PlaneDiff (r, &ep) / vn; + if (t < -1) continue; // portal edge does not reach the plane // impact point of portal edge with the plane - VectorMultSub (r, t / vn, v, x); + VectorMultSub (r, t, v, x); // project the impact point back to the edge along the velocity VectorSubtract (x, p1, y); t = DotProduct (y, vel) / DotProduct (vel, vel); @@ -333,8 +333,8 @@ box_portal_dist (const hull_t *hull, const clipport_t *portal, // all faces on box have 4 points (and edges), but we need test only // three on each face for (j = 0; j < 3; j++) { - VectorAdd (box->points->points[j], start, p1); - VectorAdd (box->points->points[j + 1], start, p2); + VectorAdd (box->points[i].points[j], start, p1); + VectorAdd (box->points[i].points[j + 1], start, p2); t = edge_portal_dist (plane, portal, p1, p2, vel); if (t < frac) frac = t; @@ -412,6 +412,7 @@ calc_impact (hull_t *hull, trace_t *trace, if (i == portal->winding->numpoints) goto finish_impact; // impact with the face of the polygon } + frac = 1.0; for (portal = leaf->portals; portal; portal = portal->next[side]) { vec_t t; From ab2ec644d69ff61e1d6fa10b8c025393aa4b772e Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 28 Nov 2011 08:57:42 +0900 Subject: [PATCH 265/334] Clip the portals when running the test cases. When the portals are too big, floats break down and break the tests. This might not be much of an issue in real maps, but my tests use "infinite" planes. --- libs/models/test/testclip.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index f0f1b154f..bd33ddfe7 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -477,6 +477,14 @@ run_test (test_t *test) goto nodeleaf_bail; } for (p = portal_list; p; p = p->next) { + for (j = 0; j < p->portal->winding->numpoints; j++) { + p->portal->winding->points[j][0] + = bound (-8192, p->portal->winding->points[j][0], 8192); + p->portal->winding->points[j][1] + = bound (-8192, p->portal->winding->points[j][1], 8192); + p->portal->winding->points[j][2] + = bound (-8192, p->portal->winding->points[j][2], 8192); + } for (j = 0; j < 2; j++) { int found = 0; From 996859c367dba054eb0eb104ae527e87607fc695 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 28 Nov 2011 09:02:16 +0900 Subject: [PATCH 266/334] Correct the projection code. That needed to be the intersection of two coplanar lines. --- libs/models/trace.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/libs/models/trace.c b/libs/models/trace.c index 67beebc1a..6db5436ee 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -277,20 +277,18 @@ edge_portal_dist (const plane_t *plane, const clipport_t *portal, { vec3_t e; vec_t frac = 1.0; - vec_t ee; plane_t ep; // set up the plane through which the edge travels VectorSubtract (p2, p1, e); - ee = DotProduct (e, e); CrossProduct (e, vel, ep.normal); ep.dist = DotProduct (p1, ep.normal); ep.type = 3; for (i = 0; i < winding->numpoints; i++) { - vec_t t, te, vn; + vec_t t, vn; const vec_t *r = winding->points[i]; const vec_t *v = edges->points[i]; - vec3_t x, y, z; + vec3_t x, y; vn = DotProduct (v, ep.normal); if (!vn) // FIXME epsilon @@ -304,13 +302,15 @@ edge_portal_dist (const plane_t *plane, const clipport_t *portal, VectorSubtract (x, p1, y); t = DotProduct (y, vel) / DotProduct (vel, vel); VectorMultSub (x, t, vel, y); + VectorSubtract (y, p1, y); + t = DotProduct (y, y) / DotProduct (e, y); + if (t < 0 || t > 1) + continue; // the edge misses the portal edge + VectorMultAdd (p1, t, e, y); + VectorSubtract (x, y, y); + t = DotProduct (y, vel) / DotProduct (vel, vel); if (t >= frac) continue; // this is not the nearest edge pair - // check projected impact point's position along the edge - VectorSubtract (y, p1, z); - te = DotProduct (z, e); - if (te < 0 || te > ee) - continue; // the edge misses the portal edge // the edges hit, and they are the closes edge pair so far frac = t; } From 60dbc0e342dd114e07c616bbfa6e90df023e3225 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 28 Nov 2011 09:24:13 +0900 Subject: [PATCH 267/334] Fix the last few bugs breaking the distance code. The code itself seems to work now. There are still some problems: the box faces are using unit vectors for the edges, or I should go back to unit vectors for the portal edges; starting in a solid corner won't always work; etc. However, that's just mopping up: the main algorithm seems to be working. --- libs/models/trace.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libs/models/trace.c b/libs/models/trace.c index 6db5436ee..bbec0f4d2 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -224,8 +224,8 @@ edge_portal_dist (const plane_t *plane, const clipport_t *portal, t1 = PlaneDiff (p1, plane); t2 = PlaneDiff (p2, plane); // ensure p1 is the closest point to the plane - if ((0 < t1 && t1 > t2) - || (0 > t1 && t1 < t2)) { + if ((0 < t2 && t2 < t1) + || (0 > t2 && t2 > t1)) { // p2 is closer to the plane, so swap the points and times const vec_t *r = p2; vec_t t = t2; @@ -242,8 +242,8 @@ edge_portal_dist (const plane_t *plane, const clipport_t *portal, vec3_t x, c; vec3_t imp; - t1 /= -vn; - if (t1 >= 1) { + t1 /= vn; + if (t1 <= -1) { // the edge doesn't make it as far as the portal's plane return 1; } @@ -257,7 +257,7 @@ edge_portal_dist (const plane_t *plane, const clipport_t *portal, if (i == winding->numpoints) { // the closer end of the edge hit the portal, so t1 is the // fraction - return t1; + return -t1; } // the closer end of the edge missed the portal, check the farther // end, but only with this portal edge. @@ -294,7 +294,7 @@ edge_portal_dist (const plane_t *plane, const clipport_t *portal, if (!vn) // FIXME epsilon continue; // portal edge is parallel to the plane t = PlaneDiff (r, &ep) / vn; - if (t < -1) + if (t < -1 || t > 0) continue; // portal edge does not reach the plane // impact point of portal edge with the plane VectorMultSub (r, t, v, x); From 2c9b07b25731e68d9683c08f36b2ea314fcb39c8 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 28 Nov 2011 10:09:24 +0900 Subject: [PATCH 268/334] Scale the box edge vectors. Now they represent the lengths of the edges as expected by the edge/polygon code. --- libs/models/trace.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/libs/models/trace.c b/libs/models/trace.c index bbec0f4d2..3271cc6ed 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -202,9 +202,17 @@ init_box (const trace_t *trace, clipbox_t *box, const vec3_t vel) } Vector3Scale (box->points[i].points[j - 1], trace->extents, box->points[i].points[j - 1]); + Vector3Scale (box->edges[i].points[j - 1], trace->extents, + box->edges[i].points[j - 1]); + VectorScale (box->edges[i].points[j - 1], 2, + box->edges[i].points[j - 1]); } Vector3Scale (box->points[i].points[3], trace->extents, box->points[i].points[3]); + Vector3Scale (box->edges[i].points[3], trace->extents, + box->edges[i].points[3]); + VectorScale (box->edges[i].points[3], 2, + box->edges[i].points[3]); } } @@ -255,7 +263,7 @@ edge_portal_dist (const plane_t *plane, const clipport_t *portal, break; // miss } if (i == winding->numpoints) { - // the closer end of the edge hit the portal, so t1 is the + // the closer end of the edge hit the portal, so -t1 is the // fraction return -t1; } From 45d55d7e9a3bf5b8966bff801c748848cc5c6879 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 28 Nov 2011 17:03:56 +0900 Subject: [PATCH 269/334] Test the simple wedge. --- libs/models/test/testclip.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index bd33ddfe7..93f8fc74d 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -15,7 +15,7 @@ # include "../trace.c" #endif -#define FloatCompare(a, b) (fabs (a - b) < 1e-6) +#define FloatCompare(a, b) (fabs (a - b) < 1e-5) #undef VectorCompare #define VectorCompare(x, y) \ (FloatCompare (x[0], y[0]) && FloatCompare (x[1], y[1]) \ @@ -366,6 +366,15 @@ test_t tests[] = { {-16, 0, 8}, {16, 0, 8}, { 1, 0, 0, 1, 0, 4}}, {"Box, Ramp", &box, &hull_ramp, {-16, 0, 5}, {16, 0, 5}, { 0.125, 0, 0, 1, 0, 4}}, + + {"Box, Simple Wedge", &box, &hull_simple_wedge, + { 0, 0, 16}, {0, 0, 0}, { 0.5, 0, 0, 1, 0, 3}}, + {"Box, Simple Wedge", &box, &hull_simple_wedge, + {-16, 0, 8}, {16, 0, 8}, { 1, 0, 0, 1, 0, 3}}, + {"Box, Simple Wedge", &box, &hull_simple_wedge, + {-16, 0, 5}, {16, 0, 5}, { 0.25, 0, 0, 1, 0, 3}}, + {"Box, Simple Wedge", &box, &hull_simple_wedge, + {-16, 0, 12}, {16, 0, 4}, { 0.5, 0, 0, 1, 0, 3}}, }; #define num_tests (sizeof (tests) / sizeof (tests[0])) From 869cd192609547884385ee7393fb00ff743ad28d Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 28 Nov 2011 17:06:04 +0900 Subject: [PATCH 270/334] Box traces can now graze a corner. --- libs/models/test/testclip.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index 93f8fc74d..d42246a48 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -336,9 +336,8 @@ test_t tests[] = { { -16, 0, 8}, {16, 0, 40}, { 0.25, 0, 0, 1, 0, 5}}, {"Box, Step 1", &box, &hull_step1, { -16, 0, 8}, {16, 0, 135}, { 0.25, 0, 0, 1, 0, 5}}, - // 136 is a corner case caused by back/front side issues and 0 {"Box, Step 1", &box, &hull_step1, - { -16, 0, 8}, {16, 0, 137}, { 1, 0, 0, 1, 0, 5}}, + { -16, 0, 8}, {16, 0, 136}, { 1, 0, 0, 1, 0, 5}}, {"Point, Covered Step", &point, &hull_covered_step, { -24, 0, 8}, {-24, 0, 72}, { 0.5, 0, 0, 1, 0, 9}}, From 985667ecba5812daaa8a176a42d98762ece513db Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 28 Nov 2011 17:12:39 +0900 Subject: [PATCH 271/334] Fix plane touching box backsideness. Because a box has size, even when touching a plane, the side on which the box is can be determined (unlike a point). --- libs/models/test/testclip.c | 4 ++++ libs/models/trace.c | 8 +++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index d42246a48..a7b655e6b 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -353,6 +353,10 @@ test_t tests[] = { { -17, 0, 8}, {-1, 0, 72}, { 1, 0, 0, 1, 0, 9}}, {"Box, Covered Step", &box, &hull_covered_step, { -8, 0, 40}, {8, 0, 72}, { 1, 0, 0, 1, 0, 9}}, + {"Box, Covered Step touch backside", &box, &hull_covered_step, + { -8, 0, 8}, {-12, 0, 12}, { 1, 0, 0, 1, 0, 9}}, + {"Point, Covered Step touch backside", &point, &hull_covered_step, + { 0, 0, 8}, {-12, 0, 12}, { 1, 0, 1, 1, 0, 9}}, {"Box, Step 2", &box, &hull_step2, { 0, 0, 64}, {0, 0, 0}, { 0.375, 0, 0, 1, 0, 5}}, diff --git a/libs/models/trace.c b/libs/models/trace.c index 3271cc6ed..031289f75 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -551,9 +551,11 @@ MOD_TraceLine (hull_t *hull, int num, num = node->children[0]; continue; } - //FIXME non-zero offset lets the object touch the plane but still be - //behind the plane - if (start_dist < -offset && end_dist < -offset) { + //non-zero offset lets the object touch the plane but still be + //behind the plane. however, point traces are assumed to be on the + //front side of the plane if touching the plane + if ((offset && start_dist <= -offset && end_dist <= -offset) + || (!offset && start_dist < -offset && end_dist < -offset)) { // entirely behind the plane plane = 0; leaf = hull->nodeleafs[num].leafs[1]; From 50b08c98fafc068d7d2a30a6bdc1f0fe100c58cc Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 28 Nov 2011 19:07:00 +0900 Subject: [PATCH 272/334] Add some snug-fit tests and fix the uncovered bugs. The tests involve the box fitting into a hole with zero slop (this would be impossible with point clipping). --- libs/models/test/testclip.c | 54 +++++++++++++++++++++++++++++++++++++ libs/models/trace.c | 21 ++++++++++----- 2 files changed, 68 insertions(+), 7 deletions(-) diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index a7b655e6b..1f123358c 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -265,6 +265,39 @@ hull_t hull_ramp = { {0, 0, 0}, }; +// 2 1 +// ss|sss|ss +// ss+-3-+ss 8 +// ss|eee|ss +// ss+-4-+ss -8 +// ss|sss|ss +// -8 8 +// looking at plane 0: back of 0 is empty, front of 0 has above hole +mclipnode_t clipnodes_hole[] = { + { 0, { 1, CONTENTS_EMPTY}}, + { 1, {CONTENTS_SOLID, 2}}, + { 2, { 3, CONTENTS_SOLID}}, + { 3, {CONTENTS_SOLID, 4}}, + { 4, {CONTENTS_EMPTY, CONTENTS_SOLID}}, +}; + +plane_t planes_hole[] = { + {{ 0, 1, 0}, 0, 1, 0}, + {{ 1, 0, 0}, 8, 0, 0}, + {{ 1, 0, 0}, -8, 0, 0}, + {{ 0, 0, 1}, 8, 2, 0}, + {{ 0, 0, 1}, -8, 2, 0}, +}; + +hull_t hull_hole = { + clipnodes_hole, + planes_hole, + 0, + 4, + {0, 0, 0}, + {0, 0, 0}, +}; + typedef struct { vec3_t extents; @@ -378,6 +411,27 @@ test_t tests[] = { {-16, 0, 5}, {16, 0, 5}, { 0.25, 0, 0, 1, 0, 3}}, {"Box, Simple Wedge", &box, &hull_simple_wedge, {-16, 0, 12}, {16, 0, 4}, { 0.5, 0, 0, 1, 0, 3}}, + + {"Box, Hole. slide in", &box, &hull_hole, + { 0, -16, 0}, { 0, 16, 0}, { 1, 0, 0, 1, 0, 13}}, + {"Box, Hole. slide out", &box, &hull_hole, + { 0, 16, 0}, { 0, -16, 0}, { 1, 0, 0, 1, 0, 13}}, + {"Box, Hole. tight", &box, &hull_hole, + { 0, 16, 0}, { 0, 16, 16}, { 0, 0, 0, 1, 0, 13}}, + {"Box, Hole. tight", &box, &hull_hole, + { 0, 16, 0}, { 0, 16, -16}, { 0, 0, 0, 1, 0, 13}}, + {"Box, Hole. tight", &box, &hull_hole, + { 0, 16, 0}, { 16, 16, 0}, { 0, 0, 0, 1, 0, 13}}, + {"Box, Hole. tight", &box, &hull_hole, + { 0, 16, 0}, {-16, 16, 0}, { 0, 0, 0, 1, 0, 13}}, + {"Box, Hole. edge", &box, &hull_hole, + { 0, -16, 1}, { 0, 16, 1}, { 0.25, 0, 0, 1, 0, 13}}, + {"Box, Hole. edge", &box, &hull_hole, + { 0, -16, -1}, { 0, 16, -1}, { 0.25, 0, 0, 1, 0, 13}}, + {"Box, Hole. edge", &box, &hull_hole, + { 1, -16, 0}, { 1, 16, 0}, { 0.25, 0, 0, 1, 0, 13}}, + {"Box, Hole. edge", &box, &hull_hole, + {-1, -16, 0}, { -1, 16, 0}, { 0.25, 0, 0, 1, 0, 13}}, }; #define num_tests (sizeof (tests) / sizeof (tests[0])) diff --git a/libs/models/trace.c b/libs/models/trace.c index 031289f75..6b338f149 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -97,7 +97,6 @@ check_in_leaf (hull_t *hull, trace_t *trace, clipleaf_t *leaf, plane_t *plane, { clipport_t *portal; int side; - int miss = 0; int i; int planenum; plane_t cutplane; @@ -107,12 +106,17 @@ check_in_leaf (hull_t *hull, trace_t *trace, clipleaf_t *leaf, plane_t *plane, planenum = plane - hull->planes; cutplane.type = 3; // generic plane v_n = DotProduct (vel, plane->normal); + if (!v_n) { + //FIXME is this correct? The assumption is that if we got to a leaf + //travelliing parallel to its plane, then we have to be in the leaf + return 1; + } for (portal = leaf->portals; portal; portal = portal->next[side]) { side = portal->leafs[1] == leaf; if (portal->planenum != planenum) continue; - for (i = 0; !miss && i < portal->winding->numpoints; i++) { + for (i = 0; i < portal->winding->numpoints; i++) { point = portal->winding->points[i]; edge = portal->edges->points[i]; // so long as the plane distance and offset are calculated using @@ -122,12 +126,15 @@ check_in_leaf (hull_t *hull, trace_t *trace, clipleaf_t *leaf, plane_t *plane, cutplane.dist = DotProduct (cutplane.normal, point); dist = PlaneDiff (org, &cutplane); offset = calc_offset (trace, &cutplane); - if (v_n >= 0) - miss = dist >= offset; - else - miss = dist <= -offset; + if (v_n > 0) { + if (dist >= offset) + break; + } else { + if (dist <= -offset) + break; + } } - if (!miss) + if (i == portal->winding->numpoints) return 1; } return 0; From 13d37f4838d35dd6760ff2ca368167819c3ae74f Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 28 Nov 2011 20:28:37 +0900 Subject: [PATCH 273/334] Add a bunch of in-solid tests. Tests where the box is only partially in a solid tend to fail (particularly when the solid is on the back side of the split plane). --- libs/models/test/testclip.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index 1f123358c..1f0c6578f 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -373,23 +373,37 @@ test_t tests[] = { { -16, 0, 8}, {16, 0, 136}, { 1, 0, 0, 1, 0, 5}}, {"Point, Covered Step", &point, &hull_covered_step, - { -24, 0, 8}, {-24, 0, 72}, { 0.5, 0, 0, 1, 0, 9}}, + {-24, 0, 8}, {-24, 0, 72}, { 0.5, 0, 0, 1, 0, 9}}, {"Box, Covered Step", &box, &hull_covered_step, - { -32, 0, 8}, {-32, 0, 72}, { 0.375, 0, 0, 1, 0, 9}}, + {-32, 0, 8}, {-32, 0, 72}, { 0.375, 0, 0, 1, 0, 9}}, {"Box, Covered Step", &box, &hull_covered_step, - { -24, 0, 8}, {-24, 0, 72}, { 0.375, 0, 0, 1, 0, 9}}, + {-24, 0, 8}, {-24, 0, 72}, { 0.375, 0, 0, 1, 0, 9}}, {"Box, Covered Step", &box, &hull_covered_step, - { -25, 0, 8}, {7, 0, 72}, { 0.375, 0, 0, 1, 0, 9}}, + {-25, 0, 8}, { 7, 0, 72}, { 0.375, 0, 0, 1, 0, 9}}, {"Box, Covered Step", &box, &hull_covered_step, - { -8, 0, 40}, {-16, 0, 40}, { 0.5, 0, 0, 1, 0, 9}}, + { -8, 0, 40}, {-16, 0, 40}, { 0.5, 0, 0, 1, 0, 9}}, {"Box, Covered Step", &box, &hull_covered_step, - { -17, 0, 8}, {-1, 0, 72}, { 1, 0, 0, 1, 0, 9}}, + {-17, 0, 8}, { -1, 0, 72}, { 1, 0, 0, 1, 0, 9}}, {"Box, Covered Step", &box, &hull_covered_step, - { -8, 0, 40}, {8, 0, 72}, { 1, 0, 0, 1, 0, 9}}, + { -8, 0, 40}, { 8, 0, 72}, { 1, 0, 0, 1, 0, 9}}, {"Box, Covered Step touch backside", &box, &hull_covered_step, - { -8, 0, 8}, {-12, 0, 12}, { 1, 0, 0, 1, 0, 9}}, + { -8, 0, 8}, {-12, 0, 12}, { 1, 0, 0, 1, 0, 9}}, {"Point, Covered Step touch backside", &point, &hull_covered_step, - { 0, 0, 8}, {-12, 0, 12}, { 1, 0, 1, 1, 0, 9}}, + { 0, 0, 8}, {-12, 0, 12}, { 1, 0, 1, 1, 0, 9}}, + {"Box, Covered Step start solid", &box, &hull_covered_step, + { -4, 0, 4}, {-12, 0, 12}, { 1, 0, 1, 1, 0, 9}}, + {"Box, Covered Step start solid", &box, &hull_covered_step, + { -4, 0, 4}, {-16, 0, 36}, { 0.875, 0, 1, 1, 0, 9}}, + {"Box, Covered Step start solid", &box, &hull_covered_step, + { -4, 0, 4}, {-16, 0, 4}, { 1, 1, 1, 0, 0, 9}}, + {"Box, Covered Step start solid", &box, &hull_covered_step, + {-12, 0, 4}, {-16, 0, 4}, { 1, 1, 1, 0, 0, 9}}, + {"Box, Covered Step start solid", &box, &hull_covered_step, + {-16, 0, 4}, { -4, 0, 4}, { 1, 1, 1, 0, 0, 9}}, + {"Box, Covered Step start solid", &box, &hull_covered_step, + { 16, 0, -16}, { 16, 0, 64}, { 1, 1, 1, 0, 0, 9}}, + {"Box, Covered Step start solid", &box, &hull_covered_step, + { 16, 0, 16}, { 16, 0, 64}, { 1, 0, 1, 1, 0, 9}}, {"Box, Step 2", &box, &hull_step2, { 0, 0, 64}, {0, 0, 0}, { 0.375, 0, 0, 1, 0, 5}}, From 7ee31dd47548fcdf6497f5f7de4cdeae920be1a8 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 28 Nov 2011 20:51:20 +0900 Subject: [PATCH 274/334] Allow the trace start to be in multiple leafs. This fixes a couple of in-solid tests, but something better is needed. --- libs/models/trace.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/libs/models/trace.c b/libs/models/trace.c index 6b338f149..2bcb38b2f 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -463,7 +463,7 @@ MOD_TraceLine (hull_t *hull, int num, vec_t start_dist, end_dist, frac[2], offset; vec3_t start, end, dist, vel; int side; - qboolean seen_empty, seen_solid; + qboolean seen_empty, seen_solid, moved; tracestack_t *tstack; tracestack_t tracestack[256]; mclipnode_t *node; @@ -476,8 +476,9 @@ MOD_TraceLine (hull_t *hull, int num, VectorNormalize (vel); tstack = tracestack; - seen_empty = 0; - seen_solid = 0; + seen_empty = false; + seen_solid = false; + moved = false; split_plane = 0; leaf = 0; plane = 0; @@ -506,7 +507,8 @@ MOD_TraceLine (hull_t *hull, int num, // whole trace as solid (this is what id does). // However, since allsolid is initialized to true, no need // to do anything. - return; + if (moved) + return; } else { // crossing from an empty leaf to a solid leaf: the trace // has collided. @@ -539,6 +541,7 @@ MOD_TraceLine (hull_t *hull, int num, VectorCopy (tstack->end, end); side = tstack->side; split_plane = tstack->plane; + moved = tstack->start_frac > 0; leaf = hull->nodeleafs[tstack->num].leafs[side ^ 1]; num = hull->clipnodes[tstack->num].children[side ^ 1]; From f9d56f2941582630cfe6a9164b01219dfa2f4ca7 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 1 Dec 2011 12:26:33 +0900 Subject: [PATCH 275/334] Add MOD_HullContents(). If trace is null or point type, or the hull doesn't have portals, or the first node is a leaf, MOD_HullContents operates in point mode (exactly the same way as SV_HullPointContents()). However, in box mode, all leafs touched by the trace are checked for their contents. The contents field of trace (a bit field) will indicate the contents type of all touched leafs. The returned contents value indicates the most important contents: solid > lava > slime > water > empty The one's complement value of the contents type is the bit number of the contents bit field. I'm not sure how useful this will be as getting the amount of overlap is currently not supported. --- include/world.h | 3 ++ libs/models/trace.c | 70 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/include/world.h b/include/world.h index 81d053833..404a0e02b 100644 --- a/include/world.h +++ b/include/world.h @@ -49,6 +49,7 @@ typedef struct trace_s { vec3_t endpos; // final position plane_t plane; // surface normal at impact struct edict_s *ent; // entity the surface is on + unsigned contents; // contents of leafs touched by trace } trace_t; @@ -117,6 +118,8 @@ hull_t *SV_HullForEntity (struct edict_s *ent, const vec3_t mins, const vec3_t maxs, vec3_t extents, vec3_t offset); void MOD_TraceLine (hull_t *hull, int num, const vec3_t start, const vec3_t end, trace_t *trace); +int MOD_HullContents (hull_t *hull, int num, const vec3_t origin, + trace_t *trace); typedef struct clipport_s { int planenum; diff --git a/libs/models/trace.c b/libs/models/trace.c index 2bcb38b2f..8bef5695a 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -455,6 +455,47 @@ finish_impact: } } +static int +trace_contents (hull_t *hull, trace_t *trace, clipleaf_t *leaf, + const vec3_t origin) +{ + clipport_t *portal; + int side; + int contents = leaf->contents; + // set the auxiliary contents data. this is a bit field of all contents + // types contained within the trace. + // contents start at -1 (empty). bit 0 represents CONTENTS_EMPTY + trace->contents |= 1 << (~contents); + // check all adjoining leafs that contain part of the trace + for (portal = leaf->portals; portal; portal = portal->next[side]) { + vec_t offset; + vec_t dist; + plane_t *plane; + int res; + + side = portal->leafs[1] == leaf; + plane = hull->planes + portal->planenum; + + dist = PlaneDiff (origin, plane); + offset = calc_offset (trace, plane); + // the side of the plane on which we are does not matter, only + // whether we're crossing the plane. merely touching the plane does + // not cause us to cross it + if (fabs (dist) >= offset) + continue; + //FIXME test portal! + res = trace_contents (hull, trace, portal->leafs[side ^ 1], origin); + //FIXME better test? + // solid > lava > slime > water > empty (desired) + // solid > current (good) + // problem is, current > sky > lava (what is best?) + if (res == CONTENTS_SOLID + || (contents != CONTENTS_SOLID && res < contents)) + contents = res; + } + return contents; +} + VISIBLE void MOD_TraceLine (hull_t *hull, int num, const vec3_t start_point, const vec3_t end_point, @@ -612,3 +653,32 @@ MOD_TraceLine (hull_t *hull, int num, num = node->children[side]; } } + +VISIBLE int +MOD_HullContents (hull_t *hull, int num, const vec3_t origin, trace_t *trace) +{ + int prevnode = -1; + int side = 0; + clipleaf_t *leaf; + // follow origin down the bsp tree to find the "central" leaf + while (num >= 0) { + vec_t d; + mclipnode_t *node; + plane_t *plane; + + node = hull->clipnodes + num; + plane = hull->planes + node->planenum; + d = PlaneDiff (origin, plane); + prevnode = num; + side = d < 0; + num = node->children[side]; + } + if (!trace || trace->type == tr_point + || prevnode == -1 || !hull->nodeleafs) { + return num; + } + // check the contents of the "central" and surrounding touched leafs + leaf = hull->nodeleafs[prevnode].leafs[side]; + trace->contents = 0; + return trace_contents (hull, trace, leaf, origin); +} From 27642a080ab38cdc5817846bd70b1a1292312356 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 1 Dec 2011 12:57:06 +0900 Subject: [PATCH 276/334] Avoid infinite recursion. --- include/world.h | 1 + libs/models/trace.c | 13 +++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/include/world.h b/include/world.h index 404a0e02b..93c562fd0 100644 --- a/include/world.h +++ b/include/world.h @@ -132,6 +132,7 @@ typedef struct clipport_s { typedef struct clipleaf_s { clipport_t *portals; int contents; + int test_count; } clipleaf_t; typedef struct nodeleaf_s { diff --git a/libs/models/trace.c b/libs/models/trace.c index 8bef5695a..e1328e4e4 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -455,6 +455,8 @@ finish_impact: } } +static int test_count; + static int trace_contents (hull_t *hull, trace_t *trace, clipleaf_t *leaf, const vec3_t origin) @@ -462,6 +464,8 @@ trace_contents (hull_t *hull, trace_t *trace, clipleaf_t *leaf, clipport_t *portal; int side; int contents = leaf->contents; + + leaf->test_count = test_count; // set the auxiliary contents data. this is a bit field of all contents // types contained within the trace. // contents start at -1 (empty). bit 0 represents CONTENTS_EMPTY @@ -472,10 +476,14 @@ trace_contents (hull_t *hull, trace_t *trace, clipleaf_t *leaf, vec_t dist; plane_t *plane; int res; + clipleaf_t *l; side = portal->leafs[1] == leaf; - plane = hull->planes + portal->planenum; + l = portal->leafs[side ^ 1]; + if (l->test_count == test_count) + continue; + plane = hull->planes + portal->planenum; dist = PlaneDiff (origin, plane); offset = calc_offset (trace, plane); // the side of the plane on which we are does not matter, only @@ -484,7 +492,7 @@ trace_contents (hull_t *hull, trace_t *trace, clipleaf_t *leaf, if (fabs (dist) >= offset) continue; //FIXME test portal! - res = trace_contents (hull, trace, portal->leafs[side ^ 1], origin); + res = trace_contents (hull, trace, l, origin); //FIXME better test? // solid > lava > slime > water > empty (desired) // solid > current (good) @@ -680,5 +688,6 @@ MOD_HullContents (hull_t *hull, int num, const vec3_t origin, trace_t *trace) // check the contents of the "central" and surrounding touched leafs leaf = hull->nodeleafs[prevnode].leafs[side]; trace->contents = 0; + test_count++; return trace_contents (hull, trace, leaf, origin); } From d9a641c6005d9fa30e4a59f51d699d6a8f70c9e9 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 3 Dec 2011 09:06:57 +0900 Subject: [PATCH 277/334] Avoid a segfault when the hull hasn't been portalized. Serves me right for forgetting to test the main engine :P --- libs/models/trace.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/libs/models/trace.c b/libs/models/trace.c index e1328e4e4..23b81696d 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -592,7 +592,8 @@ MOD_TraceLine (hull_t *hull, int num, split_plane = tstack->plane; moved = tstack->start_frac > 0; - leaf = hull->nodeleafs[tstack->num].leafs[side ^ 1]; + if (hull->nodeleafs) + leaf = hull->nodeleafs[tstack->num].leafs[side ^ 1]; num = hull->clipnodes[tstack->num].children[side ^ 1]; } @@ -606,7 +607,8 @@ MOD_TraceLine (hull_t *hull, int num, if (start_dist >= offset && end_dist >= offset) { // entirely in front of the plane plane = 0; - leaf = hull->nodeleafs[num].leafs[0]; + if (hull->nodeleafs) + leaf = hull->nodeleafs[num].leafs[0]; num = node->children[0]; continue; } @@ -617,7 +619,8 @@ MOD_TraceLine (hull_t *hull, int num, || (!offset && start_dist < -offset && end_dist < -offset)) { // entirely behind the plane plane = 0; - leaf = hull->nodeleafs[num].leafs[1]; + if (hull->nodeleafs) + leaf = hull->nodeleafs[num].leafs[1]; num = node->children[1]; continue; } @@ -657,7 +660,8 @@ MOD_TraceLine (hull_t *hull, int num, VectorMultAdd (start, frac[side], dist, end); - leaf = hull->nodeleafs[num].leafs[side]; + if (hull->nodeleafs) + leaf = hull->nodeleafs[num].leafs[side]; num = node->children[side]; } } From 9ad298a716b37bb32482a904018f0c857cd380af Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 3 Dec 2011 19:59:12 +0900 Subject: [PATCH 278/334] Check whether the portal and box intersect. Now on to creating tests for MOD_HullContents :) --- libs/models/trace.c | 129 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 128 insertions(+), 1 deletion(-) diff --git a/libs/models/trace.c b/libs/models/trace.c index 23b81696d..9b758411b 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -91,6 +91,50 @@ calc_offset (trace_t *trace, plane_t *plane) return d; } +static qboolean +point_inside_portal (const clipport_t *portal, const plane_t *plane, + const vec3_t p) +{ + vec3_t x, c; + const vec_t *n = plane->normal; + int i; + const winding_t *points = portal->winding; + const winding_t *edges = portal->edges; + + for (i = 0; i < points->numpoints; i++) { + VectorSubtract (p, points->points[i], x); + CrossProduct (x, edges->points[i], c); + if (DotProduct (c, n) <= 0) + return false; + } + return true; +} + +static qboolean +edges_intersect (const vec3_t p1, const vec3_t p2, + const vec3_t r1, const vec3_t r2) +{ + vec3_t p, r, b; + vec3_t p_r, b_p, b_r; + vec_t tp, tpd, tr, trd; + + VectorSubtract (p2, p1, p); + VectorSubtract (r2, r1, r); + VectorSubtract (r1, p1, b); + CrossProduct (p, r, p_r); + if (VectorIsZero (p_r)) + return false; + CrossProduct (b, p, b_p); + CrossProduct (b, r, b_r); + tr = DotProduct (b_p, b_p); + trd = DotProduct (b_p, p_r); + tp = DotProduct (b_r, b_r); + tpd = DotProduct (b_r, p_r); + if ((tr < 0 || tr > trd) || (tp < 0 || tp > tpd)) + return false; + return true; +} + static int check_in_leaf (hull_t *hull, trace_t *trace, clipleaf_t *leaf, plane_t *plane, const vec3_t vel, const vec3_t org) @@ -455,6 +499,88 @@ finish_impact: } } +static qboolean +portal_intersect (trace_t *trace, clipport_t *portal, plane_t *plane, + const vec3_t origin) +{ + vec3_t r; + vec_t o_n; + int i; + static vec3_t verts[][2] = { + {{ -1, -1, -1}, { 1, -1, -1}}, + {{ -1, -1, 1}, { 1, -1, 1}}, + {{ -1, 1, -1}, { 1, 1, -1}}, + {{ -1, 1, 1}, { 1, 1, 1}}, + {{ -1, -1, -1}, { -1, 1, -1}}, + {{ 1, -1, -1}, { 1, 1, -1}}, + {{ -1, -1, 1}, { -1, 1, 1}}, + {{ 1, -1, 1}, { 1, 1, 1}}, + {{ -1, -1, -1}, { -1, -1, 1}}, + {{ -1, 1, -1}, { -1, 1, 1}}, + {{ 1, -1, -1}, { 1, -1, 1}}, + {{ 1, 1, -1}, { 1, 1, 1}}, + }; + + // if any portal point is inside or touches the box, then they intersect + for (i = 0; i < portal->winding->numpoints; i++) { + VectorSubtract (portal->winding->points[i], origin, r); + if (fabs(r[0]) <= trace->extents[0] + && fabs(r[1]) <= trace->extents[1] + && fabs(r[2]) <= trace->extents[2]) + return true; + } + // if any box edge crosses or touches the plane within the portal, then + // they intersect + o_n = DotProduct (origin, plane->normal); + for (i = 0; i < 12; i++) { + vec3_t p1, p2, imp, dist; + vec_t t1, t2, frac; + + Vector3Scale (trace->extents, verts[i][0], p1); + Vector3Scale (trace->extents, verts[i][1], p2); + t1 = PlaneDiff (p1, plane) + o_n; + t2 = PlaneDiff (p2, plane) + o_n; + // if both ends of the box edge are on the same side (or touching) the + // plane, the edge does not cross the plane + // if only one end of the edge is touching, then we still have to + // check the impact point. + if ((t1 > 0 && t2 > 0) || (t1 < 0 && t2 < 0) || (t1 == t2)) + continue; + if (t1 == t2) { + int j; + // the edge is on the plane + // if either end touches the portal, then the box and portal touch + if (point_inside_portal (portal, plane, p1)) + return true; + if (point_inside_portal (portal, plane, p2)) + return true; + // if the edge intersects with a portal edge, then the box and + // portal touch + for (j = 0; j < portal->winding->numpoints; j++) { + int k = j + 1; + if (k == portal->winding->numpoints) + k = 0; + if (edges_intersect (p1, p2, portal->winding->points[j], + portal->winding->points[k])) + return true; + } + continue; + } + // since t1 and t2 are guaranteed to be on opposite sides of the plane, + // or only one touching, they are guaranteed to be unequal. Also, frac + // is guaranteed to be between 0 and 1 + frac = t1 / (t1 - t2); + VectorSubtract (p2, p1, dist); + VectorMultAdd (p1, frac, dist, imp); + VectorAdd (imp, origin, imp); + if (point_inside_portal (portal, plane, imp)) { + // the impact point is in the portal + return true; + } + } + return 0; +} + static int test_count; static int @@ -491,7 +617,8 @@ trace_contents (hull_t *hull, trace_t *trace, clipleaf_t *leaf, // not cause us to cross it if (fabs (dist) >= offset) continue; - //FIXME test portal! + if (!portal_intersect (trace, portal, plane, origin)) + continue; res = trace_contents (hull, trace, l, origin); //FIXME better test? // solid > lava > slime > water > empty (desired) From dadfb7899246907abe71a69c8933d57b03bf1c3f Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 3 Dec 2011 20:20:33 +0900 Subject: [PATCH 279/334] Split out the hull data so it can be used in other tests. --- libs/models/test/Makefile.am | 4 +- libs/models/test/hulls.c | 277 ++++++++++++++++++++++++++++++++++ libs/models/test/hulls.h | 12 ++ libs/models/test/testclip.c | 279 +---------------------------------- 4 files changed, 293 insertions(+), 279 deletions(-) create mode 100644 libs/models/test/hulls.c create mode 100644 libs/models/test/hulls.h diff --git a/libs/models/test/Makefile.am b/libs/models/test/Makefile.am index 66525bb42..792e7ed30 100644 --- a/libs/models/test/Makefile.am +++ b/libs/models/test/Makefile.am @@ -3,9 +3,9 @@ AUTOMAKE_OPTIONS= foreign INCLUDES= -I$(srcdir) -I$(top_srcdir)/include check_PROGRAMS=testclip -EXTRA_DIST= trace-id.c trace-qf-bad.c +EXTRA_DIST= trace-id.c trace-qf-bad.c hulls.h -testclip_SOURCES=testclip.c +testclip_SOURCES=testclip.c hulls.c testclip_LDADD= $(top_builddir)/libs/models/libQFmodels.la $(top_builddir)/libs/util/libQFutil.la testclip_DEPENDENCIES= $(top_builddir)/libs/models/libQFmodels.la $(top_builddir)/libs/util/libQFutil.la diff --git a/libs/models/test/hulls.c b/libs/models/test/hulls.c new file mode 100644 index 000000000..4b363a6a9 --- /dev/null +++ b/libs/models/test/hulls.c @@ -0,0 +1,277 @@ +#include "hulls.h" + +// 0,0 +// |\ . +// |s\ . +// |ss\ . +// 0 1 + +static mclipnode_t clipnodes_simple_wedge[] = { + { 0, { 1, CONTENTS_EMPTY}}, + { 1, {CONTENTS_EMPTY, CONTENTS_SOLID}}, +}; + +static plane_t planes_simple_wedge[] = { + {{1, 0, 0}, 0, 0, 0}, // 0 + {{0.8, 0, 0.6}, 0, 4, 0}, // 1 +}; + +hull_t hull_simple_wedge = { + clipnodes_simple_wedge, + planes_simple_wedge, + 0, + 1, + {0, 0, 0}, + {0, 0, 0}, +}; + +// -32 32 48 +// sss|sss| |sss +// sss|sss| |sss +// 0 1 2 + +static mclipnode_t clipnodes_tpp1[] = { + { 0, { 1, CONTENTS_SOLID}}, + { 1, { 2, CONTENTS_SOLID}}, + { 2, {CONTENTS_SOLID, CONTENTS_EMPTY}}, +}; + +static plane_t planes_tpp1[] = { + {{1, 0, 0}, -32, 0, 0}, + {{1, 0, 0}, 32, 0, 0}, + {{1, 0, 0}, 48, 0, 0}, +}; + +hull_t hull_tpp1 = { + clipnodes_tpp1, + planes_tpp1, + 0, + 2, + {0, 0, 0}, + {0, 0, 0}, +}; + +// -32 32 48 +// sss|sss| |sss +// sss|sss| |sss +// 1 0 2 + +static mclipnode_t clipnodes_tpp2[] = { + { 0, { 2, 1}}, + { 1, {CONTENTS_SOLID, CONTENTS_SOLID}}, + { 2, {CONTENTS_SOLID, CONTENTS_EMPTY}}, +}; + +static plane_t planes_tpp2[] = { + {{1, 0, 0}, 32, 0, 0}, + {{1, 0, 0}, -32, 0, 0}, + {{1, 0, 0}, 48, 0, 0}, +}; + +hull_t hull_tpp2 = { + clipnodes_tpp2, + planes_tpp2, + 0, + 2, + {0, 0, 0}, + {0, 0, 0}, +}; + +// -32 32 48 +// sss| |www|sss +// sss| |www|sss +// 1 0 2 + +static mclipnode_t clipnodes_tppw[] = { + { 0, { 2, 1}}, + { 1, {CONTENTS_EMPTY, CONTENTS_SOLID}}, + { 2, {CONTENTS_SOLID, CONTENTS_WATER}}, +}; + +static plane_t planes_tppw[] = { + {{1, 0, 0}, 32, 0, 0}, + {{1, 0, 0}, -32, 0, 0}, + {{1, 0, 0}, 48, 0, 0}, +}; + +hull_t hull_tppw = { + clipnodes_tppw, + planes_tppw, + 0, + 2, + {0, 0, 0}, + {0, 0, 0}, +}; + +// 2 +// eee|eee +// 0,32+--- 1 +// eee|sss +// ---+--- 0 +// ss0,0ss +static mclipnode_t clipnodes_step1[] = { + { 0, { 1, CONTENTS_SOLID}}, + { 1, {CONTENTS_EMPTY, 2}}, + { 2, {CONTENTS_SOLID, CONTENTS_EMPTY}}, +}; + +static plane_t planes_step1[] = { + {{0, 0, 1}, 0, 2, 0}, + {{0, 0, 1}, 32, 2, 0}, + {{1, 0, 0}, 0, 0, 0}, +}; + +hull_t hull_step1 = { + clipnodes_step1, + planes_step1, + 0, + 2, + {0, 0, 0}, + {0, 0, 0}, +}; + +// 0 +// eee|eee +// 0,32+--- 1 +// eee|sss +// ---+sss 2 +// ss0,0ss +static mclipnode_t clipnodes_step2[] = { + { 0, { 1, 2}}, + { 1, {CONTENTS_EMPTY, CONTENTS_SOLID}}, + { 2, {CONTENTS_EMPTY, CONTENTS_SOLID}}, +}; + +static plane_t planes_step2[] = { + {{1, 0, 0}, 0, 0, 0}, + {{0, 0, 1}, 32, 2, 0}, + {{0, 0, 1}, 0, 2, 0}, +}; + +hull_t hull_step2 = { + clipnodes_step2, + planes_step2, + 0, + 2, + {0, 0, 0}, + {0, 0, 0}, +}; + +// 0 +// eee|eee +// 2---+0,32 +// sss|eee +// sss+--- 1 +// ss0,0ss +static mclipnode_t clipnodes_step3[] = { + { 0, { 1, 2}}, + { 1, {CONTENTS_EMPTY, CONTENTS_SOLID}}, + { 2, {CONTENTS_EMPTY, CONTENTS_SOLID}}, +}; + +static plane_t planes_step3[] = { + {{1, 0, 0}, 0, 0, 0}, + {{0, 0, 1}, 0, 2, 0}, + {{0, 0, 1}, 32, 2, 0}, +}; + +hull_t hull_step3 = { + clipnodes_step3, + planes_step3, + 0, + 2, + {0, 0, 0}, + {0, 0, 0}, +}; + +// 3 2 +// s|e|eee +// 4-+e|-20,40 +// e|e|eee +// 0,32+--- 1 +// eee|sss +// ---+--- 0 +// ss0,0ss +static mclipnode_t clipnodes_covered_step[] = { + { 0, { 1, CONTENTS_SOLID}}, + { 1, { 3, 2}}, + { 2, {CONTENTS_SOLID, CONTENTS_EMPTY}}, + { 3, {CONTENTS_EMPTY, 4}}, + { 4, {CONTENTS_SOLID, CONTENTS_EMPTY}}, +}; + +static plane_t planes_covered_step[] = { + {{0, 0, 1}, 0, 2, 0}, + {{0, 0, 1}, 32, 2, 0}, + {{1, 0, 0}, 0, 0, 0}, + {{1, 0, 0}, -20, 0, 0}, + {{0, 0, 1}, 40, 2, 0}, +}; + +hull_t hull_covered_step = { + clipnodes_covered_step, + planes_covered_step, + 0, + 4, + {0, 0, 0}, + {0, 0, 0}, +}; + +// 0 +// eee|eee +// eee+--- 1 +// ee/0,0s +// 2 ssss +static mclipnode_t clipnodes_ramp[] = { + { 0, { 1, 2}}, + { 1, {CONTENTS_EMPTY, CONTENTS_SOLID}}, + { 2, {CONTENTS_EMPTY, CONTENTS_SOLID}}, +}; + +static plane_t planes_ramp[] = { + {{ 1, 0, 0}, 0, 0, 0}, + {{ 0, 0, 1}, 0, 2, 0}, + {{-0.6, 0, 0.8}, 0, 4, 0}, +}; + +hull_t hull_ramp = { + clipnodes_ramp, + planes_ramp, + 0, + 2, + {0, 0, 0}, + {0, 0, 0}, +}; + +// 2 1 +// ss|sss|ss +// ss+-3-+ss 8 +// ss|eee|ss +// ss+-4-+ss -8 +// ss|sss|ss +// -8 8 +// looking at plane 0: back of 0 is empty, front of 0 has above hole +static mclipnode_t clipnodes_hole[] = { + { 0, { 1, CONTENTS_EMPTY}}, + { 1, {CONTENTS_SOLID, 2}}, + { 2, { 3, CONTENTS_SOLID}}, + { 3, {CONTENTS_SOLID, 4}}, + { 4, {CONTENTS_EMPTY, CONTENTS_SOLID}}, +}; + +static plane_t planes_hole[] = { + {{ 0, 1, 0}, 0, 1, 0}, + {{ 1, 0, 0}, 8, 0, 0}, + {{ 1, 0, 0}, -8, 0, 0}, + {{ 0, 0, 1}, 8, 2, 0}, + {{ 0, 0, 1}, -8, 2, 0}, +}; + +hull_t hull_hole = { + clipnodes_hole, + planes_hole, + 0, + 4, + {0, 0, 0}, + {0, 0, 0}, +}; diff --git a/libs/models/test/hulls.h b/libs/models/test/hulls.h new file mode 100644 index 000000000..a8976f3ee --- /dev/null +++ b/libs/models/test/hulls.h @@ -0,0 +1,12 @@ +#include "world.h" + +extern hull_t hull_simple_wedge; +extern hull_t hull_tpp1; +extern hull_t hull_tpp2; +extern hull_t hull_tppw; +extern hull_t hull_step1; +extern hull_t hull_step2; +extern hull_t hull_step3; +extern hull_t hull_covered_step; +extern hull_t hull_ramp; +extern hull_t hull_hole; diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index 1f0c6578f..165121918 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -4,6 +4,8 @@ #include "getopt.h" #include "world.h" +#include "hulls.h" + #undef DIST_EPSILON #define DIST_EPSILON 0 @@ -22,283 +24,6 @@ && FloatCompare (x[2], y[2])) -// 0,0 -// |\ . -// |s\ . -// |ss\ . -// 0 1 - -mclipnode_t clipnodes_simple_wedge[] = { - { 0, { 1, CONTENTS_EMPTY}}, - { 1, {CONTENTS_EMPTY, CONTENTS_SOLID}}, -}; - -plane_t planes_simple_wedge[] = { - {{1, 0, 0}, 0, 0, 0}, // 0 - {{0.8, 0, 0.6}, 0, 4, 0}, // 1 -}; - -hull_t hull_simple_wedge = { - clipnodes_simple_wedge, - planes_simple_wedge, - 0, - 1, - {0, 0, 0}, - {0, 0, 0}, -}; - -// -32 32 48 -// sss|sss| |sss -// sss|sss| |sss -// 0 1 2 - -mclipnode_t clipnodes_tpp1[] = { - { 0, { 1, CONTENTS_SOLID}}, - { 1, { 2, CONTENTS_SOLID}}, - { 2, {CONTENTS_SOLID, CONTENTS_EMPTY}}, -}; - -plane_t planes_tpp1[] = { - {{1, 0, 0}, -32, 0, 0}, - {{1, 0, 0}, 32, 0, 0}, - {{1, 0, 0}, 48, 0, 0}, -}; - -hull_t hull_tpp1 = { - clipnodes_tpp1, - planes_tpp1, - 0, - 2, - {0, 0, 0}, - {0, 0, 0}, -}; - -// -32 32 48 -// sss|sss| |sss -// sss|sss| |sss -// 1 0 2 - -mclipnode_t clipnodes_tpp2[] = { - { 0, { 2, 1}}, - { 1, {CONTENTS_SOLID, CONTENTS_SOLID}}, - { 2, {CONTENTS_SOLID, CONTENTS_EMPTY}}, -}; - -plane_t planes_tpp2[] = { - {{1, 0, 0}, 32, 0, 0}, - {{1, 0, 0}, -32, 0, 0}, - {{1, 0, 0}, 48, 0, 0}, -}; - -hull_t hull_tpp2 = { - clipnodes_tpp2, - planes_tpp2, - 0, - 2, - {0, 0, 0}, - {0, 0, 0}, -}; - -// -32 32 48 -// sss| |www|sss -// sss| |www|sss -// 1 0 2 - -mclipnode_t clipnodes_tppw[] = { - { 0, { 2, 1}}, - { 1, {CONTENTS_EMPTY, CONTENTS_SOLID}}, - { 2, {CONTENTS_SOLID, CONTENTS_WATER}}, -}; - -plane_t planes_tppw[] = { - {{1, 0, 0}, 32, 0, 0}, - {{1, 0, 0}, -32, 0, 0}, - {{1, 0, 0}, 48, 0, 0}, -}; - -hull_t hull_tppw = { - clipnodes_tppw, - planes_tppw, - 0, - 2, - {0, 0, 0}, - {0, 0, 0}, -}; - -// 2 -// eee|eee -// 0,32+--- 1 -// eee|sss -// ---+--- 0 -// ss0,0ss -mclipnode_t clipnodes_step1[] = { - { 0, { 1, CONTENTS_SOLID}}, - { 1, {CONTENTS_EMPTY, 2}}, - { 2, {CONTENTS_SOLID, CONTENTS_EMPTY}}, -}; - -plane_t planes_step1[] = { - {{0, 0, 1}, 0, 2, 0}, - {{0, 0, 1}, 32, 2, 0}, - {{1, 0, 0}, 0, 0, 0}, -}; - -hull_t hull_step1 = { - clipnodes_step1, - planes_step1, - 0, - 2, - {0, 0, 0}, - {0, 0, 0}, -}; - -// 0 -// eee|eee -// 0,32+--- 1 -// eee|sss -// ---+sss 2 -// ss0,0ss -mclipnode_t clipnodes_step2[] = { - { 0, { 1, 2}}, - { 1, {CONTENTS_EMPTY, CONTENTS_SOLID}}, - { 2, {CONTENTS_EMPTY, CONTENTS_SOLID}}, -}; - -plane_t planes_step2[] = { - {{1, 0, 0}, 0, 0, 0}, - {{0, 0, 1}, 32, 2, 0}, - {{0, 0, 1}, 0, 2, 0}, -}; - -hull_t hull_step2 = { - clipnodes_step2, - planes_step2, - 0, - 2, - {0, 0, 0}, - {0, 0, 0}, -}; - -// 0 -// eee|eee -// 2---+0,32 -// sss|eee -// sss+--- 1 -// ss0,0ss -mclipnode_t clipnodes_step3[] = { - { 0, { 1, 2}}, - { 1, {CONTENTS_EMPTY, CONTENTS_SOLID}}, - { 2, {CONTENTS_EMPTY, CONTENTS_SOLID}}, -}; - -plane_t planes_step3[] = { - {{1, 0, 0}, 0, 0, 0}, - {{0, 0, 1}, 0, 2, 0}, - {{0, 0, 1}, 32, 2, 0}, -}; - -hull_t hull_step3 = { - clipnodes_step3, - planes_step3, - 0, - 2, - {0, 0, 0}, - {0, 0, 0}, -}; - -// 3 2 -// s|e|eee -// 4-+e|-20,40 -// e|e|eee -// 0,32+--- 1 -// eee|sss -// ---+--- 0 -// ss0,0ss -mclipnode_t clipnodes_covered_step[] = { - { 0, { 1, CONTENTS_SOLID}}, - { 1, { 3, 2}}, - { 2, {CONTENTS_SOLID, CONTENTS_EMPTY}}, - { 3, {CONTENTS_EMPTY, 4}}, - { 4, {CONTENTS_SOLID, CONTENTS_EMPTY}}, -}; - -plane_t planes_covered_step[] = { - {{0, 0, 1}, 0, 2, 0}, - {{0, 0, 1}, 32, 2, 0}, - {{1, 0, 0}, 0, 0, 0}, - {{1, 0, 0}, -20, 0, 0}, - {{0, 0, 1}, 40, 2, 0}, -}; - -hull_t hull_covered_step = { - clipnodes_covered_step, - planes_covered_step, - 0, - 4, - {0, 0, 0}, - {0, 0, 0}, -}; - -// 0 -// eee|eee -// eee+--- 1 -// ee/0,0s -// 2 ssss -mclipnode_t clipnodes_ramp[] = { - { 0, { 1, 2}}, - { 1, {CONTENTS_EMPTY, CONTENTS_SOLID}}, - { 2, {CONTENTS_EMPTY, CONTENTS_SOLID}}, -}; - -plane_t planes_ramp[] = { - {{ 1, 0, 0}, 0, 0, 0}, - {{ 0, 0, 1}, 0, 2, 0}, - {{-0.6, 0, 0.8}, 0, 4, 0}, -}; - -hull_t hull_ramp = { - clipnodes_ramp, - planes_ramp, - 0, - 2, - {0, 0, 0}, - {0, 0, 0}, -}; - -// 2 1 -// ss|sss|ss -// ss+-3-+ss 8 -// ss|eee|ss -// ss+-4-+ss -8 -// ss|sss|ss -// -8 8 -// looking at plane 0: back of 0 is empty, front of 0 has above hole -mclipnode_t clipnodes_hole[] = { - { 0, { 1, CONTENTS_EMPTY}}, - { 1, {CONTENTS_SOLID, 2}}, - { 2, { 3, CONTENTS_SOLID}}, - { 3, {CONTENTS_SOLID, 4}}, - { 4, {CONTENTS_EMPTY, CONTENTS_SOLID}}, -}; - -plane_t planes_hole[] = { - {{ 0, 1, 0}, 0, 1, 0}, - {{ 1, 0, 0}, 8, 0, 0}, - {{ 1, 0, 0}, -8, 0, 0}, - {{ 0, 0, 1}, 8, 2, 0}, - {{ 0, 0, 1}, -8, 2, 0}, -}; - -hull_t hull_hole = { - clipnodes_hole, - planes_hole, - 0, - 4, - {0, 0, 0}, - {0, 0, 0}, -}; - - typedef struct { vec3_t extents; } box_t; From 581972c905cb3dd9fe2c844004d13ae0c2c8e7b5 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 3 Dec 2011 21:13:01 +0900 Subject: [PATCH 280/334] More file splitting for code reuse. --- libs/models/test/Makefile.am | 2 +- libs/models/test/main.c | 55 ++++++++++++++++++++++++++++++++++++ libs/models/test/testclip.c | 54 +---------------------------------- 3 files changed, 57 insertions(+), 54 deletions(-) create mode 100644 libs/models/test/main.c diff --git a/libs/models/test/Makefile.am b/libs/models/test/Makefile.am index 792e7ed30..3576c79bc 100644 --- a/libs/models/test/Makefile.am +++ b/libs/models/test/Makefile.am @@ -3,7 +3,7 @@ AUTOMAKE_OPTIONS= foreign INCLUDES= -I$(srcdir) -I$(top_srcdir)/include check_PROGRAMS=testclip -EXTRA_DIST= trace-id.c trace-qf-bad.c hulls.h +EXTRA_DIST= trace-id.c trace-qf-bad.c hulls.h main.c testclip_SOURCES=testclip.c hulls.c testclip_LDADD= $(top_builddir)/libs/models/libQFmodels.la $(top_builddir)/libs/util/libQFutil.la diff --git a/libs/models/test/main.c b/libs/models/test/main.c new file mode 100644 index 000000000..a3d0a3914 --- /dev/null +++ b/libs/models/test/main.c @@ -0,0 +1,55 @@ +#define num_tests (sizeof (tests) / sizeof (tests[0])) + +static int test_enabled[num_tests] = { 0 }; + +int +main (int argc, char **argv) +{ +// vec3_t start, end; + int c; + size_t i, test; + int pass = 1; + + while ((c = getopt (argc, argv, "qvt:")) != EOF) { + switch (c) { + case 'q': + verbose--; + break; + case 'v': + verbose++; + break; + case 't': + test = atoi (optarg); + if (test < num_tests) { + test_enabled[test] = 1; + } else { + fprintf (stderr, "Bad test number (0 - %zd)\n", num_tests); + return 1; + } + break; + default: + fprintf (stderr, "-q (quiet) -v (verbose) and/or -t TEST " + "(test number)\n"); + return 1; + } + } + + for (i = 0; i < num_tests; i++) + if (test_enabled[i]) + break; + if (i == num_tests) { + for (i = 0; i < num_tests; i++) + test_enabled[i] = 1; + } + + if (verbose > 0) + printf ("start -> end => stop frac allsolid startsolid inopen " + "inwater\n"); + for (i = 0; i < num_tests; i++) { + if (!test_enabled[i]) + continue; + pass &= run_test (&tests[i]); + } + + return !pass; +} diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index 165121918..94f52f675 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -174,8 +174,6 @@ test_t tests[] = { }; #define num_tests (sizeof (tests) / sizeof (tests[0])) -static int test_enabled[num_tests] = { 0 }; - int verbose = 0; static trace_t @@ -363,54 +361,4 @@ nodeleaf_bail: return res; } -int -main (int argc, char **argv) -{ -// vec3_t start, end; - int c; - size_t i, test; - int pass = 1; - - while ((c = getopt (argc, argv, "qvt:")) != EOF) { - switch (c) { - case 'q': - verbose--; - break; - case 'v': - verbose++; - break; - case 't': - test = atoi (optarg); - if (test < num_tests) { - test_enabled[test] = 1; - } else { - fprintf (stderr, "Bad test number (0 - %zd)\n", num_tests); - return 1; - } - break; - default: - fprintf (stderr, "-q (quiet) -v (verbose) and/or -t TEST " - "(test number)\n"); - return 1; - } - } - - for (i = 0; i < num_tests; i++) - if (test_enabled[i]) - break; - if (i == num_tests) { - for (i = 0; i < num_tests; i++) - test_enabled[i] = 1; - } - - if (verbose > 0) - printf ("start -> end => stop frac allsolid startsolid inopen " - "inwater\n"); - for (i = 0; i < num_tests; i++) { - if (!test_enabled[i]) - continue; - pass &= run_test (&tests[i]); - } - - return !pass; -} +#include "main.c" From 55eb88b52c8aa3145f0a091da3cc8194bf76b67a Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 3 Dec 2011 22:09:11 +0900 Subject: [PATCH 281/334] Create some tests for MOD_HullContents. --- libs/models/test/Makefile.am | 6 +- libs/models/test/testcontents.c | 155 ++++++++++++++++++++++++++++++++ libs/models/trace.c | 3 +- 3 files changed, 162 insertions(+), 2 deletions(-) create mode 100644 libs/models/test/testcontents.c diff --git a/libs/models/test/Makefile.am b/libs/models/test/Makefile.am index 3576c79bc..14fe9e3dc 100644 --- a/libs/models/test/Makefile.am +++ b/libs/models/test/Makefile.am @@ -2,11 +2,15 @@ AUTOMAKE_OPTIONS= foreign INCLUDES= -I$(srcdir) -I$(top_srcdir)/include -check_PROGRAMS=testclip +check_PROGRAMS=testclip testcontents EXTRA_DIST= trace-id.c trace-qf-bad.c hulls.h main.c testclip_SOURCES=testclip.c hulls.c testclip_LDADD= $(top_builddir)/libs/models/libQFmodels.la $(top_builddir)/libs/util/libQFutil.la testclip_DEPENDENCIES= $(top_builddir)/libs/models/libQFmodels.la $(top_builddir)/libs/util/libQFutil.la +testcontents_SOURCES=testcontents.c hulls.c +testcontents_LDADD= $(top_builddir)/libs/models/libQFmodels.la $(top_builddir)/libs/util/libQFutil.la +testcontents_DEPENDENCIES= $(top_builddir)/libs/models/libQFmodels.la $(top_builddir)/libs/util/libQFutil.la + TESTS=$(check_PROGRAMS) diff --git a/libs/models/test/testcontents.c b/libs/models/test/testcontents.c new file mode 100644 index 000000000..5d5b66219 --- /dev/null +++ b/libs/models/test/testcontents.c @@ -0,0 +1,155 @@ +#include +#include "QF/va.h" + +#include "getopt.h" +#include "world.h" + +#include "hulls.h" + +#undef DIST_EPSILON +#define DIST_EPSILON 0 + +#ifdef TEST_ID +# include "trace-id.c" +#elif defined(TEST_QF_BAD) +# include "trace-qf-bad.c" +#else +# include "../trace.c" +#endif + +typedef struct { + vec3_t extents; +} box_t; + +typedef struct { + const char *desc; + box_t *box; + hull_t *hull; + vec3_t origin; + struct { + int contents; + unsigned contents_flags; + } expect; +} test_t; + +box_t point = { {0, 0, 0} }; +box_t box = { {8, 8, 8} }; +box_t player = { {16, 16, 28} }; + +test_t tests[] = { + {"Point, Three parallel planes 1", &point, &hull_tpp1, + {-33, 0, 0}, { CONTENTS_SOLID, 0}}, + {"Point, Three parallel planes 1", &point, &hull_tpp1, + {-32, 0, 0}, { CONTENTS_SOLID, 0}}, + {"Point, Three parallel planes 1", &point, &hull_tpp1, + {-31, 0, 0}, { CONTENTS_SOLID, 0}}, + {"Point, Three parallel planes 1", &point, &hull_tpp1, + { 31, 0, 0}, { CONTENTS_SOLID, 0}}, + {"Point, Three parallel planes 1", &point, &hull_tpp1, + { 32, 0, 0}, { CONTENTS_EMPTY, 0}}, + {"Point, Three parallel planes 1", &point, &hull_tpp1, + { 48, 0, 0}, { CONTENTS_SOLID, 0}}, + {"Point, Three parallel planes 1", &point, &hull_tpp1, + { 49, 0, 0}, { CONTENTS_SOLID, 0}}, + + {"Box, Three parallel planes 1", &box, &hull_tpp1, + {-40, 0, 0}, { CONTENTS_SOLID, 2}}, + {"Box, Three parallel planes 1", &box, &hull_tpp1, + {-32, 0, 0}, { CONTENTS_SOLID, 2}}, + {"Box, Three parallel planes 1", &box, &hull_tpp1, + { 24, 0, 0}, { CONTENTS_SOLID, 2}}, + {"Box, Three parallel planes 1", &box, &hull_tpp1, + { 31, 0, 0}, { CONTENTS_SOLID, 3}}, + {"Box, Three parallel planes 1", &box, &hull_tpp1, + { 32, 0, 0}, { CONTENTS_SOLID, 3}}, + {"Box, Three parallel planes 1", &box, &hull_tpp1, + { 33, 0, 0}, { CONTENTS_SOLID, 3}}, + {"Box, Three parallel planes 1", &box, &hull_tpp1, + { 40, 0, 0}, { CONTENTS_EMPTY, 1}}, + {"Box, Three parallel planes 1", &box, &hull_tpp1, + { 48, 0, 0}, { CONTENTS_SOLID, 3}}, + {"Box, Three parallel planes 1", &box, &hull_tpp1, + { 49, 0, 0}, { CONTENTS_SOLID, 3}}, + {"Box, Three parallel planes 1", &box, &hull_tpp1, + { 56, 0, 0}, { CONTENTS_SOLID, 2}}, + + {"Point, Three parallel planes with water", &point, &hull_tppw, + {-33, 0, 0}, { CONTENTS_SOLID, 0}}, + {"Point, Three parallel planes with water", &point, &hull_tppw, + {-32, 0, 0}, { CONTENTS_EMPTY, 0}}, + {"Point, Three parallel planes with water", &point, &hull_tppw, + { 32, 0, 0}, { CONTENTS_WATER, 0}}, + {"Point, Three parallel planes with water", &point, &hull_tppw, + { 48, 0, 0}, { CONTENTS_SOLID, 0}}, + + {"Box, Three parallel planes with water", &box, &hull_tppw, + {-32, 0, 0}, { CONTENTS_SOLID, 3}}, + {"Box, Three parallel planes with water", &box, &hull_tppw, + { 0, 0, 0}, { CONTENTS_EMPTY, 1}}, + {"Box, Three parallel planes with water", &box, &hull_tppw, + { 32, 0, 0}, { CONTENTS_WATER, 5}}, + {"Box, Three parallel planes with water", &box, &hull_tppw, + { 48, 0, 0}, { CONTENTS_SOLID, 6}}, + + {"Box, ramp", &box, &hull_ramp, + { 0, 0, 8}, { CONTENTS_EMPTY, 1}}, + {"Box, ramp", &box, &hull_ramp, + { 0, 0, 7}, { CONTENTS_SOLID, 3}}, +}; +#define num_tests (sizeof (tests) / sizeof (tests[0])) + +int verbose = 0; + +static int +do_contents (box_t *box, hull_t *hull, vec3_t origin, trace_t *trace) +{ + memset (trace, 0xff, sizeof (*trace)); + VectorCopy (box->extents, trace->extents); + // FIXME specify tract type in test spec + trace->type = box == &point ? tr_point : tr_box; + return MOD_HullContents (hull, 0, origin, trace); +} + +static int +run_test (test_t *test) +{ + const char *desc; + int res = 0; + char *expect; + char *got; + static int output = 0; + trace_t trace; + int contents; + + if (!test->hull->nodeleafs) + test->hull->nodeleafs = MOD_BuildBrushes (test->hull); + + expect = nva ("expect: (%g %g %g) => %3d %08x", + VectorExpand (test->origin), + test->expect.contents, test->expect.contents_flags); + contents = do_contents (test->box, test->hull, test->origin, &trace); + got = nva (" got: (%g %g %g) => %3d %08x", + VectorExpand (test->origin), + contents, trace.contents); + if (test->expect.contents == contents + && test->expect.contents_flags == trace.contents) + res = 1; + + if (test->desc) + desc = va ("(%d) %s", (int)(long)(test - tests), test->desc); + else + desc = va ("test #%d", (int)(long)(test - tests)); + if (verbose >= 0 || !res) { + if (output) + puts(""); + output = 1; + puts (expect); + puts (got); + printf ("%s: %s\n", res ? "PASS" : "FAIL", desc); + } + free (expect); + free (got); + return res; +} + +#include "main.c" diff --git a/libs/models/trace.c b/libs/models/trace.c index 9b758411b..b2f353474 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -812,13 +812,14 @@ MOD_HullContents (hull_t *hull, int num, const vec3_t origin, trace_t *trace) side = d < 0; num = node->children[side]; } + if (trace) + trace->contents = 0; if (!trace || trace->type == tr_point || prevnode == -1 || !hull->nodeleafs) { return num; } // check the contents of the "central" and surrounding touched leafs leaf = hull->nodeleafs[prevnode].leafs[side]; - trace->contents = 0; test_count++; return trace_contents (hull, trace, leaf, origin); } From 487a6b20ab7bfb09c7f0d482c4420d1064d7cc37 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 4 Dec 2011 09:02:12 +0900 Subject: [PATCH 282/334] Test collisions with a ridge smaller than the box. Whee, found a failing test case :) --- libs/models/test/hulls.c | 29 +++++++++++++++++++++++++++++ libs/models/test/hulls.h | 1 + libs/models/test/testclip.c | 3 +++ libs/models/test/testcontents.c | 5 +++++ 4 files changed, 38 insertions(+) diff --git a/libs/models/test/hulls.c b/libs/models/test/hulls.c index 4b363a6a9..127fe8c04 100644 --- a/libs/models/test/hulls.c +++ b/libs/models/test/hulls.c @@ -275,3 +275,32 @@ hull_t hull_hole = { {0, 0, 0}, {0, 0, 0}, }; + +// 2 3 +// eee|eee|eee +// 0,32+---+--- 1 +// eee|sss|eee +// ---+---+--- 0 +// ss0,0s8,0ss +static mclipnode_t clipnodes_ridge[] = { + { 0, { 1, CONTENTS_SOLID}}, + { 1, {CONTENTS_EMPTY, 2}}, + { 2, { 3, CONTENTS_EMPTY}}, + { 3, {CONTENTS_EMPTY, CONTENTS_SOLID}}, +}; + +static plane_t planes_ridge[] = { + {{0, 0, 1}, 0, 2, 0}, + {{0, 0, 1}, 32, 2, 0}, + {{1, 0, 0}, 0, 0, 0}, + {{1, 0, 0}, 8, 0, 0}, +}; + +hull_t hull_ridge = { + clipnodes_ridge, + planes_ridge, + 0, + 3, + {0, 0, 0}, + {0, 0, 0}, +}; diff --git a/libs/models/test/hulls.h b/libs/models/test/hulls.h index a8976f3ee..440fbfac5 100644 --- a/libs/models/test/hulls.h +++ b/libs/models/test/hulls.h @@ -10,3 +10,4 @@ extern hull_t hull_step3; extern hull_t hull_covered_step; extern hull_t hull_ramp; extern hull_t hull_hole; +extern hull_t hull_ridge; diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index 94f52f675..2ecf0fe9c 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -171,6 +171,9 @@ test_t tests[] = { { 1, -16, 0}, { 1, 16, 0}, { 0.25, 0, 0, 1, 0, 13}}, {"Box, Hole. edge", &box, &hull_hole, {-1, -16, 0}, { -1, 16, 0}, { 0.25, 0, 0, 1, 0, 13}}, + + {"Box, ridge", &box, &hull_ridge, + {4, 41, 0}, { 4, 39, 0}, { 0.5, 0, 0, 1, 0, 8}}, }; #define num_tests (sizeof (tests) / sizeof (tests[0])) diff --git a/libs/models/test/testcontents.c b/libs/models/test/testcontents.c index 5d5b66219..d69b01269 100644 --- a/libs/models/test/testcontents.c +++ b/libs/models/test/testcontents.c @@ -95,6 +95,11 @@ test_t tests[] = { { 0, 0, 8}, { CONTENTS_EMPTY, 1}}, {"Box, ramp", &box, &hull_ramp, { 0, 0, 7}, { CONTENTS_SOLID, 3}}, + + {"Box, ridge", &box, &hull_ridge, + { 4, 0, 40}, { CONTENTS_EMPTY, 1}}, + {"Box, ridge", &box, &hull_ridge, + { 4, 0, 39}, { CONTENTS_SOLID, 3}}, }; #define num_tests (sizeof (tests) / sizeof (tests[0])) From cdfc922bced223301bf823faa15780aa7d6f2d33 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 4 Dec 2011 10:47:52 +0900 Subject: [PATCH 283/334] Fix a silly test case error. --- libs/models/test/testclip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index 2ecf0fe9c..74a132190 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -173,7 +173,7 @@ test_t tests[] = { {-1, -16, 0}, { -1, 16, 0}, { 0.25, 0, 0, 1, 0, 13}}, {"Box, ridge", &box, &hull_ridge, - {4, 41, 0}, { 4, 39, 0}, { 0.5, 0, 0, 1, 0, 8}}, + {4, 0, 41}, { 4, 0, 39}, { 0.5, 0, 0, 1, 0, 8}}, }; #define num_tests (sizeof (tests) / sizeof (tests[0])) From eb5d2720e408630e1a9e638d51f840c826bf7bb6 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 4 Dec 2011 10:55:46 +0900 Subject: [PATCH 284/334] Avoid a segfault when there's no split plane. --- libs/models/trace.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/libs/models/trace.c b/libs/models/trace.c index b2f353474..29c334e81 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -688,8 +688,13 @@ MOD_TraceLine (hull_t *hull, int num, } else { // crossing from an empty leaf to a solid leaf: the trace // has collided. - calc_impact (hull, trace, start_point, end_point, leaf, - split_plane); + if (split_plane) { + calc_impact (hull, trace, start_point, end_point, leaf, + split_plane); + } else { + // if there's no split plane, then there is no impact + trace->fraction = 1.0; + } if (trace->type == tr_point) return; } From e5903a60ff3f246793b2d112250cc15dcd654f22 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 4 Dec 2011 11:00:38 +0900 Subject: [PATCH 285/334] Put the mistaken test case back in. --- libs/models/test/testclip.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index 74a132190..0d1c3696b 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -174,6 +174,8 @@ test_t tests[] = { {"Box, ridge", &box, &hull_ridge, {4, 0, 41}, { 4, 0, 39}, { 0.5, 0, 0, 1, 0, 8}}, + {"Box, ridge, all solid", &box, &hull_ridge, + {4, 41, 0}, { 4, 39, 0}, { 1, 1, 1, 0, 0, 8}}, }; #define num_tests (sizeof (tests) / sizeof (tests[0])) From ed8e09608a1097f40bb6b5f4305b43ddccab4e3e Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 4 Dec 2011 12:11:27 +0900 Subject: [PATCH 286/334] Fix the negative fractions coming from edge_portal_dist(). I have a better fix in the works, but I wanted edge_portal_dist() to be correct. --- libs/models/trace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/models/trace.c b/libs/models/trace.c index 29c334e81..5fc040c8c 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -368,7 +368,7 @@ edge_portal_dist (const plane_t *plane, const clipport_t *portal, VectorMultAdd (p1, t, e, y); VectorSubtract (x, y, y); t = DotProduct (y, vel) / DotProduct (vel, vel); - if (t >= frac) + if (t < 0 || t >= frac) continue; // this is not the nearest edge pair // the edges hit, and they are the closes edge pair so far frac = t; From 4e76aa30259db49421a0e3fc425c4e0b17eac5f0 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 4 Dec 2011 12:46:22 +0900 Subject: [PATCH 287/334] Don't split on a plane parallel to the motion. This seems to improve the start/all solid cases a little, and it should speed things up a little by avoiding unnecessary polygon tests. --- libs/models/trace.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libs/models/trace.c b/libs/models/trace.c index 5fc040c8c..a96101e7a 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -785,6 +785,10 @@ MOD_TraceLine (hull_t *hull, int num, tstack->num = num; tstack->side = side; tstack->plane = plane; + // if the move is parallel to the plane, then the plane is not a good + // split plane + if (start_dist == end_dist) + tstack->plane = split_plane; VectorCopy (end, tstack->end); VectorMultAdd (start, frac[side ^ 1], dist, tstack->start); tstack->start_frac = frac[side ^ 1]; From 053d801e9231764157481bf75fa24ef1f72fe9bd Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 4 Dec 2011 18:52:17 +0900 Subject: [PATCH 288/334] Break out the leaf visit code into its own funciton. --- libs/models/trace.c | 125 ++++++++++++++++++++++++++------------------ 1 file changed, 74 insertions(+), 51 deletions(-) diff --git a/libs/models/trace.c b/libs/models/trace.c index a96101e7a..a7f83233d 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -631,31 +631,91 @@ trace_contents (hull_t *hull, trace_t *trace, clipleaf_t *leaf, return contents; } +typedef struct { + qboolean seen_empty; + qboolean seen_solid; + qboolean moved; + plane_t *split_plane; + vec3_t vel; + const vec_t *origin; + const vec_t *start_point; + const vec_t *end_point; +} trace_state_t; + +static int +visit_leaf (hull_t *hull, int num, clipleaf_t *leaf, trace_t *trace, + trace_state_t *state) +{ + // it's not possible to not be in the leaf when doing a point trace + // if leaf is null, assume we're in the leaf + // if plane is null, the trace did not cross the last node plane + int in_leaf = 1; + if (trace->type != tr_point && leaf && state->split_plane) + in_leaf = check_in_leaf (hull, trace, leaf, state->split_plane, + state->vel, state->origin); + if (in_leaf && num == CONTENTS_SOLID) { + if (!state->seen_empty && !state->seen_solid) { + // this is the first leaf visited, thus the start leaf + trace->startsolid = state->seen_solid = true; + } else if (!state->seen_empty && state->seen_solid) { + // If crossing from one solid leaf to another, treat the + // whole trace as solid (this is what id does). + // However, since allsolid is initialized to true, no need + // to do anything. + if (state->moved) + return 1; + } else { + // crossing from an empty leaf to a solid leaf: the trace + // has collided. + if (state->split_plane) { + calc_impact (hull, trace, state->start_point, state->end_point, + leaf, state->split_plane); + } else { + // if there's no split plane, then there is no impact + trace->fraction = 1.0; + } + if (trace->type == tr_point) + return 1; + } + } else if (in_leaf) { + state->seen_empty = true; + trace->allsolid = false; + if (num == CONTENTS_EMPTY) + trace->inopen = true; + else + trace->inwater = true; + } + return 0; +} + VISIBLE void MOD_TraceLine (hull_t *hull, int num, const vec3_t start_point, const vec3_t end_point, trace_t *trace) { vec_t start_dist, end_dist, frac[2], offset; - vec3_t start, end, dist, vel; + vec3_t start, end, dist; int side; - qboolean seen_empty, seen_solid, moved; tracestack_t *tstack; tracestack_t tracestack[256]; mclipnode_t *node; - plane_t *plane, *split_plane; + plane_t *plane; clipleaf_t *leaf; + trace_state_t trace_state; VectorCopy (start_point, start); VectorCopy (end_point, end); - VectorSubtract (end, start, vel); - VectorNormalize (vel); + VectorSubtract (end, start, trace_state.vel); + VectorNormalize (trace_state.vel); tstack = tracestack; - seen_empty = false; - seen_solid = false; - moved = false; - split_plane = 0; + trace_state.start_point = start_point; + trace_state.end_point = end_point; + trace_state.origin = start; + trace_state.seen_empty = false; + trace_state.seen_solid = false; + trace_state.moved = false; + trace_state.split_plane = 0; leaf = 0; plane = 0; @@ -667,45 +727,8 @@ MOD_TraceLine (hull_t *hull, int num, while (1) { while (num < 0) { - // it's not possible to not be in the leaf when doing a point trace - // if leaf is null, assume we're in the leaf - // if plane is null, the trace did not cross the last node plane - int in_leaf = 1; - if (trace->type != tr_point && leaf && split_plane) - in_leaf = check_in_leaf (hull, trace, leaf, split_plane, - vel, start); - if (in_leaf && num == CONTENTS_SOLID) { - if (!seen_empty && !seen_solid) { - // this is the first leaf visited, thus the start leaf - trace->startsolid = seen_solid = true; - } else if (!seen_empty && seen_solid) { - // If crossing from one solid leaf to another, treat the - // whole trace as solid (this is what id does). - // However, since allsolid is initialized to true, no need - // to do anything. - if (moved) - return; - } else { - // crossing from an empty leaf to a solid leaf: the trace - // has collided. - if (split_plane) { - calc_impact (hull, trace, start_point, end_point, leaf, - split_plane); - } else { - // if there's no split plane, then there is no impact - trace->fraction = 1.0; - } - if (trace->type == tr_point) - return; - } - } else if (in_leaf) { - seen_empty = true; - trace->allsolid = false; - if (num == CONTENTS_EMPTY) - trace->inopen = true; - else - trace->inwater = true; - } + if (visit_leaf (hull, num, leaf, trace, &trace_state)) + return; // pop up the stack for a back side do { @@ -721,8 +744,8 @@ MOD_TraceLine (hull_t *hull, int num, // go down the back side VectorCopy (tstack->end, end); side = tstack->side; - split_plane = tstack->plane; - moved = tstack->start_frac > 0; + trace_state.split_plane = tstack->plane; + trace_state.moved = tstack->start_frac > 0; if (hull->nodeleafs) leaf = hull->nodeleafs[tstack->num].leafs[side ^ 1]; @@ -788,7 +811,7 @@ MOD_TraceLine (hull_t *hull, int num, // if the move is parallel to the plane, then the plane is not a good // split plane if (start_dist == end_dist) - tstack->plane = split_plane; + tstack->plane = trace_state.split_plane; VectorCopy (end, tstack->end); VectorMultAdd (start, frac[side ^ 1], dist, tstack->start); tstack->start_frac = frac[side ^ 1]; From 7da6df9dfbe4911c8070fb0204c623ab984fe0a7 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 4 Dec 2011 19:14:35 +0900 Subject: [PATCH 289/334] Use the "real" contents of the trace's location when visiting a leaf. When visiting a leaf in box mode, use trace_contents() to get the highest priority contents of any leafs touched by the box in the current location. I'm now down to one failing test case, and it's an "allsolid" issue that might be an incorrect assumption in my test case. --- libs/models/trace.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/libs/models/trace.c b/libs/models/trace.c index a7f83233d..f02544c08 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -646,14 +646,23 @@ static int visit_leaf (hull_t *hull, int num, clipleaf_t *leaf, trace_t *trace, trace_state_t *state) { + int contents; + // it's not possible to not be in the leaf when doing a point trace // if leaf is null, assume we're in the leaf // if plane is null, the trace did not cross the last node plane - int in_leaf = 1; - if (trace->type != tr_point && leaf && state->split_plane) - in_leaf = check_in_leaf (hull, trace, leaf, state->split_plane, - state->vel, state->origin); - if (in_leaf && num == CONTENTS_SOLID) { + if (trace->type != tr_point) { + if (state->split_plane + && !check_in_leaf (hull, trace, leaf, state->split_plane, + state->vel, state->origin)) + return 0; // we're not here + //FIXME this is probably slow + test_count++; + contents = trace_contents (hull, trace, leaf, state->origin); + } else { + contents = num; + } + if (contents == CONTENTS_SOLID) { if (!state->seen_empty && !state->seen_solid) { // this is the first leaf visited, thus the start leaf trace->startsolid = state->seen_solid = true; @@ -677,10 +686,10 @@ visit_leaf (hull_t *hull, int num, clipleaf_t *leaf, trace_t *trace, if (trace->type == tr_point) return 1; } - } else if (in_leaf) { + } else { state->seen_empty = true; trace->allsolid = false; - if (num == CONTENTS_EMPTY) + if (contents == CONTENTS_EMPTY) trace->inopen = true; else trace->inwater = true; From b4a497baab474f29da21ab00c644b85ace0c77d4 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 4 Dec 2011 21:12:12 +0900 Subject: [PATCH 290/334] Correctly restore the saved start point. This fixes the point test failures. --- libs/models/test/testclip.c | 8 +++++++- libs/models/trace.c | 4 +--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index 0d1c3696b..2ebe180eb 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -115,8 +115,14 @@ test_t tests[] = { { -8, 0, 8}, {-12, 0, 12}, { 1, 0, 0, 1, 0, 9}}, {"Point, Covered Step touch backside", &point, &hull_covered_step, { 0, 0, 8}, {-12, 0, 12}, { 1, 0, 1, 1, 0, 9}}, + {"Point, Covered Step start solid", &point, &hull_covered_step, + { 0, 0, -4}, {-16, 0, 12}, { 1, 0, 1, 1, 0, 9}}, + {"Point, Covered Step start solid", &point, &hull_covered_step, + { 4, 0, -4}, {-12, 0, 12}, { 1, 1, 1, 0, 0, 9}}, {"Box, Covered Step start solid", &box, &hull_covered_step, - { -4, 0, 4}, {-12, 0, 12}, { 1, 0, 1, 1, 0, 9}}, + { -4, 0, 4}, {-12, 0, 12}, { 1, 1, 1, 0, 0, 9}}, + {"Box, Covered Step start solid", &box, &hull_covered_step, + { -17, 0, 4}, {-17, 0, 12}, { 1, 0, 1, 1, 0, 9}}, {"Box, Covered Step start solid", &box, &hull_covered_step, { -4, 0, 4}, {-16, 0, 36}, { 0.875, 0, 1, 1, 0, 9}}, {"Box, Covered Step start solid", &box, &hull_covered_step, diff --git a/libs/models/trace.c b/libs/models/trace.c index f02544c08..3f4ba1f94 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -747,10 +747,8 @@ MOD_TraceLine (hull_t *hull, int num, } } while (tstack->start_frac > trace->fraction); - // set the hit point for this plane - VectorCopy (end, tstack->start); - // go down the back side + VectorCopy (tstack->start, start); VectorCopy (tstack->end, end); side = tstack->side; trace_state.split_plane = tstack->plane; From 8e512a087c2a6bcef0b471331ac10e116945d76a Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 5 Dec 2011 09:03:04 +0900 Subject: [PATCH 291/334] More failing contents tests. However, I have a plan :) --- libs/models/test/testclip.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index 2ebe180eb..5ca45cfcb 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -85,6 +85,10 @@ test_t tests[] = { { 40, 0, 0}, { 40, 8, 0}, { 1, 0, 0, 0, 1, 3}}, {"Point, Three parallel planes with water", &point, &hull_tppw, { 0, 0, 0}, { 40, 0, 0}, { 1, 0, 0, 1, 1, 3}}, + {"Box, Three parallel planes with water", &box, &hull_tppw, + {-32, 0, 0}, { 40, 0, 0}, { 1, 0, 1, 1, 1, 3}}, + {"Box, Three parallel planes with water", &box, &hull_tppw, + {-32, 0, 0}, { 20, 0, 0}, { 1, 0, 1, 1, 0, 3}}, {"Point, Step 1", &point, &hull_step1, { -16, 0, 8}, {16, 0, 24}, { 0.5, 0, 0, 1, 0, 5}}, From 3bd029d59933222eec727c98853195949db0be9e Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 5 Dec 2011 09:34:43 +0900 Subject: [PATCH 292/334] Make the contents flags clear. I got tired of not being able to remember which flag was which in the output. --- libs/models/test/testclip.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index 5ca45cfcb..594f05907 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -335,7 +335,7 @@ nodeleaf_bail: VectorSubtract (test->end, test->start, end); VectorMultAdd (test->start, test->expect.frac, end, end); expect = nva ("expect: (%g %g %g) -> (%g %g %g) => (%g %g %g)" - " %3g %d %d %d %d", + " %3g as:%d ss:%d io:%d iw:%d", test->start[0], test->start[1], test->start[2], test->end[0], test->end[1], test->end[2], end[0], end[1], end[2], @@ -344,7 +344,7 @@ nodeleaf_bail: test->expect.inopen, test->expect.inwater); trace_t trace = do_trace (test->box, test->hull, test->start, test->end); got = nva (" got: (%g %g %g) -> (%g %g %g) => (%g %g %g)" - " %3g %d %d %d %d", + " %3g as:%d ss:%d io:%d iw:%d", test->start[0], test->start[1], test->start[2], test->end[0], test->end[1], test->end[2], trace.endpos[0], trace.endpos[1], trace.endpos[2], From 8307d9f233417d88212744b6f0a151dfae630f9a Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 5 Dec 2011 14:18:13 +0900 Subject: [PATCH 293/334] Rename check_in_leaf to trace_enters_leaf. --- libs/models/trace.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libs/models/trace.c b/libs/models/trace.c index 3f4ba1f94..ff28789d6 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -136,8 +136,8 @@ edges_intersect (const vec3_t p1, const vec3_t p2, } static int -check_in_leaf (hull_t *hull, trace_t *trace, clipleaf_t *leaf, plane_t *plane, - const vec3_t vel, const vec3_t org) +trace_enters_leaf (hull_t *hull, trace_t *trace, clipleaf_t *leaf, + plane_t *plane, const vec3_t vel, const vec3_t org) { clipport_t *portal; int side; @@ -653,8 +653,8 @@ visit_leaf (hull_t *hull, int num, clipleaf_t *leaf, trace_t *trace, // if plane is null, the trace did not cross the last node plane if (trace->type != tr_point) { if (state->split_plane - && !check_in_leaf (hull, trace, leaf, state->split_plane, - state->vel, state->origin)) + && !trace_enters_leaf (hull, trace, leaf, state->split_plane, + state->vel, state->origin)) return 0; // we're not here //FIXME this is probably slow test_count++; From c588d28b96df4b31a66622182608ff98102f79cc Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 5 Dec 2011 14:18:47 +0900 Subject: [PATCH 294/334] Clear contents flags before calling trace_contents. --- libs/models/trace.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libs/models/trace.c b/libs/models/trace.c index ff28789d6..b824f8244 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -658,6 +658,7 @@ visit_leaf (hull_t *hull, int num, clipleaf_t *leaf, trace_t *trace, return 0; // we're not here //FIXME this is probably slow test_count++; + trace->contents = 0; contents = trace_contents (hull, trace, leaf, state->origin); } else { contents = num; From 4419d4c4ad104663b8f47fea1085de3b10aa227e Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 5 Dec 2011 21:47:21 +0900 Subject: [PATCH 295/334] Move the trace into the leaf before testing the contents. The trace is moved as far into the leaf as possible without leaving the other side of the leaf. This ensures that trace_contents is started from a good location. There is currently a problem with traces that stradle a plane getting, but this has cleared up all the current contents related tests. --- libs/models/trace.c | 43 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/libs/models/trace.c b/libs/models/trace.c index b824f8244..94f5e9bc1 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -65,7 +65,7 @@ typedef struct { } tracestack_t; static inline float -calc_offset (trace_t *trace, plane_t *plane) +calc_offset (const trace_t *trace, const plane_t *plane) { vec_t d = 0; vec3_t Rn; @@ -636,12 +636,41 @@ typedef struct { qboolean seen_solid; qboolean moved; plane_t *split_plane; - vec3_t vel; + vec3_t dist; const vec_t *origin; const vec_t *start_point; const vec_t *end_point; } trace_state_t; +static void +trace_to_leaf (const hull_t *hull, const clipleaf_t *leaf, + const trace_t *trace, const trace_state_t *state, vec3_t stop) +{ + clipport_t *portal; + plane_t *plane; + int side; + vec_t frac = 1; + vec_t t1, t2, offset, f; + qboolean clipped = false; + + for (portal = leaf->portals; portal; portal = portal->next[side]) { + side = portal->leafs[1] == leaf; + plane = hull->planes + portal->planenum; + t1 = PlaneDiff (state->start_point, plane); + t2 = PlaneDiff (state->end_point, plane); + offset = calc_offset (trace, plane); + f = (t1 + (t1 < 0 ? offset : -offset)) / (t1 - t2); + if (f > 0) { + clipped = true; + if (f < frac) + frac = f; + } + } + if (!clipped) + frac = 0; + VectorMultAdd (state->start_point, frac, state->dist, stop); +} + static int visit_leaf (hull_t *hull, int num, clipleaf_t *leaf, trace_t *trace, trace_state_t *state) @@ -652,14 +681,17 @@ visit_leaf (hull_t *hull, int num, clipleaf_t *leaf, trace_t *trace, // if leaf is null, assume we're in the leaf // if plane is null, the trace did not cross the last node plane if (trace->type != tr_point) { + vec3_t origin; + if (state->split_plane && !trace_enters_leaf (hull, trace, leaf, state->split_plane, - state->vel, state->origin)) + state->dist, state->origin)) return 0; // we're not here //FIXME this is probably slow + trace_to_leaf (hull, leaf, trace, state, origin); test_count++; trace->contents = 0; - contents = trace_contents (hull, trace, leaf, state->origin); + contents = trace_contents (hull, trace, leaf, origin); } else { contents = num; } @@ -715,8 +747,7 @@ MOD_TraceLine (hull_t *hull, int num, VectorCopy (start_point, start); VectorCopy (end_point, end); - VectorSubtract (end, start, trace_state.vel); - VectorNormalize (trace_state.vel); + VectorSubtract (end, start, trace_state.dist); tstack = tracestack; trace_state.start_point = start_point; From 9a9079a2b392424feb08051f81b41752039c5bb9 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 5 Dec 2011 21:51:33 +0900 Subject: [PATCH 296/334] Correct the start-solid in a corner test. It turns out that the box trace CAN get out of the solid from that location (though a similar point trace can not). This is because of my decision to allow non-points to touch a plane from either side without crossing the plane, whereas a point touching a plane is always considered to be on the front side of the plane as there is no further information to disambiguate on which side of the plane the point is. --- libs/models/test/testclip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index 594f05907..e0156cd11 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -124,7 +124,7 @@ test_t tests[] = { {"Point, Covered Step start solid", &point, &hull_covered_step, { 4, 0, -4}, {-12, 0, 12}, { 1, 1, 1, 0, 0, 9}}, {"Box, Covered Step start solid", &box, &hull_covered_step, - { -4, 0, 4}, {-12, 0, 12}, { 1, 1, 1, 0, 0, 9}}, + { -4, 0, 4}, {-12, 0, 12}, { 1, 0, 1, 1, 0, 9}}, {"Box, Covered Step start solid", &box, &hull_covered_step, { -17, 0, 4}, {-17, 0, 12}, { 1, 0, 1, 1, 0, 9}}, {"Box, Covered Step start solid", &box, &hull_covered_step, From 4c17ca9583f11f01a5880d90b17419688415b731 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 6 Dec 2011 08:46:04 +0900 Subject: [PATCH 297/334] Break out trace_hits_portal() from trace_enters_leaf(). --- libs/models/trace.c | 64 +++++++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 28 deletions(-) diff --git a/libs/models/trace.c b/libs/models/trace.c index 94f5e9bc1..1f5ea62b8 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -135,53 +135,61 @@ edges_intersect (const vec3_t p1, const vec3_t p2, return true; } -static int +static qboolean +trace_hits_portal (hull_t *hull, trace_t *trace, clipport_t *portal, + const vec3_t start, const vec3_t vel) +{ + int i; + vec_t *point; + vec_t *edge; + vec_t dist, offset, vn; + plane_t *plane; + plane_t cutplane; + + plane = hull->planes + portal->planenum; + vn = DotProduct (vel, plane->normal); + cutplane.type = 3; // generic plane + for (i = 0; i < portal->winding->numpoints; i++) { + point = portal->winding->points[i]; + edge = portal->edges->points[i]; + // so long as the plane distance and offset are calculated using + // the same normal vector, the normal vector length does not + // matter. + CrossProduct (vel, edge, cutplane.normal); + cutplane.dist = DotProduct (cutplane.normal, point); + dist = PlaneDiff (start, &cutplane); + offset = calc_offset (trace, &cutplane); + if ((vn > 0 && dist >= offset) || (vn < 0 && dist <= -offset)) + return false; + } + return true; +} + +static qboolean trace_enters_leaf (hull_t *hull, trace_t *trace, clipleaf_t *leaf, plane_t *plane, const vec3_t vel, const vec3_t org) { clipport_t *portal; int side; - int i; int planenum; - plane_t cutplane; - vec_t offset, dist, v_n; - vec_t *point, *edge; + vec_t v_n; planenum = plane - hull->planes; - cutplane.type = 3; // generic plane v_n = DotProduct (vel, plane->normal); if (!v_n) { //FIXME is this correct? The assumption is that if we got to a leaf //travelliing parallel to its plane, then we have to be in the leaf - return 1; + return true; } for (portal = leaf->portals; portal; portal = portal->next[side]) { side = portal->leafs[1] == leaf; if (portal->planenum != planenum) continue; - for (i = 0; i < portal->winding->numpoints; i++) { - point = portal->winding->points[i]; - edge = portal->edges->points[i]; - // so long as the plane distance and offset are calculated using - // the same normal vector, the normal vector length does not - // matter. - CrossProduct (vel, edge, cutplane.normal); - cutplane.dist = DotProduct (cutplane.normal, point); - dist = PlaneDiff (org, &cutplane); - offset = calc_offset (trace, &cutplane); - if (v_n > 0) { - if (dist >= offset) - break; - } else { - if (dist <= -offset) - break; - } - } - if (i == portal->winding->numpoints) - return 1; + if (trace_hits_portal (hull, trace, portal, org, vel)) + return true; } - return 0; + return false; } typedef struct { From 8fe703d747888926bbb30f258d7556e0ce050b71 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 6 Dec 2011 17:27:05 +0900 Subject: [PATCH 298/334] Trace to adjoining leafs when necessary. When the trace stradles a plane in the current leaf, check the other side of the portal, too, as it is possible that leaf will restrict the movement of the trace. All current tests pass! However, I can think of some situations (and I already have a solution) where things will fail, but that's next. --- libs/models/trace.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/libs/models/trace.c b/libs/models/trace.c index 1f5ea62b8..f5ed722c7 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -650,8 +650,8 @@ typedef struct { const vec_t *end_point; } trace_state_t; -static void -trace_to_leaf (const hull_t *hull, const clipleaf_t *leaf, +static vec_t +trace_to_leaf (const hull_t *hull, clipleaf_t *leaf, const trace_t *trace, const trace_state_t *state, vec3_t stop) { clipport_t *portal; @@ -660,7 +660,9 @@ trace_to_leaf (const hull_t *hull, const clipleaf_t *leaf, vec_t frac = 1; vec_t t1, t2, offset, f; qboolean clipped = false; + clipleaf_t *l; + leaf->test_count = test_count; for (portal = leaf->portals; portal; portal = portal->next[side]) { side = portal->leafs[1] == leaf; plane = hull->planes + portal->planenum; @@ -668,6 +670,10 @@ trace_to_leaf (const hull_t *hull, const clipleaf_t *leaf, t2 = PlaneDiff (state->end_point, plane); offset = calc_offset (trace, plane); f = (t1 + (t1 < 0 ? offset : -offset)) / (t1 - t2); + l = portal->leafs[side^1]; + if (f < 0 && l->contents != CONTENTS_SOLID + && l->test_count != test_count) + f = trace_to_leaf (hull, l, trace, state, 0); if (f > 0) { clipped = true; if (f < frac) @@ -676,7 +682,9 @@ trace_to_leaf (const hull_t *hull, const clipleaf_t *leaf, } if (!clipped) frac = 0; - VectorMultAdd (state->start_point, frac, state->dist, stop); + if (stop) + VectorMultAdd (state->start_point, frac, state->dist, stop); + return frac; } static int @@ -695,11 +703,15 @@ visit_leaf (hull_t *hull, int num, clipleaf_t *leaf, trace_t *trace, && !trace_enters_leaf (hull, trace, leaf, state->split_plane, state->dist, state->origin)) return 0; // we're not here - //FIXME this is probably slow - trace_to_leaf (hull, leaf, trace, state, origin); - test_count++; - trace->contents = 0; - contents = trace_contents (hull, trace, leaf, origin); + contents = leaf->contents; + if (contents != CONTENTS_SOLID) { + //FIXME this is probably slow + test_count++; + trace_to_leaf (hull, leaf, trace, state, origin); + test_count++; + trace->contents = 0; + contents = trace_contents (hull, trace, leaf, origin); + } } else { contents = num; } From f496f4d26028cc6f6136336c6525c5f9d60e6905 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 6 Dec 2011 20:47:57 +0900 Subject: [PATCH 299/334] Whee, more tests that break things :) --- libs/models/test/hulls.c | 32 ++++++++++++++++++++++++++++++++ libs/models/test/hulls.h | 1 + libs/models/test/testclip.c | 5 +++++ 3 files changed, 38 insertions(+) diff --git a/libs/models/test/hulls.c b/libs/models/test/hulls.c index 127fe8c04..5c87b4128 100644 --- a/libs/models/test/hulls.c +++ b/libs/models/test/hulls.c @@ -304,3 +304,35 @@ hull_t hull_ridge = { {0, 0, 0}, {0, 0, 0}, }; + +// 1 2 +// ss\sss/eeee +// sss\s/eeeee +// 3 ----. 0,0 e +// wwwww\eeeee +// wwwwww\eeee +// 0 -------.--- -20 +// sssssssssss +// sssssssssss +static mclipnode_t clipnodes_cave[] = { + { 0, { 1, CONTENTS_SOLID}}, + { 1, { 2, 3}}, + { 2, {CONTENTS_SOLID, CONTENTS_EMPTY}}, + { 3, {CONTENTS_SOLID, CONTENTS_WATER}}, +}; + +static plane_t planes_cave[] = { + {{ 0, 0, 1}, -20, 2, 0}, + {{ 0.6, 0, 0.8}, 0, 3, 0}, + {{-0.8, 0, 0.6}, 0, 3, 0}, + {{ 0, 0, 1}, 0, 2, 0}, +}; + +hull_t hull_cave = { + clipnodes_cave, + planes_cave, + 0, + 3, + {0, 0, 0}, + {0, 0, 0}, +}; diff --git a/libs/models/test/hulls.h b/libs/models/test/hulls.h index 440fbfac5..47bd6f76a 100644 --- a/libs/models/test/hulls.h +++ b/libs/models/test/hulls.h @@ -11,3 +11,4 @@ extern hull_t hull_covered_step; extern hull_t hull_ramp; extern hull_t hull_hole; extern hull_t hull_ridge; +extern hull_t hull_cave; diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index e0156cd11..8eef36b73 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -186,6 +186,11 @@ test_t tests[] = { {4, 0, 41}, { 4, 0, 39}, { 0.5, 0, 0, 1, 0, 8}}, {"Box, ridge, all solid", &box, &hull_ridge, {4, 41, 0}, { 4, 39, 0}, { 1, 1, 1, 0, 0, 8}}, + + {"Box, cave. start solid", &box, &hull_cave, + { 4, 0, -16}, { 4, 0, 0}, { 0.5, 0, 1, 0, 1, 6}}, + {"Box, cave. start solid", &box, &hull_cave, + {-8, 0, -16}, { -8, 0, 0}, { 0.5, 0, 1, 0, 1, 6}}, }; #define num_tests (sizeof (tests) / sizeof (tests[0])) From 632817fed5789625c622cbef241ff8980c44069d Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 6 Dec 2011 20:48:31 +0900 Subject: [PATCH 300/334] Fail properly when the portals are bogus. --- libs/models/test/testclip.c | 38 ++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index 8eef36b73..ace754872 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -243,7 +243,7 @@ run_test (test_t *test) { const char *desc; vec3_t end; - int res = 0; + int err = 0; char *expect; char *got; static int output = 0; @@ -266,17 +266,17 @@ run_test (test_t *test) && (hull->nodeleafs[i].leafs[j]->contents != hull->clipnodes[i].children[j]))) { printf ("bad nodeleaf %d %d\n", i, j); - res = 1; + err = 1; } } if (hull->nodeleafs[i].leafs[0] && (hull->nodeleafs[i].leafs[0] == hull->nodeleafs[i].leafs[1])) { printf ("bad nodeleaf %d %d\n", i, j); - res = 1; + err = 1; } } - if (res) + if (err) goto nodeleaf_bail; for (i = hull->firstclipnode; i <= hull->lastclipnode; i++) { for (j = 0; j < 2; j++) { @@ -288,14 +288,14 @@ run_test (test_t *test) } for (i = 0, p = portal_list; p; i++, p = p->next) { if (!p->portal->winding || !p->portal->edges) { - res = 1; + err = 1; printf ("portal with missing vertex/edge information\n"); } } - if (res) + if (err) goto nodeleaf_bail; if (i != test->expect.num_portals) { - res = 1; + err = 1; printf ("bad portal count: %d %d\n", test->expect.num_portals, i); goto nodeleaf_bail; } @@ -318,14 +318,14 @@ run_test (test_t *test) side = portal->leafs[1] == leaf; if (!side && portal->leafs[0] != leaf) { printf ("mislinked portal\n"); - res = 1; + err = 1; } if (portal == p->portal) found = 1; } if (!found) { printf ("portal unreachable from leaf\n"); - res = 1; + err = 1; } } } @@ -356,29 +356,29 @@ nodeleaf_bail: trace.fraction, trace.allsolid, trace.startsolid, trace.inopen, trace.inwater); - if (VectorCompare (end, trace.endpos) - && FloatCompare (test->expect.frac, trace.fraction) - && test->expect.allsolid == trace.allsolid - && test->expect.startsolid == trace.startsolid - && test->expect.inopen == trace.inopen - && test->expect.inwater == trace.inwater) - res = 1; + if (!(VectorCompare (end, trace.endpos) + && FloatCompare (test->expect.frac, trace.fraction) + && test->expect.allsolid == trace.allsolid + && test->expect.startsolid == trace.startsolid + && test->expect.inopen == trace.inopen + && test->expect.inwater == trace.inwater)) + err = 1; if (test->desc) desc = va ("(%d) %s", (int)(long)(test - tests), test->desc); else desc = va ("test #%d", (int)(long)(test - tests)); - if (verbose >= 0 || !res) { + if (verbose >= 0 || err) { if (output) puts(""); output = 1; puts (expect); puts (got); - printf ("%s: %s\n", res ? "PASS" : "FAIL", desc); + printf ("%s: %s\n", !err ? "PASS" : "FAIL", desc); } free (expect); free (got); - return res; + return !err; } #include "main.c" From 2b65f81b72252db36c8f87b161088a2eabee995e Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 6 Dec 2011 20:50:09 +0900 Subject: [PATCH 301/334] Use a saner "infinity". 8e6 is just too big for reasonable floating point. This fixes the bogus portals. --- libs/models/winding.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/models/winding.c b/libs/models/winding.c index 455707a36..a58cd4260 100644 --- a/libs/models/winding.c +++ b/libs/models/winding.c @@ -39,7 +39,7 @@ static __attribute__ ((used)) const char rcsid[] = #include "QF/winding.h" -#define BOGUS (8e6) +#define BOGUS (65336.0) /** \addtogroup qfbsp_winding */ From 8c840a7003107a1e49e988e16616fce2664e64ce Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 6 Dec 2011 22:06:25 +0900 Subject: [PATCH 302/334] Sanitize trace_hits_plane(). While unit normals aren't needed, they were too big for sane math. Now epsilon can be used for the distance tests. One of the two new tests passes now :). --- libs/models/trace.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/libs/models/trace.c b/libs/models/trace.c index f5ed722c7..fa80b3895 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -55,6 +55,8 @@ static __attribute__ ((used)) const char rcsid[] = #define DIST_EPSILON (0.03125) #endif +#define PLANE_EPSILON (0.001) + typedef struct { vec3_t start; vec3_t end; @@ -64,6 +66,15 @@ typedef struct { plane_t *plane; } tracestack_t; +static void +fast_norm (vec3_t v) +{ + vec_t m; + + m = fabs (v[0]) + fabs (v[1]) + fabs (v[2]); + VectorScale (v, 1 / m, v); +} + static inline float calc_offset (const trace_t *trace, const plane_t *plane) { @@ -156,10 +167,12 @@ trace_hits_portal (hull_t *hull, trace_t *trace, clipport_t *portal, // the same normal vector, the normal vector length does not // matter. CrossProduct (vel, edge, cutplane.normal); + fast_norm (cutplane.normal); cutplane.dist = DotProduct (cutplane.normal, point); dist = PlaneDiff (start, &cutplane); offset = calc_offset (trace, &cutplane); - if ((vn > 0 && dist >= offset) || (vn < 0 && dist <= -offset)) + if ((vn > 0 && dist >= offset - PLANE_EPSILON) + || (vn < 0 && dist <= -offset + PLANE_EPSILON)) return false; } return true; From ff693a956a578613cba76f1fce50a01dc29d26ce Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 6 Dec 2011 22:09:40 +0900 Subject: [PATCH 303/334] Avoid missed portals in trace_to_leaf(). --- libs/models/trace.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libs/models/trace.c b/libs/models/trace.c index fa80b3895..c87c2463f 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -147,8 +147,8 @@ edges_intersect (const vec3_t p1, const vec3_t p2, } static qboolean -trace_hits_portal (hull_t *hull, trace_t *trace, clipport_t *portal, - const vec3_t start, const vec3_t vel) +trace_hits_portal (const hull_t *hull, const trace_t *trace, + clipport_t *portal, const vec3_t start, const vec3_t vel) { int i; vec_t *point; @@ -678,6 +678,9 @@ trace_to_leaf (const hull_t *hull, clipleaf_t *leaf, leaf->test_count = test_count; for (portal = leaf->portals; portal; portal = portal->next[side]) { side = portal->leafs[1] == leaf; + if (!trace_hits_portal (hull, trace, portal, + state->start_point, state->dist)) + continue; plane = hull->planes + portal->planenum; t1 = PlaneDiff (state->start_point, plane); t2 = PlaneDiff (state->end_point, plane); From 4f13d19b7ebedd4b1a607c8fb5ccbb0e322b22fd Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 7 Dec 2011 10:35:58 +0900 Subject: [PATCH 304/334] Optimize edges_intersect(). I found wolfram's line-line intersection page and noticed their equation for the time of intersection was rather different to mine. After analyzing the differences, it turns out they produce exactly the same results (when the lines are coplanar), but their method allows me to eliminate one dot product (4->3). Not only that, but it turns out that their method works equally well for skew lines (ie, non-coplanar). mine: CxA.CxA ------- CxA.AxB theirs: CxA.AxB ------- AxB.AxB --- libs/models/trace.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/libs/models/trace.c b/libs/models/trace.c index c87c2463f..78ed5c798 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -127,7 +127,7 @@ edges_intersect (const vec3_t p1, const vec3_t p2, { vec3_t p, r, b; vec3_t p_r, b_p, b_r; - vec_t tp, tpd, tr, trd; + vec_t tp, tr, den; VectorSubtract (p2, p1, p); VectorSubtract (r2, r1, r); @@ -137,11 +137,10 @@ edges_intersect (const vec3_t p1, const vec3_t p2, return false; CrossProduct (b, p, b_p); CrossProduct (b, r, b_r); - tr = DotProduct (b_p, b_p); - trd = DotProduct (b_p, p_r); - tp = DotProduct (b_r, b_r); - tpd = DotProduct (b_r, p_r); - if ((tr < 0 || tr > trd) || (tp < 0 || tp > tpd)) + tr = DotProduct (b_p, p_r); + tp = DotProduct (b_r, p_r); + den = DotProduct (p_r, p_r); + if ((tr < 0 || tr > den) || (tp < 0 || tp > den)) return false; return true; } From fc14826cd69be2b4806481f7895c897316b9b774 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 7 Dec 2011 10:42:39 +0900 Subject: [PATCH 305/334] Reorganize the code a little. --- libs/models/trace.c | 192 ++++++++++++++++++++++---------------------- 1 file changed, 96 insertions(+), 96 deletions(-) diff --git a/libs/models/trace.c b/libs/models/trace.c index 78ed5c798..9b9f29ce1 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -57,6 +57,24 @@ static __attribute__ ((used)) const char rcsid[] = #define PLANE_EPSILON (0.001) +typedef struct { + plane_t planes[3]; + winding_t points[3]; + winding_t edges[3]; + clipport_t portals[3]; +} clipbox_t; + +typedef struct { + qboolean seen_empty; + qboolean seen_solid; + qboolean moved; + plane_t *split_plane; + vec3_t dist; + const vec_t *origin; + const vec_t *start_point; + const vec_t *end_point; +} trace_state_t; + typedef struct { vec3_t start; vec3_t end; @@ -75,12 +93,89 @@ fast_norm (vec3_t v) VectorScale (v, 1 / m, v); } +/** Initialize the clipbox representing the faces that might hit the portal. + + When a box is moving, at most three of its faces might hit the portal. + Those faces all face such that the dot product of their normal and the + box's velocity is positive (ie, n.v > 0). When the motion is in an axial + plane, only two faces might hit. For axial motion, only one face. + + The faces are set up such that the first point of each winding is the + leading corner of the box, and the edges are set up such that testing + only the first three edges of each winding covers all nine edges (ie, + the forth edge of one face is the reverse of the first edge of the next + face). + + The windings are clockwise when looking down the face's normal (ie, when + looking at the front of the face). +*/ +static void +init_box (const trace_t *trace, clipbox_t *box, const vec3_t vel) +{ + vec3_t p; + int u[3]; + int i, j, k; + vec_t s[2] = {1, -1}; + + //FIXME rotated box + for (i = 0; i < 3; i++) + u[i] = (vel[i] >= 0 ? 1 : -1); + Vector3Scale (u, trace->extents, p); + for (i = 0; i < 3; i++) { + box->portals[i].planenum = i; + box->portals[i].next[0] = 0; + box->portals[i].next[0] = 0; + box->portals[i].leafs[0] = 0; + box->portals[i].leafs[0] = 0; + box->portals[i].winding = &box->points[i]; + box->portals[i].edges = &box->edges[i]; + + VectorZero (box->planes[i].normal); + box->planes[i].normal[i] = u[i]; + box->planes[i].dist = DotProduct (p, box->planes[i].normal); + box->planes[i].type = i; + + box->points[i].numpoints = 4; + box->edges[i].numpoints = 4; + VectorCopy (u, box->points[i].points[0]); + VectorZero (box->edges[i].points[0]); + j = (i + (u[0]*u[1]*u[2] + 3) / 2) % 3; + box->edges[i].points[0][j] = -u[j]; + for (j = 1; j < 4; j++) { + box->points[i].points[j][i] = box->points[i].points[j - 1][i]; + box->edges[i].points[j][i] = box->edges[i].points[j - 1][i]; + for (k = 0; k < 2; k++) { + int a, b; + a = (i + 1 + k) % 3; + b = (i + 2 - k) % 3; + box->points[i].points[j][a] + = s[k] * u[i] * box->points[i].points[j - 1][b]; + box->edges[i].points[j][a] + = s[k] * u[i] * box->edges[i].points[j - 1][b]; + } + Vector3Scale (box->points[i].points[j - 1], trace->extents, + box->points[i].points[j - 1]); + Vector3Scale (box->edges[i].points[j - 1], trace->extents, + box->edges[i].points[j - 1]); + VectorScale (box->edges[i].points[j - 1], 2, + box->edges[i].points[j - 1]); + } + Vector3Scale (box->points[i].points[3], trace->extents, + box->points[i].points[3]); + Vector3Scale (box->edges[i].points[3], trace->extents, + box->edges[i].points[3]); + VectorScale (box->edges[i].points[3], 2, + box->edges[i].points[3]); + } +} + static inline float calc_offset (const trace_t *trace, const plane_t *plane) { vec_t d = 0; vec3_t Rn; + //FIXME rotated box/ellipsoid switch (trace->type) { case tr_point: break; @@ -204,89 +299,6 @@ trace_enters_leaf (hull_t *hull, trace_t *trace, clipleaf_t *leaf, return false; } -typedef struct { - plane_t planes[3]; - winding_t points[3]; - winding_t edges[3]; - clipport_t portals[3]; -} clipbox_t; - -/** Initialize the clipbox representing the faces that might hit the portal. - - When a box is moving, at most three of its faces might hit the portal. - Those faces all face such that the dot product of their normal and the - box's velocity is positive (ie, n.v > 0). When the motion is in an axial - plane, only two faces might hit. For axial motion, only one face. - - The faces are set up such that the first point of each winding is the - leading corner of the box, and the edges are set up such that testing - only the first three edges of each winding covers all nine edges (ie, - the forth edge of one face is the reverse of the first edge of the next - face). - - The windings are clockwise when looking down the face's normal (ie, when - looking at the front of the face). -*/ -static void -init_box (const trace_t *trace, clipbox_t *box, const vec3_t vel) -{ - vec3_t p; - int u[3]; - int i, j, k; - vec_t s[2] = {1, -1}; - - //FIXME rotated box - for (i = 0; i < 3; i++) - u[i] = (vel[i] >= 0 ? 1 : -1); - Vector3Scale (u, trace->extents, p); - for (i = 0; i < 3; i++) { - box->portals[i].planenum = i; - box->portals[i].next[0] = 0; - box->portals[i].next[0] = 0; - box->portals[i].leafs[0] = 0; - box->portals[i].leafs[0] = 0; - box->portals[i].winding = &box->points[i]; - box->portals[i].edges = &box->edges[i]; - - VectorZero (box->planes[i].normal); - box->planes[i].normal[i] = u[i]; - box->planes[i].dist = DotProduct (p, box->planes[i].normal); - box->planes[i].type = i; - - box->points[i].numpoints = 4; - box->edges[i].numpoints = 4; - VectorCopy (u, box->points[i].points[0]); - VectorZero (box->edges[i].points[0]); - j = (i + (u[0]*u[1]*u[2] + 3) / 2) % 3; - box->edges[i].points[0][j] = -u[j]; - for (j = 1; j < 4; j++) { - box->points[i].points[j][i] = box->points[i].points[j - 1][i]; - box->edges[i].points[j][i] = box->edges[i].points[j - 1][i]; - for (k = 0; k < 2; k++) { - int a, b; - a = (i + 1 + k) % 3; - b = (i + 2 - k) % 3; - box->points[i].points[j][a] - = s[k] * u[i] * box->points[i].points[j - 1][b]; - box->edges[i].points[j][a] - = s[k] * u[i] * box->edges[i].points[j - 1][b]; - } - Vector3Scale (box->points[i].points[j - 1], trace->extents, - box->points[i].points[j - 1]); - Vector3Scale (box->edges[i].points[j - 1], trace->extents, - box->edges[i].points[j - 1]); - VectorScale (box->edges[i].points[j - 1], 2, - box->edges[i].points[j - 1]); - } - Vector3Scale (box->points[i].points[3], trace->extents, - box->points[i].points[3]); - Vector3Scale (box->edges[i].points[3], trace->extents, - box->edges[i].points[3]); - VectorScale (box->edges[i].points[3], 2, - box->edges[i].points[3]); - } -} - static vec_t edge_portal_dist (const plane_t *plane, const clipport_t *portal, const vec3_t p1, const vec3_t p2, const vec3_t vel) @@ -651,17 +663,6 @@ trace_contents (hull_t *hull, trace_t *trace, clipleaf_t *leaf, return contents; } -typedef struct { - qboolean seen_empty; - qboolean seen_solid; - qboolean moved; - plane_t *split_plane; - vec3_t dist; - const vec_t *origin; - const vec_t *start_point; - const vec_t *end_point; -} trace_state_t; - static vec_t trace_to_leaf (const hull_t *hull, clipleaf_t *leaf, const trace_t *trace, const trace_state_t *state, vec3_t stop) @@ -709,11 +710,10 @@ visit_leaf (hull_t *hull, int num, clipleaf_t *leaf, trace_t *trace, int contents; // it's not possible to not be in the leaf when doing a point trace - // if leaf is null, assume we're in the leaf - // if plane is null, the trace did not cross the last node plane if (trace->type != tr_point) { vec3_t origin; + // if split_plane is null, the trace did not cross the last node plane if (state->split_plane && !trace_enters_leaf (hull, trace, leaf, state->split_plane, state->dist, state->origin)) From 6a4021517b382330d071e7e1e1c7321e03453e6b Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 7 Dec 2011 10:54:37 +0900 Subject: [PATCH 306/334] Move the box face info into trace_state and init only once. Then clean up the mess of excess function paramenters. --- libs/models/trace.c | 52 ++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/libs/models/trace.c b/libs/models/trace.c index 9b9f29ce1..91c54c2f3 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -73,6 +73,7 @@ typedef struct { const vec_t *origin; const vec_t *start_point; const vec_t *end_point; + clipbox_t box; } trace_state_t; typedef struct { @@ -411,13 +412,16 @@ edge_portal_dist (const plane_t *plane, const clipport_t *portal, static vec_t box_portal_dist (const hull_t *hull, const clipport_t *portal, - const clipbox_t *box, const vec3_t start, const vec3_t vel) + const trace_state_t *state) { vec3_t nvel; plane_t *plane = hull->planes + portal->planenum; int i, j; vec_t frac, t; vec3_t p1, p2; + const clipbox_t *box = &state->box; + const vec_t *start = state->start_point; + const vec_t *vel = state->dist; frac = 1.0; for (i = 0; i < 3; i++) { @@ -450,16 +454,14 @@ box_portal_dist (const hull_t *hull, const clipport_t *portal, } static inline void -calc_impact (hull_t *hull, trace_t *trace, - const vec3_t start, const vec3_t end, - clipleaf_t *leaf, plane_t *plane) +calc_impact (hull_t *hull, trace_t *trace, trace_state_t *state, + clipleaf_t *leaf) { vec_t t1, t2, frac, offset; - vec3_t dist; - t1 = PlaneDiff (start, plane); - t2 = PlaneDiff (end, plane); - offset = calc_offset (trace, plane); + t1 = PlaneDiff (state->start_point, state->split_plane); + t2 = PlaneDiff (state->end_point, state->split_plane); + offset = calc_offset (trace, state->split_plane); if (t1 < 0) { frac = (t1 + offset + DIST_EPSILON) / (t1 - t2); @@ -475,18 +477,14 @@ calc_impact (hull_t *hull, trace_t *trace, int planenum; clipport_t *portal; vec3_t impact; - clipbox_t box; - planenum = plane - hull->planes; + planenum = state->split_plane - hull->planes; - VectorSubtract (end, start, dist); - VectorMultAdd (start, frac, dist, impact); - if (DotProduct (dist, plane->normal) > 0) - VectorMultAdd (impact, offset, plane->normal, impact); + VectorMultAdd (state->start_point, frac, state->dist, impact); + if (DotProduct (state->dist, state->split_plane->normal) > 0) + VectorMultAdd (impact, offset, state->split_plane->normal, impact); else - VectorMultSub (impact, offset, plane->normal, impact); - - init_box (trace, &box, dist); + VectorMultSub (impact, offset, state->split_plane->normal, impact); for (portal = leaf->portals; portal; portal = portal->next[side]) { side = portal->leafs[1] == leaf; @@ -496,7 +494,7 @@ calc_impact (hull_t *hull, trace_t *trace, vec3_t r, s; VectorSubtract (impact, portal->winding->points[i], r); CrossProduct (r, portal->edges->points[i], s); - if (DotProduct (s, plane->normal) > 0) + if (DotProduct (s, state->split_plane->normal) > 0) continue; // "hit" break; // "miss"; } @@ -510,7 +508,7 @@ calc_impact (hull_t *hull, trace_t *trace, side = portal->leafs[1] == leaf; if (portal->planenum != planenum) continue; - t = box_portal_dist (hull, portal, &box, start, dist); + t = box_portal_dist (hull, portal, state); if (t < frac) frac = t; } @@ -518,15 +516,14 @@ calc_impact (hull_t *hull, trace_t *trace, finish_impact: if (frac < trace->fraction) { trace->fraction = frac; - VectorSubtract (end, start, dist); - VectorMultAdd (start, frac, dist, trace->endpos); + VectorMultAdd (state->start_point, frac, state->dist, trace->endpos); if (t1 < 0) { // invert plane paramterers - VectorNegate (plane->normal, trace->plane.normal); - trace->plane.dist = -plane->dist; + VectorNegate (state->split_plane->normal, trace->plane.normal); + trace->plane.dist = -state->split_plane->dist; } else { - VectorCopy (plane->normal, trace->plane.normal); - trace->plane.dist = plane->dist; + VectorCopy (state->split_plane->normal, trace->plane.normal); + trace->plane.dist = state->split_plane->dist; } } } @@ -745,8 +742,7 @@ visit_leaf (hull_t *hull, int num, clipleaf_t *leaf, trace_t *trace, // crossing from an empty leaf to a solid leaf: the trace // has collided. if (state->split_plane) { - calc_impact (hull, trace, state->start_point, state->end_point, - leaf, state->split_plane); + calc_impact (hull, trace, state, leaf); } else { // if there's no split plane, then there is no impact trace->fraction = 1.0; @@ -792,6 +788,8 @@ MOD_TraceLine (hull_t *hull, int num, trace_state.seen_solid = false; trace_state.moved = false; trace_state.split_plane = 0; + init_box (trace, &trace_state.box, trace_state.dist); + leaf = 0; plane = 0; From 9d2914474c94988c2c797dbaf7630625b0d58d25 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 7 Dec 2011 12:16:58 +0900 Subject: [PATCH 307/334] Fix the edge vectors when bounding the portal points. --- libs/models/test/testclip.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index ace754872..b860da690 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -308,6 +308,8 @@ run_test (test_t *test) p->portal->winding->points[j][2] = bound (-8192, p->portal->winding->points[j][2], 8192); } + FreeWinding (p->portal->edges); + p->portal->edges = WindingVectors (p->portal->winding, 0); for (j = 0; j < 2; j++) { int found = 0; From 5af88d33fe06d70930036acf568c26c3a2cf65e9 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 7 Dec 2011 12:17:51 +0900 Subject: [PATCH 308/334] Trace to the current portal rather than the portal's plane. --- libs/models/trace.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/libs/models/trace.c b/libs/models/trace.c index 91c54c2f3..a727332ed 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -665,24 +665,25 @@ trace_to_leaf (const hull_t *hull, clipleaf_t *leaf, const trace_t *trace, const trace_state_t *state, vec3_t stop) { clipport_t *portal; - plane_t *plane; int side; vec_t frac = 1; - vec_t t1, t2, offset, f; + plane_t *plane; + vec_t f; qboolean clipped = false; clipleaf_t *l; + trace_state_t lstate = *state; leaf->test_count = test_count; for (portal = leaf->portals; portal; portal = portal->next[side]) { side = portal->leafs[1] == leaf; + plane = hull->planes + portal->planenum; + if (plane == state->split_plane) + continue; if (!trace_hits_portal (hull, trace, portal, state->start_point, state->dist)) continue; - plane = hull->planes + portal->planenum; - t1 = PlaneDiff (state->start_point, plane); - t2 = PlaneDiff (state->end_point, plane); - offset = calc_offset (trace, plane); - f = (t1 + (t1 < 0 ? offset : -offset)) / (t1 - t2); + lstate.split_plane = plane; + f = box_portal_dist (hull, portal, &lstate); l = portal->leafs[side^1]; if (f < 0 && l->contents != CONTENTS_SOLID && l->test_count != test_count) From 4ed8b69e2455637e50d96dd1db0f12fe582e6e33 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 7 Dec 2011 12:20:04 +0900 Subject: [PATCH 309/334] Check the cross product length before testing its direction. This fixes the bogus portal crossings. --- libs/models/trace.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libs/models/trace.c b/libs/models/trace.c index a727332ed..a3e66dc21 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -211,6 +211,8 @@ point_inside_portal (const clipport_t *portal, const plane_t *plane, for (i = 0; i < points->numpoints; i++) { VectorSubtract (p, points->points[i], x); CrossProduct (x, edges->points[i], c); + if (DotProduct (c, c) < PLANE_EPSILON) + return false; if (DotProduct (c, n) <= 0) return false; } From ccbc69a7f59b52089d918754f50f2f8f1635a576 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 7 Dec 2011 13:31:21 +0900 Subject: [PATCH 310/334] Carve out some more cave and add some more tests. One of them even breaks the code :) --- libs/models/test/hulls.c | 32 +++++++++++++++++++++----------- libs/models/test/testclip.c | 8 ++++++-- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/libs/models/test/hulls.c b/libs/models/test/hulls.c index 5c87b4128..4479f08e9 100644 --- a/libs/models/test/hulls.c +++ b/libs/models/test/hulls.c @@ -305,20 +305,27 @@ hull_t hull_ridge = { {0, 0, 0}, }; -// 1 2 -// ss\sss/eeee -// sss\s/eeeee -// 3 ----. 0,0 e -// wwwww\eeeee -// wwwwww\eeee -// 0 -------.--- -20 -// sssssssssss -// sssssssssss +// 5 +// ssssssssssss|6e +// 1 sssssss 2 s.ee +// \sssssss/ss/|ee +// s\sssss/ss/e|ee +// ss\s 4.--.--.-- 20 +// sss\s/eeeeeeeee +// 3 ----. 0,0 eeeee +// wwwww\eeeeeeeee +// wwwwww\eeeeeeee +// 0 -------.------- -20 +// sssssssssssssss +// sssssssssssssss static mclipnode_t clipnodes_cave[] = { { 0, { 1, CONTENTS_SOLID}}, { 1, { 2, 3}}, - { 2, {CONTENTS_SOLID, CONTENTS_EMPTY}}, + { 2, {CONTENTS_SOLID, 4}}, { 3, {CONTENTS_SOLID, CONTENTS_WATER}}, + { 4, { 5, CONTENTS_EMPTY}}, + { 5, {CONTENTS_EMPTY, 6}}, + { 6, {CONTENTS_SOLID, CONTENTS_EMPTY}}, }; static plane_t planes_cave[] = { @@ -326,13 +333,16 @@ static plane_t planes_cave[] = { {{ 0.6, 0, 0.8}, 0, 3, 0}, {{-0.8, 0, 0.6}, 0, 3, 0}, {{ 0, 0, 1}, 0, 2, 0}, + {{ 0, 0, 1}, 20, 2, 0}, + {{ 1, 0, 0}, 50, 0, 0}, + {{-0.8, 0, 0.6}, -20, 3, 0}, }; hull_t hull_cave = { clipnodes_cave, planes_cave, 0, - 3, + 6, {0, 0, 0}, {0, 0, 0}, }; diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index b860da690..4b560c2f8 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -188,9 +188,13 @@ test_t tests[] = { {4, 41, 0}, { 4, 39, 0}, { 1, 1, 1, 0, 0, 8}}, {"Box, cave. start solid", &box, &hull_cave, - { 4, 0, -16}, { 4, 0, 0}, { 0.5, 0, 1, 0, 1, 6}}, + { 4, 0, -16}, { 4, 0, 0}, { 0.5, 0, 1, 0, 1, 14}}, {"Box, cave. start solid", &box, &hull_cave, - {-8, 0, -16}, { -8, 0, 0}, { 0.5, 0, 1, 0, 1, 6}}, + { -8, 0, -16}, { -8, 0, 0}, { 0.5, 0, 1, 0, 1, 14}}, + {"Box, cave. start solid", &box, &hull_cave, + { 54, 0, -16}, { 54, 0, 56}, { 0.5, 0, 1, 1, 0, 14}}, + {"Box, cave", &box, &hull_cave, + { 54, 0, 12}, { 54, 0, 28}, { 0.5, 0, 0, 1, 0, 14}}, }; #define num_tests (sizeof (tests) / sizeof (tests[0])) From 66dffef936e084b5f3f94b43198f69ab9d5b60aa Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 7 Dec 2011 15:31:33 +0900 Subject: [PATCH 311/334] Get trace_to_leaf working a little better. I think the recursion decision needs a little more work, but this gets the current tests working (though there's still a failure due to fp math). --- libs/models/test/testclip.c | 7 +++++-- libs/models/trace.c | 20 ++++++++++++++------ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index 4b560c2f8..d7d4db31d 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -44,8 +44,9 @@ typedef struct { } expect; } test_t; -box_t point = { {0, 0, 0} }; -box_t box = { {8, 8, 8} }; +box_t point = { { 0, 0, 0} }; +box_t box = { { 8, 8, 8} }; +box_t bigbox = { { 8, 8, 24} }; box_t player = { {16, 16, 28} }; test_t tests[] = { @@ -195,6 +196,8 @@ test_t tests[] = { { 54, 0, -16}, { 54, 0, 56}, { 0.5, 0, 1, 1, 0, 14}}, {"Box, cave", &box, &hull_cave, { 54, 0, 12}, { 54, 0, 28}, { 0.5, 0, 0, 1, 0, 14}}, + {"Big Box, cave. start solid", &bigbox, &hull_cave, + { 54, 0, 0}, { 54, 0, 8}, { 0.5, 0, 1, 1, 0, 14}}, }; #define num_tests (sizeof (tests) / sizeof (tests[0])) diff --git a/libs/models/trace.c b/libs/models/trace.c index a3e66dc21..398dc9857 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -667,10 +667,10 @@ trace_to_leaf (const hull_t *hull, clipleaf_t *leaf, const trace_t *trace, const trace_state_t *state, vec3_t stop) { clipport_t *portal; + plane_t *plane; int side; vec_t frac = 1; - plane_t *plane; - vec_t f; + vec_t t1, t2, offset, f; qboolean clipped = false; clipleaf_t *l; trace_state_t lstate = *state; @@ -684,13 +684,21 @@ trace_to_leaf (const hull_t *hull, clipleaf_t *leaf, if (!trace_hits_portal (hull, trace, portal, state->start_point, state->dist)) continue; - lstate.split_plane = plane; - f = box_portal_dist (hull, portal, &lstate); l = portal->leafs[side^1]; + if (l->test_count == test_count) + continue; + t1 = PlaneDiff (state->start_point, plane); + t2 = PlaneDiff (state->end_point, plane); + offset = calc_offset (trace, plane); + f = (t1 + (t1 < 0 ? offset : -offset)) / (t1 - t2); if (f < 0 && l->contents != CONTENTS_SOLID - && l->test_count != test_count) + && l->test_count != test_count) { f = trace_to_leaf (hull, l, trace, state, 0); - if (f > 0) { + } else { + lstate.split_plane = plane; + f = box_portal_dist (hull, portal, &lstate); + } + if (f >= 0) { clipped = true; if (f < frac) frac = f; From 2a27db146e9f1ef908988f05172f3526378ca28b Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 7 Dec 2011 15:35:19 +0900 Subject: [PATCH 312/334] Use a bit of epsilon in trace_contents(). All tests pass again. --- libs/models/trace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/models/trace.c b/libs/models/trace.c index 398dc9857..c72609763 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -646,7 +646,7 @@ trace_contents (hull_t *hull, trace_t *trace, clipleaf_t *leaf, // the side of the plane on which we are does not matter, only // whether we're crossing the plane. merely touching the plane does // not cause us to cross it - if (fabs (dist) >= offset) + if (fabs (dist) >= offset - PLANE_EPSILON) continue; if (!portal_intersect (trace, portal, plane, origin)) continue; From 9f32004599841a1f7889fbba09e5a29efa4bf436 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 7 Dec 2011 17:26:54 +0900 Subject: [PATCH 313/334] Add a fixme. I've had enough of this for the moment, but I'm pretty sure the test needs some more consideration, and I'll probably forget about it if I don't mark it. --- libs/models/trace.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libs/models/trace.c b/libs/models/trace.c index c72609763..3e802f403 100644 --- a/libs/models/trace.c +++ b/libs/models/trace.c @@ -687,6 +687,7 @@ trace_to_leaf (const hull_t *hull, clipleaf_t *leaf, l = portal->leafs[side^1]; if (l->test_count == test_count) continue; + //FIXME the decision on whether to recurse needs to be reviewed t1 = PlaneDiff (state->start_point, plane); t2 = PlaneDiff (state->end_point, plane); offset = calc_offset (trace, plane); @@ -704,6 +705,7 @@ trace_to_leaf (const hull_t *hull, clipleaf_t *leaf, frac = f; } } + //printf ("%d %g\n", clipped, frac); if (!clipped) frac = 0; if (stop) @@ -731,9 +733,12 @@ visit_leaf (hull_t *hull, int num, clipleaf_t *leaf, trace_t *trace, //FIXME this is probably slow test_count++; trace_to_leaf (hull, leaf, trace, state, origin); + //printf ("(%g %g %g) (%g %g %g)\n", + //VectorExpand (state->start_point), VectorExpand (origin)); test_count++; trace->contents = 0; contents = trace_contents (hull, trace, leaf, origin); + //printf ("%d\n", contents); } } else { contents = num; @@ -834,6 +839,7 @@ MOD_TraceLine (hull_t *hull, int num, leaf = hull->nodeleafs[tstack->num].leafs[side ^ 1]; num = hull->clipnodes[tstack->num].children[side ^ 1]; } + //printf ("%d\n", num); node = hull->clipnodes + num; plane = hull->planes + node->planenum; From fceed07d0b06f01a79d00f817b1133b821b2fee1 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 8 Dec 2011 08:45:53 +0900 Subject: [PATCH 314/334] Tidy up my diagrams. --- libs/models/test/hulls.c | 82 ++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 42 deletions(-) diff --git a/libs/models/test/hulls.c b/libs/models/test/hulls.c index 4479f08e9..261957512 100644 --- a/libs/models/test/hulls.c +++ b/libs/models/test/hulls.c @@ -13,7 +13,7 @@ static mclipnode_t clipnodes_simple_wedge[] = { static plane_t planes_simple_wedge[] = { {{1, 0, 0}, 0, 0, 0}, // 0 - {{0.8, 0, 0.6}, 0, 4, 0}, // 1 + {{0.8, 0, 0.6}, 0, 4, 0}, // 1 }; hull_t hull_simple_wedge = { @@ -103,12 +103,11 @@ hull_t hull_tppw = { {0, 0, 0}, }; -// 2 -// eee|eee -// 0,32+--- 1 -// eee|sss -// ---+--- 0 -// ss0,0ss +// 2 +// 32 ---+--- 1 +// |sss +// ---+--- 0 +// ss0,0ss static mclipnode_t clipnodes_step1[] = { { 0, { 1, CONTENTS_SOLID}}, { 1, {CONTENTS_EMPTY, 2}}, @@ -130,12 +129,12 @@ hull_t hull_step1 = { {0, 0, 0}, }; -// 0 -// eee|eee -// 0,32+--- 1 -// eee|sss -// ---+sss 2 -// ss0,0ss +// 0 +// | +// 32 +--- 1 +// |sss +// ---+sss 2 +// ss0,0ss static mclipnode_t clipnodes_step2[] = { { 0, { 1, 2}}, { 1, {CONTENTS_EMPTY, CONTENTS_SOLID}}, @@ -158,9 +157,9 @@ hull_t hull_step2 = { }; // 0 -// eee|eee -// 2---+0,32 -// sss|eee +// | +// 2---+ 32 +// sss| // sss+--- 1 // ss0,0ss static mclipnode_t clipnodes_step3[] = { @@ -184,14 +183,14 @@ hull_t hull_step3 = { {0, 0, 0}, }; -// 3 2 -// s|e|eee -// 4-+e|-20,40 -// e|e|eee -// 0,32+--- 1 -// eee|sss -// ---+--- 0 -// ss0,0ss +// 3 2 +// ss| | +// 4 --+ | -20,40 +// | | +// 32 --+-+--- 1 +// |sss +// ---+--- 0 +// ss0,0ss static mclipnode_t clipnodes_covered_step[] = { { 0, { 1, CONTENTS_SOLID}}, { 1, { 3, 2}}, @@ -218,9 +217,9 @@ hull_t hull_covered_step = { }; // 0 -// eee|eee -// eee+--- 1 -// ee/0,0s +// | +// 0,0+--- 1 +// /ssss // 2 ssss static mclipnode_t clipnodes_ramp[] = { { 0, { 1, 2}}, @@ -246,7 +245,7 @@ hull_t hull_ramp = { // 2 1 // ss|sss|ss // ss+-3-+ss 8 -// ss|eee|ss +// ss| |ss // ss+-4-+ss -8 // ss|sss|ss // -8 8 @@ -276,12 +275,11 @@ hull_t hull_hole = { {0, 0, 0}, }; -// 2 3 -// eee|eee|eee -// 0,32+---+--- 1 -// eee|sss|eee -// ---+---+--- 0 -// ss0,0s8,0ss +// 2 3 +// 32 ---+---+--- 1 +// |sss| +// ---+---+--- 0 +// ss0,0s8,0ss static mclipnode_t clipnodes_ridge[] = { { 0, { 1, CONTENTS_SOLID}}, { 1, {CONTENTS_EMPTY, 2}}, @@ -306,15 +304,15 @@ hull_t hull_ridge = { }; // 5 -// ssssssssssss|6e -// 1 sssssss 2 s.ee -// \sssssss/ss/|ee -// s\sssss/ss/e|ee +// ssssssssssss|6 +// 1 sssssss 2 s. +// \sssssss/ss/| +// s\sssss/ss/ | // ss\s 4.--.--.-- 20 -// sss\s/eeeeeeeee -// 3 ----. 0,0 eeeee -// wwwww\eeeeeeeee -// wwwwww\eeeeeeee +// sss\s/ . +// 3 ----. 0,0 . +// wwwww\ . +// wwwwww\ . // 0 -------.------- -20 // sssssssssssssss // sssssssssssssss From 45288a1a7f1ee338e354ca8bad0feede81647c6e Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 8 Dec 2011 11:02:19 +0900 Subject: [PATCH 315/334] Fix the ghastly sound quality. Due to quake's original sound engine using a push model, the actual place to which the sound data should be written is not necessarily where the "hardware" dma cursor is, but rather where the last write finished off. Thus, the correct output location is indicated by snd_paintedtime rather than snd_shm->framepos. --- libs/audio/renderer/snd_dma.c | 2 +- libs/audio/targets/snd_alsa.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/audio/renderer/snd_dma.c b/libs/audio/renderer/snd_dma.c index 727664112..f687140d7 100644 --- a/libs/audio/renderer/snd_dma.c +++ b/libs/audio/renderer/snd_dma.c @@ -82,7 +82,7 @@ s_xfer_paint_buffer (portable_samplepair_t *paintbuffer, int count, p = (float *) paintbuffer; count *= snd_shm->channels; out_max = (snd_shm->frames * snd_shm->channels) - 1; - out_idx = snd_shm->framepos * snd_shm->channels; + out_idx = snd_paintedtime * snd_shm->channels; while (out_idx > out_max) out_idx -= out_max + 1; step = 3 - snd_shm->channels; diff --git a/libs/audio/targets/snd_alsa.c b/libs/audio/targets/snd_alsa.c index 19af26ad3..55f0369ea 100644 --- a/libs/audio/targets/snd_alsa.c +++ b/libs/audio/targets/snd_alsa.c @@ -150,7 +150,7 @@ SNDDMA_ni_xfer (portable_samplepair_t *paintbuffer, int count, float volume) p = (float *) paintbuffer; out_max = sn.frames - 1; - out_idx = sn.framepos; + out_idx = *plugin_info_snd_output_data.paintedtime; while (out_idx > out_max) out_idx -= out_max + 1; From d3cf5c4b7591e01f25375ffcdfe7910e89c5e48a Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 8 Dec 2011 11:32:33 +0900 Subject: [PATCH 316/334] Beg for mmap access. If the default sound device does not support mmap access, retry with plughw. However, assume the user knows best and do not retry if snd_device has been set to anything, including "default". QF alsa support now works out of the box with pulseaudio. --- libs/audio/targets/snd_alsa.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/libs/audio/targets/snd_alsa.c b/libs/audio/targets/snd_alsa.c index 55f0369ea..d3fa440a4 100644 --- a/libs/audio/targets/snd_alsa.c +++ b/libs/audio/targets/snd_alsa.c @@ -227,14 +227,13 @@ SNDDMA_Init (void) stereo = snd_stereo->int_val; if (!pcmname) pcmname = "default"; - +retry_open: err = qfsnd_pcm_open (&pcm, pcmname, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); if (0 > err) { Sys_Printf ("Error: audio open error: %s\n", qfsnd_strerror (err)); return 0; } - Sys_Printf ("Using PCM %s.\n", pcmname); err = qfsnd_pcm_hw_params_any (pcm, hw); if (0 > err) { @@ -253,11 +252,18 @@ SNDDMA_Init (void) if (0 > err) { Sys_MaskPrintf (SYS_SND, "ALSA: Failure to set noninterleaved PCM " "access. %s\n", qfsnd_strerror (err)); + // "default" did not work, so retry with "plughw". However do not + // second guess the user, even if the user specified "default". + if (!snd_device->string[0] && !strcmp (pcmname, "default")) { + pcmname = "plughw"; + goto retry_open; + } Sys_Printf ("ALSA: could not set mmap access\n"); goto error; } sn.xfer = SNDDMA_ni_xfer; } + Sys_Printf ("Using PCM %s.\n", pcmname); switch (bps) { From f9877ce0e0a2678d60fe37c6f59d2acdc6a2daf2 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 8 Dec 2011 14:58:08 +0900 Subject: [PATCH 317/334] Add a function to free a hull's portal information. --- include/world.h | 1 + libs/models/portal.c | 52 +++++++++++++++++++++++++++++++++++++++----- 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/include/world.h b/include/world.h index 93c562fd0..2e56655af 100644 --- a/include/world.h +++ b/include/world.h @@ -140,5 +140,6 @@ typedef struct nodeleaf_s { } nodeleaf_t; nodeleaf_t *MOD_BuildBrushes (hull_t *hull); +void MOD_FreeBrushes (hull_t *hull); #endif // __world_h diff --git a/libs/models/portal.c b/libs/models/portal.c index d7170b0d1..661827f18 100644 --- a/libs/models/portal.c +++ b/libs/models/portal.c @@ -47,18 +47,20 @@ static __attribute__ ((used)) const char rcsid[] = "$Id$"; #include "world.h" -static clipleaf_t * -alloc_leaf (void) -{ - return calloc (1, sizeof (clipleaf_t)); -} - static clipport_t * alloc_portal (void) { return calloc (1, sizeof (clipport_t)); } +static void +free_portal (clipport_t *portal) +{ + FreeWinding (portal->winding); + FreeWinding (portal->edges); + free (portal); +} + static void remove_portal (clipport_t *portal, clipleaf_t *leaf) { @@ -75,6 +77,27 @@ remove_portal (clipport_t *portal, clipleaf_t *leaf) } } +static clipleaf_t * +alloc_leaf (void) +{ + return calloc (1, sizeof (clipleaf_t)); +} + +static void +free_leaf (clipleaf_t *leaf) +{ + if (!leaf) + return; + while (leaf->portals) { + clipport_t *portal = leaf->portals; + int side = portal->leafs[1] == leaf; + leaf->portals = portal->next[side]; + remove_portal (portal, portal->leafs[side ^ 1]); + free_portal (portal); + } + free (leaf); +} + static void add_portal (clipport_t *portal, clipleaf_t *front, clipleaf_t *back) { @@ -195,3 +218,20 @@ MOD_BuildBrushes (hull_t *hull) } return nodeleafs; } + +void +MOD_FreeBrushes (hull_t *hull) +{ + int i, j; + int numnodes; + + if (!hull || !hull->nodeleafs) + return; + numnodes = hull->lastclipnode + 1; + for (i = 0; i < numnodes; i++) { + for (j = 0; j < 2; j++) + free_leaf (hull->nodeleafs[i].leafs[j]); + } + free (hull->nodeleafs); + hull->nodeleafs = 0; +} From 8aa5a8139c8408b5c26c9f20dcb66b7bc728b6b9 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 8 Dec 2011 14:59:35 +0900 Subject: [PATCH 318/334] Split out the portal sanity tests. With this, the portal code can be tested separately, including the freeing of the portal information. --- libs/models/test/Makefile.am | 6 +- libs/models/test/testclip.c | 195 ++++++++++++--------------------- libs/models/test/testportals.c | 181 ++++++++++++++++++++++++++++++ 3 files changed, 255 insertions(+), 127 deletions(-) create mode 100644 libs/models/test/testportals.c diff --git a/libs/models/test/Makefile.am b/libs/models/test/Makefile.am index 14fe9e3dc..2014a546c 100644 --- a/libs/models/test/Makefile.am +++ b/libs/models/test/Makefile.am @@ -2,7 +2,7 @@ AUTOMAKE_OPTIONS= foreign INCLUDES= -I$(srcdir) -I$(top_srcdir)/include -check_PROGRAMS=testclip testcontents +check_PROGRAMS=testclip testcontents testportals EXTRA_DIST= trace-id.c trace-qf-bad.c hulls.h main.c testclip_SOURCES=testclip.c hulls.c @@ -13,4 +13,8 @@ testcontents_SOURCES=testcontents.c hulls.c testcontents_LDADD= $(top_builddir)/libs/models/libQFmodels.la $(top_builddir)/libs/util/libQFutil.la testcontents_DEPENDENCIES= $(top_builddir)/libs/models/libQFmodels.la $(top_builddir)/libs/util/libQFutil.la +testportals_SOURCES=testportals.c hulls.c +testportals_LDADD= $(top_builddir)/libs/models/libQFmodels.la $(top_builddir)/libs/util/libQFutil.la +testportals_DEPENDENCIES= $(top_builddir)/libs/models/libQFmodels.la $(top_builddir)/libs/util/libQFutil.la + TESTS=$(check_PROGRAMS) diff --git a/libs/models/test/testclip.c b/libs/models/test/testclip.c index d7d4db31d..a6639b436 100644 --- a/libs/models/test/testclip.c +++ b/libs/models/test/testclip.c @@ -40,7 +40,6 @@ typedef struct { qboolean startsolid; qboolean inopen; qboolean inwater; - int num_portals; } expect; } test_t; @@ -51,153 +50,153 @@ box_t player = { {16, 16, 28} }; test_t tests[] = { {"Point, Three parallel planes 1", &point, &hull_tpp1, - {-64, 0, 0}, { 64, 0, 0}, { 1, 1, 1, 0, 0, 3}}, + {-64, 0, 0}, { 64, 0, 0}, { 1, 1, 1, 0, 0}}, {"Point, Three parallel planes 1", &point, &hull_tpp1, - { 0, 0, 0}, { 40, 0, 0}, { 1, 0, 1, 1, 0, 3}}, + { 0, 0, 0}, { 40, 0, 0}, { 1, 0, 1, 1, 0}}, {"Point, Three parallel planes 1", &point, &hull_tpp1, - { 40, 0, 0}, {-88, 0, 0}, {0.0625, 0, 0, 1, 0, 3}}, + { 40, 0, 0}, {-88, 0, 0}, {0.0625, 0, 0, 1, 0}}, {"Point, Three parallel planes 1", &point, &hull_tpp1, - { 0, 0, 0}, { 64, 0, 0}, { 0.75, 0, 1, 1, 0, 3}}, + { 0, 0, 0}, { 64, 0, 0}, { 0.75, 0, 1, 1, 0}}, {"Point, Three parallel planes 1", &point, &hull_tpp1, - { 0, 0, 0}, { 0, 8, 0}, { 1, 1, 1, 0, 0, 3}}, + { 0, 0, 0}, { 0, 8, 0}, { 1, 1, 1, 0, 0}}, {"Point, Three parallel planes 1", &point, &hull_tpp1, - { 40, 0, 0}, { 40, 8, 0}, { 1, 0, 0, 1, 0, 3}}, + { 40, 0, 0}, { 40, 8, 0}, { 1, 0, 0, 1, 0}}, {"Point, Three parallel planes 2", &point, &hull_tpp2, - {-64, 0, 0}, { 64, 0, 0}, { 1, 1, 1, 0, 0, 3}}, + {-64, 0, 0}, { 64, 0, 0}, { 1, 1, 1, 0, 0}}, {"Point, Three parallel planes 2", &point, &hull_tpp2, - { 0, 0, 0}, { 40, 0, 0}, { 1, 0, 1, 1, 0, 3}}, + { 0, 0, 0}, { 40, 0, 0}, { 1, 0, 1, 1, 0}}, {"Point, Three parallel planes 2", &point, &hull_tpp2, - { 40, 0, 0}, {-88, 0, 0}, {0.0625, 0, 0, 1, 0, 3}}, + { 40, 0, 0}, {-88, 0, 0}, {0.0625, 0, 0, 1, 0}}, {"Point, Three parallel planes 2", &point, &hull_tpp2, - { 0, 0, 0}, { 64, 0, 0}, { 0.75, 0, 1, 1, 0, 3}}, + { 0, 0, 0}, { 64, 0, 0}, { 0.75, 0, 1, 1, 0}}, {"Point, Three parallel planes with water", &point, &hull_tppw, - {-64, 0, 0}, { 64, 0, 0}, { 0.875, 0, 1, 1, 1, 3}}, + {-64, 0, 0}, { 64, 0, 0}, { 0.875, 0, 1, 1, 1}}, {"Point, Three parallel planes with water", &point, &hull_tppw, - { 0, 0, 0}, { 40, 0, 0}, { 1, 0, 0, 1, 1, 3}}, + { 0, 0, 0}, { 40, 0, 0}, { 1, 0, 0, 1, 1}}, {"Point, Three parallel planes with water", &point, &hull_tppw, - { 40, 0, 0}, {-88, 0, 0}, {0.5625, 0, 0, 1, 1, 3}}, + { 40, 0, 0}, {-88, 0, 0}, {0.5625, 0, 0, 1, 1}}, {"Point, Three parallel planes with water", &point, &hull_tppw, - { 0, 0, 0}, { 64, 0, 0}, { 0.75, 0, 0, 1, 1, 3}}, + { 0, 0, 0}, { 64, 0, 0}, { 0.75, 0, 0, 1, 1}}, {"Point, Three parallel planes with water", &point, &hull_tppw, - { 0, 0, 0}, { 0, 8, 0}, { 1, 0, 0, 1, 0, 3}}, + { 0, 0, 0}, { 0, 8, 0}, { 1, 0, 0, 1, 0}}, {"Point, Three parallel planes with water", &point, &hull_tppw, - { 40, 0, 0}, { 40, 8, 0}, { 1, 0, 0, 0, 1, 3}}, + { 40, 0, 0}, { 40, 8, 0}, { 1, 0, 0, 0, 1}}, {"Point, Three parallel planes with water", &point, &hull_tppw, - { 0, 0, 0}, { 40, 0, 0}, { 1, 0, 0, 1, 1, 3}}, + { 0, 0, 0}, { 40, 0, 0}, { 1, 0, 0, 1, 1}}, {"Box, Three parallel planes with water", &box, &hull_tppw, - {-32, 0, 0}, { 40, 0, 0}, { 1, 0, 1, 1, 1, 3}}, + {-32, 0, 0}, { 40, 0, 0}, { 1, 0, 1, 1, 1}}, {"Box, Three parallel planes with water", &box, &hull_tppw, - {-32, 0, 0}, { 20, 0, 0}, { 1, 0, 1, 1, 0, 3}}, + {-32, 0, 0}, { 20, 0, 0}, { 1, 0, 1, 1, 0}}, {"Point, Step 1", &point, &hull_step1, - { -16, 0, 8}, {16, 0, 24}, { 0.5, 0, 0, 1, 0, 5}}, + { -16, 0, 8}, {16, 0, 24}, { 0.5, 0, 0, 1, 0}}, {"Box, Step 1", &box, &hull_step1, - { -16, 0, 8}, {16, 0, 24}, { 0.25, 0, 0, 1, 0, 5}}, + { -16, 0, 8}, {16, 0, 24}, { 0.25, 0, 0, 1, 0}}, {"Box, Step 1", &box, &hull_step1, - { -16, 0, 8}, {16, 0, 40}, { 0.25, 0, 0, 1, 0, 5}}, + { -16, 0, 8}, {16, 0, 40}, { 0.25, 0, 0, 1, 0}}, {"Box, Step 1", &box, &hull_step1, - { -16, 0, 8}, {16, 0, 135}, { 0.25, 0, 0, 1, 0, 5}}, + { -16, 0, 8}, {16, 0, 135}, { 0.25, 0, 0, 1, 0}}, {"Box, Step 1", &box, &hull_step1, - { -16, 0, 8}, {16, 0, 136}, { 1, 0, 0, 1, 0, 5}}, + { -16, 0, 8}, {16, 0, 136}, { 1, 0, 0, 1, 0}}, {"Point, Covered Step", &point, &hull_covered_step, - {-24, 0, 8}, {-24, 0, 72}, { 0.5, 0, 0, 1, 0, 9}}, + { -24, 0, 8}, {-24, 0, 72}, { 0.5, 0, 0, 1, 0}}, {"Box, Covered Step", &box, &hull_covered_step, - {-32, 0, 8}, {-32, 0, 72}, { 0.375, 0, 0, 1, 0, 9}}, + { -32, 0, 8}, {-32, 0, 72}, { 0.375, 0, 0, 1, 0}}, {"Box, Covered Step", &box, &hull_covered_step, - {-24, 0, 8}, {-24, 0, 72}, { 0.375, 0, 0, 1, 0, 9}}, + { -24, 0, 8}, {-24, 0, 72}, { 0.375, 0, 0, 1, 0}}, {"Box, Covered Step", &box, &hull_covered_step, - {-25, 0, 8}, { 7, 0, 72}, { 0.375, 0, 0, 1, 0, 9}}, + { -25, 0, 8}, { 7, 0, 72}, { 0.375, 0, 0, 1, 0}}, {"Box, Covered Step", &box, &hull_covered_step, - { -8, 0, 40}, {-16, 0, 40}, { 0.5, 0, 0, 1, 0, 9}}, + { -8, 0, 40}, {-16, 0, 40}, { 0.5, 0, 0, 1, 0}}, {"Box, Covered Step", &box, &hull_covered_step, - {-17, 0, 8}, { -1, 0, 72}, { 1, 0, 0, 1, 0, 9}}, + { -17, 0, 8}, { -1, 0, 72}, { 1, 0, 0, 1, 0}}, {"Box, Covered Step", &box, &hull_covered_step, - { -8, 0, 40}, { 8, 0, 72}, { 1, 0, 0, 1, 0, 9}}, + { -8, 0, 40}, { 8, 0, 72}, { 1, 0, 0, 1, 0}}, {"Box, Covered Step touch backside", &box, &hull_covered_step, - { -8, 0, 8}, {-12, 0, 12}, { 1, 0, 0, 1, 0, 9}}, + { -8, 0, 8}, {-12, 0, 12}, { 1, 0, 0, 1, 0}}, {"Point, Covered Step touch backside", &point, &hull_covered_step, - { 0, 0, 8}, {-12, 0, 12}, { 1, 0, 1, 1, 0, 9}}, + { 0, 0, 8}, {-12, 0, 12}, { 1, 0, 1, 1, 0}}, {"Point, Covered Step start solid", &point, &hull_covered_step, - { 0, 0, -4}, {-16, 0, 12}, { 1, 0, 1, 1, 0, 9}}, + { 0, 0, -4}, {-16, 0, 12}, { 1, 0, 1, 1, 0}}, {"Point, Covered Step start solid", &point, &hull_covered_step, - { 4, 0, -4}, {-12, 0, 12}, { 1, 1, 1, 0, 0, 9}}, + { 4, 0, -4}, {-12, 0, 12}, { 1, 1, 1, 0, 0}}, {"Box, Covered Step start solid", &box, &hull_covered_step, - { -4, 0, 4}, {-12, 0, 12}, { 1, 0, 1, 1, 0, 9}}, + { -4, 0, 4}, {-12, 0, 12}, { 1, 0, 1, 1, 0}}, {"Box, Covered Step start solid", &box, &hull_covered_step, - { -17, 0, 4}, {-17, 0, 12}, { 1, 0, 1, 1, 0, 9}}, + { -17, 0, 4}, {-17, 0, 12}, { 1, 0, 1, 1, 0}}, {"Box, Covered Step start solid", &box, &hull_covered_step, - { -4, 0, 4}, {-16, 0, 36}, { 0.875, 0, 1, 1, 0, 9}}, + { -4, 0, 4}, {-16, 0, 36}, { 0.875, 0, 1, 1, 0}}, {"Box, Covered Step start solid", &box, &hull_covered_step, - { -4, 0, 4}, {-16, 0, 4}, { 1, 1, 1, 0, 0, 9}}, + { -4, 0, 4}, {-16, 0, 4}, { 1, 1, 1, 0, 0}}, {"Box, Covered Step start solid", &box, &hull_covered_step, - {-12, 0, 4}, {-16, 0, 4}, { 1, 1, 1, 0, 0, 9}}, + { -12, 0, 4}, {-16, 0, 4}, { 1, 1, 1, 0, 0}}, {"Box, Covered Step start solid", &box, &hull_covered_step, - {-16, 0, 4}, { -4, 0, 4}, { 1, 1, 1, 0, 0, 9}}, + { -16, 0, 4}, { -4, 0, 4}, { 1, 1, 1, 0, 0}}, {"Box, Covered Step start solid", &box, &hull_covered_step, - { 16, 0, -16}, { 16, 0, 64}, { 1, 1, 1, 0, 0, 9}}, + { 16, 0, -16}, { 16, 0, 64}, { 1, 1, 1, 0, 0}}, {"Box, Covered Step start solid", &box, &hull_covered_step, - { 16, 0, 16}, { 16, 0, 64}, { 1, 0, 1, 1, 0, 9}}, + { 16, 0, 16}, { 16, 0, 64}, { 1, 0, 1, 1, 0}}, {"Box, Step 2", &box, &hull_step2, - { 0, 0, 64}, {0, 0, 0}, { 0.375, 0, 0, 1, 0, 5}}, + { 0, 0, 64}, {0, 0, 0}, { 0.375, 0, 0, 1, 0}}, {"Box, Step 3", &box, &hull_step3, - { 0, 0, 64}, {0, 0, 0}, { 0.375, 0, 0, 1, 0, 5}}, + { 0, 0, 64}, {0, 0, 0}, { 0.375, 0, 0, 1, 0}}, {"Box, Ramp", &box, &hull_ramp, - { 0, 0, 16}, {0, 0, 0}, { 0.5, 0, 0, 1, 0, 4}}, + { 0, 0, 16}, { 0, 0, 0}, { 0.5, 0, 0, 1, 0}}, {"Box, Ramp", &box, &hull_ramp, - {-16, 0, 8}, {16, 0, 8}, { 1, 0, 0, 1, 0, 4}}, + {-16, 0, 8}, {16, 0, 8}, { 1, 0, 0, 1, 0}}, {"Box, Ramp", &box, &hull_ramp, - {-16, 0, 5}, {16, 0, 5}, { 0.125, 0, 0, 1, 0, 4}}, + {-16, 0, 5}, {16, 0, 5}, { 0.125, 0, 0, 1, 0}}, {"Box, Simple Wedge", &box, &hull_simple_wedge, - { 0, 0, 16}, {0, 0, 0}, { 0.5, 0, 0, 1, 0, 3}}, + { 0, 0, 16}, { 0, 0, 0}, { 0.5, 0, 0, 1, 0}}, {"Box, Simple Wedge", &box, &hull_simple_wedge, - {-16, 0, 8}, {16, 0, 8}, { 1, 0, 0, 1, 0, 3}}, + {-16, 0, 8}, {16, 0, 8}, { 1, 0, 0, 1, 0}}, {"Box, Simple Wedge", &box, &hull_simple_wedge, - {-16, 0, 5}, {16, 0, 5}, { 0.25, 0, 0, 1, 0, 3}}, + {-16, 0, 5}, {16, 0, 5}, { 0.25, 0, 0, 1, 0}}, {"Box, Simple Wedge", &box, &hull_simple_wedge, - {-16, 0, 12}, {16, 0, 4}, { 0.5, 0, 0, 1, 0, 3}}, + {-16, 0, 12}, {16, 0, 4}, { 0.5, 0, 0, 1, 0}}, {"Box, Hole. slide in", &box, &hull_hole, - { 0, -16, 0}, { 0, 16, 0}, { 1, 0, 0, 1, 0, 13}}, + { 0, -16, 0}, { 0, 16, 0}, { 1, 0, 0, 1, 0}}, {"Box, Hole. slide out", &box, &hull_hole, - { 0, 16, 0}, { 0, -16, 0}, { 1, 0, 0, 1, 0, 13}}, + { 0, 16, 0}, { 0, -16, 0}, { 1, 0, 0, 1, 0}}, {"Box, Hole. tight", &box, &hull_hole, - { 0, 16, 0}, { 0, 16, 16}, { 0, 0, 0, 1, 0, 13}}, + { 0, 16, 0}, { 0, 16, 16}, { 0, 0, 0, 1, 0}}, {"Box, Hole. tight", &box, &hull_hole, - { 0, 16, 0}, { 0, 16, -16}, { 0, 0, 0, 1, 0, 13}}, + { 0, 16, 0}, { 0, 16, -16}, { 0, 0, 0, 1, 0}}, {"Box, Hole. tight", &box, &hull_hole, - { 0, 16, 0}, { 16, 16, 0}, { 0, 0, 0, 1, 0, 13}}, + { 0, 16, 0}, { 16, 16, 0}, { 0, 0, 0, 1, 0}}, {"Box, Hole. tight", &box, &hull_hole, - { 0, 16, 0}, {-16, 16, 0}, { 0, 0, 0, 1, 0, 13}}, + { 0, 16, 0}, {-16, 16, 0}, { 0, 0, 0, 1, 0}}, {"Box, Hole. edge", &box, &hull_hole, - { 0, -16, 1}, { 0, 16, 1}, { 0.25, 0, 0, 1, 0, 13}}, + { 0, -16, 1}, { 0, 16, 1}, { 0.25, 0, 0, 1, 0}}, {"Box, Hole. edge", &box, &hull_hole, - { 0, -16, -1}, { 0, 16, -1}, { 0.25, 0, 0, 1, 0, 13}}, + { 0, -16, -1}, { 0, 16, -1}, { 0.25, 0, 0, 1, 0}}, {"Box, Hole. edge", &box, &hull_hole, - { 1, -16, 0}, { 1, 16, 0}, { 0.25, 0, 0, 1, 0, 13}}, + { 1, -16, 0}, { 1, 16, 0}, { 0.25, 0, 0, 1, 0}}, {"Box, Hole. edge", &box, &hull_hole, - {-1, -16, 0}, { -1, 16, 0}, { 0.25, 0, 0, 1, 0, 13}}, + {-1, -16, 0}, { -1, 16, 0}, { 0.25, 0, 0, 1, 0}}, {"Box, ridge", &box, &hull_ridge, - {4, 0, 41}, { 4, 0, 39}, { 0.5, 0, 0, 1, 0, 8}}, + {4, 0, 41}, { 4, 0, 39}, { 0.5, 0, 0, 1, 0}}, {"Box, ridge, all solid", &box, &hull_ridge, - {4, 41, 0}, { 4, 39, 0}, { 1, 1, 1, 0, 0, 8}}, + {4, 41, 0}, { 4, 39, 0}, { 1, 1, 1, 0, 0}}, {"Box, cave. start solid", &box, &hull_cave, - { 4, 0, -16}, { 4, 0, 0}, { 0.5, 0, 1, 0, 1, 14}}, + { 4, 0, -16}, { 4, 0, 0}, { 0.5, 0, 1, 0, 1}}, {"Box, cave. start solid", &box, &hull_cave, - { -8, 0, -16}, { -8, 0, 0}, { 0.5, 0, 1, 0, 1, 14}}, + { -8, 0, -16}, { -8, 0, 0}, { 0.5, 0, 1, 0, 1}}, {"Box, cave. start solid", &box, &hull_cave, - { 54, 0, -16}, { 54, 0, 56}, { 0.5, 0, 1, 1, 0, 14}}, + { 54, 0, -16}, { 54, 0, 56}, { 0.5, 0, 1, 1, 0}}, {"Box, cave", &box, &hull_cave, - { 54, 0, 12}, { 54, 0, 28}, { 0.5, 0, 0, 1, 0, 14}}, + { 54, 0, 12}, { 54, 0, 28}, { 0.5, 0, 0, 1, 0}}, {"Big Box, cave. start solid", &bigbox, &hull_cave, - { 54, 0, 0}, { 54, 0, 8}, { 0.5, 0, 1, 1, 0, 14}}, + { 54, 0, 0}, { 54, 0, 8}, { 0.5, 0, 1, 1, 0}}, }; #define num_tests (sizeof (tests) / sizeof (tests[0])) @@ -260,31 +259,9 @@ run_test (test_t *test) hull_t *hull = test->hull; int i, j; portlist_t *p; - clipport_t *portal; clipleaf_t *leaf; - int side; hull->nodeleafs = MOD_BuildBrushes (hull); - for (i = hull->firstclipnode; i <= hull->lastclipnode; i++) { - for (j = 0; j < 2; j++) { - if (((hull->clipnodes[i].children[j] >= 0) - != (!hull->nodeleafs[i].leafs[j])) - || (hull->nodeleafs[i].leafs[j] - && (hull->nodeleafs[i].leafs[j]->contents - != hull->clipnodes[i].children[j]))) { - printf ("bad nodeleaf %d %d\n", i, j); - err = 1; - } - } - if (hull->nodeleafs[i].leafs[0] - && (hull->nodeleafs[i].leafs[0] - == hull->nodeleafs[i].leafs[1])) { - printf ("bad nodeleaf %d %d\n", i, j); - err = 1; - } - } - if (err) - goto nodeleaf_bail; for (i = hull->firstclipnode; i <= hull->lastclipnode; i++) { for (j = 0; j < 2; j++) { leaf = hull->nodeleafs[i].leafs[j]; @@ -293,19 +270,6 @@ run_test (test_t *test) portal_list = collect_portals (leaf->portals, portal_list); } } - for (i = 0, p = portal_list; p; i++, p = p->next) { - if (!p->portal->winding || !p->portal->edges) { - err = 1; - printf ("portal with missing vertex/edge information\n"); - } - } - if (err) - goto nodeleaf_bail; - if (i != test->expect.num_portals) { - err = 1; - printf ("bad portal count: %d %d\n", test->expect.num_portals, i); - goto nodeleaf_bail; - } for (p = portal_list; p; p = p->next) { for (j = 0; j < p->portal->winding->numpoints; j++) { p->portal->winding->points[j][0] @@ -317,29 +281,8 @@ run_test (test_t *test) } FreeWinding (p->portal->edges); p->portal->edges = WindingVectors (p->portal->winding, 0); - for (j = 0; j < 2; j++) { - int found = 0; - - leaf = p->portal->leafs[j]; - for (portal = leaf->portals; portal; - portal = portal->next[side]) { - //printf("%p %d %p %p %p\n", p, j, leaf, portal, p->portal); - side = portal->leafs[1] == leaf; - if (!side && portal->leafs[0] != leaf) { - printf ("mislinked portal\n"); - err = 1; - } - if (portal == p->portal) - found = 1; - } - if (!found) { - printf ("portal unreachable from leaf\n"); - err = 1; - } - } } } -nodeleaf_bail: while (portal_list) { portlist_t *t = portal_list; portal_list = portal_list->next; diff --git a/libs/models/test/testportals.c b/libs/models/test/testportals.c new file mode 100644 index 000000000..f5f31f4e6 --- /dev/null +++ b/libs/models/test/testportals.c @@ -0,0 +1,181 @@ +#include +#include "QF/va.h" + +#include "getopt.h" +#include "world.h" +#include "QF/winding.h" + +#include "hulls.h" + +#define FloatCompare(a, b) (fabs (a - b) < 1e-5) +#undef VectorCompare +#define VectorCompare(x, y) \ + (FloatCompare (x[0], y[0]) && FloatCompare (x[1], y[1]) \ + && FloatCompare (x[2], y[2])) + + +typedef struct { + const char *desc; + hull_t *hull; + struct { + int num_portals; + } expect; +} test_t; + +test_t tests[] = { + {"Three parallel planes 1", + &hull_tpp1, { 3}}, + {"Three parallel planes 2", + &hull_tpp2, { 3}}, + {"Three parallel planes with water", + &hull_tppw, { 3}}, + {"Step 1", + &hull_step1, { 5}}, + {"Covered Step", + &hull_covered_step, { 9}}, + {"Step 2", + &hull_step2, { 5}}, + {"Step 3", + &hull_step3, { 5}}, + {"Ramp", + &hull_ramp, { 4}}, + {"Simple Wedge", + &hull_simple_wedge, { 3}}, + {"Hole", + &hull_hole, {13}}, + {"ridge", + &hull_ridge, { 8}}, + {"cave", + &hull_cave, {14}}, +}; +#define num_tests (sizeof (tests) / sizeof (tests[0])) + +int verbose = 0; + +typedef struct portlist_s { + struct portlist_s *next; + clipport_t *portal; +} portlist_t; + +static portlist_t * +collect_portals (clipport_t *portal, portlist_t *portal_list) +{ + portlist_t *p; + + if (!portal) + return portal_list; + for (p = portal_list; p; p = p->next) + if (p->portal == portal) + return portal_list; + p = malloc (sizeof (portlist_t)); + p->portal = portal; + p->next = portal_list; + portal_list = p; + portal_list = collect_portals (portal->next[0], portal_list); + portal_list = collect_portals (portal->next[1], portal_list); + return portal_list; +} + +static int +run_test (test_t *test) +{ + const char *desc; + int err = 0; + static int output = 0; + portlist_t *portal_list = 0; + + if (!test->hull->nodeleafs) { + hull_t *hull = test->hull; + int i, j; + portlist_t *p; + clipport_t *portal; + clipleaf_t *leaf; + int side; + + hull->nodeleafs = MOD_BuildBrushes (hull); + for (i = hull->firstclipnode; i <= hull->lastclipnode; i++) { + for (j = 0; j < 2; j++) { + if (((hull->clipnodes[i].children[j] >= 0) + != (!hull->nodeleafs[i].leafs[j])) + || (hull->nodeleafs[i].leafs[j] + && (hull->nodeleafs[i].leafs[j]->contents + != hull->clipnodes[i].children[j]))) { + printf ("bad nodeleaf %d %d\n", i, j); + err = 1; + } + } + if (hull->nodeleafs[i].leafs[0] + && (hull->nodeleafs[i].leafs[0] + == hull->nodeleafs[i].leafs[1])) { + printf ("bad nodeleaf %d %d\n", i, j); + err = 1; + } + } + if (err) + goto nodeleaf_bail; + for (i = hull->firstclipnode; i <= hull->lastclipnode; i++) { + for (j = 0; j < 2; j++) { + leaf = hull->nodeleafs[i].leafs[j]; + if (!leaf) + continue; + portal_list = collect_portals (leaf->portals, portal_list); + } + } + for (i = 0, p = portal_list; p; i++, p = p->next) { + if (!p->portal->winding || !p->portal->edges) { + err = 1; + printf ("portal with missing vertex/edge information\n"); + } + } + if (err) + goto nodeleaf_bail; + if (i != test->expect.num_portals) { + err = 1; + printf ("bad portal count: %d %d\n", test->expect.num_portals, i); + goto nodeleaf_bail; + } + for (p = portal_list; p; p = p->next) { + for (j = 0; j < 2; j++) { + int found = 0; + + leaf = p->portal->leafs[j]; + for (portal = leaf->portals; portal; + portal = portal->next[side]) { + //printf("%p %d %p %p %p\n", p, j, leaf, portal, p->portal); + side = portal->leafs[1] == leaf; + if (!side && portal->leafs[0] != leaf) { + printf ("mislinked portal\n"); + err = 1; + } + if (portal == p->portal) + found = 1; + } + if (!found) { + printf ("portal unreachable from leaf\n"); + err = 1; + } + } + } + } +nodeleaf_bail: + while (portal_list) { + portlist_t *t = portal_list; + portal_list = portal_list->next; + free (t); + } + MOD_FreeBrushes (test->hull); + + if (test->desc) + desc = va ("(%d) %s", (int)(long)(test - tests), test->desc); + else + desc = va ("test #%d", (int)(long)(test - tests)); + if (verbose >= 0 || err) { + if (output) + puts(""); + output = 1; + printf ("%s: %s\n", !err ? "PASS" : "FAIL", desc); + } + return !err; +} + +#include "main.c" From b4a387897b1a44e9fb6134e1526835abd045785b Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 8 Dec 2011 17:30:44 +0900 Subject: [PATCH 319/334] Expand the tabs. --- NEWS | 120 +++++++++++++++++++++++++++++------------------------------ 1 file changed, 60 insertions(+), 60 deletions(-) diff --git a/NEWS b/NEWS index 0efabf97f..9969d0bc2 100644 --- a/NEWS +++ b/NEWS @@ -2,64 +2,64 @@ NEWS for the QuakeForge project ------------------------------- Changes from 0.5.5 - o General enhancements - * protocol 666 support from fitzquake (nq) - * large map support from fitzquake - * fullscreen mode is now compliant with modern window managers - * wide screens supported. Use the vid_aspect cvar to specify the - screen's aspect ratio (eg, 4:3, 16:9, 800:480 etc). - * lighting tweaks - * don't lose sound when switching workplaces in X - * correct resampling of sound effects for 48kHz sound output (or any - other rate, for that matter). - * support up to 7.1 channel sound files. However, output is still - limited to two channels. - * "lagged dlights" in mvds fixed - * flac sound file support - * support multiple directories in fs_sharepath - * new savegame format (property list) - * map entities can use property lists - * JACK audio output - * http download support - * CPQW support - * gold-key/radiation-symbol bug in rock2 fixed - * support for very big maps (eg marcher.bsp) - * beams (lightning etc) can be any length - * unlimited beams - * unlimited loaded models - * unlimited efrags - * support for Japanese keyboards - * particle improvements - * nq can now release the CPU when it is not needed (cl_usleep 1) - o Ruamoko (QuakeC) - * plist access - * entity parsing support - * quake script parsing support - * dynamic strings - * mutable strings - * progs can provide their own entity parsing function. A sample - implementation is available. - o qfcc - * man page documentation - * function overloading - * allow entity.vector.x (etc) instead of entity.vector_x - * many ObjectiveQuakeC fixes - * optional constant-vector parameter space optimisation (slows down - the code, though): can compile the version of frogbot that has - waypoints for almost 300 maps. - * rcall support - * static local vars - * more pointer support - * better compatibility with qcc - * preprocess progs.src - * one-pass compilation of progs.src based code when using cpp - * qccx escape codes supported. As there are conflicts with qfcc's - escape codes, --qccx-escapes can be used to select qccx instead of - qfcc. - o Tools - * filter for displaying item information from a map (itemslist.py) - * wad tool improvements - * qfbsp can extract the entities data from bsp files. + o General enhancements + * protocol 666 support from fitzquake (nq) + * large map support from fitzquake + * fullscreen mode is now compliant with modern window managers + * wide screens supported. Use the vid_aspect cvar to specify the + screen's aspect ratio (eg, 4:3, 16:9, 800:480 etc). + * lighting tweaks + * don't lose sound when switching workplaces in X + * correct resampling of sound effects for 48kHz sound output (or any + other rate, for that matter). + * support up to 7.1 channel sound files. However, output is still + limited to two channels. + * "lagged dlights" in mvds fixed + * flac sound file support + * support multiple directories in fs_sharepath + * new savegame format (property list) + * map entities can use property lists + * JACK audio output + * http download support + * CPQW support + * gold-key/radiation-symbol bug in rock2 fixed + * support for very big maps (eg marcher.bsp) + * beams (lightning etc) can be any length + * unlimited beams + * unlimited loaded models + * unlimited efrags + * support for Japanese keyboards + * particle improvements + * nq can now release the CPU when it is not needed (cl_usleep 1) + o Ruamoko (QuakeC) + * plist access + * entity parsing support + * quake script parsing support + * dynamic strings + * mutable strings + * progs can provide their own entity parsing function. A sample + implementation is available. + o qfcc + * man page documentation + * function overloading + * allow entity.vector.x (etc) instead of entity.vector_x + * many ObjectiveQuakeC fixes + * optional constant-vector parameter space optimisation (slows down + the code, though): can compile the version of frogbot that has + waypoints for almost 300 maps. + * rcall support + * static local vars + * more pointer support + * better compatibility with qcc + * preprocess progs.src + * one-pass compilation of progs.src based code when using cpp + * qccx escape codes supported. As there are conflicts with qfcc's + escape codes, --qccx-escapes can be used to select qccx instead of + qfcc. + o Tools + * filter for displaying item information from a map (itemslist.py) + * wad tool improvements + * qfbsp can extract the entities data from bsp files. Changes from 0.5.4 o General enhancements @@ -145,8 +145,8 @@ Changes from 0.5.4 * new cvar from Grievre to control "fake" filtering and change the fake kick default * fix bug where certain looped sounds would cause a hang - * 64 bit compile fixes - * alias models are no longer black on maps with no lighting info + * 64 bit compile fixes + * alias models are no longer black on maps with no lighting info o qfcc enhancements. * conforms better to Objective-C sematics * "struct" support closer to that of C (ie, separate namespace) From 9e3db08fddd5ee69f14eb9d8abf94f81ed421335 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 8 Dec 2011 20:10:29 +0900 Subject: [PATCH 320/334] Update NEWS --- NEWS | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/NEWS b/NEWS index 9969d0bc2..18c8d93f5 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,46 @@ NEWS for the QuakeForge project Changes from 0.5.5 o General enhancements + * many limits removed + o unlimited nails (client side) + o unlimited visible entities + o unlimited static entities + o for BSP files, only limits dictated by the format remain + * linux joystick improvements: + o default device is /dev/input/js0 + o up to 18 buttons + * developer cvar is now a bit field + o 1 everything + o 2 warnings + o 4 video + o 8 file system: not found + o 16 file system: found + o 32 file system: general + o 64 networking + o 128 ruamoko: objects + o 256 ruamoko: messages + o 512 sound + o 1024 GL textures + * ALSA sound support now works with PulseAudio by default + * NQ now works on multi-homed hosts + * OpenBSD networking fixes + * loss of contact with the jack server is now detected. no more + hanging on shutdown after jack flakes out. + * fishey rendering fixed + * crash gracefully when a map has too many entities (rather than + silently dropping them: coag3 wasn't fun with missing ents) + * players can jump off pretty much anything (controllable via + sv_jump_any) + * funny size sound buffers no longer a problem + * RLE encoding for PCX output + * plugins moved to ${libdir}/quakeforge/plugins + * IPv6 support now working + * rotating bsp model support + * alsa 0.9 support dropped + * transparent map entities + * support map specified skyboxes + * NQ's maximum velocity is now spherical rather than cubical + * truncate long level names in NQ's HUD * protocol 666 support from fitzquake (nq) * large map support from fitzquake * fullscreen mode is now compliant with modern window managers @@ -32,6 +72,7 @@ Changes from 0.5.5 * particle improvements * nq can now release the CPU when it is not needed (cl_usleep 1) o Ruamoko (QuakeC) + * installed headers/libs now in ${prefix}/lib/qfcc * plist access * entity parsing support * quake script parsing support @@ -40,6 +81,20 @@ Changes from 0.5.5 * progs can provide their own entity parsing function. A sample implementation is available. o qfcc + * major rewrite of parser and code generation + o C style declarations fully supported (bit fields ignored) + o dead code elimination + o better constant folding + o Objective-QC runtime data moved into far data to avoid taking + precious near data defs. + o missing return statements in non-void functions now detected + with a suitable warning + o pointers and arrays now use C syntax + o "integer" now "int" + * field aliasing: .SEL thinkMethod = think; + * diagnostic variables + __PRETTY_FUNCTION__ __FUNCTION__ __LINE__ and __FILE__ + * NIL renamed to nil * man page documentation * function overloading * allow entity.vector.x (etc) instead of entity.vector_x @@ -56,10 +111,14 @@ Changes from 0.5.5 * qccx escape codes supported. As there are conflicts with qfcc's escape codes, --qccx-escapes can be used to select qccx instead of qfcc. + * explicit references to classes and categories via + "@reference ClassName;" or "@reference ClassName(CategoryName);" o Tools * filter for displaying item information from a map (itemslist.py) * wad tool improvements * qfbsp can extract the entities data from bsp files. + * qflmp: converts between lmp and pcx + * io_mesh_qfmdl: blender mdl import/export script Changes from 0.5.4 o General enhancements From 1c82956dd7bcb93ac6c24cc07897bae6a1fa2b77 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 8 Dec 2011 21:50:55 +0900 Subject: [PATCH 321/334] net_udp.c FIONREAD fix from Ozkan Sezer. net_udp.c: Fixed FIONREAD ioctl to take an int* argument instead of an unsigned long*. --- libs/net/nm/net_udp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/net/nm/net_udp.c b/libs/net/nm/net_udp.c index ec62320a0..fecc2036e 100644 --- a/libs/net/nm/net_udp.c +++ b/libs/net/nm/net_udp.c @@ -417,7 +417,7 @@ UDP_Connect (int socket, netadr_t *addr) int UDP_CheckNewConnections (void) { - unsigned long available; + int available; AF_address_t from; socklen_t fromlen = sizeof (from); char buff[1]; From 693d51859eb76dfdef0ef405e8b3c4a4063f6b77 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 8 Dec 2011 22:10:20 +0900 Subject: [PATCH 322/334] Ignore the test programs. --- .gitignore | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index bfaa7c6ae..cac91fb6e 100644 --- a/.gitignore +++ b/.gitignore @@ -118,7 +118,9 @@ core # /libs/ # /libs/audio/ -/libs/audio/testsound + +# /libs/audio/test/ +/libs/audio/test/testsound # /libs/audio/cd/ @@ -139,7 +141,11 @@ core # /libs/image/ # /libs/models/ -/libs/models/testclip + +# /libs/models/test/ +/libs/models/test/testclip +/libs/models/test/testcontents +/libs/models/test/testportals # /libs/models/alias/ @@ -162,6 +168,10 @@ core # /libs/util/ +# /libs/util/test +/libs/util/test/test-qfs +/libs/util/test/test-quat + # /libs/video/ # /libs/video/renderer/ From 2edac1a4387232ac75e5ca684be4a9bf3594abf9 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 8 Dec 2011 22:16:59 +0900 Subject: [PATCH 323/334] Nuke a sprintf. --- libs/net/nc/net_udp6.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/libs/net/nc/net_udp6.c b/libs/net/nc/net_udp6.c index 6112c2a31..b0552e6e7 100644 --- a/libs/net/nc/net_udp6.c +++ b/libs/net/nc/net_udp6.c @@ -248,7 +248,7 @@ NET_CompareAdr (netadr_t a, netadr_t b) const char * NET_AdrToString (netadr_t a) { - static char s[64]; + static dstring_t *s; char base[64]; AF_address_t ss; @@ -273,13 +273,15 @@ NET_AdrToString (netadr_t a) if (getnameinfo (&ss.sa, SS_LEN(&ss.ss), base, sizeof (base), NULL, 0, NI_NUMERICHOST)) strcpy (base, ""); + if (!s) + s = dstring_new (); if (ss.ss.ss_family == AF_INET6) { - sprintf (s, "[%s]:%d", base, ntohs (a.port)); + dsprintf (s, "[%s]:%d", base, ntohs (a.port)); } else { - sprintf (s, "%s:%d", base, ntohs (a.port)); + dsprintf (s, "%s:%d", base, ntohs (a.port)); } - return s; + return s->str; } const char * From 85168913299ccae65c29535f2963d521704a6ef3 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 9 Dec 2011 11:27:46 +0900 Subject: [PATCH 324/334] Edit the package version when building a release. --- tools/build_scripts/qf-release | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/build_scripts/qf-release b/tools/build_scripts/qf-release index 0ec8d4a50..df517874f 100755 --- a/tools/build_scripts/qf-release +++ b/tools/build_scripts/qf-release @@ -68,6 +68,10 @@ mv quakeforge quakeforge-$ver cd quakeforge-$ver git checkout $tag_name cp NEWS $RELEASE +if test "$tag_name" != master; then + sed -e "s/git-master/$tag_name/" configure.ac > configure.ac- + mv configure.ac- configure.ac +fi mkdir -p linux.o qf-win32.o ./bootstrap #begin linux From 054e52528e6ba5d6a32e124c4aa6f7a0086ffd19 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 9 Dec 2011 18:41:52 +0900 Subject: [PATCH 325/334] Revive the loading plaque. At the request of scar3crow. --- nq/include/client.h | 2 ++ nq/source/cl_main.c | 5 ++++- nq/source/cl_screen.c | 13 +++++++++++++ nq/source/host.c | 2 +- nq/source/host_cmd.c | 11 ++++++----- 5 files changed, 26 insertions(+), 7 deletions(-) diff --git a/nq/include/client.h b/nq/include/client.h index 27ca00f17..2477e63d8 100644 --- a/nq/include/client.h +++ b/nq/include/client.h @@ -159,6 +159,8 @@ extern client_static_t cls; */ typedef struct { + qboolean loading; + int movemessages; // Since connecting to this server throw out // the first couple, so the player doesn't // accidentally do something the first frame diff --git a/nq/source/cl_main.c b/nq/source/cl_main.c index 59ffa6c6b..3181d4b73 100644 --- a/nq/source/cl_main.c +++ b/nq/source/cl_main.c @@ -300,7 +300,7 @@ CL_SignonReply (void) break; case 4: -// SCR_EndLoadingPlaque (); // allow normal screen updates + cl.loading = false; break; } } @@ -316,6 +316,9 @@ CL_NextDemo (void) if (cls.demonum == -1) return; // don't play demos + cl.loading = true; + CL_UpdateScreen(cl.time); + if (!cls.demos[cls.demonum][0] || cls.demonum == MAX_DEMOS) { cls.demonum = 0; if (!cls.demos[cls.demonum][0]) { diff --git a/nq/source/cl_screen.c b/nq/source/cl_screen.c index 7ed435d0d..90d257bce 100644 --- a/nq/source/cl_screen.c +++ b/nq/source/cl_screen.c @@ -64,6 +64,18 @@ SCR_DrawNet (void) Draw_Pic (scr_vrect.x + 64, scr_vrect.y, scr_net); } +static void +SCR_DrawLoading (void) +{ + qpic_t *pic; + + if (!cl.loading) + return; + pic = Draw_CachePic ("gfx/loading.lmp", 1); + Draw_Pic ((vid.conwidth - pic->width) / 2, + (vid.conheight - 48 - pic->height) / 2, pic); +} + static SCR_Func scr_funcs_normal[] = { Draw_Crosshair, SCR_DrawRam, @@ -73,6 +85,7 @@ static SCR_Func scr_funcs_normal[] = { Sbar_DrawCenterPrint, Sbar_Draw, Con_DrawConsole, + SCR_DrawLoading, 0 }; diff --git a/nq/source/host.c b/nq/source/host.c index a37a23cda..b923ca835 100644 --- a/nq/source/host.c +++ b/nq/source/host.c @@ -192,7 +192,7 @@ Host_Error (const char *error, ...) inerror = true; -// SCR_EndLoadingPlaque (); // reenable screen updates + cl.loading = false; va_start (argptr, error); dvsprintf (str, error, argptr); diff --git a/nq/source/host_cmd.c b/nq/source/host_cmd.c index 15c518702..6a23e3faf 100644 --- a/nq/source/host_cmd.c +++ b/nq/source/host_cmd.c @@ -299,7 +299,8 @@ Host_Map_f (void) CL_Disconnect (); Host_ShutdownServer (false); -// SCR_BeginLoadingPlaque (); + cl.loading = true; + CL_UpdateScreen (cl.time); cls.mapstring[0] = 0; for (i = 0; i < Cmd_Argc (); i++) { @@ -379,7 +380,8 @@ Host_Restart_f (void) static void Host_Reconnect_f (void) { -// SCR_BeginLoadingPlaque (); + cl.loading = true; + CL_UpdateScreen (cl.time); cls.signon = 0; // need new connection messages } @@ -623,9 +625,8 @@ Host_Loadgame_f (void) dsprintf (name, "%s/%s", qfs_gamedir->dir.def, Cmd_Argv (1)); QFS_DefaultExtension (name, ".sav"); - // we can't call SCR_BeginLoadingPlaque, because too much stack space has - // been used. The menu calls it before stuffing loadgame command -// SCR_BeginLoadingPlaque (); + cl.loading = true; + CL_UpdateScreen (cl.time); Sys_Printf ("Loading game from %s...\n", name->str); f = QFS_Open (name->str, "rz"); From 361255cf31951d0472fe442a8176b4079f97a517 Mon Sep 17 00:00:00 2001 From: Jeff Teunissen Date: Fri, 9 Dec 2011 22:36:41 -0500 Subject: [PATCH 326/334] Ruamoko: New math constants, some new math functions Also, switch all of the math builtins functions we use from Rua to the ones that accept and return floats, avoiding conversions to/from double. --- libs/ruamoko/rua_math.c | 60 +++++++++++----- ruamoko/include/math.h | 152 +++++++++++++++++++++++++++++++--------- 2 files changed, 163 insertions(+), 49 deletions(-) diff --git a/libs/ruamoko/rua_math.c b/libs/ruamoko/rua_math.c index 8a8b80b6e..c5d7ca35e 100644 --- a/libs/ruamoko/rua_math.c +++ b/libs/ruamoko/rua_math.c @@ -47,100 +47,124 @@ static __attribute__ ((used)) const char rcsid[] = static void bi_sin (progs_t *pr) { - R_FLOAT (pr) = sin (P_FLOAT (pr, 0)); + R_FLOAT (pr) = sinf (P_FLOAT (pr, 0)); } static void bi_cos (progs_t *pr) { - R_FLOAT (pr) = cos (P_FLOAT (pr, 0)); + R_FLOAT (pr) = cosf (P_FLOAT (pr, 0)); } static void bi_tan (progs_t *pr) { - R_FLOAT (pr) = tan (P_FLOAT (pr, 0)); + R_FLOAT (pr) = tanf (P_FLOAT (pr, 0)); } static void bi_asin (progs_t *pr) { - R_FLOAT (pr) = asin (P_FLOAT (pr, 0)); + R_FLOAT (pr) = asinf (P_FLOAT (pr, 0)); } static void bi_acos (progs_t *pr) { - R_FLOAT (pr) = acos (P_FLOAT (pr, 0)); + R_FLOAT (pr) = acosf (P_FLOAT (pr, 0)); } static void bi_atan (progs_t *pr) { - R_FLOAT (pr) = atan (P_FLOAT (pr, 0)); + R_FLOAT (pr) = atanf (P_FLOAT (pr, 0)); } static void bi_atan2 (progs_t *pr) { - R_FLOAT (pr) = atan2 (P_FLOAT (pr, 0), P_FLOAT (pr, 1)); + R_FLOAT (pr) = atan2f (P_FLOAT (pr, 0), P_FLOAT (pr, 1)); } static void bi_log (progs_t *pr) { - R_FLOAT (pr) = log (P_FLOAT (pr, 0)); + R_FLOAT (pr) = logf (P_FLOAT (pr, 0)); +} + +static void +bi_log2 (progs_t *pr) +{ + R_FLOAT (pr) = log2f (P_FLOAT (pr, 0)); } static void bi_log10 (progs_t *pr) { - R_FLOAT (pr) = log10 (P_FLOAT (pr, 0)); + R_FLOAT (pr) = log10f (P_FLOAT (pr, 0)); } static void bi_pow (progs_t *pr) { - R_FLOAT (pr) = pow (P_FLOAT (pr, 0), P_FLOAT (pr, 1)); + R_FLOAT (pr) = powf (P_FLOAT (pr, 0), P_FLOAT (pr, 1)); +} + +static void +bi_sqrt (progs_t *pr) +{ + R_FLOAT (pr) = sqrtf (P_FLOAT (pr, 0)); +} + +static void +bi_cbrt (progs_t *pr) +{ + R_FLOAT (pr) = cbrtf (P_FLOAT (pr, 0)); +} + +static void +bi_hypot (progs_t *pr) +{ + R_FLOAT (pr) = hypotf (P_FLOAT (pr, 0), P_FLOAT (pr, 1)); } static void bi_sinh (progs_t *pr) { - R_FLOAT (pr) = sinh (P_FLOAT (pr, 0)); + R_FLOAT (pr) = sinhf (P_FLOAT (pr, 0)); } static void bi_cosh (progs_t *pr) { - R_FLOAT (pr) = cosh (P_FLOAT (pr, 0)); + R_FLOAT (pr) = coshf (P_FLOAT (pr, 0)); } static void bi_tanh (progs_t *pr) { - R_FLOAT (pr) = tanh (P_FLOAT (pr, 0)); + R_FLOAT (pr) = tanhf (P_FLOAT (pr, 0)); } static void bi_asinh (progs_t *pr) { double y = P_FLOAT (pr, 0); - R_FLOAT (pr) = log (y + sqrt (y * y + 1)); + R_FLOAT (pr) = logf (y + sqrtf (y * y + 1)); } static void bi_acosh (progs_t *pr) { double y = P_FLOAT (pr, 0); - R_FLOAT (pr) = log (y + sqrt (y * y - 1)); + R_FLOAT (pr) = logf (y + sqrtf (y * y - 1)); } static void bi_atanh (progs_t *pr) { double y = P_FLOAT (pr, 0); - R_FLOAT (pr) = log ((1 + y) / (1 - y)) / 2; + R_FLOAT (pr) = logf ((1 + y) / (1 - y)) / 2; } static builtin_t builtins[] = { @@ -152,8 +176,12 @@ static builtin_t builtins[] = { {"atan", bi_atan, -1}, {"atan2", bi_atan2, -1}, {"log", bi_log, -1}, + {"log2", bi_log2, -1}, {"log10", bi_log10, -1}, {"pow", bi_pow, -1}, + {"sqrt", bi_sqrt, -1}, + {"cbrt", bi_cbrt, -1}, + {"hypot", bi_hypot, -1}, {"sinh", bi_sinh, -1}, {"cosh", bi_cosh, -1}, {"tanh", bi_tanh, -1}, diff --git a/ruamoko/include/math.h b/ruamoko/include/math.h index d666f61f4..b6d6eac9f 100644 --- a/ruamoko/include/math.h +++ b/ruamoko/include/math.h @@ -32,7 +32,7 @@ #define __ruamoko_math_h /** - \defgroup math Math Functions + \defgroup math Math Definitions \{ */ @@ -41,6 +41,8 @@ */ @extern float random (void); +///\name Conversions +//\{ /** Returns the integer component of \a f */ @@ -70,31 +72,43 @@ Returns the absolute value of \a f */ @extern float fabs (float f); +//\} -/**************************************************************************** - * VECTORS * - ****************************************************************************/ +///\name Exponentials and Logarithms +//\{ +/** + Returns the natural log of \a x. +*/ +@extern float log (float x); /** - Transform vector \a v into a unit vector (a vector with a length of 1). - The direction is not changed, except for (possible) roundoff errors. + Returns the base-2 log of \a x. */ -@extern vector normalize (vector v); +@extern float log2 (float x); /** - Return the length of vector \a v + Returns the base-10 log of \a x. */ -@extern float vlen (vector v); +@extern float log10 (float x); /** - Returns the yaw angle ("bearing"), in degrees, associated with vector \a v. + Returns \a x to the \a y power */ -@extern float vectoyaw (vector v); +@extern float pow (float x, float y); /** - Returns a vector 'pitch yaw 0' corresponding to vector \a v. + Returns the square root of \a x */ -@extern vector vectoangles (vector v); +@extern float sqrt (float x); + +/** + Returns the cube root of \a x +*/ +@extern float cbrt (float x); +//\} + +///\name Trigonometric functions +//\{ /** Returns the sine of \a x. @@ -128,27 +142,99 @@ @extern float atan2 (float y, float x); /** - Returns the natural log of \a x. + Returns the length of the hypotenuse of a right triangle with sides \a x + and \a y. That is, this function returns + sqrt (\a x*\a x + \a y*\a y). */ -@extern float log (float x); - -/** - Returns the base-10 log of \a x. -*/ -@extern float log10 (float x); - -/** - Returns \a x to the \a y power -*/ -@extern float pow (float x, float y); - -@extern float sinh (float x); -@extern float cosh (float x); -@extern float tanh (float x); -@extern float asinh (float x); -@extern float acosh (float x); -@extern float atanh (float x); - +@extern float hypot (float x, float y); //\} +///\name Hyperbolic functions +//\{ +/** + Returns the hyperbolic sine of \a x +*/ +@extern float sinh (float x); + +/** + Returns the hyperbolic cosine of \a x +*/ +@extern float cosh (float x); + +/** + Returns the hyperbolic tangent of \a x +*/ +@extern float tanh (float x); + +/** + Returns the area hyperbolic sine of \a x +*/ +@extern float asinh (float x); + +/** + Returns the area hyperbolic cosine of \a x +*/ +@extern float acosh (float x); + +/** + Returns the area hyperbolic tangent of \a x +*/ +@extern float atanh (float x); +//\} + +///\name Vector Functions +//\{ +/** + Transform vector \a v into a unit vector (a vector with a length of 1). + The direction is not changed, except for (possible) rounding errors. +*/ +@extern vector normalize (vector v); + +/** + Return the length of vector \a v +*/ +@extern float vlen (vector v); + +/** + Returns the yaw angle ("bearing"), in degrees, associated with vector \a v. +*/ +@extern float vectoyaw (vector v); + +/** + Returns a vector 'pitch yaw 0' corresponding to vector \a v. +*/ +@extern vector vectoangles (vector v); +//\} + +/** + \name Constants + Constants for speeding up math calculations. + These constants are defined to replace some common math functions. Since + these are the same values that would be returned by any math functions or + floating-point calculations, these allow you to get the results without + actually calling them. + \note There does not appear to be a portable way to translate C's HUGE_VAL + value, the basis for positive and negative infinities, to Ruamoko. + \{ +*/ +# define M_E 2.7182818284590452354 ///< Euler's number \em e, the irrational base of the natural logarithm and a really neat thing +# define M_LOG2E 1.4426950408889634074 ///< The log, base 2, of \em e: log2 (\ref M_E) +# define M_LOG10E 0.43429448190325182765 ///< The log, base 10, of \em e: log10 (\ref M_E) +# define M_LN2 0.69314718055994530942 ///< The natural log evaluated at 2: log (2) +# define M_LN10 2.30258509299404568402 ///< The natural log evaluated at 10: log (10) +# define M_PI 3.14159265358979323846 ///< The most famous irrational number, and the sixteenth letter of the Greek alphabet +# define M_PI_2 1.57079632679489661923 ///< Half of pi, (\ref M_PI/2) +# define M_PI_4 0.78539816339744830962 ///< One quarter of pi, (\ref M_PI/4) +# define M_PI_6 0.52359877559829887308 ///< One sixth of pi, (\ref M_PI/6) +# define M_1_PI 0.31830988618379067154 ///< The reciprocal of pi, (1/\ref M_PI) +# define M_2_PI 0.63661977236758134308 ///< Twice the reciprocal of pi, (2/\ref M_PI) +# define M_2_SQRTPI 1.12837916709551257390 ///< Twice the reciprocal of the square root of pi, 2/\ref sqrt(\ref M_PI) +# define M_SQRT2 1.41421356237309504880 ///< The square root of 2 +# define M_SQRT1_2 0.70710678118654752440 ///< 1/sqrt(2) +# define M_SQRT3 1.73205080756887729353 ///< The square root of 3 +# define M_SQRT1_3 0.57735026918962576451 ///< 1/sqrt(3) +/** + \} Constants + \} Math Definitions +*/ #endif //__ruamoko_math_h From 4f4d6b5675f893db168eecf3d0eec65c1277adcc Mon Sep 17 00:00:00 2001 From: Jeff Teunissen Date: Fri, 9 Dec 2011 22:42:43 -0500 Subject: [PATCH 327/334] OK, now import them... Duh. --- ruamoko/lib/math.r | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ruamoko/lib/math.r b/ruamoko/lib/math.r index 59a76bbc2..8d0c51342 100644 --- a/ruamoko/lib/math.r +++ b/ruamoko/lib/math.r @@ -22,6 +22,7 @@ float (float x) acos = #0; float (float x) atan = #0; float (float y, float x) atan2 = #0; float (float x) log = #0; +float (float x) log2 = #0; float (float x) log10 = #0; float (float x, float y) pow = #0; float (float x) sinh = #0; @@ -30,3 +31,6 @@ float (float x) tanh = #0; float (float x) asinh = #0; float (float x) acosh = #0; float (float x) atanh = #0; +float (float x) sqrt = #0; +float (float x) cbrt = #0; +float (float x, float y) hypot = #0; From d9d56760e13de2dd99e48d9c6dc302799cfeefda Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 10 Dec 2011 13:10:28 +0900 Subject: [PATCH 328/334] Add cvars to control the keys for menus and console. The backquote is not always usable for toggling the console, and the new bind system doesn't automatically bind a key to both game and console imts (by design). Thus create a cvar that allows the "always works" console toggle to be specified in eg $fs_globalcfg. While I'm at it, do one for the menus, too. --- include/QF/keys.h | 2 ++ libs/video/targets/keys.c | 41 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/include/QF/keys.h b/include/QF/keys.h index 4c99bd0c9..c9ce3bfd3 100644 --- a/include/QF/keys.h +++ b/include/QF/keys.h @@ -406,6 +406,8 @@ typedef struct { extern keydest_t key_dest; extern imt_t game_target; +extern knum_t key_togglemenu; +extern knum_t key_toggleconsole; extern struct keybind_s { char *str; diff --git a/libs/video/targets/keys.c b/libs/video/targets/keys.c index 318583964..b2ff0b0c7 100644 --- a/libs/video/targets/keys.c +++ b/libs/video/targets/keys.c @@ -62,6 +62,8 @@ cvar_t *in_bind_imt; VISIBLE keydest_t key_dest = key_console; VISIBLE imt_t game_target = IMT_CONSOLE; +VISIBLE knum_t key_togglemenu = QFK_ESCAPE; +VISIBLE knum_t key_toggleconsole = QFK_BACKQUOTE; VISIBLE struct keybind_s keybindings[IMT_LAST][QFK_LAST]; VISIBLE int keydown[QFK_LAST]; @@ -737,6 +739,40 @@ in_bind_imt_f (cvar_t *var) } } +static void +in_key_togglemenu_f (cvar_t *var) +{ + int k; + + if (!*var->string) { + key_togglemenu = QFK_ESCAPE; + return; + } + if ((k = Key_StringToKeynum (var->string)) == -1) { + k = QFK_ESCAPE; + Sys_Printf ("\"%s\" is not a valid key. setting to \"K_ESCAPE\"\n", + var->string); + } + key_togglemenu = k; +} + +static void +in_key_toggleconsole_f (cvar_t *var) +{ + int k; + + if (!*var->string) { + key_toggleconsole = -1; + return; + } + if ((k = Key_StringToKeynum (var->string)) == -1) { + Sys_Printf ("\"%s\" is not a valid key. not setting\n", + var->string); + return; + } + key_toggleconsole = k; +} + static void Key_InputMappingTable_f (void) { @@ -893,6 +929,11 @@ Key_Init_Cvars (void) in_bind_imt = Cvar_Get ("in_bind_imt", "imt_default", CVAR_ARCHIVE, in_bind_imt_f, "imt parameter for the bind and " "unbind wrappers to in_bind and in_unbind"); + Cvar_Get ("in_key_togglemenu", "", CVAR_NONE, in_key_togglemenu_f, + "Key for toggling the menu."); + Cvar_Get ("in_key_toggleconsole", "K_BACKQUOTE", CVAR_NONE, + in_key_toggleconsole_f, + "Key for toggling the console."); } const char * From 49451eea80a8a346065ed302ed391d7b51a60450 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 10 Dec 2011 13:22:36 +0900 Subject: [PATCH 329/334] Use the new menu/console bingings. Now, the console toggle will always work (so long as the console is toggleable in the first place). --- libs/console/client.c | 51 +++++++++++++++++++++------------------ libs/video/targets/keys.c | 2 +- 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/libs/console/client.c b/libs/console/client.c index ae84a521d..bd9959b30 100644 --- a/libs/console/client.c +++ b/libs/console/client.c @@ -461,30 +461,35 @@ C_KeyEvent (knum_t key, short unicode, qboolean down) return; } - if (down && (key == QFK_ESCAPE || unicode == '\x1b')) { - switch (key_dest) { - case key_menu: - Menu_Leave (); - return; - case key_message: - if (chat_team) { - Con_ClearTyping (say_team_line, 1); - } else { - Con_ClearTyping (say_line, 1); - } - key_dest = key_game; - game_target = IMT_0; - return; - case key_console: - if (!con_data.force_commandline) { - Cbuf_AddText (con_data.cbuf, "toggleconsole\n"); + if (down) { + if (key == key_togglemenu) { + switch (key_dest) { + case key_menu: + Menu_Leave (); return; - } - case key_game: - Menu_Enter (); - return; - default: - Sys_Error ("Bad key_dest"); + case key_message: + if (chat_team) { + Con_ClearTyping (say_team_line, 1); + } else { + Con_ClearTyping (say_line, 1); + } + key_dest = key_game; + game_target = IMT_0; + return; + case key_console: + if (!con_data.force_commandline) { + Cbuf_AddText (con_data.cbuf, "toggleconsole\n"); + return; + } + case key_game: + Menu_Enter (); + return; + default: + Sys_Error ("Bad key_dest"); + } + } else if (key == key_toggleconsole) { + ToggleConsole_f (); + return; } } diff --git a/libs/video/targets/keys.c b/libs/video/targets/keys.c index b2ff0b0c7..08178cdaf 100644 --- a/libs/video/targets/keys.c +++ b/libs/video/targets/keys.c @@ -857,7 +857,7 @@ Key_Event (knum_t key, short unicode, qboolean down) } // handle escape specially, so the user can never unbind it - if (unicode == '\x1b' || key == QFK_ESCAPE) { + if (key == key_togglemenu || key == key_toggleconsole) { Key_Console (key, unicode); return; } From 14d8e8669f6ca496fcda147e32ae2c2e831cc9bd Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 10 Dec 2011 13:56:02 +0900 Subject: [PATCH 330/334] Rework the legacy bind/unbind commands. in_bind_imt is now gone. I guess mercury was right in that it was a poor design. However, it was (and still is necessary) to support "bind" and "unbind". Now, instead, they work only with the IMT_MOD table. IMT_MOD sits below IMT_0 in the imt hierarchy. If the key is not bound in IMT_0+, then IMT_MOD will be checked. This way, "bind" and "unbind" can never mess with a user's more sophisticated binding setup. --- include/QF/keys.h | 1 + libs/video/targets/keys.c | 40 +++++++++------------------------------ 2 files changed, 10 insertions(+), 31 deletions(-) diff --git a/include/QF/keys.h b/include/QF/keys.h index c9ce3bfd3..ecc208ada 100644 --- a/include/QF/keys.h +++ b/include/QF/keys.h @@ -369,6 +369,7 @@ typedef enum { typedef enum { IMT_CONSOLE, + IMT_MOD, IMT_0, IMT_1, IMT_2, diff --git a/libs/video/targets/keys.c b/libs/video/targets/keys.c index 08178cdaf..10160a8a5 100644 --- a/libs/video/targets/keys.c +++ b/libs/video/targets/keys.c @@ -58,8 +58,6 @@ static __attribute__ ((used)) const char rcsid[] = /* key up events are sent even if in console mode */ -cvar_t *in_bind_imt; - VISIBLE keydest_t key_dest = key_console; VISIBLE imt_t game_target = IMT_CONSOLE; VISIBLE knum_t key_togglemenu = QFK_ESCAPE; @@ -78,6 +76,7 @@ typedef struct { imtname_t imtnames[] = { {"IMT_CONSOLE", IMT_CONSOLE}, + {"IMT_MOD", IMT_MOD}, {"IMT_0", IMT_0}, {"IMT_1", IMT_1}, {"IMT_2", IMT_2}, @@ -424,6 +423,8 @@ Key_Game (knum_t key, short unicode) kb = Key_GetBinding (game_target, key); if (!kb && (game_target > IMT_0)) kb = Key_GetBinding (IMT_0, key); + if (!kb) + kb = Key_GetBinding (IMT_MOD, key); /* Sys_DPrintf("kb %p, game_target %d, key_dest %d, key %d\n", kb, @@ -662,14 +663,14 @@ Key_Unbind_f (void) return; } key = OK_TranslateKeyName (Cmd_Argv (1)); - Key_In_Unbind (in_bind_imt->string, key); + Key_In_Unbind ("imt_mod", key); } static void Key_Bind_f (void) { int c, i; - const char *imt, *key, *cmd = 0; + const char *key, *cmd = 0; char cmd_buf[1024]; c = Cmd_Argc (); @@ -679,8 +680,6 @@ Key_Bind_f (void) return; } - imt = in_bind_imt->string; - key = OK_TranslateKeyName (Cmd_Argv (1)); if (c >= 3) { @@ -694,51 +693,33 @@ Key_Bind_f (void) } } - Key_In_Bind (imt, key, cmd); + Key_In_Bind ("imt_mod", key, cmd); } static void Key_GIB_Bind_Get_f (void) { - const char *imt, *key, *cmd; - int t, k; + const char *key, *cmd; + int k; if (GIB_Argc () != 2) { GIB_USAGE ("key"); return; } - imt = in_bind_imt->string; - key = OK_TranslateKeyName (GIB_Argv (1)); - if ((t = Key_StringToIMTnum (imt)) == -1) { - GIB_Error ("bind", "bind::get: invalid imt %s", imt); - return; - } - if ((k = Key_StringToKeynum (key)) == -1) { GIB_Error ("bind", "bind::get: invalid key %s", key); return; } - if (!(cmd = Key_GetBinding (t, k))) + if (!(cmd = Key_GetBinding (IMT_MOD, k))) GIB_Return (""); else GIB_Return (cmd); } - -static void -in_bind_imt_f (cvar_t *var) -{ - if (Key_StringToIMTnum (var->string) == -1) { - Sys_Printf ("\"%s\" is not a valid imt. setting to \"imt_default\"\n", - var->string); - Cvar_Set (var, "imt_default"); - } -} - static void in_key_togglemenu_f (cvar_t *var) { @@ -926,9 +907,6 @@ Key_Init (cbuf_t *cb) void Key_Init_Cvars (void) { - in_bind_imt = Cvar_Get ("in_bind_imt", "imt_default", CVAR_ARCHIVE, - in_bind_imt_f, "imt parameter for the bind and " - "unbind wrappers to in_bind and in_unbind"); Cvar_Get ("in_key_togglemenu", "", CVAR_NONE, in_key_togglemenu_f, "Key for toggling the menu."); Cvar_Get ("in_key_toggleconsole", "K_BACKQUOTE", CVAR_NONE, From 81a16c925baac18b2af389b8636401efeae4a64d Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 10 Dec 2011 14:21:12 +0900 Subject: [PATCH 331/334] Add IMT_DEMO for demo playback bindings. This will allow special key bindings for use during demo playback without interfering with normal keys. --- include/QF/keys.h | 2 ++ libs/video/targets/keys.c | 53 ++++++++++++++++++++++++++++++--------- 2 files changed, 43 insertions(+), 12 deletions(-) diff --git a/include/QF/keys.h b/include/QF/keys.h index ecc208ada..b15e36321 100644 --- a/include/QF/keys.h +++ b/include/QF/keys.h @@ -369,6 +369,7 @@ typedef enum { typedef enum { IMT_CONSOLE, + IMT_DEMO, IMT_MOD, IMT_0, IMT_1, @@ -393,6 +394,7 @@ typedef enum { // key_none should, preferably, be last typedef enum { key_game, + key_demo, key_console, key_message, key_menu, diff --git a/libs/video/targets/keys.c b/libs/video/targets/keys.c index 10160a8a5..f08bebcde 100644 --- a/libs/video/targets/keys.c +++ b/libs/video/targets/keys.c @@ -76,6 +76,7 @@ typedef struct { imtname_t imtnames[] = { {"IMT_CONSOLE", IMT_CONSOLE}, + {"IMT_DEMO", IMT_DEMO}, {"IMT_MOD", IMT_MOD}, {"IMT_0", IMT_0}, {"IMT_1", IMT_1}, @@ -409,6 +410,23 @@ keyname_t keynames[] = { }; +static void +process_binding (knum_t key, const char *kb) +{ + char cmd[1024]; + + if (kb[0] == '+') { + if (keydown[key]) + snprintf (cmd, sizeof (cmd), "%s %d\n", kb, key); + else + snprintf (cmd, sizeof (cmd), "-%s %d\n", kb + 1, key); + } else { + if (!keydown[key]) + return; + snprintf (cmd, sizeof (cmd), "%s\n", kb); + } + Cbuf_AddText (cbuf, cmd); +} /* Key_Game @@ -418,7 +436,6 @@ static qboolean Key_Game (knum_t key, short unicode) { const char *kb; - char cmd[1024]; kb = Key_GetBinding (game_target, key); if (!kb && (game_target > IMT_0)) @@ -436,20 +453,29 @@ Key_Game (knum_t key, short unicode) if (keydown[key] > 1) return true; - if (kb[0] == '+') { - if (keydown[key]) - snprintf (cmd, sizeof (cmd), "%s %d\n", kb, key); - else - snprintf (cmd, sizeof (cmd), "-%s %d\n", kb + 1, key); - } else { - if (!keydown[key]) - return true; - snprintf (cmd, sizeof (cmd), "%s\n", kb); - } - Cbuf_AddText (cbuf, cmd); + process_binding (key, kb); return true; } +/* + Key_Demo + + Interactive line editing and console scrollback +*/ +static void +Key_Demo (knum_t key, short unicode) +{ + const char *kb; + + // escape is un-bindable + if (keydown[key] == 1 && key && Key_Game (key, unicode)) + return; + + kb = Key_GetBinding (IMT_DEMO, key); + if (kb) + process_binding (key, kb); +} + /* Key_Console @@ -851,6 +877,9 @@ Key_Event (knum_t key, short unicode, qboolean down) case key_game: Key_Game (key, unicode); break; + case key_demo: + Key_Demo (key, unicode); + break; case key_message: case key_menu: case key_console: From 3ae17e4d37114b27386efdb0d6eacd3569fe7ce1 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 10 Dec 2011 14:49:56 +0900 Subject: [PATCH 332/334] Fix a silly omission. Must not check for IMT_MOD bindings when using IMT_CONSOLE etc. --- libs/video/targets/keys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/video/targets/keys.c b/libs/video/targets/keys.c index f08bebcde..f9261aa84 100644 --- a/libs/video/targets/keys.c +++ b/libs/video/targets/keys.c @@ -440,7 +440,7 @@ Key_Game (knum_t key, short unicode) kb = Key_GetBinding (game_target, key); if (!kb && (game_target > IMT_0)) kb = Key_GetBinding (IMT_0, key); - if (!kb) + if (!kb && (game_target >= IMT_MOD)) kb = Key_GetBinding (IMT_MOD, key); /* From 16c8b2a18de76824057611f430bc105a59f77259 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 10 Dec 2011 15:18:50 +0900 Subject: [PATCH 333/334] Use the new demo imt. There are some problems with menus and the console messing up the key_dest state (they assume console/menu or game, nothing else), but otherwise things seem to work. --- libs/console/client.c | 1 + nq/source/cl_demo.c | 4 ++-- nq/source/cl_main.c | 9 +++++++-- nq/source/sbar.c | 6 ++++-- qw/source/cl_main.c | 9 +++++++-- qw/source/sbar.c | 6 ++++-- 6 files changed, 25 insertions(+), 10 deletions(-) diff --git a/libs/console/client.c b/libs/console/client.c index bd9959b30..cd6d905e0 100644 --- a/libs/console/client.c +++ b/libs/console/client.c @@ -482,6 +482,7 @@ C_KeyEvent (knum_t key, short unicode, qboolean down) return; } case key_game: + case key_demo: Menu_Enter (); return; default: diff --git a/nq/source/cl_demo.c b/nq/source/cl_demo.c index abcb8b1ec..07e3ed2b9 100644 --- a/nq/source/cl_demo.c +++ b/nq/source/cl_demo.c @@ -357,8 +357,8 @@ CL_StartDemo (void) cls.demoplayback = true; CL_SetState (ca_connected); cls.forcetrack = 0; - key_dest = key_game; - game_target = IMT_0; + key_dest = key_demo; + game_target = IMT_DEMO; while ((c = Qgetc (cls.demofile)) != '\n') if (c == '-') diff --git a/nq/source/cl_main.c b/nq/source/cl_main.c index 3181d4b73..1f7215709 100644 --- a/nq/source/cl_main.c +++ b/nq/source/cl_main.c @@ -429,8 +429,13 @@ CL_SetState (cactive_t state) if (state == ca_active) { // entering active state r_active = true; - game_target = IMT_0; - key_dest = key_game; + if (cls.demoplayback) { + game_target = IMT_DEMO; + key_dest = key_demo; + } else { + game_target = IMT_0; + key_dest = key_game; + } IN_ClearStates (); VID_SetCaption (""); } else if (old_state == ca_active) { diff --git a/nq/source/sbar.c b/nq/source/sbar.c index a7a8a7c23..f752d6e04 100644 --- a/nq/source/sbar.c +++ b/nq/source/sbar.c @@ -1252,7 +1252,8 @@ Sbar_FinaleOverlay (void) { int remaining; - if (key_dest != key_game) + //FIXME cleaner test + if (key_dest != key_game && key_dest != key_demo) return; scr_copyeverything = 1; @@ -1272,7 +1273,8 @@ Sbar_DrawCenterPrint (void) if (centertime_off <= 0) return; - if (key_dest != key_game) + //FIXME cleaner test + if (key_dest != key_game && key_dest != key_demo) return; Sbar_DrawCenterString (overlay_view, -1); diff --git a/qw/source/cl_main.c b/qw/source/cl_main.c index c931db4a8..2d7e5409c 100644 --- a/qw/source/cl_main.c +++ b/qw/source/cl_main.c @@ -1160,8 +1160,13 @@ CL_SetState (cactive_t state) VID_SetCaption (cls.servername->str); IN_ClearStates (); r_active = true; - game_target = IMT_0; - key_dest = key_game; + if (cls.demoplayback) { + game_target = IMT_DEMO; + key_dest = key_demo; + } else { + game_target = IMT_0; + key_dest = key_game; + } // Auto demo recorder starts here if (cl_autorecord->int_val && !cls.demoplayback diff --git a/qw/source/sbar.c b/qw/source/sbar.c index 676958f71..0cdcb5e5d 100644 --- a/qw/source/sbar.c +++ b/qw/source/sbar.c @@ -1712,7 +1712,8 @@ Sbar_FinaleOverlay (void) { int remaining; - if (key_dest != key_game) + //FIXME cleaner test + if (key_dest != key_game && key_dest != key_demo) return; scr_copyeverything = 1; @@ -1732,7 +1733,8 @@ Sbar_DrawCenterPrint (void) if (centertime_off <= 0) return; - if (key_dest != key_game) + //FIXME cleaner test + if (key_dest != key_game && key_dest != key_demo) return; Sbar_DrawCenterString (overlay_view, -1); From c3d41326b3195b4168938fa6adc0a4575d72d382 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 10 Dec 2011 16:14:25 +0900 Subject: [PATCH 334/334] Do key dest changing properly. key_demo wasn't so well thought out. This seems to be much better (and nq is known to be working nicely). --- include/QF/keys.h | 6 +++--- libs/console/client.c | 28 ++++++++---------------- libs/console/menu.c | 21 ++++++------------ libs/video/targets/keys.c | 45 ++++++++++++++++++--------------------- nq/source/cl_demo.c | 6 ++++-- nq/source/cl_main.c | 14 +++--------- nq/source/sbar.c | 4 ++-- qw/source/cl_demo.c | 5 +++++ qw/source/cl_main.c | 11 ++-------- qw/source/sbar.c | 4 ++-- 10 files changed, 58 insertions(+), 86 deletions(-) diff --git a/include/QF/keys.h b/include/QF/keys.h index b15e36321..2b736891e 100644 --- a/include/QF/keys.h +++ b/include/QF/keys.h @@ -369,8 +369,8 @@ typedef enum { typedef enum { IMT_CONSOLE, - IMT_DEMO, IMT_MOD, + IMT_DEMO, IMT_0, IMT_1, IMT_2, @@ -394,7 +394,6 @@ typedef enum { // key_none should, preferably, be last typedef enum { key_game, - key_demo, key_console, key_message, key_menu, @@ -408,7 +407,7 @@ typedef struct { } kbutton_t; extern keydest_t key_dest; -extern imt_t game_target; +extern imt_t key_game_target; extern knum_t key_togglemenu; extern knum_t key_toggleconsole; @@ -425,6 +424,7 @@ void Key_WriteBindings (QFile *f); void Key_ClearStates (void); const char *Key_GetBinding (imt_t imt, knum_t key); void Key_SetBinding (imt_t target, knum_t keynum, const char *binding); +void Key_SetKeyDest(keydest_t kd); const char *Key_KeynumToString (knum_t keynum); diff --git a/libs/console/client.c b/libs/console/client.c index cd6d905e0..1c926087f 100644 --- a/libs/console/client.c +++ b/libs/console/client.c @@ -120,11 +120,9 @@ ToggleConsole_f (void) Con_ClearTyping (input_line, 0); if (key_dest == key_console && !con_data.force_commandline) { - key_dest = key_game; - game_target = IMT_0; + Key_SetKeyDest (key_game); } else { - key_dest = key_console; - game_target = IMT_CONSOLE; + Key_SetKeyDest (key_console); } ClearNotify (); @@ -136,11 +134,9 @@ ToggleChat_f (void) Con_ClearTyping (input_line, 0); if (key_dest == key_console && !con_data.force_commandline) { - key_dest = key_game; - game_target = IMT_0; + Key_SetKeyDest (key_game); } else { - key_dest = key_console; - game_target = IMT_CONSOLE; + Key_SetKeyDest (key_console); } ClearNotify (); @@ -162,8 +158,7 @@ MessageMode_f (void) if (con_data.force_commandline) return; chat_team = false; - key_dest = key_message; - game_target = IMT_CONSOLE; + Key_SetKeyDest (key_message); } static void @@ -172,8 +167,7 @@ MessageMode2_f (void) if (con_data.force_commandline) return; chat_team = true; - key_dest = key_message; - game_target = IMT_CONSOLE; + Key_SetKeyDest (key_message); } static void @@ -329,8 +323,7 @@ C_Say (inputline_t *il) Cbuf_AddText (con_data.cbuf, "say \""); Cbuf_AddText (con_data.cbuf, line); Cbuf_AddText (con_data.cbuf, "\"\n"); - key_dest = key_game; - game_target = IMT_0; + Key_SetKeyDest (key_game); } static void @@ -343,8 +336,7 @@ C_SayTeam (inputline_t *il) Cbuf_AddText (con_data.cbuf, "say_team \""); Cbuf_AddText (con_data.cbuf, line); Cbuf_AddText (con_data.cbuf, "\"\n"); - key_dest = key_game; - game_target = IMT_0; + Key_SetKeyDest (key_game); } static void @@ -473,8 +465,7 @@ C_KeyEvent (knum_t key, short unicode, qboolean down) } else { Con_ClearTyping (say_line, 1); } - key_dest = key_game; - game_target = IMT_0; + Key_SetKeyDest (key_game); return; case key_console: if (!con_data.force_commandline) { @@ -482,7 +473,6 @@ C_KeyEvent (knum_t key, short unicode, qboolean down) return; } case key_game: - case key_demo: Menu_Enter (); return; default: diff --git a/libs/console/menu.c b/libs/console/menu.c index 79c9beae0..e9614e1dd 100644 --- a/libs/console/menu.c +++ b/libs/console/menu.c @@ -367,8 +367,7 @@ bi_Menu_SelectMenu (progs_t *pr) if (name && *name) menu = Hash_Find (menu_hash, name); if (menu) { - key_dest = key_menu; - game_target = IMT_CONSOLE; + Key_SetKeyDest (key_menu); if (menu->enter_hook) { run_menu_pre (); PR_ExecuteProgram (&menu_pr_state, menu->enter_hook); @@ -378,11 +377,9 @@ bi_Menu_SelectMenu (progs_t *pr) if (name && *name) Sys_Printf ("no menu \"%s\"\n", name); if (con_data.force_commandline) { - key_dest = key_console; - game_target = IMT_CONSOLE; + Key_SetKeyDest (key_console); } else { - key_dest = key_game; - game_target = IMT_0; + Key_SetKeyDest (key_game); } } } @@ -700,12 +697,10 @@ void Menu_Enter () { if (!top_menu) { - key_dest = key_console; - game_target = IMT_CONSOLE; + Key_SetKeyDest (key_console); return; } - key_dest = key_menu; - game_target = IMT_CONSOLE; + Key_SetKeyDest (key_menu); menu = Hash_Find (menu_hash, top_menu); if (menu && menu->enter_hook) { run_menu_pre (); @@ -726,11 +721,9 @@ Menu_Leave () menu = menu->parent; if (!menu) { if (con_data.force_commandline) { - key_dest = key_console; - game_target = IMT_CONSOLE; + Key_SetKeyDest (key_console); } else { - key_dest = key_game; - game_target = IMT_0; + Key_SetKeyDest (key_game); } } } diff --git a/libs/video/targets/keys.c b/libs/video/targets/keys.c index f9261aa84..46f8cbc38 100644 --- a/libs/video/targets/keys.c +++ b/libs/video/targets/keys.c @@ -59,13 +59,14 @@ static __attribute__ ((used)) const char rcsid[] = /* key up events are sent even if in console mode */ VISIBLE keydest_t key_dest = key_console; -VISIBLE imt_t game_target = IMT_CONSOLE; +VISIBLE imt_t key_game_target = IMT_0; VISIBLE knum_t key_togglemenu = QFK_ESCAPE; VISIBLE knum_t key_toggleconsole = QFK_BACKQUOTE; VISIBLE struct keybind_s keybindings[IMT_LAST][QFK_LAST]; VISIBLE int keydown[QFK_LAST]; +static imt_t game_target = IMT_CONSOLE; static int keyhelp; static cbuf_t *cbuf; @@ -76,8 +77,8 @@ typedef struct { imtname_t imtnames[] = { {"IMT_CONSOLE", IMT_CONSOLE}, - {"IMT_DEMO", IMT_DEMO}, {"IMT_MOD", IMT_MOD}, + {"IMT_DEMO", IMT_DEMO}, {"IMT_0", IMT_0}, {"IMT_1", IMT_1}, {"IMT_2", IMT_2}, @@ -457,25 +458,6 @@ Key_Game (knum_t key, short unicode) return true; } -/* - Key_Demo - - Interactive line editing and console scrollback -*/ -static void -Key_Demo (knum_t key, short unicode) -{ - const char *kb; - - // escape is un-bindable - if (keydown[key] == 1 && key && Key_Game (key, unicode)) - return; - - kb = Key_GetBinding (IMT_DEMO, key); - if (kb) - process_binding (key, kb); -} - /* Key_Console @@ -877,9 +859,6 @@ Key_Event (knum_t key, short unicode, qboolean down) case key_game: Key_Game (key, unicode); break; - case key_demo: - Key_Demo (key, unicode); - break; case key_message: case key_menu: case key_console: @@ -965,3 +944,21 @@ Key_SetBinding (imt_t target, knum_t keynum, const char *binding) keybindings[target][keynum].str = strdup(binding); } } + +VISIBLE void +Key_SetKeyDest(keydest_t kd) +{ + key_dest = kd; + switch (key_dest) { + default: + Sys_Error ("Bad key_dest"); + case key_game: + game_target = key_game_target; + break; + case key_console: + case key_message: + case key_menu: + game_target = IMT_CONSOLE; + break; + } +} diff --git a/nq/source/cl_demo.c b/nq/source/cl_demo.c index 07e3ed2b9..cbcef2c38 100644 --- a/nq/source/cl_demo.c +++ b/nq/source/cl_demo.c @@ -127,6 +127,8 @@ CL_StopPlayback (void) cls.demofile = NULL; CL_SetState (ca_disconnected); cls.demoplayback = 0; + key_game_target = IMT_0; + Key_SetKeyDest (key_game); if (cls.timedemo) CL_FinishTimeDemo (); @@ -357,8 +359,8 @@ CL_StartDemo (void) cls.demoplayback = true; CL_SetState (ca_connected); cls.forcetrack = 0; - key_dest = key_demo; - game_target = IMT_DEMO; + key_game_target = IMT_DEMO; + Key_SetKeyDest (key_game); while ((c = Qgetc (cls.demofile)) != '\n') if (c == '-') diff --git a/nq/source/cl_main.c b/nq/source/cl_main.c index 1f7215709..d83421658 100644 --- a/nq/source/cl_main.c +++ b/nq/source/cl_main.c @@ -259,8 +259,7 @@ CL_EstablishConnection (const char *host) CL_SetState (ca_connected); cls.signon = 0; // need all the signon messages // before playing - key_dest = key_game; - game_target = IMT_0; + Key_SetKeyDest (key_game); } /* @@ -429,20 +428,13 @@ CL_SetState (cactive_t state) if (state == ca_active) { // entering active state r_active = true; - if (cls.demoplayback) { - game_target = IMT_DEMO; - key_dest = key_demo; - } else { - game_target = IMT_0; - key_dest = key_game; - } + Key_SetKeyDest (key_game); IN_ClearStates (); VID_SetCaption (""); } else if (old_state == ca_active) { // leaving active state r_active = false; - game_target = IMT_CONSOLE; - key_dest = key_console; + Key_SetKeyDest (key_console); VID_SetCaption ("Disconnected"); } if (state == ca_connected) diff --git a/nq/source/sbar.c b/nq/source/sbar.c index f752d6e04..7c94ea651 100644 --- a/nq/source/sbar.c +++ b/nq/source/sbar.c @@ -1253,7 +1253,7 @@ Sbar_FinaleOverlay (void) int remaining; //FIXME cleaner test - if (key_dest != key_game && key_dest != key_demo) + if (key_dest != key_game) return; scr_copyeverything = 1; @@ -1274,7 +1274,7 @@ Sbar_DrawCenterPrint (void) return; //FIXME cleaner test - if (key_dest != key_game && key_dest != key_demo) + if (key_dest != key_game) return; Sbar_DrawCenterString (overlay_view, -1); diff --git a/qw/source/cl_demo.c b/qw/source/cl_demo.c index f45b6ac27..4af44cffc 100644 --- a/qw/source/cl_demo.c +++ b/qw/source/cl_demo.c @@ -49,6 +49,7 @@ static __attribute__ ((used)) const char rcsid[] = "$Id$"; #include "QF/cmd.h" #include "QF/cvar.h" #include "QF/dstring.h" +#include "QF/keys.h" #include "QF/msg.h" #include "QF/qendian.h" #include "QF/sys.h" @@ -147,6 +148,8 @@ CL_StopPlayback (void) cls.demoplayback2 = 0; demotime_cached = 0; net_blocksend = 0; + key_game_target = IMT_0; + Key_SetKeyDest (key_game); if (cls.timedemo) CL_FinishTimeDemo (); @@ -898,6 +901,8 @@ CL_StartDemo (void) } cls.demoplayback = true; + key_game_target = IMT_DEMO; + Key_SetKeyDest (key_game); net_blocksend = 1; if (strequal (QFS_FileExtension (name->str), ".mvd")) { cls.demoplayback2 = true; diff --git a/qw/source/cl_main.c b/qw/source/cl_main.c index 2d7e5409c..c075eeeb0 100644 --- a/qw/source/cl_main.c +++ b/qw/source/cl_main.c @@ -1149,8 +1149,7 @@ CL_SetState (cactive_t state) // leaving active state IN_ClearStates (); r_active = false; - game_target = IMT_CONSOLE; - key_dest = key_console; + Key_SetKeyDest (key_console); // Auto demo recorder stops here if (cl_autorecord->int_val && cls.demorecording) @@ -1160,13 +1159,7 @@ CL_SetState (cactive_t state) VID_SetCaption (cls.servername->str); IN_ClearStates (); r_active = true; - if (cls.demoplayback) { - game_target = IMT_DEMO; - key_dest = key_demo; - } else { - game_target = IMT_0; - key_dest = key_game; - } + Key_SetKeyDest (key_game); // Auto demo recorder starts here if (cl_autorecord->int_val && !cls.demoplayback diff --git a/qw/source/sbar.c b/qw/source/sbar.c index 0cdcb5e5d..ce94bf9c6 100644 --- a/qw/source/sbar.c +++ b/qw/source/sbar.c @@ -1713,7 +1713,7 @@ Sbar_FinaleOverlay (void) int remaining; //FIXME cleaner test - if (key_dest != key_game && key_dest != key_demo) + if (key_dest != key_game) return; scr_copyeverything = 1; @@ -1734,7 +1734,7 @@ Sbar_DrawCenterPrint (void) return; //FIXME cleaner test - if (key_dest != key_game && key_dest != key_demo) + if (key_dest != key_game) return; Sbar_DrawCenterString (overlay_view, -1);