diff options
-rwxr-xr-x | compile | 1 | ||||
-rw-r--r-- | compile.bat | 1 | ||||
-rw-r--r-- | src/trace.c | 101 | ||||
-rw-r--r-- | src/trace.h | 60 |
4 files changed, 163 insertions, 0 deletions
@@ -81,6 +81,7 @@ src="\ os.c portalcolours.c sst.c + trace.c xhair.c x86.c" if [ "$dbg" = 1 ]; then src="$src \ diff --git a/compile.bat b/compile.bat index ca632ed..a4a6a10 100644 --- a/compile.bat +++ b/compile.bat @@ -95,6 +95,7 @@ setlocal DisableDelayedExpansion :+ portalcolours.c
:+ rinput.c
:+ sst.c
+:+ trace.c
:+ xhair.c
:+ x86.c
:: just tack these on, whatever (repeated condition because of expansion memes)
diff --git a/src/trace.c b/src/trace.c new file mode 100644 index 0000000..0a301a7 --- /dev/null +++ b/src/trace.c @@ -0,0 +1,101 @@ +/* + * Copyright © 2023 Willian Henrique <wsimanbrazil@yahoo.com.br> + * Copyright © 2024 Michael Smith <mikesmiffy128@gmail.com> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include "engineapi.h" +#include "errmsg.h" +#include "feature.h" +#include "gametype.h" +#include "intdefs.h" +#include "trace.h" + +FEATURE() + +struct ray { + // these have type VectorAligned in the engine, which occupies 16 bytes + struct vec3f _Alignas(16) start, delta, startoff, extents; + // align to 16 since "extents" is supposed to occupy 16 bytes. + // TODO(compat): this member isn't in every engine branch + const float _Alignas(16) (*worldaxistransform)[3][4]; + bool isray, isswept; +}; + +static void *srvtrace; + +DECL_VFUNC(void, TraceRay, 5, struct ray *, uint /*mask*/, void */*filter*/, + struct CGameTrace *) + +static inline bool nonzero(struct vec3f v) { + union { struct vec3f v; struct { unsigned int x, y, z; }; } u = {v}; + return (u.x | u.y | u.z) << 1 != 0; // ignore sign bit +} + +struct CGameTrace trace_line(struct vec3f start, struct vec3f end, uint mask, + void *filt) { + struct CGameTrace t; + struct vec3f delta = {end.x - start.x, end.y - start.y, end.z - start.z}; + struct ray r = { + .isray = true, + .isswept = nonzero(delta), + .start = start, + .delta = delta + }; + TraceRay(srvtrace, &r, mask, filt, &t); + return t; +} + +struct CGameTrace trace_hull(struct vec3f start, struct vec3f end, + struct vec3f mins, struct vec3f maxs, uint mask, void *filt) { + struct CGameTrace t; + struct vec3f delta = {end.x - start.x, end.y - start.y, end.z - start.z}; + struct vec3f extents = { + (maxs.x - mins.x) * 0.5f, + (maxs.y - mins.y) * 0.5f, + (maxs.z - mins.z) * 0.5f + }; + struct ray r = { + // NOTE: could maybe hardcode this to false, but we copy engine logic + // just on the off chance we're tracing some insanely thin hull + .isray = (extents.x * extents.x + r.extents.y * r.extents.y + + extents.z * extents.z) < 1e-6, + .isswept = nonzero(delta), + .start = start, + .delta = delta, + .extents = extents, + .startoff = { + (mins.x + maxs.x) * -0.5f, + (mins.y + maxs.y) * -0.5f, + (mins.z + maxs.z) * -0.5f + } + }; + TraceRay(srvtrace, &r, mask, filt, &t); + return t; +} + +PREINIT { + // TODO(compat): restricting this to tested branches for now + return GAMETYPE_MATCHES(L4D); +} + +INIT { + if (!(srvtrace = factory_engine("EngineTraceServer003", 0))) { + errmsg_errorx("couldn't get server-side tracing interface"); + return false; + } + return true; +} + +// vi: sw=4 ts=4 noet tw=80 cc=80 diff --git a/src/trace.h b/src/trace.h new file mode 100644 index 0000000..82d2dac --- /dev/null +++ b/src/trace.h @@ -0,0 +1,60 @@ +/* + * Copyright © 2023 Willian Henrique <wsimanbrazil@yahoo.com.br> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef INC_TRACE_H +#define INC_TRACE_H + +#include "intdefs.h" +#include "engineapi.h" + +struct CBaseTrace { + struct vec3f startpos, endpos; + struct { + struct vec3f normal; + float dist; + u8 type, signbits; + //u8 pad[2]; + } plane; // surface normal at impact + float frac; + int contents; + ushort dispflags; + bool allsolid, startsolid; +}; + +struct CGameTrace { + struct CBaseTrace base; + float fracleftsolid; + struct { + const char *name; + short surfprops; + ushort flags; + } surf; + int hitgroup; + short physbone; + ushort worldsurfidx; // not in every branch, but doesn't break ABI + void *ent; // CBaseEntity (C_BaseEntity in client.dll) + int hitbox; +}; + +struct CGameTrace trace_line(struct vec3f start, struct vec3f end, uint mask, + void *filt); + +struct CGameTrace trace_hull(struct vec3f start, struct vec3f end, + struct vec3f mins, struct vec3f maxs, uint mask, void *filt); + +#endif + +// vi: sw=4 ts=4 noet tw=80 cc=80 |