mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-24 12:42:32 +00:00
Merge branch 'master' into wip-trails
This commit is contained in:
commit
6423c13108
371 changed files with 25968 additions and 7437 deletions
82
config.d/attributes.m4
Normal file
82
config.d/attributes.m4
Normal file
|
@ -0,0 +1,82 @@
|
|||
dnl ==================================================================
|
||||
dnl Checks for compiler attributes
|
||||
dnl ==================================================================
|
||||
|
||||
AC_MSG_CHECKING(for __attribute__)
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[[static __attribute__ ((unused)) const char *foo = "bar";]]
|
||||
[[int bar(void);]],
|
||||
[[return bar();]])],
|
||||
[AC_DEFINE(HAVE___ATTRIBUTE__)
|
||||
AC_MSG_RESULT(yes)],
|
||||
[AC_MSG_RESULT(no)]
|
||||
)
|
||||
AH_VERBATIM([HAVE___ATTRIBUTE__],
|
||||
[/* Define this if the GCC __attribute__ keyword is available */
|
||||
#undef HAVE___ATTRIBUTE__
|
||||
#ifndef HAVE___ATTRIBUTE__
|
||||
# define __attribute__(x)
|
||||
#endif])
|
||||
|
||||
AC_MSG_CHECKING(for __attribute__ ((visibility)))
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[[void foo (void);]]
|
||||
[[__attribute__ ((visibility ("default"))) void foo (void) {}]]
|
||||
[[int bar(void);]],
|
||||
[[return bar();]]
|
||||
)],
|
||||
[AC_DEFINE(HAVE___ATTRIBUTE__VISIBILITY)
|
||||
AC_MSG_RESULT(yes)],
|
||||
[AC_MSG_RESULT(no)]
|
||||
)
|
||||
AH_VERBATIM([HAVE___ATTRIBUTE__VISIBILITY],
|
||||
[/* Define this if the GCC visibility __attribute__ is available */
|
||||
#undef HAVE___ATTRIBUTE__VISIBILITY
|
||||
#ifdef HAVE___ATTRIBUTE__VISIBILITY
|
||||
# define VISIBLE __attribute__((visibility ("default")))
|
||||
#else
|
||||
# define VISIBLE
|
||||
#endif])
|
||||
|
||||
AC_MSG_CHECKING(for __attribute__ ((designated_init)))
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[[struct x { char y; } __attribute__ ((designated_init));]]
|
||||
[[int bar(void);]],
|
||||
[[return bar();]]
|
||||
)],
|
||||
[AC_DEFINE(HAVE___ATTRIBUTE__DESIGNATED_INIT)
|
||||
AC_MSG_RESULT(yes)],
|
||||
[AC_MSG_RESULT(no)]
|
||||
)
|
||||
AH_VERBATIM([HAVE___ATTRIBUTE__DESIGNATED_INIT],
|
||||
[/* Define this if the GCC designated_init __attribute__ is available */
|
||||
#undef HAVE___ATTRIBUTE__DESIGNATED_INIT
|
||||
#ifdef HAVE___ATTRIBUTE__DESIGNATED_INIT
|
||||
# define DESIGNATED_INIT __attribute__((designated_init))
|
||||
#else
|
||||
# define DESIGNATED_INIT
|
||||
#endif])
|
||||
|
||||
if test "x$SYSTYPE" = "xWIN32"; then
|
||||
AC_MSG_CHECKING(for __attribute__ ((gcc_struct)))
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[[typedef struct { int foo; }]]
|
||||
[[__attribute__ ((gcc_struct)) gcc_struct_test;]],
|
||||
[[return gcc_struct_test.foo]])],
|
||||
[AC_DEFINE(HAVE___ATTRIBUTE__GCC_STRUCT)
|
||||
AC_MSG_RESULT(yes)],
|
||||
[AC_MSG_RESULT(no)
|
||||
])
|
||||
fi
|
||||
AH_VERBATIM([HAVE___ATTRIBUTE__GCC_STRUCT],
|
||||
[/* Define this if the GCC gcc_struct __attribute__ is available */
|
||||
#undef HAVE___ATTRIBUTE__GCC_STRUCT
|
||||
#ifdef HAVE___ATTRIBUTE__GCC_STRUCT
|
||||
# define GCC_STRUCT __attribute__((gcc_struct))
|
||||
#else
|
||||
# define GCC_STRUCT
|
||||
#endif])
|
|
@ -329,7 +329,7 @@ if test x"${top_need_libs}" = xyes; then
|
|||
qfac_include_qf_input="\$(include_qf_input)"
|
||||
qfac_include_qf_math="\$(include_qf_math)"
|
||||
qfac_include_qf_plugin="\$(include_qf_plugin)"
|
||||
qfac_include_qf_progs="\$(include_qf_progs)"
|
||||
qfac_include_qf_progs="\$(include_qf_progs) \$(include_qf_progs_gen)"
|
||||
qfac_include_qf_scene="\$(include_qf_scene)"
|
||||
qfac_include_qf_simd="\$(include_qf_simd)"
|
||||
qfac_include_qf_ui="\$(include_qf_ui)"
|
||||
|
|
|
@ -6,6 +6,18 @@ else
|
|||
cvs_def_disabled="!= xno"
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING(for clang)
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[[]],
|
||||
[[#ifndef __clang__],
|
||||
[ choke me],
|
||||
[#endif]])],
|
||||
[CLANG=yes],
|
||||
[CLANG=no]
|
||||
)
|
||||
AC_MSG_RESULT($CLANG)
|
||||
|
||||
AC_MSG_CHECKING(for CFLAGS pre-set)
|
||||
leave_cflags_alone=no
|
||||
if test "x$CFLAGS" != "x"; then
|
||||
|
@ -29,10 +41,14 @@ AC_LINK_IFELSE(
|
|||
)
|
||||
AH_VERBATIM([HAVE_C99INLINE],
|
||||
[#undef HAVE_C99INLINE
|
||||
#ifdef HAVE_C99INLINE
|
||||
# define GNU89INLINE
|
||||
#ifdef __clang__
|
||||
# define GNU89INLINE static
|
||||
#else
|
||||
# define GNU89INLINE extern
|
||||
# ifdef HAVE_C99INLINE
|
||||
# define GNU89INLINE
|
||||
# else
|
||||
# define GNU89INLINE extern
|
||||
# endif
|
||||
#endif])
|
||||
|
||||
if test "x$GCC" = xyes; then
|
||||
|
@ -82,7 +98,7 @@ dnl We want warnings, lots of warnings...
|
|||
dnl The help text should be INVERTED before release!
|
||||
dnl when in git, this test defaults to ENABLED.
|
||||
dnl In a release, this test defaults to DISABLED.
|
||||
if test "x$GCC" = "xyes"; then
|
||||
if test "x$GCC" = "xyes" -a "x$leave_cflags_alone" != xyes; then
|
||||
if test "x$enable_Werror" $cvs_def_enabled; then
|
||||
CFLAGS="$CFLAGS -Wall -Werror -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations"
|
||||
else
|
||||
|
@ -91,6 +107,10 @@ if test "x$GCC" = "xyes"; then
|
|||
CFLAGS="$CFLAGS -fno-common"
|
||||
fi
|
||||
|
||||
if test "x$CLANG" = xyes -a "x$leave_cflags_alone" != xyes; then
|
||||
CFLAGS="$CFLAGS -Wno-misleading-indentation"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(optimize,
|
||||
AS_HELP_STRING([--disable-optimize],
|
||||
[compile without optimizations (for development)]),
|
||||
|
@ -146,8 +166,8 @@ if test "x$optimize" = xyes -a "x$leave_cflags_alone" != "xyes"; then
|
|||
dnl if test "$CC_MAJ" -ge 4; then
|
||||
dnl QF_CC_OPTION(-finline-limit=32000 -Winline)
|
||||
dnl fi
|
||||
dnl heavy="-O2 $CFLAGS -ffast-math -fno-unsafe-math-optimizations -funroll-loops -fomit-frame-pointer"
|
||||
heavy="-O2 $CFLAGS -fno-fast-math -funroll-loops -fomit-frame-pointer "
|
||||
dnl heavy="-O2 -ffast-math -fno-unsafe-math-optimizations -funroll-loops -fomit-frame-pointer"
|
||||
heavy="-O2 -fno-fast-math -funroll-loops -fomit-frame-pointer "
|
||||
CFLAGS="$saved_cflags"
|
||||
light="-O2"
|
||||
AC_ARG_ENABLE(strict-aliasing,
|
||||
|
@ -229,7 +249,7 @@ AC_ARG_ENABLE(profile,
|
|||
[compile with profiling (for development)]),
|
||||
profile=$enable_profile
|
||||
)
|
||||
if test "x$profile" = xyes; then
|
||||
if test "x$profile" = xyes -a "x$leave_cflags_alone" != xyes; then
|
||||
BUILD_TYPE="$BUILD_TYPE Profile"
|
||||
if test "x$GCC" = xyes; then
|
||||
CFLAGS="`echo $CFLAGS | sed -e 's/-fomit-frame-pointer//g'` -pg"
|
||||
|
@ -240,7 +260,7 @@ if test "x$profile" = xyes; then
|
|||
fi
|
||||
|
||||
check_pipe=no
|
||||
if test "x$GCC" = xyes; then
|
||||
if test "x$GCC" = xyes -a "x$leave_cflags_alone" != xyes; then
|
||||
dnl Check for -pipe vs -save-temps.
|
||||
AC_MSG_CHECKING(for -pipe vs -save-temps)
|
||||
AC_ARG_ENABLE(save-temps,
|
||||
|
@ -279,7 +299,7 @@ dnl with many compilers that do not support the latest ISO standards. Well,
|
|||
dnl that is our cover story -- the reality is that we like them and do not want
|
||||
dnl to give them up. :)
|
||||
dnl Make the compiler swallow its pride...
|
||||
if test "x$GCC" != xyes; then
|
||||
if test "x$GCC" != xyes -a "x$CLANG" != xyes -a "x$leave_cflags_alone" != xyes; then
|
||||
AC_MSG_CHECKING(for how to deal with BCPL-style comments)
|
||||
case "${host}" in
|
||||
*-aix*)
|
||||
|
@ -300,6 +320,25 @@ if test "x$GCC" != xyes; then
|
|||
esac
|
||||
fi
|
||||
|
||||
if test "x$leave_cflags_alone" != xyes; then
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[[bool flag = true;]],
|
||||
[[return flag ? 1 : 0]])],
|
||||
[],
|
||||
[QF_CC_OPTION_TEST(-std=gnu23,[],QF_CC_OPTION(-std=gnu2x))]
|
||||
)
|
||||
fi
|
||||
AC_MSG_CHECKING([for c23])
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[[bool flag = true;]
|
||||
[int bar (void);]],
|
||||
[[return bar();]])],
|
||||
[AC_MSG_RESULT(yes)],
|
||||
[AC_MSG_ERROR(QuakeForge requires C23 to compile)]
|
||||
)
|
||||
|
||||
AS="$CC"
|
||||
if test "x$SYSTYPE" = "xWIN32"; then
|
||||
ASFLAGS="\$(DEFS) \$(CFLAGS) \$(CPPFLAGS) \$(DEFAULT_INCLUDES) \$(INCLUDES) -D_WIN32"
|
||||
|
|
|
@ -30,3 +30,19 @@ AC_SUBST(HARFBUZZ_LIBS)
|
|||
if test "x$HAVE_HARFBUZZ" == "xyes"; then
|
||||
AC_DEFINE(HAVE_HARFBUZZ, 1, [Define if you have the HarfBuzz library])
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(fontconfig,
|
||||
AS_HELP_STRING([--disable-fontconfig], [disable fontconfig support]))
|
||||
if test "x$enable_fontconfig" != "xno"; then
|
||||
if test "x$PKG_CONFIG" != "x"; then
|
||||
PKG_CHECK_MODULES([FONTCONFIG], [fontconfig], HAVE_FONTCONFIG=yes, HAVE_FONTCONFIG=no)
|
||||
fi
|
||||
else
|
||||
HAVE_FONTCONFIG=no
|
||||
FONTCONFIG_LIBS=
|
||||
fi
|
||||
AC_SUBST(FONTCONFIG_LIBS)
|
||||
|
||||
if test "x$HAVE_FONTCONFIG" == "xyes"; then
|
||||
AC_DEFINE(HAVE_FONTCONFIG, 1, [Define if you have the fontconfig library])
|
||||
fi
|
||||
|
|
|
@ -48,20 +48,20 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <dlfcn.h>]], [[int foo = RTLD_DEEP
|
|||
])
|
||||
fi
|
||||
|
||||
dnl Checks for stricmp/strcasecmp
|
||||
#dnl Checks for stricmp/strcasecmp
|
||||
#AC_CHECK_FUNC(strcasecmp,
|
||||
# ,
|
||||
# AC_CHECK_FUNC(stricmp,
|
||||
# AC_DEFINE(strcasecmp, stricmp)
|
||||
# )
|
||||
#)
|
||||
AC_CHECK_FUNC(strcasecmp, strcasecmp=yes, strcasecmp=no)
|
||||
if test "x$strcasecmp" = xno; then
|
||||
AC_CHECK_FUNC(stricmp,
|
||||
AC_DEFINE(strcasecmp, stricmp, [Define strcasecmp as stricmp if you have one but not the other]),
|
||||
AC_MSG_ERROR([Neither stricmp nor strcasecmp found])
|
||||
)
|
||||
fi
|
||||
#AC_CHECK_FUNC(strcasecmp, strcasecmp=yes, strcasecmp=no)
|
||||
#if test "x$strcasecmp" = xno; then
|
||||
# AC_CHECK_FUNC(stricmp,
|
||||
# AC_DEFINE(strcasecmp, stricmp, [Define strcasecmp as stricmp if you have one but not the other]),
|
||||
# AC_MSG_ERROR([Neither stricmp nor strcasecmp found])
|
||||
# )
|
||||
#fi
|
||||
|
||||
dnl Check for vsnprintf
|
||||
if test "x$ac_cv_func_vsnprintf" = "xno" -a \
|
||||
|
@ -80,14 +80,14 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[fnmatch();]])],[BUILD_FNMATCH=no
|
|||
AM_CONDITIONAL(BUILD_FNMATCH, test "x$BUILD_FNMATCH" = "xyes")
|
||||
|
||||
AC_MSG_CHECKING(for opendir)
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[opendir();]])],[BUILD_DIRENT=no
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[extern void opendir(); opendir();]])],[BUILD_DIRENT=no
|
||||
AC_MSG_RESULT(yes)],[BUILD_DIRENT=yes
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
AM_CONDITIONAL(BUILD_DIRENT, test "x$BUILD_DIRENT" = "xyes")
|
||||
|
||||
AC_MSG_CHECKING(for getopt_long)
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[getopt_long();]])],[BUILD_GETOPT=no
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[extern void getopt_long(); getopt_long();]])],[BUILD_GETOPT=no
|
||||
AC_MSG_RESULT(yes)],[BUILD_GETOPT=yes
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
|
|
|
@ -14,47 +14,6 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <unistd.h>]], [[int foo = _SC_PAGE
|
|||
])
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING(for __attribute__)
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[static __attribute__ ((unused)) const char *foo = "bar";]], [[]])],[AC_DEFINE(HAVE___ATTRIBUTE__)
|
||||
AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no)
|
||||
])
|
||||
AH_VERBATIM([HAVE___ATTRIBUTE__],
|
||||
[/* Define this if the GCC __attribute__ keyword is available */
|
||||
#undef HAVE___ATTRIBUTE__
|
||||
#ifndef HAVE___ATTRIBUTE__
|
||||
# define __attribute__(x)
|
||||
#endif])
|
||||
|
||||
AC_MSG_CHECKING(for __attribute__ ((visibility)))
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[void foo (void);
|
||||
__attribute__ ((sivibility ("default"))) void foo (void) {}]], [[]])],[AC_DEFINE(HAVE___ATTRIBUTE__VISIBILITY)
|
||||
AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no)
|
||||
])
|
||||
AH_VERBATIM([HAVE___ATTRIBUTE__VISIBILITY],
|
||||
[/* Define this if the GCC visibility __attribute__ is available */
|
||||
#undef HAVE___ATTRIBUTE__VISIBILITY
|
||||
#ifdef HAVE___ATTRIBUTE__VISIBILITY
|
||||
# define VISIBLE __attribute__((visibility ("default")))
|
||||
#else
|
||||
# define VISIBLE
|
||||
#endif])
|
||||
|
||||
if test "x$SYSTYPE" = "xWIN32"; then
|
||||
AC_MSG_CHECKING(for __attribute__ ((gcc_struct)))
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[typedef struct { int foo; }
|
||||
__attribute__ ((gcc_struct)) gcc_struct_test;]], [[]])],[AC_DEFINE(HAVE___ATTRIBUTE__GCC_STRUCT)
|
||||
AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no)
|
||||
])
|
||||
fi
|
||||
AH_VERBATIM([HAVE___ATTRIBUTE__GCC_STRUCT],
|
||||
[/* Define this if the GCC gcc_struct __attribute__ is available */
|
||||
#undef HAVE___ATTRIBUTE__GCC_STRUCT
|
||||
#ifdef HAVE___ATTRIBUTE__GCC_STRUCT
|
||||
# define GCC_STRUCT __attribute__((gcc_struct))
|
||||
#else
|
||||
# define GCC_STRUCT
|
||||
#endif])
|
||||
|
||||
AC_MSG_CHECKING(for __builtin_expect)
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[int x;]], [[if (__builtin_expect(!x, 1)) {}]])],[AC_DEFINE(HAVE___BUILTIN_EXPECT)
|
||||
AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no)
|
||||
|
|
30
configure.ac
30
configure.ac
|
@ -54,7 +54,27 @@ case "$host_os" in
|
|||
;;
|
||||
*)
|
||||
dnl Checks for working -lm
|
||||
AC_CHECK_LIB(m, pow,, AC_MSG_ERROR([math library (-lm) appears broken]))
|
||||
AC_MSG_CHECKING(for pow and atan2 in standard library)
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[[#include <math.h>
|
||||
int func_ind;
|
||||
double (*func[])(double, double) = {pow, atan2};]],
|
||||
[[return (int)(func[func_ind])(2, 3);]])],
|
||||
[AC_MSG_RESULT(yes)],
|
||||
[AC_MSG_RESULT(no)
|
||||
AC_MSG_CHECKING(for pow and atan2 in -lm)
|
||||
LIBS="-lm $LIBS"
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[[#include <math.h>
|
||||
int func_ind;
|
||||
double (*func[])(double, double) = {pow, atan2};]],
|
||||
[[return (int)(func[func_ind])(2, 3);]])],
|
||||
[AC_MSG_RESULT(yes)],
|
||||
[AC_MSG_ERROR([math library (-lm) appears broken])]
|
||||
)]
|
||||
)
|
||||
;;
|
||||
esac
|
||||
|
||||
|
@ -70,6 +90,11 @@ m4_include(config.d/sdl.m4)
|
|||
m4_include(config.d/curses.m4)
|
||||
m4_include(config.d/freetype.m4)
|
||||
|
||||
m4_include(config.d/networking.m4)
|
||||
|
||||
m4_include(config.d/compiling.m4)
|
||||
m4_include(config.d/attributes.m4)
|
||||
|
||||
dnl ==================================================================
|
||||
dnl Checks for system type
|
||||
dnl ==================================================================
|
||||
|
@ -115,13 +140,10 @@ m4_include(config.d/joystick.m4)
|
|||
m4_include(config.d/evdev.m4)
|
||||
m4_include(config.d/cdrom.m4)
|
||||
|
||||
m4_include(config.d/networking.m4)
|
||||
|
||||
m4_include(config.d/paths.m4)
|
||||
|
||||
m4_include(config.d/build_control.m4)
|
||||
m4_include(config.d/qfcc.m4)
|
||||
m4_include(config.d/compiling.m4)
|
||||
|
||||
AC_ARG_ENABLE(static-doc,
|
||||
AS_HELP_STRING([--enable-static-doc],
|
||||
|
|
|
@ -12,6 +12,7 @@ EXTRA_DIST += \
|
|||
include/block8.h \
|
||||
include/bsearch.h \
|
||||
include/buildnum.h \
|
||||
include/cl_console.h \
|
||||
include/compat.h \
|
||||
include/context_sdl.h \
|
||||
include/context_win.h \
|
||||
|
@ -62,12 +63,10 @@ EXTRA_DIST += \
|
|||
include/quicksort.h \
|
||||
include/r_cvar.h \
|
||||
include/r_dynamic.h \
|
||||
include/r_font.h \
|
||||
include/r_internal.h \
|
||||
include/r_local.h \
|
||||
include/r_scrap.h \
|
||||
include/r_shared.h \
|
||||
include/r_text.h \
|
||||
include/regex.h \
|
||||
include/rua_internal.h \
|
||||
include/skin_stencil.h \
|
||||
|
|
|
@ -60,7 +60,7 @@ typedef struct elechain_s {
|
|||
struct elechain_s *next;
|
||||
int model_index;
|
||||
elements_t *elements;
|
||||
vec4f_t *transform;
|
||||
const vec4f_t *transform;
|
||||
float *color;
|
||||
} elechain_t;
|
||||
|
||||
|
|
|
@ -151,6 +151,9 @@ include_qf_progs = \
|
|||
include/QF/progs/pr_type.h \
|
||||
include/QF/progs/pr_type_names.h
|
||||
|
||||
include_qf_progs_gen = \
|
||||
include/QF/progs/pr_opcode.hinc
|
||||
|
||||
include_qf_scene = \
|
||||
include/QF/scene/camera.h \
|
||||
include/QF/scene/entity.h \
|
||||
|
@ -172,8 +175,10 @@ include_qf_simd = \
|
|||
include_qf_ui = \
|
||||
include/QF/ui/canvas.h \
|
||||
include/QF/ui/font.h \
|
||||
include/QF/ui/imui.h \
|
||||
include/QF/ui/inputline.h \
|
||||
include/QF/ui/passage.h \
|
||||
include/QF/ui/shaper.h \
|
||||
include/QF/ui/text.h \
|
||||
include/QF/ui/txtbuffer.h \
|
||||
include/QF/ui/view.h \
|
||||
|
@ -188,12 +193,14 @@ include_qf_vulkan = \
|
|||
include/QF/Vulkan/debug.h \
|
||||
include/QF/Vulkan/descriptor.h \
|
||||
include/QF/Vulkan/device.h \
|
||||
include/QF/Vulkan/dsmanager.h \
|
||||
include/QF/Vulkan/funclist.h \
|
||||
include/QF/Vulkan/image.h \
|
||||
include/QF/Vulkan/instance.h \
|
||||
include/QF/Vulkan/memory.h \
|
||||
include/QF/Vulkan/pipeline.h \
|
||||
include/QF/Vulkan/projection.h \
|
||||
include/QF/Vulkan/render.h \
|
||||
include/QF/Vulkan/resource.h \
|
||||
include/QF/Vulkan/qf_alias.h \
|
||||
include/QF/Vulkan/qf_bsp.h \
|
||||
|
@ -202,12 +209,12 @@ include_qf_vulkan = \
|
|||
include/QF/Vulkan/qf_iqm.h \
|
||||
include/QF/Vulkan/qf_lighting.h \
|
||||
include/QF/Vulkan/qf_lightmap.h \
|
||||
include/QF/Vulkan/qf_main.h \
|
||||
include/QF/Vulkan/qf_matrices.h \
|
||||
include/QF/Vulkan/qf_model.h \
|
||||
include/QF/Vulkan/qf_output.h \
|
||||
include/QF/Vulkan/qf_palette.h \
|
||||
include/QF/Vulkan/qf_particles.h \
|
||||
include/QF/Vulkan/qf_planes.h \
|
||||
include/QF/Vulkan/qf_scene.h \
|
||||
include/QF/Vulkan/qf_sprite.h \
|
||||
include/QF/Vulkan/qf_texture.h \
|
||||
|
|
|
@ -22,6 +22,7 @@ typedef struct qfv_bufferbarrier_s {
|
|||
enum {
|
||||
qfv_LT_Undefined_to_TransferDst,
|
||||
qfv_LT_Undefined_to_General,
|
||||
qfv_LT_Undefined_to_ShaderReadOnly,
|
||||
qfv_LT_TransferDst_to_TransferSrc,
|
||||
qfv_LT_TransferDst_to_General,
|
||||
qfv_LT_TransferDst_to_ShaderReadOnly,
|
||||
|
|
|
@ -14,7 +14,7 @@ struct tex_s;
|
|||
typedef void (*capfunc_t) (struct tex_s *screencap, void *data);
|
||||
|
||||
typedef struct qfv_capture_frame_s {
|
||||
VkBuffer buffer;
|
||||
struct qfv_resobj_s *buffer;
|
||||
byte *data;
|
||||
|
||||
bool initiated;
|
||||
|
@ -27,12 +27,10 @@ typedef struct qfv_capture_frame_set_s
|
|||
|
||||
typedef struct qfv_capturectx_s {
|
||||
qfv_capture_frame_set_t frames;
|
||||
struct qfv_device_s *device;
|
||||
VkExtent2D extent;
|
||||
size_t imgsize;
|
||||
size_t memsize;
|
||||
byte *data;
|
||||
VkDeviceMemory memory;
|
||||
struct qfv_resource_s *resources;
|
||||
} qfv_capturectx_t;
|
||||
|
||||
struct vulkan_ctx_s;
|
||||
|
|
46
include/QF/Vulkan/mouse_pick.h
Normal file
46
include/QF/Vulkan/mouse_pick.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
#ifndef __QF_Vulkan_mouse_pick_h
|
||||
#define __QF_Vulkan_mouse_pick_h
|
||||
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
#define VK_NO_PROTOTYPES
|
||||
#endif
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
#include "QF/darray.h"
|
||||
#include "QF/qtypes.h"
|
||||
|
||||
#define mousepick_size 5
|
||||
|
||||
struct vulkan_ctx_s;
|
||||
typedef void (*mousepickfunc_t) (const uint32_t *entid, void *data);
|
||||
|
||||
typedef struct qfv_mousepick_frame_s {
|
||||
VkBuffer entid_buffer;
|
||||
uint32_t *entid_data;
|
||||
|
||||
bool initiated;
|
||||
mousepickfunc_t callback;
|
||||
void *callback_data;
|
||||
uint32_t x, y;
|
||||
VkOffset3D offset;
|
||||
VkExtent3D extent;
|
||||
VkImage entid_image;
|
||||
} qfv_mousepick_frame_t;
|
||||
|
||||
typedef struct qfv_mousepick_frame_set_s
|
||||
DARRAY_TYPE (qfv_mousepick_frame_t) qfv_mousepick_frame_set_t;
|
||||
|
||||
typedef struct qfv_mousepickctx_s {
|
||||
qfv_mousepick_frame_set_t frames;
|
||||
struct qfv_resobj_s *entid_res;
|
||||
struct qfv_resource_s *resources;
|
||||
} qfv_mousepickctx_t;
|
||||
|
||||
struct vulkan_ctx_s;
|
||||
|
||||
void QFV_MousePick_Init (struct vulkan_ctx_s *ctx);
|
||||
void QFV_MousePick_Shutdown (struct vulkan_ctx_s *ctx);
|
||||
void QFV_MousePick_Read (struct vulkan_ctx_s *ctx, uint32_t x, uint32_t y,
|
||||
mousepickfunc_t callback, void *data);
|
||||
|
||||
#endif//__QF_Vulkan_mouse_pick_h
|
|
@ -5,8 +5,19 @@
|
|||
|
||||
void QFV_Orthographic (mat4f_t proj, float xmin, float xmax,
|
||||
float ymin, float ymax, float znear, float zfar);
|
||||
void QFV_OrthographicV (mat4f_t proj, vec4f_t mins, vec4f_t maxs);
|
||||
// fov_x and fov_y are tan(fov/2) for x and y respectively
|
||||
void QFV_PerspectiveTan (mat4f_t proj, float fov_x, float fov_y);
|
||||
void QFV_PerspectiveCos (mat4f_t proj, float fov);
|
||||
void QFV_PerspectiveTan (mat4f_t proj, float fov_x, float fov_y,
|
||||
float nearclip);
|
||||
void QFV_InversePerspectiveTan (mat4f_t proj, float fov_x, float fov_y,
|
||||
float nearclip);
|
||||
void QFV_PerspectiveTanFar (mat4f_t proj, float fov_x, float fov_y,
|
||||
float nearclip, float farclip);
|
||||
void QFV_InversePerspectiveTanFar (mat4f_t proj, float fov_x, float fov_y,
|
||||
float nearclip, float farclip);
|
||||
void QFV_PerspectiveCos (mat4f_t proj, float fov, float nearclip);
|
||||
|
||||
extern const mat4f_t qfv_z_up;
|
||||
extern const mat4f_t qfv_box_rotations[6];
|
||||
|
||||
#endif//__QF_Vulkan_projection_h
|
||||
|
|
|
@ -38,6 +38,11 @@
|
|||
#include "QF/Vulkan/qf_vid.h"
|
||||
#include "QF/Vulkan/command.h"
|
||||
|
||||
enum {
|
||||
alias_main,
|
||||
alias_shadow,
|
||||
};
|
||||
|
||||
typedef struct aliasvrt_s {
|
||||
float vertex[4];
|
||||
float normal[4];
|
||||
|
|
|
@ -270,6 +270,7 @@ typedef struct bsp_pass_s {
|
|||
vec4f_t position; ///< view position
|
||||
const struct mod_brush_s *brush;///< data for current model
|
||||
struct bspctx_s *bsp_context; ///< owning bsp context
|
||||
struct entqueue_s *entqueue; ///< entities to render this pass
|
||||
/** \name GPU data
|
||||
*
|
||||
* The indices to be drawn and the entity ids associated with each draw
|
||||
|
@ -324,6 +325,14 @@ typedef enum {
|
|||
QFV_bspNumPasses
|
||||
} QFV_BspQueue;
|
||||
|
||||
typedef enum {
|
||||
QFV_bspMain,
|
||||
QFV_bspShadow,
|
||||
QFV_bspDebug,
|
||||
|
||||
QFV_bspNumStages
|
||||
} QFV_BspPass;
|
||||
|
||||
typedef struct bspframe_s {
|
||||
uint32_t *index_data; // pointer into mega-buffer for this frame (c)
|
||||
uint32_t index_offset; // offset of index_data within mega-buffer (c)
|
||||
|
@ -331,7 +340,6 @@ typedef struct bspframe_s {
|
|||
uint32_t *entid_data;
|
||||
uint32_t entid_offset;
|
||||
uint32_t entid_count;
|
||||
qfv_cmdbufferset_t cmdSet;
|
||||
} bspframe_t;
|
||||
|
||||
typedef struct bspframeset_s
|
||||
|
@ -364,10 +372,11 @@ typedef struct bspctx_s {
|
|||
VkDescriptorSet skybox_descriptor;
|
||||
|
||||
bsp_pass_t main_pass; ///< camera view depth, gbuffer, etc
|
||||
bsp_pass_t shadow_pass;
|
||||
bsp_pass_t debug_pass;
|
||||
|
||||
VkSampler sampler;
|
||||
|
||||
VkDeviceMemory texture_memory;
|
||||
size_t vertex_buffer_size;
|
||||
size_t index_buffer_size;
|
||||
VkBuffer vertex_buffer;
|
||||
|
@ -388,6 +397,7 @@ void Vulkan_BuildDisplayLists (model_t **models, int num_models,
|
|||
void Vulkan_Bsp_Init (struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_Bsp_Setup (struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_Bsp_Shutdown (struct vulkan_ctx_s *ctx);
|
||||
bsp_pass_t *Vulkan_Bsp_GetPass (struct vulkan_ctx_s *ctx, QFV_BspPass pass_ind);
|
||||
///@}
|
||||
|
||||
#endif//__QF_Vulkan_qf_bsp_h
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#include "QF/Vulkan/qf_vid.h"
|
||||
#include "QF/Vulkan/command.h"
|
||||
|
||||
#define COMPOSE_IMAGE_INFOS 1
|
||||
#define COMPOSE_IMAGE_INFOS 3
|
||||
|
||||
typedef struct composeframe_s {
|
||||
VkDescriptorImageInfo imageInfo[COMPOSE_IMAGE_INFOS];
|
||||
|
|
|
@ -37,75 +37,115 @@
|
|||
#include "QF/Vulkan/qf_vid.h"
|
||||
#include "QF/Vulkan/command.h"
|
||||
#include "QF/Vulkan/image.h"
|
||||
#include "QF/Vulkan/render.h"
|
||||
#include "QF/simd/types.h"
|
||||
|
||||
typedef struct qfv_lightmatset_s DARRAY_TYPE (mat4f_t) qfv_lightmatset_t;
|
||||
|
||||
#define MaxLights 768
|
||||
#define MaxLights 2048
|
||||
|
||||
#define ST_NONE 0 // no shadows
|
||||
#define ST_PLANE 1 // single plane shadow map (small spotlight)
|
||||
#define ST_CASCADE 2 // cascaded shadow maps
|
||||
#define ST_CUBE 3 // cubemap (omni, large spotlight)
|
||||
enum {
|
||||
ST_NONE, // no shadows
|
||||
ST_PLANE, // single plane shadow map (small spotlight)
|
||||
ST_CASCADE, // cascaded shadow maps
|
||||
ST_CUBE, // cubemap (omni, large spotlight)
|
||||
|
||||
typedef struct qfv_light_buffer_s {
|
||||
light_t lights[MaxLights] __attribute__((aligned(16)));
|
||||
int lightCount;
|
||||
//mat4f_t shadowMat[MaxLights];
|
||||
//vec4f_t shadowCascade[MaxLights];
|
||||
} qfv_light_buffer_t;
|
||||
ST_COUNT
|
||||
};
|
||||
|
||||
enum {
|
||||
lighting_main,
|
||||
lighting_shadow,
|
||||
lighting_debug,
|
||||
};
|
||||
|
||||
typedef struct qfv_light_render_s {
|
||||
// mat_id (13) map_id (5) layer (11) type (2)
|
||||
uint32_t id_data;
|
||||
// light style (6)
|
||||
uint32_t style;
|
||||
} qfv_light_render_t;
|
||||
|
||||
#define LIGHTING_BUFFER_INFOS 1
|
||||
#define LIGHTING_ATTACH_INFOS 5
|
||||
#define LIGHTING_ATTACH_INFOS 4
|
||||
#define LIGHTING_SHADOW_INFOS 32
|
||||
#define LIGHTING_DESCRIPTORS (LIGHTING_BUFFER_INFOS + LIGHTING_ATTACH_INFOS + 1)
|
||||
|
||||
typedef struct qfv_framebufferset_s
|
||||
DARRAY_TYPE (VkFramebuffer) qfv_framebufferset_t;
|
||||
|
||||
typedef struct light_queue_s {
|
||||
uint16_t start;
|
||||
uint16_t count;
|
||||
} light_queue_t;
|
||||
|
||||
typedef struct lightingframe_s {
|
||||
VkDescriptorSet shadowmat_set;
|
||||
VkDescriptorSet lights_set;
|
||||
VkDescriptorSet attach_set;
|
||||
|
||||
VkBuffer shadowmat_buffer;
|
||||
VkBuffer light_buffer;
|
||||
VkDescriptorBufferInfo bufferInfo[LIGHTING_BUFFER_INFOS];
|
||||
VkDescriptorImageInfo attachInfo[LIGHTING_ATTACH_INFOS];
|
||||
VkDescriptorImageInfo shadowInfo[LIGHTING_SHADOW_INFOS];
|
||||
union {
|
||||
VkWriteDescriptorSet descriptors[LIGHTING_DESCRIPTORS];
|
||||
struct {
|
||||
VkWriteDescriptorSet bufferWrite[LIGHTING_BUFFER_INFOS];
|
||||
VkWriteDescriptorSet attachWrite[LIGHTING_ATTACH_INFOS];
|
||||
VkWriteDescriptorSet shadowWrite;
|
||||
};
|
||||
};
|
||||
VkBuffer render_buffer;
|
||||
VkBuffer style_buffer;
|
||||
VkBuffer id_buffer;
|
||||
VkBuffer entid_buffer;
|
||||
light_queue_t light_queue[4];
|
||||
|
||||
qfv_imageviewset_t views;
|
||||
qfv_framebufferset_t framebuffers;
|
||||
} lightingframe_t;
|
||||
|
||||
typedef struct lightingframeset_s
|
||||
DARRAY_TYPE (lightingframe_t) lightingframeset_t;
|
||||
|
||||
typedef struct light_renderer_s {
|
||||
VkRenderPass renderPass; // shared
|
||||
VkFramebuffer framebuffer;
|
||||
VkImage image; // shared
|
||||
VkImageView view;
|
||||
uint32_t size;
|
||||
uint32_t layer;
|
||||
uint32_t numLayers;
|
||||
int mode;
|
||||
} light_renderer_t;
|
||||
typedef struct light_control_s {
|
||||
uint8_t renderpass_index;
|
||||
uint8_t map_index;
|
||||
uint16_t size;
|
||||
uint16_t layer;
|
||||
uint8_t numLayers;
|
||||
uint8_t mode;
|
||||
uint16_t light_id;
|
||||
uint16_t matrix_id;
|
||||
} light_control_t;
|
||||
|
||||
typedef struct light_control_set_s
|
||||
DARRAY_TYPE (light_control_t) light_control_set_t;
|
||||
|
||||
typedef struct light_renderer_set_s
|
||||
DARRAY_TYPE (light_renderer_t) light_renderer_set_t;
|
||||
|
||||
typedef struct lightingctx_s {
|
||||
lightingframeset_t frames;
|
||||
VkPipeline pipeline;
|
||||
VkSampler sampler;
|
||||
VkDeviceMemory light_memory;
|
||||
struct qfv_resource_s *shadow_resources;
|
||||
struct qfv_resource_s *light_resources;
|
||||
|
||||
qfv_lightmatset_t light_mats;
|
||||
qfv_imageset_t light_images;
|
||||
light_renderer_set_t light_renderers;
|
||||
VkImage *map_images;
|
||||
VkImageView *map_views;
|
||||
bool *map_cube;
|
||||
int num_maps;
|
||||
VkImage default_map;
|
||||
VkImageView default_view_cube;
|
||||
VkImageView default_view_2d;
|
||||
|
||||
VkRenderPass renderpass_6;
|
||||
VkRenderPass renderpass_4;
|
||||
VkRenderPass renderpass_1;
|
||||
light_control_set_t light_control;
|
||||
|
||||
qfv_attachmentinfo_t shadow_info;
|
||||
|
||||
VkSampler shadow_sampler;
|
||||
VkDescriptorSet shadow_cube_set;
|
||||
VkDescriptorSet shadow_2d_set;
|
||||
|
||||
VkBuffer splat_verts;
|
||||
VkBuffer splat_inds;
|
||||
|
||||
vec4f_t world_mins;
|
||||
vec4f_t world_maxs;
|
||||
|
||||
uint32_t dynamic_base;
|
||||
uint32_t dynamic_matrix_base;
|
||||
uint32_t dynamic_count;
|
||||
struct lightingdata_s *ldata;
|
||||
struct scene_s *scene;
|
||||
} lightingctx_t;
|
||||
|
@ -116,5 +156,7 @@ void Vulkan_Lighting_Init (struct vulkan_ctx_s *ctx);
|
|||
void Vulkan_Lighting_Setup (struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_Lighting_Shutdown (struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_LoadLights (struct scene_s *scene, struct vulkan_ctx_s *ctx);
|
||||
VkDescriptorSet Vulkan_Lighting_Descriptors (struct vulkan_ctx_s *ctx,
|
||||
int frame) __attribute__((pure));
|
||||
|
||||
#endif//__QF_Vulkan_qf_lighting_h
|
||||
|
|
|
@ -61,6 +61,8 @@ typedef struct matrixctx_s {
|
|||
double sky_time;
|
||||
int dirty;
|
||||
|
||||
float fov_x, fov_y;
|
||||
|
||||
matrixframeset_t frames;
|
||||
|
||||
struct qfv_resource_s *resource;
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "QF/darray.h"
|
||||
#include "QF/Vulkan/qf_vid.h"
|
||||
#include "QF/Vulkan/command.h"
|
||||
#include "QF/Vulkan/render.h"
|
||||
|
||||
typedef struct outputframe_s {
|
||||
VkImageView input;
|
||||
|
@ -47,6 +48,7 @@ typedef struct outputctx_s {
|
|||
VkSampler sampler;
|
||||
VkImageView input;
|
||||
VkFramebuffer *framebuffers; // one per swapchain image
|
||||
qfv_attachmentinfo_t swapchain_info;
|
||||
} outputctx_t;
|
||||
|
||||
struct vulkan_ctx_s;
|
||||
|
|
62
include/QF/Vulkan/qf_planes.h
Normal file
62
include/QF/Vulkan/qf_planes.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
qf_planes.h
|
||||
|
||||
Vulkan debug planes rendering
|
||||
|
||||
Copyright (C) 2023 Bill Currie <bill@taniwha.org>
|
||||
|
||||
Author: Bill Currie <bill@taniwha.org>
|
||||
Date: 2023/7/20
|
||||
|
||||
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
|
||||
|
||||
*/
|
||||
#ifndef __QF_Vulkan_qf_planes_h
|
||||
#define __QF_Vulkan_qf_planes_h
|
||||
|
||||
#include "QF/darray.h"
|
||||
#include "QF/model.h"
|
||||
#include "QF/modelgen.h"
|
||||
#include "QF/Vulkan/qf_vid.h"
|
||||
#include "QF/Vulkan/command.h"
|
||||
|
||||
typedef struct planes_frame_s {
|
||||
VkDescriptorSet descriptor;
|
||||
} planes_frame_t;
|
||||
|
||||
typedef struct planes_frameset_s
|
||||
DARRAY_TYPE (planes_frame_t) planes_frameset_t;
|
||||
|
||||
typedef struct planesctx_s {
|
||||
planes_frameset_t frames;
|
||||
VkSampler sampler;
|
||||
struct qfv_dsmanager_s *dsmanager;
|
||||
struct qfv_resource_s *resources;
|
||||
} planesctx_t;
|
||||
|
||||
struct vulkan_ctx_s;
|
||||
struct entity_s;
|
||||
struct mod_planes_ctx_s;
|
||||
struct planes_s;
|
||||
|
||||
void Vulkan_Planes_Init (struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_Planes_Setup (struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_Planes_Shutdown (struct vulkan_ctx_s *ctx);
|
||||
|
||||
#endif//__QF_Vulkan_qf_planes_h
|
|
@ -64,6 +64,7 @@ typedef struct scenectx_s {
|
|||
struct qfv_resource_s *entities;
|
||||
scnframeset_t frames;
|
||||
int max_entities;
|
||||
struct scene_s *scene;
|
||||
} scenectx_t;
|
||||
|
||||
struct vulkan_ctx_s;
|
||||
|
@ -77,4 +78,6 @@ VkDescriptorSet Vulkan_Scene_Descriptors (struct vulkan_ctx_s *ctx) __attribute_
|
|||
int Vulkan_Scene_AddEntity (struct vulkan_ctx_s *ctx, struct entity_s entity);
|
||||
void Vulkan_Scene_Flush (struct vulkan_ctx_s *ctx);
|
||||
|
||||
void Vulkan_NewScene (struct scene_s *scene, struct vulkan_ctx_s *ctx);
|
||||
|
||||
#endif//__QF_Vulkan_qf_scene_h
|
||||
|
|
|
@ -21,9 +21,12 @@ typedef struct qfv_transtate_s {
|
|||
typedef struct translucentframe_s {
|
||||
VkDescriptorSet flat;
|
||||
VkDescriptorSet cube;
|
||||
VkImage heads;
|
||||
VkImage cube_heads;
|
||||
VkBuffer state;
|
||||
struct qfv_resobj_s *heads;
|
||||
struct qfv_resobj_s *cube_heads;
|
||||
struct qfv_resobj_s *heads_view;
|
||||
struct qfv_resobj_s *cube_heads_view;
|
||||
struct qfv_resobj_s *state;
|
||||
struct qfv_resobj_s *frags;
|
||||
} translucentframe_t;
|
||||
|
||||
typedef struct translucentframeset_s
|
||||
|
@ -32,6 +35,7 @@ typedef struct translucentframeset_s
|
|||
typedef struct translucentctx_s {
|
||||
translucentframeset_t frames;
|
||||
struct qfv_resource_s *resources;
|
||||
VkExtent2D extent;
|
||||
|
||||
int maxFragments;
|
||||
} translucentctx_t;
|
||||
|
@ -43,7 +47,5 @@ void Vulkan_Translucent_Setup (struct vulkan_ctx_s *ctx);
|
|||
void Vulkan_Translucent_Shutdown (struct vulkan_ctx_s *ctx);
|
||||
VkDescriptorSet Vulkan_Translucent_Descriptors (struct vulkan_ctx_s *ctx,
|
||||
int frame)__attribute__((pure));
|
||||
void Vulkan_Translucent_CreateBuffers (struct vulkan_ctx_s *ctx,
|
||||
VkExtent2D extent);
|
||||
|
||||
#endif//__QF_Vulkan_qf_translucent_h
|
||||
|
|
|
@ -64,7 +64,7 @@ enum {
|
|||
QFV_attachEmission,
|
||||
QFV_attachNormal,
|
||||
QFV_attachPosition,
|
||||
QFV_attachOpaque,
|
||||
QFV_attachLight,
|
||||
QFV_attachSwapchain,
|
||||
};
|
||||
|
||||
|
|
|
@ -81,6 +81,7 @@ typedef struct qfv_imageinfo_s {
|
|||
VkImageTiling tiling;
|
||||
VkImageUsageFlags usage;
|
||||
VkImageLayout initialLayout;
|
||||
struct qfv_resobj_s *object;
|
||||
} qfv_imageinfo_t;
|
||||
|
||||
typedef struct qfv_imageviewinfo_s {
|
||||
|
@ -91,6 +92,7 @@ typedef struct qfv_imageviewinfo_s {
|
|||
VkFormat format;
|
||||
VkComponentMapping components;
|
||||
VkImageSubresourceRange subresourceRange;
|
||||
struct qfv_resobj_s *object;
|
||||
} qfv_imageviewinfo_t;
|
||||
|
||||
typedef struct qfv_bufferinfo_s {
|
||||
|
@ -303,6 +305,12 @@ typedef struct qfv_samplerinfo_s {
|
|||
} qfv_samplerinfo_t;
|
||||
|
||||
#ifndef __QFCC__
|
||||
typedef struct qfv_time_s {
|
||||
int64_t cur_time;
|
||||
int64_t min_time;
|
||||
int64_t max_time;
|
||||
} qfv_time_t;
|
||||
|
||||
typedef struct qfv_label_s {
|
||||
vec4f_t color;
|
||||
const char *name;
|
||||
|
@ -355,6 +363,8 @@ typedef struct qfv_renderpass_s {
|
|||
qfv_framebufferinfo_t *framebufferinfo;
|
||||
VkImageView output;
|
||||
qfv_reference_t outputref;
|
||||
|
||||
struct qfv_resource_s *resources;
|
||||
} qfv_renderpass_t;
|
||||
|
||||
typedef struct qfv_render_s {
|
||||
|
@ -382,13 +392,11 @@ typedef struct qfv_step_s {
|
|||
qfv_render_t *render;
|
||||
qfv_compute_t *compute;
|
||||
qfv_process_t *process;
|
||||
qfv_time_t time;
|
||||
} qfv_step_t;
|
||||
|
||||
typedef struct qfv_job_s {
|
||||
qfv_label_t label;
|
||||
struct qfv_resource_s *resources;
|
||||
struct qfv_resobj_s *images;
|
||||
struct qfv_resobj_s *image_views;
|
||||
|
||||
uint32_t num_renderpasses;
|
||||
uint32_t num_pipelines;
|
||||
|
@ -401,6 +409,7 @@ typedef struct qfv_job_s {
|
|||
qfv_cmdbufferset_t commands;
|
||||
uint32_t num_dsmanagers;
|
||||
struct qfv_dsmanager_s **dsmanager;
|
||||
qfv_time_t time;
|
||||
} qfv_job_t;
|
||||
|
||||
typedef struct qfv_renderframe_s {
|
||||
|
@ -412,14 +421,19 @@ typedef struct qfv_renderframe_s {
|
|||
|
||||
typedef struct qfv_renderframeset_s
|
||||
DARRAY_TYPE (qfv_renderframe_t) qfv_renderframeset_t;
|
||||
typedef struct qfv_attachmentinfoset_s
|
||||
DARRAY_TYPE (qfv_attachmentinfo_t *) qfv_attachmentinfoset_t;
|
||||
|
||||
typedef struct qfv_renderctx_s {
|
||||
struct hashctx_s *hashctx;
|
||||
exprtab_t task_functions;
|
||||
qfv_attachmentinfoset_t external_attachments;
|
||||
qfv_jobinfo_t *jobinfo;
|
||||
qfv_samplerinfo_t *samplerinfo;
|
||||
qfv_job_t *job;
|
||||
qfv_job_t *job;
|
||||
qfv_renderframeset_t frames;
|
||||
int64_t size_time;
|
||||
struct qfv_renderdebug_s *debug;
|
||||
} qfv_renderctx_t;
|
||||
|
||||
typedef struct qfv_taskctx_s {
|
||||
|
@ -427,11 +441,14 @@ typedef struct qfv_taskctx_s {
|
|||
qfv_pipeline_t *pipeline;
|
||||
qfv_renderpass_t *renderpass;
|
||||
VkCommandBuffer cmd;
|
||||
void *data;
|
||||
} qfv_taskctx_t;
|
||||
|
||||
VkCommandBuffer QFV_GetCmdBuffer (struct vulkan_ctx_s *ctx, bool secondary);
|
||||
void QFV_AppendCmdBuffer (struct vulkan_ctx_s *ctx, VkCommandBuffer cmd);
|
||||
|
||||
void QFV_RunRenderPass (struct vulkan_ctx_s *ctx, qfv_renderpass_t *renderpass,
|
||||
uint32_t width, uint32_t height, void *data);
|
||||
void QFV_RunRenderJob (struct vulkan_ctx_s *ctx);
|
||||
void QFV_LoadRenderInfo (struct vulkan_ctx_s *ctx, const char *name);
|
||||
void QFV_LoadSamplerInfo (struct vulkan_ctx_s *ctx, const char *name);
|
||||
|
@ -439,8 +456,13 @@ void QFV_BuildRender (struct vulkan_ctx_s *ctx);
|
|||
void QFV_Render_Init (struct vulkan_ctx_s *ctx);
|
||||
void QFV_Render_Shutdown (struct vulkan_ctx_s *ctx);
|
||||
void QFV_Render_AddTasks (struct vulkan_ctx_s *ctx, exprsym_t *task_sys);
|
||||
void QFV_Render_AddAttachments (struct vulkan_ctx_s *ctx,
|
||||
uint32_t num_attachments,
|
||||
qfv_attachmentinfo_t **attachments);
|
||||
|
||||
void QFV_CreateFramebuffer (struct vulkan_ctx_s *ctx, qfv_renderpass_t *rp);
|
||||
void QFV_DestroyFramebuffer (struct vulkan_ctx_s *ctx, qfv_renderpass_t *rp);
|
||||
void QFV_CreateFramebuffer (struct vulkan_ctx_s *ctx, qfv_renderpass_t *rp,
|
||||
VkExtent2D extent);
|
||||
|
||||
struct qfv_dsmanager_s *
|
||||
QFV_Render_DSManager (struct vulkan_ctx_s *ctx,
|
||||
|
@ -449,6 +471,12 @@ VkSampler QFV_Render_Sampler (struct vulkan_ctx_s *ctx, const char *name);
|
|||
|
||||
qfv_step_t *QFV_GetStep (const exprval_t *param, qfv_job_t *job);
|
||||
qfv_step_t *QFV_FindStep (const char *step, qfv_job_t *job) __attribute__((pure));
|
||||
struct qfv_resobj_s *QFV_FindResource (const char *name, qfv_renderpass_t *rp) __attribute__((pure));
|
||||
|
||||
struct imui_ctx_s;
|
||||
void QFV_Render_UI (struct vulkan_ctx_s *ctx, struct imui_ctx_s *imui_ctx);
|
||||
void QFV_Render_Menu (struct vulkan_ctx_s *ctx, struct imui_ctx_s *imui_ctx);
|
||||
void QFV_Render_UI_Shutdown (struct vulkan_ctx_s *ctx);
|
||||
|
||||
#endif//__QFCC__
|
||||
|
||||
|
|
|
@ -25,6 +25,11 @@ typedef struct qfv_stagebuf_s {
|
|||
void *data;
|
||||
} qfv_stagebuf_t;
|
||||
|
||||
typedef struct qfv_scatter_s {
|
||||
VkDeviceSize srcOffset;
|
||||
VkDeviceSize dstOffset;
|
||||
VkDeviceSize length;
|
||||
} qfv_scatter_t;
|
||||
|
||||
qfv_stagebuf_t *QFV_CreateStagingBuffer (struct qfv_device_s *device,
|
||||
const char *name, size_t size,
|
||||
|
@ -38,6 +43,9 @@ struct qfv_bufferbarrier_s;
|
|||
void QFV_PacketCopyBuffer (qfv_packet_t *packet,
|
||||
VkBuffer dstBuffer, VkDeviceSize offset,
|
||||
const struct qfv_bufferbarrier_s *dstBarrier);
|
||||
void QFV_PacketScatterBuffer (qfv_packet_t *packet, VkBuffer dstBuffer,
|
||||
uint32_t count, qfv_scatter_t *scatter,
|
||||
const struct qfv_bufferbarrier_s *dstBarrier);
|
||||
struct qfv_imagebarrier_s;
|
||||
void QFV_PacketCopyImage (qfv_packet_t *packet, VkImage dstImage,
|
||||
int width, int height,
|
||||
|
|
|
@ -106,6 +106,9 @@ static struct DARRAY_TYPE(t *) n##_blocks = DARRAY_STATIC_INIT(8)
|
|||
v = (t *) calloc (1, sizeof (t)); \
|
||||
} while (0)
|
||||
|
||||
#define ALLOC_STATE(t,n) \
|
||||
static t *n##_freelist;
|
||||
|
||||
#define FREE(n, p) do { free (p); } while (0)
|
||||
#endif
|
||||
|
||||
|
|
|
@ -112,7 +112,7 @@ typedef struct lump_s {
|
|||
\ingroup formats_bsp
|
||||
*/
|
||||
///@{
|
||||
/** Holdes version and lump offset information.
|
||||
/** Holds version and lump offset information.
|
||||
|
||||
Always at offset 0 of the BSP file.
|
||||
*/
|
||||
|
@ -186,7 +186,7 @@ typedef struct dmiptexlump_s {
|
|||
The beginning of the name of the texture specifies some of the texture's
|
||||
properties:
|
||||
- sky The texture is used for the dual-layer skies. Expected
|
||||
to be 256x128. Sky face get special treatment by the
|
||||
to be 256x128. Sky faces get special treatment by the
|
||||
renderer.
|
||||
- * "Water" face. Texture-warped by the renderer. Usually
|
||||
unlit (ie, always full-bright).
|
||||
|
@ -195,6 +195,7 @@ typedef struct dmiptexlump_s {
|
|||
the texture belongs and the texture's position in that
|
||||
sequence. The rest of the name specifies the group name.
|
||||
\ref bsp_texture_animation
|
||||
- { Tranclucent surface (community extension).
|
||||
|
||||
The texture may be rectangular, but the size must be a multiple of 16
|
||||
pixels in both directions.
|
||||
|
@ -239,7 +240,7 @@ typedef struct dplane_s {
|
|||
|
||||
/** \defgroup bsp_plane_definition Plane definitions
|
||||
\ingroup bsp_planes
|
||||
Planes are always canonical in that thier normals always point along
|
||||
Planes are always canonical in that their normals always point along
|
||||
a positive axis for axial planes ((1, 0, 0), (0, 1, 0), or (0, 0, 1)),
|
||||
or the largest component is positive.
|
||||
*/
|
||||
|
@ -276,8 +277,8 @@ typedef struct dplane_s {
|
|||
|
||||
The node's plane divides the space into a front side and a back side,
|
||||
where a point is in front of the plane if its dot product with the plane
|
||||
normal is positive or 0, and ond behind (in back of) the plane if the
|
||||
dot product is negative.
|
||||
normal is positive or 0, and behind (in back of) the plane if the dot
|
||||
product is negative.
|
||||
*/
|
||||
typedef struct dnode_s { //BSP2 version (bsp 29 version is in bspfile.c)
|
||||
uint32_t planenum; ///< Index of plane defining this node
|
||||
|
@ -328,7 +329,7 @@ typedef struct texinfo_s {
|
|||
/// For each index, the first three elements are the X, Y, Z components
|
||||
/// of the basis vector, and the fourth component is the offset. Can be
|
||||
/// viewed as a 2 row x 4 column matrix (\a M) that is multiplied by
|
||||
/// a homogeneos vector (\a v) for a face vertex to determine that
|
||||
/// a homogeneous vector (\a v) for a face vertex to determine that
|
||||
/// vertex's UV coordinates (ie, \a M \a v)
|
||||
float vecs[2][4];
|
||||
/// Index of the miptex block in the texture data lump
|
||||
|
@ -350,7 +351,7 @@ typedef struct texinfo_s {
|
|||
/** \defgroup bsp_edges BSP edges lump
|
||||
\ingroup formats_bsp
|
||||
|
||||
\note Edge 0 is never used as negative edge indices are indicate
|
||||
\note Edge 0 is never used as negative edge indices indicate
|
||||
counterclockwise use of the edge in a face.
|
||||
*/
|
||||
///@{
|
||||
|
|
|
@ -27,6 +27,10 @@
|
|||
#ifndef __QF_expr_h
|
||||
#define __QF_expr_h
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
struct exprval_s;
|
||||
|
@ -57,7 +61,7 @@ typedef struct exprtype_s {
|
|||
binop_t *binops;
|
||||
unop_t *unops;
|
||||
void *data;
|
||||
} __attribute__((designated_init)) exprtype_t;
|
||||
} DESIGNATED_INIT exprtype_t;
|
||||
|
||||
typedef struct exprval_s {
|
||||
exprtype_t *type;
|
||||
|
|
|
@ -59,7 +59,6 @@ typedef enum {
|
|||
|
||||
extern int con_linewidth;
|
||||
extern struct plugin_s *con_module;
|
||||
extern struct console_data_s con_data;
|
||||
|
||||
//extern int con_totallines;
|
||||
//extern bool con_initialized;
|
||||
|
@ -69,7 +68,7 @@ void Con_DrawConsole (void);
|
|||
|
||||
void Con_Printf (const char *fmt, ...) __attribute__((format(PRINTF, 1, 2)));
|
||||
void Con_Print (const char *fmt, va_list args) __attribute__((format(PRINTF, 1, 0)));
|
||||
void Con_SetState (con_state_t state);
|
||||
void Con_SetState (con_state_t state, bool hide_mouse);
|
||||
|
||||
struct inputline_s;
|
||||
// wrapper function to attempt to either complete the command line
|
||||
|
|
|
@ -131,6 +131,8 @@ void ECS_DelSubpoolRange (ecs_registry_t *registry, uint32_t component,
|
|||
uint32_t id);
|
||||
ECSINLINE ecs_range_t ECS_GetSubpoolRange (ecs_registry_t *registry,
|
||||
uint32_t component, uint32_t id);
|
||||
void ECS_MoveSubpoolLast (ecs_registry_t *registry, uint32_t component,
|
||||
uint32_t id);
|
||||
|
||||
#undef ECSINLINE
|
||||
#ifndef IMPLEMENT_ECS_Funcs
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
*/
|
||||
///@{
|
||||
|
||||
struct imui_ctx_s;
|
||||
struct ecs_registry_s;
|
||||
typedef struct component_s {
|
||||
size_t size;
|
||||
|
@ -51,6 +52,9 @@ typedef struct component_s {
|
|||
uint32_t (*rangeid) (struct ecs_registry_s *reg, uint32_t ent,
|
||||
uint32_t comp);
|
||||
const char *name;
|
||||
void (*ui) (void *comp, struct imui_ctx_s *imui_ctx,
|
||||
struct ecs_registry_s *reg, uint32_t ent,
|
||||
void *data);
|
||||
} component_t;
|
||||
|
||||
#define COMPINLINE GNU89INLINE inline
|
||||
|
@ -60,6 +64,9 @@ COMPINLINE void Component_ResizeArray (const component_t *component,
|
|||
COMPINLINE void *Component_MoveElements (const component_t *component,
|
||||
void *array, uint32_t dstIndex,
|
||||
uint32_t srcIndex, uint32_t count);
|
||||
COMPINLINE void Component_RotateElements (const component_t *component,
|
||||
void *array, uint32_t dstIndex,
|
||||
uint32_t srcIndex, uint32_t count);
|
||||
COMPINLINE void Component_SwapElements (const component_t *component,
|
||||
void *a, void *b);
|
||||
COMPINLINE void *Component_CopyElements (const component_t *component,
|
||||
|
@ -98,6 +105,49 @@ Component_MoveElements (const component_t *component,
|
|||
return memmove (dst, src, count * component->size);
|
||||
}
|
||||
|
||||
COMPINLINE void
|
||||
Component_RotateElements (const component_t *component,
|
||||
void *array, uint32_t dstIndex, uint32_t srcIndex,
|
||||
uint32_t count)
|
||||
{
|
||||
if (dstIndex == srcIndex) {
|
||||
puts ("a");
|
||||
return;
|
||||
}
|
||||
auto dst = (byte *) array + dstIndex * component->size;
|
||||
auto src = (byte *) array + srcIndex * component->size;
|
||||
size_t countSize = count * component->size;
|
||||
if (dstIndex < srcIndex) {
|
||||
uint32_t bcount = srcIndex - dstIndex;
|
||||
size_t bcountSize = bcount * component->size;
|
||||
if (count < bcount) {
|
||||
byte tmp[countSize];
|
||||
memcpy (tmp, src, countSize);
|
||||
memmove (dst + countSize, dst, bcountSize);
|
||||
memcpy (dst, tmp, countSize);
|
||||
} else {
|
||||
byte tmp[bcountSize];
|
||||
memcpy (tmp, dst, bcountSize);
|
||||
memmove (dst, src, countSize);
|
||||
memcpy (dst + countSize, tmp, bcountSize);
|
||||
}
|
||||
} else if (dstIndex < srcIndex + count) {
|
||||
uint32_t bcount = dstIndex - srcIndex;
|
||||
size_t bcountSize = bcount * component->size;
|
||||
byte tmp[bcountSize];
|
||||
memcpy (tmp, src + countSize, bcountSize);
|
||||
memmove (dst, src, countSize);
|
||||
memcpy (src, tmp, bcountSize);
|
||||
} else {
|
||||
uint32_t bcount = dstIndex - srcIndex;
|
||||
size_t bcountSize = bcount * component->size;
|
||||
byte tmp[countSize];
|
||||
memcpy (tmp, src, countSize);
|
||||
memmove (src, src + countSize, bcountSize);
|
||||
memcpy (dst, tmp, countSize);
|
||||
}
|
||||
}
|
||||
|
||||
COMPINLINE void
|
||||
Component_SwapElements (const component_t *component, void *a, void *b)
|
||||
{
|
||||
|
|
|
@ -48,11 +48,13 @@ ENTINLINE uint32_t Ent_Generation (uint32_t id);
|
|||
ENTINLINE uint32_t Ent_NextGen (uint32_t id);
|
||||
|
||||
ENTINLINE int Ent_HasComponent (uint32_t ent, uint32_t comp,
|
||||
ecs_registry_t *reg);
|
||||
ecs_registry_t *reg);
|
||||
ENTINLINE void *Ent_GetComponent (uint32_t ent, uint32_t comp,
|
||||
ecs_registry_t *reg);
|
||||
ecs_registry_t *reg);
|
||||
ENTINLINE void *Ent_SafeGetComponent (uint32_t ent, uint32_t comp,
|
||||
ecs_registry_t *reg);
|
||||
ENTINLINE void *Ent_SetComponent (uint32_t ent, uint32_t comp,
|
||||
ecs_registry_t *registry, const void *data);
|
||||
ecs_registry_t *registry, const void *data);
|
||||
|
||||
#undef ENTINLINE
|
||||
#ifndef IMPLEMENT_ECS_ENTITY_Funcs
|
||||
|
@ -103,6 +105,18 @@ Ent_GetComponent (uint32_t ent, uint32_t comp, ecs_registry_t *reg)
|
|||
return data + ind * component->size;
|
||||
}
|
||||
|
||||
ENTINLINE void *
|
||||
Ent_SafeGetComponent (uint32_t ent, uint32_t comp, ecs_registry_t *reg)
|
||||
{
|
||||
if (!ECS_EntValid (ent, reg) || !Ent_HasComponent (ent, comp, reg)) {
|
||||
return 0;
|
||||
}
|
||||
const component_t *component = ®->components.a[comp];
|
||||
uint32_t ind = reg->comp_pools[comp].sparse[Ent_Index (ent)];
|
||||
byte *data = reg->comp_pools[comp].data;
|
||||
return data + ind * component->size;
|
||||
}
|
||||
|
||||
void *Ent_AddComponent (uint32_t ent, uint32_t comp, ecs_registry_t *registry);
|
||||
void Ent_RemoveComponent (uint32_t ent, uint32_t comp,
|
||||
ecs_registry_t *registry);
|
||||
|
|
|
@ -57,18 +57,24 @@ typedef struct hierarchy_s {
|
|||
uint32_t *childCount;
|
||||
uint32_t *childIndex;
|
||||
uint32_t *parentIndex;
|
||||
uint32_t *nextIndex;
|
||||
uint32_t *lastIndex;
|
||||
const hierarchy_type_t *type;
|
||||
void **components;
|
||||
struct ecs_registry_s *reg;
|
||||
uint32_t href_comp;
|
||||
bool tree_mode; // use for fast building
|
||||
} hierarchy_t;
|
||||
|
||||
#define nullindex (~0u)
|
||||
|
||||
hierarchy_t *Hierarchy_New (struct ecs_registry_s *reg, uint32_t href_comp,
|
||||
const hierarchy_type_t *type, int createRoot);
|
||||
void Hierarchy_Reserve (hierarchy_t *hierarchy, uint32_t count);
|
||||
hierarchy_t *Hierarchy_Copy (struct ecs_registry_s *reg, uint32_t href_comp,
|
||||
const hierarchy_t *src);
|
||||
void Hierarchy_Delete (hierarchy_t *hierarchy);
|
||||
void Hierarchy_SetTreeMode (hierarchy_t *hierarchy, bool tree_mode);
|
||||
|
||||
uint32_t Hierarchy_InsertHierarchy (hierarchy_t *dst, const hierarchy_t *src,
|
||||
uint32_t dstParent, uint32_t srcRoot);
|
||||
|
|
|
@ -349,7 +349,11 @@ IN_ClampAxis (in_axis_t *axis, float minval, float maxval)
|
|||
void IN_ButtonAction (in_button_t *buttin, int id, int pressed);
|
||||
|
||||
int IN_RegisterButton (in_button_t *button);
|
||||
int IN_UnregisterButton (in_button_t *button);
|
||||
void IN_ButtonInit (void);
|
||||
int IN_RegisterAxis (in_axis_t *axis);
|
||||
int IN_UnregisterAxis (in_axis_t *axis);
|
||||
void IN_AxisInit (void);
|
||||
in_button_t *IN_FindButton (const char *name);
|
||||
void IN_ButtonClearStates (void);
|
||||
in_axis_t *IN_FindAxis (const char *name);
|
||||
|
@ -367,7 +371,6 @@ struct IE_event_s;
|
|||
int IN_Binding_HandleEvent (const struct IE_event_s *ie_event);
|
||||
void IN_Binding_Activate (void);
|
||||
void IN_Binding_Init (void);
|
||||
void IN_Binding_Shutdown (void);
|
||||
struct plitem_s;
|
||||
void IN_Binding_SaveConfig (struct plitem_s *config);
|
||||
void IN_Binding_LoadConfig (struct plitem_s *config);
|
||||
|
|
|
@ -48,6 +48,7 @@ typedef enum {
|
|||
ies_capslock = 2,
|
||||
ies_control = 4,
|
||||
ies_alt = 8,
|
||||
ies_numlock = 16,
|
||||
} IE_shift;
|
||||
|
||||
typedef enum {
|
||||
|
@ -121,6 +122,7 @@ typedef struct IE_event_s {
|
|||
|
||||
typedef int ie_handler_t (const IE_event_t *, void *data);
|
||||
|
||||
void IN_Event_Init (void);
|
||||
int IE_Send_Event (const IE_event_t *event);
|
||||
int IE_Add_Handler (ie_handler_t *event_handler, void *data);
|
||||
void IE_Remove_Handler (int handle);
|
||||
|
|
|
@ -130,7 +130,6 @@ void IMT_BindButton (imt_t *imt, int button, const char *binding);
|
|||
bool IMT_ProcessAxis (int axis, int value);
|
||||
bool IMT_ProcessButton (int button, int state);
|
||||
void IMT_Init (void);
|
||||
void IMT_Shutdown (void);
|
||||
struct plitem_s;
|
||||
void IMT_SaveConfig (struct plitem_s *config);
|
||||
void IMT_SaveAxisConfig (struct plitem_s *axes, int axis_ind, int dev_axis);
|
||||
|
|
|
@ -31,7 +31,7 @@ typedef struct iqmmesh_s {
|
|||
uint32_t first_triangle, num_triangles;
|
||||
} iqmmesh;
|
||||
|
||||
enum {
|
||||
typedef enum : uint32_t {
|
||||
IQM_POSITION = 0,
|
||||
IQM_TEXCOORD = 1,
|
||||
IQM_NORMAL = 2,
|
||||
|
@ -40,9 +40,9 @@ enum {
|
|||
IQM_BLENDWEIGHTS = 5,
|
||||
IQM_COLOR = 6,
|
||||
IQM_CUSTOM = 0x10
|
||||
};
|
||||
} iqmverttype;
|
||||
|
||||
enum {
|
||||
typedef enum : uint32_t {
|
||||
IQM_BYTE = 0,
|
||||
IQM_UBYTE = 1,
|
||||
IQM_SHORT = 2,
|
||||
|
@ -52,7 +52,7 @@ enum {
|
|||
IQM_HALF = 6,
|
||||
IQM_FLOAT = 7,
|
||||
IQM_DOUBLE = 8
|
||||
};
|
||||
} iqmformat;
|
||||
|
||||
typedef struct iqmtriangle_s {
|
||||
uint32_t vertex[3];
|
||||
|
@ -84,21 +84,21 @@ typedef struct iqmpose_s {
|
|||
float channelscale[10];
|
||||
} iqmpose;
|
||||
|
||||
typedef enum : uint32_t {
|
||||
IQM_LOOP = 1<<0
|
||||
} iqmanimflags;
|
||||
|
||||
typedef struct iqmanim_s {
|
||||
uint32_t name;
|
||||
uint32_t first_frame, num_frames;
|
||||
float framerate;
|
||||
uint32_t flags;
|
||||
iqmanimflags flags;
|
||||
} iqmanim;
|
||||
|
||||
enum {
|
||||
IQM_LOOP = 1<<0
|
||||
};
|
||||
|
||||
typedef struct iqmvertexarray_s {
|
||||
uint32_t type;
|
||||
iqmverttype type;
|
||||
uint32_t flags;
|
||||
uint32_t format;
|
||||
iqmformat format;
|
||||
uint32_t size;
|
||||
uint32_t offset;
|
||||
} iqmvertexarray;
|
||||
|
|
|
@ -79,7 +79,7 @@ typedef struct instsurf_s {
|
|||
struct instsurf_s *tex_chain; ///< next in texture chain
|
||||
struct instsurf_s *lm_chain; ///< next in lightmap chain
|
||||
struct msurface_s *surface; ///< surface to render
|
||||
vec4f_t *transform;
|
||||
const vec4f_t *transform;
|
||||
float *color;
|
||||
} instsurf_t;
|
||||
|
||||
|
@ -369,18 +369,22 @@ typedef enum {
|
|||
mod_alias,
|
||||
mod_iqm,
|
||||
|
||||
mod_light,
|
||||
|
||||
mod_num_types
|
||||
} modtype_t;
|
||||
|
||||
#define EF_ROCKET 1 // leave a trail
|
||||
#define EF_GRENADE 2 // leave a trail
|
||||
#define EF_GIB 4 // leave a trail
|
||||
#define EF_ROTATE 8 // rotate (bonus items)
|
||||
#define EF_TRACER 16 // green split trail
|
||||
#define EF_ZOMGIB 32 // small blood trail
|
||||
#define EF_TRACER2 64 // orange split trail + rotate
|
||||
#define EF_TRACER3 128 // purple trail
|
||||
#define EF_GLOWTRAIL 4096 // glowcolor particle trail
|
||||
typedef enum {
|
||||
ME_ROCKET = 1, // leave a trail
|
||||
ME_GRENADE = 2, // leave a trail
|
||||
ME_GIB = 4, // leave a trail
|
||||
ME_ROTATE = 8, // rotate (bonus items)
|
||||
ME_TRACER = 16, // green split trail
|
||||
ME_ZOMGIB = 32, // small blood trail
|
||||
ME_TRACER2 = 64, // orange split trail + rotate
|
||||
ME_TRACER3 = 128, // purple trail
|
||||
ME_GLOWTRAIL = 4096, // glowcolor particle trail
|
||||
} modeffects_t;
|
||||
|
||||
typedef struct model_s {
|
||||
//FIXME use pointers. needs care in bsp submodel loading
|
||||
|
@ -389,13 +393,12 @@ typedef struct model_s {
|
|||
const struct vpath_s *vpath;// virtual path where this model was found
|
||||
bool needload; // bmodels and sprites don't cache normally
|
||||
aliashdr_t *aliashdr; // if not null, alias model is not cached
|
||||
bool hasfullbrights;
|
||||
|
||||
modtype_t type;
|
||||
int numframes;
|
||||
synctype_t synctype;
|
||||
|
||||
int flags;
|
||||
modeffects_t effects;
|
||||
|
||||
// lighting info
|
||||
float min_light;
|
||||
|
@ -407,10 +410,6 @@ typedef struct model_s {
|
|||
// FIXME: bbox cruft has to stay until sw rendering gets updated
|
||||
vec3_t mins, maxs;
|
||||
|
||||
// solid volume for clipping
|
||||
bool clipbox;
|
||||
vec3_t clipmins, clipmaxs;
|
||||
|
||||
// brush model
|
||||
//FIXME should be a pointer (submodels make things tricky)
|
||||
mod_brush_t brush;
|
||||
|
@ -432,13 +431,12 @@ model_t *Mod_ForName (const char *name, bool crash);
|
|||
void Mod_TouchModel (const char *name);
|
||||
void Mod_UnloadModel (model_t *model);
|
||||
// brush specific
|
||||
mleaf_t *Mod_PointInLeaf (vec4f_t p, model_t *model) __attribute__((pure));
|
||||
struct set_s *Mod_LeafPVS (const mleaf_t *leaf, const model_t *model);
|
||||
|
||||
void Mod_LeafPVS_set (const mleaf_t *leaf, const model_t *model, byte defvis,
|
||||
struct set_s *pvs);
|
||||
void Mod_LeafPVS_mix (const mleaf_t *leaf, const model_t *model, byte defvis,
|
||||
struct set_s *pvs);
|
||||
mleaf_t *Mod_PointInLeaf (vec4f_t p, const mod_brush_t *brush) __attribute__((pure));
|
||||
struct set_s;
|
||||
void Mod_LeafPVS_set (const mleaf_t *leaf, const mod_brush_t *brush,
|
||||
byte defvis, struct set_s *pvs);
|
||||
void Mod_LeafPVS_mix (const mleaf_t *leaf, const mod_brush_t *brush,
|
||||
byte defvis, struct set_s *pvs);
|
||||
|
||||
void Mod_Print (void);
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ typedef struct console_funcs_s {
|
|||
void (*process_input) (void);
|
||||
void (*draw_console) (void);
|
||||
void (*new_map) (void);
|
||||
void (*set_state) (con_state_t state);
|
||||
void (*set_state) (con_state_t state, bool hide_mouse);
|
||||
} console_funcs_t;
|
||||
|
||||
typedef struct console_data_s {
|
||||
|
|
|
@ -83,13 +83,13 @@ typedef struct vid_model_funcs_s {
|
|||
struct tex_s;
|
||||
struct font_s;
|
||||
struct draw_charbuffer_s;
|
||||
struct imui_ctx_s;
|
||||
|
||||
typedef void (*capfunc_t) (struct tex_s *screencap, void *data);
|
||||
|
||||
typedef struct vid_render_funcs_s {
|
||||
void (*init) (void);
|
||||
void (*UpdateScreen) (struct transform_s camera, double realtime,
|
||||
SCR_Func *scr_funcs);
|
||||
void (*UpdateScreen) (SCR_Func *scr_funcs);
|
||||
void (*Draw_CharBuffer) (int x, int y, struct draw_charbuffer_s *buffer);
|
||||
void (*Draw_SetScale) (int scale);
|
||||
void (*Draw_Character) (int x, int y, unsigned ch);
|
||||
|
@ -117,7 +117,6 @@ typedef struct vid_render_funcs_s {
|
|||
int (*Draw_AddFont) (struct font_s *font);
|
||||
void (*Draw_Glyph) (int x, int y, int fontid, int glyphid, int c);
|
||||
|
||||
|
||||
struct psystem_s *(*ParticleSystem) (void);
|
||||
void (*R_Init) (void);
|
||||
void (*R_ClearState) (void);
|
||||
|
@ -143,6 +142,8 @@ typedef struct vid_render_funcs_s {
|
|||
|
||||
void (*capture_screen) (capfunc_t callback, void *data);
|
||||
|
||||
void (*debug_ui) (struct imui_ctx_s *imui_ctx);
|
||||
|
||||
vid_model_funcs_t *model_funcs;
|
||||
} vid_render_funcs_t;
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@ extern const char * const pr_type_name[ev_type_count];
|
|||
#define RESERVED_OFS 28
|
||||
|
||||
|
||||
typedef enum {
|
||||
typedef enum : pr_ushort_t {
|
||||
OP_DONE_v6p,
|
||||
OP_MUL_F_v6p,
|
||||
OP_MUL_V_v6p,
|
||||
|
@ -432,7 +432,7 @@ typedef enum {
|
|||
} pr_opcode_v6p_e;
|
||||
#define OP_BREAK 0x8000
|
||||
|
||||
typedef enum {
|
||||
typedef enum : pr_ushort_t {
|
||||
#ifndef IN_DOXYGEN
|
||||
#include "QF/progs/pr_opcode.hinc"
|
||||
#endif
|
||||
|
@ -489,8 +489,8 @@ extern const opcode_t pr_opcodes[512];
|
|||
const opcode_t *PR_Opcode (pr_ushort_t opcode) __attribute__((const));
|
||||
|
||||
typedef struct dstatement_s {
|
||||
pr_opcode_e op:16; // will be pr_opcode_v6p_e for older progs
|
||||
pr_ushort_t a,b,c;
|
||||
pr_opcode_e op; // will be pr_opcode_v6p_e for older progs
|
||||
pr_short_t a,b,c;
|
||||
} GCC_STRUCT dstatement_t;
|
||||
|
||||
typedef struct ddef_s {
|
||||
|
@ -563,7 +563,7 @@ typedef struct pr_va_list_s {
|
|||
|(((0x##c) & 0xfff) << 0) )
|
||||
#define PROG_ID_VERSION 6
|
||||
#define PROG_V6P_VERSION PROG_VERSION_ENCODE(0,fff,00a)
|
||||
#define PROG_VERSION PROG_VERSION_ENCODE(0,fff,010)
|
||||
#define PROG_VERSION PROG_VERSION_ENCODE(0,fff,011)
|
||||
|
||||
typedef struct pr_chunk_s {
|
||||
pr_uint_t offset;
|
||||
|
|
|
@ -49,6 +49,7 @@ typedef enum {
|
|||
ty_class,
|
||||
ty_alias,
|
||||
ty_handle,
|
||||
ty_algebra,
|
||||
} ty_meta_e;
|
||||
|
||||
typedef struct qfot_alias_s {
|
||||
|
@ -105,6 +106,13 @@ typedef struct qfot_array_s {
|
|||
pr_int_t size; ///< number of elements in array
|
||||
} qfot_array_t;
|
||||
|
||||
typedef struct qfot_algebra_s {
|
||||
etype_t type; ///< always ev_float or ev_double
|
||||
pr_int_t width; ///< components in multivector
|
||||
pr_ptr_t algebra; ///< algebra descriptor
|
||||
pr_int_t element; ///< element within algebra
|
||||
} qfot_algebra_t;
|
||||
|
||||
/** QFO type encoding.
|
||||
|
||||
\note As this holds a union of all type representations, and those
|
||||
|
@ -126,6 +134,7 @@ typedef struct qfot_type_s {
|
|||
pr_string_t class; ///< ty_class
|
||||
qfot_alias_t alias; ///< ty_alias
|
||||
qfot_handle_t handle; ///< ty_handle
|
||||
qfot_algebra_t algebra; ///< ty_algebra
|
||||
};
|
||||
} qfot_type_t;
|
||||
|
||||
|
|
|
@ -52,22 +52,6 @@
|
|||
typedef uint8_t byte;
|
||||
#endif
|
||||
|
||||
#if __STDC_VERSION__ < 202000
|
||||
#define auto __auto_type
|
||||
#ifndef _DEF_BOOL_
|
||||
# define _DEF_BOOL_
|
||||
// KJB Undefined true and false defined in SciTech's DEBUG.H header
|
||||
# ifdef __cplusplus
|
||||
# define __bool_true_false_are_defined
|
||||
# endif
|
||||
# ifndef __bool_true_false_are_defined
|
||||
# undef true
|
||||
# undef false
|
||||
typedef enum {false, true} bool;
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// From mathlib...
|
||||
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)
|
||||
|
|
|
@ -96,22 +96,16 @@ typedef struct subpic_s {
|
|||
|
||||
// dynamic lights ===========================================================
|
||||
|
||||
typedef struct dlight_s
|
||||
{
|
||||
int key; // so entities can reuse same entry
|
||||
vec3_t origin;
|
||||
typedef struct dlight_s {
|
||||
vec4f_t origin;
|
||||
vec4f_t color;
|
||||
float radius;
|
||||
float die; // stop lighting after this time
|
||||
float decay; // drop this each second
|
||||
float minlight; // don't add when contributing less
|
||||
float color[4];
|
||||
} dlight_t;
|
||||
|
||||
extern dlight_t *r_dlights;
|
||||
extern unsigned int r_maxdlights;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
int length;
|
||||
char map[MAX_STYLESTRING];
|
||||
char average;
|
||||
|
@ -180,8 +174,6 @@ void R_LoadModule (struct vid_internal_s *vid_internal);
|
|||
struct progs_s;
|
||||
void R_Progs_Init (struct progs_s *pr);
|
||||
|
||||
dlight_t *R_AllocDlight (int key);
|
||||
void R_DecayLights (double frametime);
|
||||
void Fog_Update (float density, float red, float green, float blue,
|
||||
float time);
|
||||
struct plitem_s;
|
||||
|
|
|
@ -75,12 +75,14 @@ typedef struct visibility_s {
|
|||
typedef struct renderer_s {
|
||||
struct model_s *model; // NULL = no model
|
||||
struct skin_s *skin;
|
||||
unsigned fullbright:1;
|
||||
unsigned noshadows:1;
|
||||
unsigned onlyshadows:1;
|
||||
unsigned depthhack:1;
|
||||
float colormod[4]; // color tint and alpha for model
|
||||
int skinnum; // for Alias models
|
||||
int fullbright;
|
||||
float min_light;
|
||||
int render_id;
|
||||
mat4f_t full_transform;
|
||||
} renderer_t;
|
||||
|
||||
typedef struct entityset_s DARRAY_TYPE (entity_t) entityset_t;
|
||||
|
@ -150,6 +152,8 @@ Entity_Transform (entity_t ent)
|
|||
}
|
||||
|
||||
struct mod_brush_s;
|
||||
efrag_t **R_LinkEfrag (struct mleaf_s *leaf, entity_t ent, uint32_t queue,
|
||||
efrag_t **lastlink);
|
||||
void R_AddEfrags (struct mod_brush_s *, entity_t ent);
|
||||
void R_ShutdownEfrags (void);
|
||||
void R_ClearEfragChain (efrag_t *ef);
|
||||
|
|
|
@ -53,15 +53,7 @@ typedef struct light_s {
|
|||
vec4f_t attenuation;
|
||||
} light_t;
|
||||
|
||||
typedef struct lightset_s DARRAY_TYPE (light_t) lightset_t;
|
||||
typedef struct lightleafset_s DARRAY_TYPE (int) lightintset_t;
|
||||
typedef struct lightvisset_s DARRAY_TYPE (byte) lightvisset_t;
|
||||
|
||||
typedef struct lightingdata_s {
|
||||
lightset_t lights;
|
||||
lightintset_t lightstyles;
|
||||
lightintset_t lightleafs;
|
||||
lightvisset_t lightvis;
|
||||
struct set_s *sun_pvs;
|
||||
// A fat PVS of leafs visible from visible leafs so hidden lights can
|
||||
// illuminate the leafs visible to the player
|
||||
|
@ -73,8 +65,11 @@ typedef struct lightingdata_s {
|
|||
lightingdata_t *Light_CreateLightingData (struct scene_s *scene);
|
||||
void Light_DestroyLightingData (lightingdata_t *ldata);
|
||||
void Light_ClearLights (lightingdata_t *ldata);
|
||||
void Light_AddLight (lightingdata_t *ldata, const light_t *light, int style);
|
||||
void Light_AddLight (lightingdata_t *ldata, const light_t *light,
|
||||
uint32_t style);
|
||||
void Light_EnableSun (lightingdata_t *ldata);
|
||||
void Light_FindVisibleLights (lightingdata_t *ldata);
|
||||
void Light_DecayLights (lightingdata_t *ldata, float frametime,
|
||||
double realtime);
|
||||
void Light_LinkLight (lightingdata_t *ldata, uint32_t entid);
|
||||
|
||||
#endif//__QF_scene_light_h
|
||||
|
|
|
@ -49,6 +49,14 @@ enum scene_components {
|
|||
scene_old_origin, //XXX FIXME XXX should not be here
|
||||
scene_colormap,
|
||||
|
||||
scene_dynlight,
|
||||
|
||||
scene_light,
|
||||
scene_efrags,
|
||||
scene_lightstyle,
|
||||
scene_lightleaf,
|
||||
scene_lightid,
|
||||
|
||||
//FIXME these should probably be private to the sw renderer (and in a
|
||||
//group, which needs to be implemented), but need to sort out a good
|
||||
//scheme for semi-dynamic components
|
||||
|
@ -69,7 +77,13 @@ typedef struct scene_s {
|
|||
struct lightingdata_s *lights;
|
||||
} scene_t;
|
||||
|
||||
scene_t *Scene_NewScene (void);
|
||||
typedef struct scene_system_s {
|
||||
struct ecs_system_s *system;
|
||||
const struct component_s *components;
|
||||
uint32_t component_count;
|
||||
} scene_system_t;
|
||||
|
||||
scene_t *Scene_NewScene (scene_system_t *extra_systems);
|
||||
void Scene_DeleteScene (scene_t *scene);
|
||||
struct entity_s Scene_CreateEntity (scene_t *scene);
|
||||
void Scene_DestroyEntity (scene_t *scene, struct entity_s entity);
|
||||
|
|
|
@ -40,8 +40,7 @@ typedef void (*SCR_Func)(void);
|
|||
// scr_funcs is a null terminated array
|
||||
void SCR_UpdateScreen (struct transform_s camera, double realtime,
|
||||
SCR_Func *scr_funcs);
|
||||
void SCR_UpdateScreen_legacy (struct transform_s camera, double realtime,
|
||||
SCR_Func *scr_funcs);
|
||||
void SCR_UpdateScreen_legacy (SCR_Func *scr_funcs);
|
||||
void SCR_SetFOV (float fov);
|
||||
// control whether the 3d viewport is user-controlled or always fullscreen
|
||||
void SCR_SetFullscreen (bool fullscreen);
|
||||
|
@ -54,6 +53,10 @@ extern int r_zgraph;
|
|||
extern int scr_copytop;
|
||||
extern bool scr_skipupdate;
|
||||
|
||||
extern bool r_lock_viewleaf;
|
||||
extern bool r_override_camera;
|
||||
extern struct transform_s r_camera;
|
||||
|
||||
struct view_pos_s;
|
||||
void R_TimeGraph (struct view_pos_s abs, struct view_pos_s len);
|
||||
void R_ZGraph (struct view_pos_s abs, struct view_pos_s len);
|
||||
|
|
|
@ -47,7 +47,7 @@ extern int sys_sleep;
|
|||
|
||||
extern int developer;
|
||||
|
||||
|
||||
extern bool sys_quake_encoding;
|
||||
extern const char sys_char_map[256];
|
||||
|
||||
typedef struct date_s {
|
||||
|
@ -131,6 +131,8 @@ size_t Sys_PageSize (void);
|
|||
void *Sys_Alloc (size_t size);
|
||||
void Sys_Free (void *mem, size_t size);
|
||||
int Sys_LockMemory (void *mem, size_t size);
|
||||
size_t Sys_PeakRSS (void);
|
||||
size_t Sys_CurrentRSS (void);
|
||||
|
||||
int Sys_ProcessorCount (void);
|
||||
|
||||
|
|
|
@ -44,18 +44,26 @@ enum {
|
|||
canvas_cachepic,
|
||||
canvas_fill,
|
||||
canvas_charbuff,
|
||||
canvas_passage_glyphs, // copy of text_passage_glyphs
|
||||
canvas_glyphs, // copy of text_passage_glyphs
|
||||
canvas_func,
|
||||
canvas_outline,
|
||||
canvas_lateupdate,
|
||||
|
||||
// last so deleting an entity removes the grouped components first
|
||||
// also, does not have a subpool
|
||||
canvas_canvas,
|
||||
|
||||
canvas_comp_count
|
||||
};
|
||||
|
||||
typedef struct canvas_s {
|
||||
uint32_t range[canvas_comp_count];
|
||||
ecs_registry_t *reg;
|
||||
uint32_t base;
|
||||
int16_t draw_order;
|
||||
int16_t draw_group;
|
||||
bool visible;
|
||||
uint32_t range[canvas_canvas];
|
||||
} canvas_t;
|
||||
|
||||
extern const struct component_s canvas_components[canvas_comp_count];
|
||||
|
@ -65,6 +73,7 @@ typedef struct canvas_system_s {
|
|||
uint32_t base;
|
||||
uint32_t view_base;
|
||||
uint32_t text_base;
|
||||
uint32_t imui_base;
|
||||
} canvas_system_t;
|
||||
|
||||
struct view_s;
|
||||
|
@ -87,9 +96,15 @@ uint32_t Canvas_New (canvas_system_t canvas_sys);
|
|||
void Canvas_Draw (canvas_system_t canvas_sys);
|
||||
void Canvas_SortComponentPool (canvas_system_t canvas_sys, uint32_t ent,
|
||||
uint32_t component);
|
||||
void Canvas_SetLen (canvas_system_t canvas_sys, view_pos_t len);
|
||||
void Canvas_SetLen (canvas_system_t canvas_sys, uint32_t ent, view_pos_t len);
|
||||
CANVASINLINE view_t Canvas_GetRootView (canvas_system_t canvas_sys,
|
||||
uint32_t ent);
|
||||
CANVASINLINE bool *Canvas_Visible (canvas_system_t canvas_sys, uint32_t ent);
|
||||
CANVASINLINE int16_t *Canvas_DrawGroup (canvas_system_t canvas_sys,
|
||||
uint32_t ent);
|
||||
CANVASINLINE int16_t *Canvas_DrawOrder (canvas_system_t canvas_sys,
|
||||
uint32_t ent);
|
||||
void Canvas_DrawSort (canvas_system_t canvas_sys);
|
||||
|
||||
#undef CANVASINLINE
|
||||
#ifndef IMPLEMENT_CANVAS_Funcs
|
||||
|
@ -106,6 +121,33 @@ Canvas_GetRootView (canvas_system_t canvas_sys, uint32_t ent)
|
|||
return View_FromEntity (viewsys, ent);
|
||||
}
|
||||
|
||||
CANVASINLINE
|
||||
bool *
|
||||
Canvas_Visible (canvas_system_t canvas_sys, uint32_t ent)
|
||||
{
|
||||
uint32_t comp = canvas_sys.base + canvas_canvas;
|
||||
auto canvas = (canvas_t *) Ent_GetComponent (ent, comp, canvas_sys.reg);
|
||||
return &canvas->visible;
|
||||
}
|
||||
|
||||
CANVASINLINE
|
||||
int16_t *
|
||||
Canvas_DrawGroup (canvas_system_t canvas_sys, uint32_t ent)
|
||||
{
|
||||
uint32_t comp = canvas_sys.base + canvas_canvas;
|
||||
auto canvas = (canvas_t *) Ent_GetComponent (ent, comp, canvas_sys.reg);
|
||||
return &canvas->draw_group;
|
||||
}
|
||||
|
||||
CANVASINLINE
|
||||
int16_t *
|
||||
Canvas_DrawOrder (canvas_system_t canvas_sys, uint32_t ent)
|
||||
{
|
||||
uint32_t comp = canvas_sys.base + canvas_canvas;
|
||||
auto canvas = (canvas_t *) Ent_GetComponent (ent, comp, canvas_sys.reg);
|
||||
return &canvas->draw_order;
|
||||
}
|
||||
|
||||
#undef CANVASINLINE
|
||||
|
||||
#endif//__QF_scene_canvas_h
|
||||
|
|
|
@ -57,5 +57,7 @@ typedef struct font_s {
|
|||
void Font_Init (void);
|
||||
void Font_Free (font_t *font);
|
||||
font_t *Font_Load (QFile *font_file, int size);
|
||||
// free the returned string
|
||||
char *Font_SystemFont (const char *font_pattern);
|
||||
|
||||
#endif//__QF_ui_font_h
|
||||
|
|
208
include/QF/ui/imui.h
Normal file
208
include/QF/ui/imui.h
Normal file
|
@ -0,0 +1,208 @@
|
|||
/*
|
||||
imui.h
|
||||
|
||||
Immediate mode user interface
|
||||
|
||||
Copyright (C) 2023 Bill Currie <bill@taniwha.org>
|
||||
|
||||
Author: Bill Currie <bill@taniwha.org>
|
||||
Date: 2023/07/01
|
||||
|
||||
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
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __QF_ui_imui_h
|
||||
#define __QF_ui_imui_h
|
||||
|
||||
#include "QF/ui/view.h"
|
||||
|
||||
typedef struct imui_ctx_s imui_ctx_t;
|
||||
struct canvas_system_s;
|
||||
struct IE_event_s;
|
||||
|
||||
enum {
|
||||
imui_percent_x, ///< int
|
||||
imui_percent_y, ///< int
|
||||
imui_reference, ///< imui_reference_t
|
||||
|
||||
imui_comp_count
|
||||
};
|
||||
|
||||
extern const component_t imui_components[imui_comp_count];
|
||||
|
||||
typedef enum {
|
||||
imui_size_none,
|
||||
imui_size_pixels,
|
||||
imui_size_fittext,
|
||||
imui_size_percent,
|
||||
imui_size_fitchildren,
|
||||
imui_size_expand,
|
||||
} imui_size_t;
|
||||
|
||||
typedef union imui_color_s {
|
||||
struct {
|
||||
uint32_t normal;
|
||||
uint32_t hot;
|
||||
uint32_t active;
|
||||
};
|
||||
uint32_t color[3];
|
||||
} imui_color_t;
|
||||
|
||||
typedef struct imui_style_s {
|
||||
imui_color_t background;
|
||||
imui_color_t foreground;
|
||||
imui_color_t text;
|
||||
} imui_style_t;
|
||||
|
||||
typedef struct imui_reference_s {
|
||||
uint32_t ref_id;
|
||||
} imui_reference_t;
|
||||
|
||||
typedef struct imui_window_s {
|
||||
const char *name;
|
||||
int xpos;
|
||||
int ypos;
|
||||
int xlen;
|
||||
int ylen;
|
||||
int group_offset;
|
||||
int mode;
|
||||
bool is_open;
|
||||
bool is_collapsed;
|
||||
|
||||
const char *reference;
|
||||
grav_t reference_gravity;
|
||||
grav_t anchor_gravity;
|
||||
struct imui_window_s *parent; // for submenus
|
||||
bool no_collapse;
|
||||
} imui_window_t;
|
||||
|
||||
typedef struct imui_io_s {
|
||||
view_pos_t mouse;
|
||||
uint32_t buttons;
|
||||
uint32_t pressed;
|
||||
uint32_t released;
|
||||
uint32_t hot;
|
||||
uint32_t active;
|
||||
} imui_io_t;
|
||||
|
||||
imui_ctx_t *IMUI_NewContext (struct canvas_system_s canvas_sys,
|
||||
const char *font, float fontsize);
|
||||
void IMUI_DestroyContext (imui_ctx_t *ctx);
|
||||
|
||||
void IMUI_SetVisible (imui_ctx_t *ctx, bool visible);
|
||||
void IMUI_SetSize (imui_ctx_t *ctx, int xlen, int ylen);
|
||||
bool IMUI_ProcessEvent (imui_ctx_t *ctx, const struct IE_event_s *ie_event);
|
||||
imui_io_t IMUI_GetIO (imui_ctx_t *ctx) __attribute__((pure));
|
||||
void IMUI_BeginFrame (imui_ctx_t *ctx);
|
||||
void IMUI_Draw (imui_ctx_t *ctx);
|
||||
|
||||
int IMUI_PushLayout (imui_ctx_t *ctx, bool vertical);
|
||||
void IMUI_PopLayout (imui_ctx_t *ctx);
|
||||
void IMUI_Layout_SetXSize (imui_ctx_t *ctx, imui_size_t size, int value);
|
||||
void IMUI_Layout_SetYSize (imui_ctx_t *ctx, imui_size_t size, int value);
|
||||
|
||||
int IMUI_PushStyle (imui_ctx_t *ctx, const imui_style_t *style);
|
||||
void IMUI_PopStyle (imui_ctx_t *ctx);
|
||||
void IMUI_Style_Update (imui_ctx_t *ctx, const imui_style_t *style);
|
||||
void IMUI_Style_Fetch (const imui_ctx_t *ctx, imui_style_t *style);
|
||||
|
||||
void IMUI_Label (imui_ctx_t *ctx, const char *label);
|
||||
void IMUI_Labelf (imui_ctx_t *ctx, const char *fmt, ...)__attribute__((format(PRINTF,2,3)));
|
||||
bool IMUI_Button (imui_ctx_t *ctx, const char *label);
|
||||
bool IMUI_Checkbox (imui_ctx_t *ctx, bool *flag, const char *label);
|
||||
void IMUI_Radio (imui_ctx_t *ctx, int *curvalue, int value, const char *label);
|
||||
void IMUI_Slider (imui_ctx_t *ctx, float *value, float minval, float maxval,
|
||||
const char *label);
|
||||
void IMUI_Spacer (imui_ctx_t *ctx,
|
||||
imui_size_t xsize, int xvalue,
|
||||
imui_size_t ysize, int yvalue);
|
||||
|
||||
int IMUI_StartPanel (imui_ctx_t *ctx, imui_window_t *panel);
|
||||
int IMUI_ExtendPanel (imui_ctx_t *ctx, const char *panel_name);
|
||||
void IMUI_EndPanel (imui_ctx_t *ctx);
|
||||
|
||||
int IMUI_StartMenu (imui_ctx_t *ctx, imui_window_t *menu, bool vertical);
|
||||
void IMUI_EndMenu (imui_ctx_t *ctx);
|
||||
bool IMUI_MenuItem (imui_ctx_t *ctx, const char *label, bool collapse);
|
||||
|
||||
int IMUI_StartWindow (imui_ctx_t *ctx, imui_window_t *window);
|
||||
void IMUI_EndWindow (imui_ctx_t *ctx);
|
||||
|
||||
#define IMUI_DeferLoop(begin, end) \
|
||||
for (int _i_ = (begin); !_i_; _i_++, (end))
|
||||
|
||||
// #define IMUI_context to an imui_ctx_t * variable
|
||||
|
||||
#define UI_Label(label) \
|
||||
IMUI_Label(IMUI_context, label)
|
||||
|
||||
#define UI_Labelf(fmt...) \
|
||||
IMUI_Labelf(IMUI_context, fmt)
|
||||
|
||||
#define UI_Button(label) \
|
||||
IMUI_Button(IMUI_context, label)
|
||||
|
||||
#define UI_Checkbox(flag, label) \
|
||||
IMUI_Checkbox(IMUI_context, flag, label)
|
||||
|
||||
#define UI_Radio(state, value, label) \
|
||||
IMUI_Radio(IMUI_context, state, value, label)
|
||||
|
||||
#define UI_Slider(value, minval, maxval, label) \
|
||||
IMUI_Slider(IMUI_context, value, minval, maxval, label)
|
||||
|
||||
#define UI_FlexibleSpace() \
|
||||
IMUI_Spacer(IMUI_context, imui_size_expand, 100, imui_size_expand, 100)
|
||||
|
||||
#define UI_Layout(vertical) \
|
||||
IMUI_DeferLoop (IMUI_PushLayout (IMUI_context, vertical), \
|
||||
IMUI_PopLayout (IMUI_context ))
|
||||
|
||||
#define UI_Panel(panel) \
|
||||
IMUI_DeferLoop (IMUI_StartPanel (IMUI_context, panel), \
|
||||
IMUI_EndPanel (IMUI_context))
|
||||
|
||||
#define UI_ExtendPanel(panel_name) \
|
||||
IMUI_DeferLoop (IMUI_ExtendPanel (IMUI_context, panel_name), \
|
||||
IMUI_EndPanel (IMUI_context))
|
||||
|
||||
#define UI_Menu(menu) \
|
||||
IMUI_DeferLoop (IMUI_StartMenu (IMUI_context, menu, true), \
|
||||
IMUI_EndMenu (IMUI_context))
|
||||
|
||||
#define UI_MenuBar(menu) \
|
||||
IMUI_DeferLoop (IMUI_StartMenu (IMUI_context, menu, false), \
|
||||
IMUI_EndMenu (IMUI_context))
|
||||
|
||||
#define UI_MenuItem(label) \
|
||||
IMUI_MenuItem (IMUI_context, label, true)
|
||||
|
||||
#define UI_Window(window) \
|
||||
IMUI_DeferLoop (IMUI_StartWindow (IMUI_context, window), \
|
||||
IMUI_EndWindow (IMUI_context))
|
||||
|
||||
#define UI_Style(style) \
|
||||
IMUI_DeferLoop (IMUI_PushStyle (IMUI_context, style), \
|
||||
IMUI_PopStyle (IMUI_context ))
|
||||
|
||||
#define UI_Horizontal UI_Layout(false)
|
||||
#define UI_Vertical UI_Layout(true)
|
||||
|
||||
#endif//__QF_ui_imui_h
|
58
include/QF/ui/shaper.h
Normal file
58
include/QF/ui/shaper.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
shaper.h
|
||||
|
||||
Text shaping system
|
||||
|
||||
Copyright (C) 2023 Bill Currie <bill@taniwha.org>
|
||||
|
||||
Author: Bill Currie <bill@taniwha.org>
|
||||
Date: 2023/07/07
|
||||
|
||||
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
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __QF_ui_shaper_h
|
||||
#define __QF_ui_shaper_h
|
||||
|
||||
#include "QF/ui/text.h"
|
||||
|
||||
typedef struct text_shaper_s text_shaper_t;
|
||||
|
||||
typedef struct shaped_glyphs_s {
|
||||
const hb_glyph_info_t *glyphInfo;
|
||||
const hb_glyph_position_t *glyphPos;
|
||||
unsigned count;
|
||||
} shaped_glyphs_t;
|
||||
|
||||
typedef struct shaping_s {
|
||||
const script_component_t *script;
|
||||
const featureset_t *features;
|
||||
const struct font_s *font;
|
||||
} shaping_t;
|
||||
|
||||
text_shaper_t *Shaper_New (void);
|
||||
void Shaper_Delete (text_shaper_t *shaper);
|
||||
void Shaper_FlushUnused (text_shaper_t *shaper);
|
||||
|
||||
shaped_glyphs_t Shaper_ShapeText (text_shaper_t *shaper,
|
||||
const shaping_t *control,
|
||||
const char *text, size_t text_len);
|
||||
|
||||
#endif//__QF_ui_shaper_h
|
|
@ -77,9 +77,11 @@ enum {
|
|||
text_passage_glyphs,
|
||||
// glyphs for a single text object
|
||||
text_glyphs,
|
||||
// tint color for glyphs
|
||||
text_color,
|
||||
// text_script, text_font and text_features on the passage root object set
|
||||
// the defaults for all text objects in the passage. The settings can be
|
||||
// overridden at the paragraph level or individiual text object level by
|
||||
// overridden at the paragraph level or individual text object level by
|
||||
// adding the appropriate component to that text object.
|
||||
// script settings for the text object
|
||||
text_script,
|
||||
|
@ -104,16 +106,28 @@ extern hb_feature_t CligOn;
|
|||
|
||||
struct font_s;
|
||||
struct passage_s;
|
||||
struct text_shaper_s;
|
||||
|
||||
struct view_s Text_View (ecs_system_t viewsys,
|
||||
struct font_s *font, struct passage_s *passage);
|
||||
void Text_SetScript (ecs_system_t textsys, uint32_t textid,
|
||||
typedef struct text_system_s {
|
||||
ecs_registry_t *reg;
|
||||
uint32_t view_base;
|
||||
uint32_t text_base;
|
||||
} text_system_t;
|
||||
|
||||
struct view_s Text_PassageView (text_system_t textsys,
|
||||
struct font_s *font, struct passage_s *passage);
|
||||
struct view_s Text_StringView (text_system_t textsys, struct view_s parent,
|
||||
struct font_s *font,
|
||||
const char *str, uint32_t len,
|
||||
script_component_t *sc, featureset_t *fs,
|
||||
struct text_shaper_s *shaper);
|
||||
void Text_SetScript (text_system_t textsys, uint32_t textid,
|
||||
const char *lang, hb_script_t script, text_dir_e dir);
|
||||
void Text_SetFont (ecs_system_t textsys, uint32_t textid,
|
||||
void Text_SetFont (text_system_t textsys, uint32_t textid,
|
||||
struct font_s *font);
|
||||
void Text_SetFeatures (ecs_system_t textsys, uint32_t textid,
|
||||
void Text_SetFeatures (text_system_t textsys, uint32_t textid,
|
||||
featureset_t *features);
|
||||
void Text_AddFeature (ecs_system_t textsys, uint32_t textid,
|
||||
void Text_AddFeature (text_system_t textsys, uint32_t textid,
|
||||
hb_feature_t feature);
|
||||
|
||||
#endif//__QF_ui_text_h
|
||||
|
|
|
@ -83,6 +83,12 @@ typedef struct viewcont_s {
|
|||
unsigned resize_y:1; ///< If true, view's height follows parent's.
|
||||
unsigned bol_suppress:1; ///< If true, view_flow skips at start of line.
|
||||
unsigned flow_size:1; ///< If true, view's size is adjusted to flow.
|
||||
unsigned semantic_x:3; ///< layout size control (IMUI_SizeKind)
|
||||
unsigned semantic_y:3; ///< layout size control (IMUI_SizeKind)
|
||||
unsigned free_x:1; ///< don't set position automatically
|
||||
unsigned free_y:1; ///< don't set position automatically
|
||||
unsigned vertical:1; ///< true: layout is vertical, else horizontal
|
||||
unsigned active:1; ///< can respond to the mouse
|
||||
} viewcont_t;
|
||||
|
||||
enum {
|
||||
|
@ -160,7 +166,7 @@ VIEWINLINE view_pos_t View_GetAbs (view_t view);
|
|||
VIEWINLINE view_pos_t View_GetRel (view_t view);
|
||||
VIEWINLINE void View_SetLen (view_t view, int x, int y);
|
||||
VIEWINLINE view_pos_t View_GetLen (view_t view);
|
||||
VIEWINLINE viewcont_t* View_Control (view_t view);
|
||||
VIEWINLINE viewcont_t *View_Control (view_t view);
|
||||
VIEWINLINE void View_SetGravity (view_t view, grav_t grav);
|
||||
VIEWINLINE grav_t View_GetGravity (view_t view);
|
||||
VIEWINLINE void View_SetVisible (view_t view, int visible);
|
||||
|
|
|
@ -45,6 +45,8 @@ typedef struct {
|
|||
unsigned short *colormap16; // 256 * VID_GRADES size
|
||||
unsigned int *colormap32; // 256 * VID_GRADES size
|
||||
int fullbright; // index of first fullbright color
|
||||
int x;
|
||||
int y;
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
int numpages;
|
||||
|
@ -71,8 +73,10 @@ void VID_Init_Cvars (void);
|
|||
// the palette data will go away after the call, so it must be copied off if
|
||||
// the video driver will need it again
|
||||
void VID_Init (byte *palette, byte *colormap);
|
||||
void VID_SendSize (void);
|
||||
void VID_SetPalette (byte *palette, byte *colormap);
|
||||
void VID_SetCaption (const char *text);
|
||||
void VID_SetCursor (bool visible);
|
||||
void VID_ClearMemory (void);
|
||||
|
||||
void VID_OnPaletteChange_AddListener (viddef_listener_t listener, void *data);
|
||||
|
|
13
include/cl_console.h
Normal file
13
include/cl_console.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
#ifndef __cl_console_h
|
||||
#define __cl_console_h
|
||||
|
||||
extern struct console_data_s con_data;
|
||||
extern bool con_debug;
|
||||
|
||||
void Con_Debug_Init (void);
|
||||
void Con_Debug_InitCvars (void);
|
||||
void Con_Debug_Shutdown (void);
|
||||
void Con_Debug_Draw (void);
|
||||
void Con_Show_Mouse (bool visible);
|
||||
|
||||
#endif//__cl_console_h
|
|
@ -31,17 +31,28 @@
|
|||
#define __client_effects_h
|
||||
|
||||
#include "QF/simd/types.h"
|
||||
#include "QF/ecs/component.h"
|
||||
|
||||
enum {
|
||||
effect_light, // light entity id
|
||||
effect_muzzleflash, // light entity id
|
||||
|
||||
effect_comp_count,
|
||||
};
|
||||
|
||||
extern const component_t effect_components[effect_comp_count];
|
||||
extern struct ecs_system_s effect_system;
|
||||
|
||||
struct entity_s;
|
||||
struct entity_state_s;
|
||||
|
||||
void CL_NewDlight (int key, vec4f_t org, int effects, byte glow_size,
|
||||
byte glow_color, double time);
|
||||
void CL_ModelEffects (struct entity_s ent, int num, int glow_color,
|
||||
void CL_NewDlight (struct entity_s ent, vec4f_t org, int effects,
|
||||
byte glow_size, byte glow_color, double time);
|
||||
void CL_ModelEffects (struct entity_s ent, int glow_color,
|
||||
double time);
|
||||
void CL_EntityEffects (int num, struct entity_s ent,
|
||||
struct entity_state_s *state, double time);
|
||||
void CL_MuzzleFlash (vec4f_t position, vec4f_t fv, float zoffset, int num,
|
||||
double time);
|
||||
void CL_EntityEffects (struct entity_s ent, struct entity_state_s *state,
|
||||
double time);
|
||||
void CL_MuzzleFlash (struct entity_s ent, vec4f_t position, vec4f_t fv,
|
||||
float zoffset, double time);
|
||||
|
||||
#endif//__client_effects_h
|
||||
|
|
|
@ -101,7 +101,9 @@ typedef struct viewstate_s {
|
|||
#define VF_GIB 2
|
||||
|
||||
struct msg_s;
|
||||
struct scene_s;
|
||||
|
||||
void V_NewScene (viewstate_t *vs, struct scene_s *scene);
|
||||
void V_Init (viewstate_t *vs);
|
||||
void V_Init_Cvars (void);
|
||||
void V_RenderView (viewstate_t *vs);
|
||||
|
|
|
@ -66,6 +66,7 @@ void CL_ParseBaseline (struct msg_s *msg, struct entity_state_s *baseline,
|
|||
void CL_ParseStatic (struct msg_s *msg, int version);
|
||||
void CL_MapCfg (const char *mapname);
|
||||
void CL_World_NewMap (const char *mapname, const char *skyname);
|
||||
void CL_World_Clear (void);
|
||||
void CL_LoadLights (struct plitem_s *entities, struct scene_s *scene);
|
||||
|
||||
#endif//__client_world_h
|
||||
|
|
|
@ -57,6 +57,7 @@ extern int x_height;
|
|||
extern int x_shmeventtype;
|
||||
extern Time x_time;
|
||||
extern Time x_mouse_time;
|
||||
extern Cursor x_nullcursor;
|
||||
extern bool oktodraw;
|
||||
extern bool x_have_focus;
|
||||
|
||||
|
|
|
@ -123,6 +123,7 @@ typedef struct
|
|||
int color;
|
||||
} zpointdesc_t;
|
||||
|
||||
extern int d_framecount;
|
||||
extern int r_drawflat;
|
||||
extern int r_framecount; // sequence # of current frame since Quake
|
||||
// started
|
||||
|
|
|
@ -45,8 +45,6 @@ typedef enum {
|
|||
|
||||
struct entity_s;
|
||||
|
||||
void R_PushDlights (const vec3_t entorigin);
|
||||
void R_MaxDlightsCheck (int max_dlights);
|
||||
void R_Particles_Init_Cvars (void);
|
||||
void R_Particle_New (const char *type, int texnum, const vec3_t org,
|
||||
float scale, const vec3_t vel, float die, int color,
|
||||
|
|
|
@ -50,8 +50,19 @@ void R_RunParticles (float dT);
|
|||
struct scene_s;
|
||||
void R_NewScene (struct scene_s *scene);
|
||||
|
||||
typedef struct visstate_s {
|
||||
const struct mleaf_s *viewleaf;
|
||||
int *node_visframes;
|
||||
int *leaf_visframes;
|
||||
int *face_visframes;
|
||||
int visframecount;
|
||||
const struct mod_brush_s *brush;
|
||||
} visstate_t;
|
||||
|
||||
extern visstate_t r_visstate;//FIXME
|
||||
|
||||
// LordHavoc: relative bmodel lighting
|
||||
void R_PushDlights (const vec3_t entorigin);
|
||||
void R_PushDlights (const vec3_t entorigin, const visstate_t *visstate);
|
||||
void R_DrawWaterSurfaces (void);
|
||||
|
||||
void *D_SurfaceCacheAddress (void) __attribute__((pure));
|
||||
|
@ -65,10 +76,7 @@ void R_LoadSkys (const char *);
|
|||
|
||||
void R_ClearEfrags (void);
|
||||
|
||||
void R_FindNearLights (vec4f_t pos, int count, dlight_t **lights);
|
||||
dlight_t *R_AllocDlight (int key);
|
||||
void R_DecayLights (double frametime);
|
||||
void R_ClearDlights (void);
|
||||
int R_FindNearLights (vec4f_t pos, int count, dlight_t **lights);
|
||||
|
||||
int R_InitGraphTextures (int base);
|
||||
|
||||
|
@ -77,11 +85,9 @@ struct animation_s;
|
|||
struct transform_s;
|
||||
void R_DrawAliasModel (struct entity_s *e);
|
||||
|
||||
void R_MarkLeaves (struct mleaf_s *viewleaf, int *node_visframes,
|
||||
int *leaf_visframes, int *face_visframes);
|
||||
extern int *r_node_visframes;
|
||||
extern int *r_leaf_visframes;
|
||||
extern int *r_face_visframes;
|
||||
struct set_s;
|
||||
void R_MarkLeavesPVS (visstate_t *state, const struct set_s *pvs);
|
||||
void R_MarkLeaves (visstate_t *state, const struct mleaf_s *viewleaf);
|
||||
|
||||
void GL_SetPalette (void *data, const byte *palette);
|
||||
void GLSL_SetPalette (void *data, const byte *palette);
|
||||
|
|
|
@ -120,8 +120,6 @@ extern plane_t screenedge[4];
|
|||
|
||||
extern vec4f_t r_entorigin;
|
||||
|
||||
extern int r_visframecount;
|
||||
|
||||
//=============================================================================
|
||||
|
||||
extern int vstartscan;
|
||||
|
@ -310,7 +308,7 @@ void R_SetupFrame (void);
|
|||
void R_cshift_f (void);
|
||||
void R_EmitEdge (mvertex_t *pv0, mvertex_t *pv1);
|
||||
void R_ClipEdge (mvertex_t *pv0, mvertex_t *pv1, clipplane_t *clip);
|
||||
void R_RecursiveMarkLights (mod_brush_t *brush, vec4f_t lightorigin,
|
||||
void R_RecursiveMarkLights (const mod_brush_t *brush, vec4f_t lightorigin,
|
||||
struct dlight_s *light, int bit, int node_id);
|
||||
|
||||
void R_LoadSkys (const char *);
|
||||
|
|
|
@ -10,6 +10,7 @@ typedef struct vid_system_s {
|
|||
void (*set_palette) (byte *palette, byte *colormap);
|
||||
void (*init_cvars) (void);
|
||||
void (*update_fullscreen) (int fullscreen);
|
||||
void (*set_cursor) (bool visible);
|
||||
} vid_system_t;
|
||||
|
||||
extern vid_system_t vid_system;
|
||||
|
@ -37,7 +38,7 @@ extern int vid_system_gamma;
|
|||
extern float vid_gamma;
|
||||
|
||||
void VID_GetWindowSize (int def_w, int def_h);
|
||||
void VID_SetWindowSize (int width, int height);
|
||||
void VID_SetWindow (int x, int y, int width, int height);
|
||||
|
||||
void VID_InitGamma (const byte *);
|
||||
bool VID_SetGamma (double);
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include "QF/qtypes.h"
|
||||
#include "QF/simd/types.h"
|
||||
|
||||
#define VA_CTX_COUNT 64
|
||||
|
||||
typedef struct qfv_renderpassset_s
|
||||
DARRAY_TYPE (struct qfv_orenderpass_s *) qfv_renderpassset_t;
|
||||
|
||||
|
@ -38,6 +40,7 @@ typedef struct vulkan_ctx_s {
|
|||
struct scriptctx_s *script_context;
|
||||
struct qfv_renderctx_s *render_context;
|
||||
struct qfv_capturectx_s *capture_context;
|
||||
struct qfv_mousepickctx_s *mousepick_context;
|
||||
struct texturectx_s *texture_context;
|
||||
struct matrixctx_s *matrix_context;
|
||||
struct translucentctx_s *translucent_context;
|
||||
|
@ -47,6 +50,7 @@ typedef struct vulkan_ctx_s {
|
|||
struct scenectx_s *scene_context;
|
||||
struct palettectx_s *palette_context;
|
||||
struct particlectx_s *particle_context;
|
||||
struct planesctx_s *planes_context;
|
||||
struct spritectx_s *sprite_context;
|
||||
struct drawctx_s *draw_context;
|
||||
struct lightingctx_s *lighting_context;
|
||||
|
|
|
@ -38,10 +38,12 @@
|
|||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#include "QF/ecs.h"
|
||||
#include "QF/render.h"
|
||||
|
||||
#include "QF/plugin/vid_render.h" //FIXME
|
||||
#include "QF/scene/entity.h"
|
||||
#include "QF/scene/light.h"
|
||||
#include "QF/scene/scene.h"
|
||||
|
||||
#include "client/entities.h"
|
||||
|
@ -49,16 +51,61 @@
|
|||
#include "client/particles.h"
|
||||
#include "client/world.h"
|
||||
|
||||
ecs_system_t effect_system;
|
||||
|
||||
const component_t effect_components[effect_comp_count] = {
|
||||
[effect_light] = {
|
||||
.size = sizeof (uint32_t),
|
||||
.name = "effect light",
|
||||
},
|
||||
[effect_muzzleflash] = {
|
||||
.size = sizeof (uint32_t),
|
||||
.name = "muzzle flash",
|
||||
},
|
||||
};
|
||||
|
||||
#define c_light (effect_system.base + effect_light)
|
||||
|
||||
static bool
|
||||
has_light (entity_t ent)
|
||||
{
|
||||
return Ent_HasComponent (ent.id, c_light, ent.reg);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
get_light (entity_t ent)
|
||||
{
|
||||
return *(uint32_t *) Ent_GetComponent (ent.id, c_light, ent.reg);
|
||||
}
|
||||
|
||||
static void
|
||||
set_light (entity_t ent, uint32_t light)
|
||||
{
|
||||
Ent_SetComponent (ent.id, c_light, ent.reg, &light);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
attach_light_ent (entity_t ent)
|
||||
{
|
||||
uint32_t light = nullent;
|
||||
if (has_light (ent)) {
|
||||
light = get_light (ent);
|
||||
}
|
||||
if (!ECS_EntValid (light, ent.reg)) {
|
||||
light = ECS_NewEntity (ent.reg);
|
||||
set_light (ent, light);
|
||||
}
|
||||
return light;
|
||||
}
|
||||
|
||||
void
|
||||
CL_NewDlight (int key, vec4f_t org, int effects, byte glow_size,
|
||||
CL_NewDlight (entity_t ent, vec4f_t org, int effects, byte glow_size,
|
||||
byte glow_color, double time)
|
||||
{
|
||||
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};
|
||||
static quat_t blue = {0.05, 0.05, 0.5, 0.7};
|
||||
static quat_t purple = {0.5, 0.05, 0.5, 0.7};
|
||||
static vec4f_t normal = {0.4, 0.2, 0.05, 0.7};
|
||||
static vec4f_t red = {0.5, 0.05, 0.05, 0.7};
|
||||
static vec4f_t blue = {0.05, 0.05, 0.5, 0.7};
|
||||
static vec4f_t purple = {0.5, 0.05, 0.5, 0.7};
|
||||
|
||||
effects &= EF_BLUE | EF_RED | EF_BRIGHTLIGHT | EF_DIMLIGHT;
|
||||
if (!effects) {
|
||||
|
@ -66,60 +113,56 @@ CL_NewDlight (int key, vec4f_t org, int effects, byte glow_size,
|
|||
return;
|
||||
}
|
||||
|
||||
dl = R_AllocDlight (key);
|
||||
if (!dl)
|
||||
return;
|
||||
VectorCopy (org, dl->origin);
|
||||
float radius = 0;
|
||||
float die = time + 0.1;
|
||||
vec4f_t color = normal;
|
||||
|
||||
if (effects & (EF_BLUE | EF_RED | EF_BRIGHTLIGHT | EF_DIMLIGHT)) {
|
||||
radius = 200 + (rand () & 31);
|
||||
if (effects & EF_BRIGHTLIGHT) {
|
||||
radius += 200;
|
||||
dl->origin[2] += 16;
|
||||
org[2] += 16;
|
||||
}
|
||||
if (effects & EF_DIMLIGHT)
|
||||
if (effects & ~EF_DIMLIGHT)
|
||||
radius -= 100;
|
||||
dl->radius = radius;
|
||||
dl->die = time + 0.1;
|
||||
|
||||
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;
|
||||
case EF_RED | EF_BLUE: color = purple; break;
|
||||
case EF_RED: color = red; break;
|
||||
case EF_BLUE: color = blue; break;
|
||||
default: color = normal; break;
|
||||
}
|
||||
}
|
||||
|
||||
if (glow_size) {
|
||||
dl->radius += glow_size < 128 ? glow_size * 8.0 :
|
||||
(glow_size - 256) * 8.0;
|
||||
dl->die = time + 0.1;
|
||||
radius += glow_size < 128 ? glow_size * 8.0 : (glow_size - 256) * 8.0;
|
||||
if (glow_color) {
|
||||
if (glow_color == 255) {
|
||||
dl->color[0] = dl->color[1] = dl->color[2] = 1.0;
|
||||
color = (vec4f_t) { 1, 1, 1, 0.7 };
|
||||
} else {
|
||||
byte *tempcolor;
|
||||
|
||||
tempcolor = (byte *) &d_8to24table[glow_color];
|
||||
VectorScale (tempcolor, 1 / 255.0, dl->color);
|
||||
VectorScale (tempcolor, 1 / 255.0, color);
|
||||
color[3] = 0.7;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t light = attach_light_ent (ent);
|
||||
Ent_SetComponent (light, scene_dynlight, ent.reg, &(dlight_t) {
|
||||
.origin = org,
|
||||
.color = color,
|
||||
.radius = radius,
|
||||
.die = die,
|
||||
});
|
||||
Light_LinkLight (cl_world.scene->lights, light);
|
||||
}
|
||||
|
||||
void
|
||||
CL_ModelEffects (entity_t ent, int num, int glow_color, double time)
|
||||
CL_ModelEffects (entity_t ent, int glow_color, double time)
|
||||
{
|
||||
dlight_t *dl;
|
||||
transform_t transform = Entity_Transform (ent);
|
||||
renderer_t *renderer = Ent_GetComponent (ent.id, scene_renderer, cl_world.scene->reg);
|
||||
model_t *model = renderer->model;
|
||||
|
@ -127,54 +170,36 @@ CL_ModelEffects (entity_t ent, int num, int glow_color, double time)
|
|||
vec4f_t ent_origin = Transform_GetWorldPosition (transform);
|
||||
|
||||
// add automatic particle trails
|
||||
if (model->flags & EF_ROCKET) {
|
||||
dl = R_AllocDlight (num);
|
||||
if (dl) {
|
||||
VectorCopy (ent_origin, dl->origin);
|
||||
dl->radius = 200.0;
|
||||
dl->die = time + 0.1;
|
||||
if (model->effects & ME_ROCKET) {
|
||||
uint32_t light = attach_light_ent (ent);
|
||||
Ent_SetComponent (light, scene_dynlight, ent.reg, &(dlight_t) {
|
||||
.origin = ent_origin,
|
||||
//FIXME VectorCopy (r_firecolor, dl->color);
|
||||
VectorSet (0.9, 0.7, 0.0, dl->color);
|
||||
dl->color[3] = 0.7;
|
||||
}
|
||||
.color = { 0.9, 0.7, 0.0, 0.7 },
|
||||
.radius = 200,
|
||||
.die = time + 0.1,
|
||||
});
|
||||
Light_LinkLight (cl_world.scene->lights, light);
|
||||
clp_funcs->RocketTrail (*old_origin, ent_origin);
|
||||
} else if (model->flags & EF_GRENADE)
|
||||
renderer->noshadows = 1;
|
||||
} else if (model->effects & ME_GRENADE)
|
||||
clp_funcs->GrenadeTrail (*old_origin, ent_origin);
|
||||
else if (model->flags & EF_GIB)
|
||||
else if (model->effects & ME_GIB)
|
||||
clp_funcs->BloodTrail (*old_origin, ent_origin);
|
||||
else if (model->flags & EF_ZOMGIB)
|
||||
else if (model->effects & ME_ZOMGIB)
|
||||
clp_funcs->SlightBloodTrail (*old_origin, ent_origin);
|
||||
else if (model->flags & EF_TRACER)
|
||||
else if (model->effects & ME_TRACER)
|
||||
clp_funcs->WizTrail (*old_origin, ent_origin);
|
||||
else if (model->flags & EF_TRACER2)
|
||||
else if (model->effects & ME_TRACER2)
|
||||
clp_funcs->FlameTrail (*old_origin, ent_origin);
|
||||
else if (model->flags & EF_TRACER3)
|
||||
else if (model->effects & ME_TRACER3)
|
||||
clp_funcs->VoorTrail (*old_origin, ent_origin);
|
||||
else if (model->flags & EF_GLOWTRAIL)
|
||||
else if (model->effects & ME_GLOWTRAIL)
|
||||
clp_funcs->GlowTrail (*old_origin, ent_origin, glow_color);
|
||||
}
|
||||
|
||||
void
|
||||
CL_MuzzleFlash (vec4f_t position, vec4f_t fv, float zoffset, int num,
|
||||
double time)
|
||||
{
|
||||
dlight_t *dl = R_AllocDlight (num);
|
||||
if (dl) {
|
||||
position += 18 * fv;
|
||||
VectorCopy (position, dl->origin);
|
||||
dl->origin[2] += zoffset;
|
||||
dl->radius = 200 + (rand () & 31);
|
||||
dl->die = 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;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CL_EntityEffects (int num, entity_t ent, entity_state_t *state, double time)
|
||||
CL_EntityEffects (entity_t ent, entity_state_t *state, double time)
|
||||
{
|
||||
transform_t transform = Entity_Transform (ent);
|
||||
vec4f_t position = Transform_GetWorldPosition (transform);
|
||||
|
@ -182,6 +207,6 @@ CL_EntityEffects (int num, entity_t ent, entity_state_t *state, double time)
|
|||
clp_funcs->EntityParticles (position);
|
||||
if (state->effects & EF_MUZZLEFLASH) {
|
||||
vec4f_t fv = Transform_Forward (transform);
|
||||
CL_MuzzleFlash (position, fv, 16, num, time);
|
||||
CL_MuzzleFlash (ent, position, fv, 16, time);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ in_axis_t in_move_side = {
|
|||
in_axis_t in_move_up = {
|
||||
.mode = ina_set,
|
||||
.name = "move.up",
|
||||
.description = "Move up (positive) or down (negative)",
|
||||
.description = "Move up (negative) or down (positive)",
|
||||
};
|
||||
|
||||
in_axis_t in_cam_forward = {
|
||||
|
@ -581,7 +581,7 @@ static int
|
|||
cl_key_event (const IE_event_t *ie_event)
|
||||
{
|
||||
if (ie_event->key.code == QFK_ESCAPE) {
|
||||
Con_SetState (con_menu);
|
||||
Con_SetState (con_menu, true);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include "QF/plist.h"
|
||||
#include "QF/progs.h" //for ED_ConvertToPlist
|
||||
#include "QF/set.h"
|
||||
#include "QF/ecs.h"
|
||||
#include "QF/scene/entity.h"
|
||||
#include "QF/scene/light.h"
|
||||
#include "QF/scene/scene.h"
|
||||
#include "QF/simd/vec4f.h"
|
||||
|
@ -17,8 +19,12 @@
|
|||
#include "client/world.h"
|
||||
|
||||
static void
|
||||
dump_light (light_t *light, int leaf)
|
||||
dump_light (light_t *light, efrag_t *efrags)
|
||||
{
|
||||
int leafcount = 0;
|
||||
for (auto e = efrags; e; e = e->leafnext) {
|
||||
leafcount++;
|
||||
}
|
||||
Sys_MaskPrintf (SYS_lighting,
|
||||
"[%g, %g, %g] %g, "
|
||||
"[%g, %g, %g, %g], [%g %g %g] %g, [%g, %g, %g, %g] %d\n",
|
||||
|
@ -26,7 +32,7 @@ dump_light (light_t *light, int leaf)
|
|||
VEC4_EXP (light->position),
|
||||
VEC4_EXP (light->direction),
|
||||
VEC4_EXP (light->attenuation),
|
||||
leaf);
|
||||
leafcount);
|
||||
}
|
||||
|
||||
static float
|
||||
|
@ -323,8 +329,12 @@ CL_LoadLights (plitem_t *entities, scene_t *scene)
|
|||
}
|
||||
PL_Release (targets);
|
||||
|
||||
for (size_t i = 0; i < ldata->lights.size; i++) {
|
||||
dump_light (&ldata->lights.a[i], ldata->lightleafs.a[i]);
|
||||
auto lights = &scene->reg->comp_pools[scene_light];
|
||||
auto lefrags = &scene->reg->comp_pools[scene_efrags];
|
||||
for (uint32_t i = 0; i < lights->count; i++) {
|
||||
auto light = &((light_t *)lights->data)[i];
|
||||
auto efrags = ((efrag_t **)lefrags->data)[i];
|
||||
dump_light (light, efrags);
|
||||
}
|
||||
Sys_MaskPrintf (SYS_lighting, "loaded %zd lights\n", ldata->lights.size);
|
||||
Sys_MaskPrintf (SYS_lighting, "loaded %d lights\n", lights->count);
|
||||
}
|
||||
|
|
|
@ -99,13 +99,59 @@ static view_t loading_view;
|
|||
static view_t ram_view;
|
||||
static view_t turtle_view;
|
||||
static view_t pause_view;
|
||||
static view_t crosshair_view;
|
||||
static view_t cshift_view;
|
||||
static view_t centerprint_view;
|
||||
|
||||
static viewstate_t *_vs;//FIXME ick
|
||||
|
||||
canvas_system_t cl_canvas_sys;
|
||||
|
||||
static ecs_system_t cl_view_system;
|
||||
|
||||
static view_t
|
||||
clscr_view (int x, int y, int w, int h, grav_t gravity)
|
||||
{
|
||||
auto view = View_New (cl_view_system, cl_screen_view);
|
||||
View_SetPos (view, x, y);
|
||||
View_SetLen (view, w, h);
|
||||
View_SetGravity (view, gravity);
|
||||
View_SetVisible (view, 0);
|
||||
return view;
|
||||
}
|
||||
|
||||
static void
|
||||
SCR_CShift (void)
|
||||
clscr_set_pic (view_t view, qpic_t *pic)
|
||||
{
|
||||
Ent_SetComponent (view.id, canvas_pic, view.reg, &pic);
|
||||
}
|
||||
|
||||
static void
|
||||
clscr_set_cachepic (view_t view, const char *name)
|
||||
{
|
||||
Ent_SetComponent (view.id, canvas_cachepic, view.reg, &name);
|
||||
}
|
||||
|
||||
static void
|
||||
clscr_set_canvas_func (view_t view, canvas_func_f func)
|
||||
{
|
||||
Ent_SetComponent (view.id, canvas_func, view.reg, &func);
|
||||
}
|
||||
|
||||
static void
|
||||
cl_draw_crosshair (view_pos_t abs, view_pos_t len)
|
||||
{
|
||||
r_funcs->Draw_Crosshair ();
|
||||
}
|
||||
|
||||
static void
|
||||
cl_draw_centerprint (view_pos_t abs, view_pos_t len)
|
||||
{
|
||||
Sbar_DrawCenterPrint ();
|
||||
}
|
||||
|
||||
static void
|
||||
SCR_CShift (view_pos_t abs, view_pos_t len)
|
||||
{
|
||||
mleaf_t *leaf;
|
||||
int contents = CONTENTS_EMPTY;
|
||||
|
@ -113,7 +159,7 @@ SCR_CShift (void)
|
|||
if (_vs->active && cl_world.scene->worldmodel) {
|
||||
vec4f_t origin;
|
||||
origin = Transform_GetWorldPosition (_vs->camera_transform);
|
||||
leaf = Mod_PointInLeaf (origin, cl_world.scene->worldmodel);
|
||||
leaf = Mod_PointInLeaf (origin, &cl_world.scene->worldmodel->brush);
|
||||
contents = leaf->contents;
|
||||
}
|
||||
V_SetContentsColor (_vs, contents);
|
||||
|
@ -140,17 +186,13 @@ scr_draw_views (void)
|
|||
double msg_time = _vs->realtime - _vs->last_servermessage;
|
||||
View_SetVisible (net_view, (!_vs->demoplayback && msg_time >= 0.3));
|
||||
View_SetVisible (loading_view, _vs->loading);
|
||||
View_SetVisible (crosshair_view, !_vs->intermission);
|
||||
// FIXME cvar callbacks
|
||||
View_SetVisible (timegraph_view, r_timegraph);
|
||||
View_SetVisible (zgraph_view, r_zgraph);
|
||||
|
||||
if (!_vs->intermission) {
|
||||
r_funcs->Draw_Crosshair ();//FIXME canvas_func
|
||||
}
|
||||
Con_DrawConsole ();
|
||||
Canvas_Draw (cl_canvas_sys);
|
||||
SCR_CShift ();//FIXME canvas_func
|
||||
Sbar_DrawCenterPrint ();//FIXME canvas_func
|
||||
}
|
||||
|
||||
static SCR_Func scr_funcs[] = {
|
||||
|
@ -167,10 +209,9 @@ cl_set_size (void)
|
|||
{
|
||||
int xlen = cl_xlen / cl_scale;
|
||||
int ylen = cl_ylen / cl_scale;
|
||||
printf ("cl_set_size: %d %d %d\n", cl_scale, xlen, ylen);
|
||||
//View_SetLen (cl_screen_view, xlen, ylen);
|
||||
//View_UpdateHierarchy (cl_screen_view);
|
||||
Canvas_SetLen (cl_canvas_sys, (view_pos_t) { xlen, ylen });
|
||||
//printf ("cl_set_size: %d %d %d\n", cl_scale, xlen, ylen);
|
||||
Canvas_SetLen (cl_canvas_sys, cl_canvas, (view_pos_t) { xlen, ylen });
|
||||
Canvas_SetLen (cl_canvas_sys, hud_canvas, (view_pos_t) { xlen, ylen });
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -188,11 +229,58 @@ cl_vidsize_listener (void *data, const viddef_t *vdef)
|
|||
cl_set_size ();
|
||||
}
|
||||
|
||||
static void
|
||||
cl_create_views (void)
|
||||
{
|
||||
qpic_t *pic;
|
||||
const char *name;
|
||||
auto vid = r_data->vid;
|
||||
|
||||
pic = r_funcs->Draw_PicFromWad ("ram");
|
||||
ram_view = clscr_view (32, 0, pic->width, pic->height, grav_northwest);
|
||||
clscr_set_pic (ram_view, pic);
|
||||
|
||||
pic = r_funcs->Draw_PicFromWad ("turtle");
|
||||
turtle_view = clscr_view (32, 0, pic->width, pic->height, grav_northwest);
|
||||
clscr_set_pic (turtle_view, pic);
|
||||
|
||||
pic = r_funcs->Draw_PicFromWad ("net");
|
||||
net_view = clscr_view (64, 0, pic->width, pic->height, grav_northwest);
|
||||
clscr_set_pic (net_view, pic);
|
||||
|
||||
timegraph_view = clscr_view (0, 0, vid->width, 100, grav_southwest);
|
||||
clscr_set_canvas_func (timegraph_view, R_TimeGraph);
|
||||
View_SetVisible (timegraph_view, r_timegraph);
|
||||
|
||||
zgraph_view = clscr_view (0, 0, vid->width, 100, grav_southwest);
|
||||
clscr_set_canvas_func (zgraph_view, R_ZGraph);
|
||||
View_SetVisible (zgraph_view, r_zgraph);
|
||||
|
||||
name = "gfx/loading.lmp";
|
||||
pic = r_funcs->Draw_CachePic (name, 1);
|
||||
loading_view = clscr_view (0, -24, pic->width, pic->height, grav_center);
|
||||
clscr_set_cachepic (loading_view, name);
|
||||
|
||||
name = "gfx/pause.lmp";
|
||||
pic = r_funcs->Draw_CachePic (name, 1);
|
||||
pause_view = clscr_view (0, -24, pic->width, pic->height, grav_center);
|
||||
clscr_set_cachepic (pause_view, name);
|
||||
|
||||
crosshair_view = clscr_view (0, 0, vid->width, vid->height, grav_northwest);
|
||||
clscr_set_canvas_func (crosshair_view, cl_draw_crosshair);
|
||||
|
||||
cshift_view = clscr_view (0, 0, vid->width, vid->height, grav_northwest);
|
||||
clscr_set_canvas_func (cshift_view, SCR_CShift);
|
||||
View_SetVisible (cshift_view, 1);
|
||||
|
||||
centerprint_view = clscr_view (0, 0, vid->width, vid->height,
|
||||
grav_northwest);
|
||||
clscr_set_canvas_func (centerprint_view, cl_draw_centerprint);
|
||||
}
|
||||
|
||||
void
|
||||
CL_Init_Screen (void)
|
||||
{
|
||||
qpic_t *pic;
|
||||
|
||||
__auto_type reg = ECS_NewRegistry ();
|
||||
Canvas_InitSys (&cl_canvas_sys, reg);
|
||||
if (con_module) {
|
||||
|
@ -207,7 +295,7 @@ CL_Init_Screen (void)
|
|||
cl_xlen = viddef.width;
|
||||
cl_ylen = viddef.height;
|
||||
|
||||
ecs_system_t vsys = {
|
||||
cl_view_system = (ecs_system_t) {
|
||||
.reg = reg,
|
||||
.base = cl_canvas_sys.view_base,
|
||||
};
|
||||
|
@ -222,68 +310,11 @@ CL_Init_Screen (void)
|
|||
View_SetGravity (cl_screen_view, grav_northwest);
|
||||
View_SetVisible (cl_screen_view, 1);
|
||||
|
||||
pic = r_funcs->Draw_PicFromWad ("ram");
|
||||
ram_view = View_New (vsys, cl_screen_view);
|
||||
View_SetPos (ram_view, 32, 0);
|
||||
View_SetLen (ram_view, pic->width, pic->height);
|
||||
View_SetGravity (ram_view, grav_northwest);
|
||||
Ent_SetComponent (ram_view.id, canvas_pic, ram_view.reg, &pic);
|
||||
View_SetVisible (ram_view, 0);
|
||||
|
||||
pic = r_funcs->Draw_PicFromWad ("turtle");
|
||||
turtle_view = View_New (vsys, cl_screen_view);
|
||||
View_SetPos (turtle_view, 32, 0);
|
||||
View_SetLen (turtle_view, pic->width, pic->height);
|
||||
View_SetGravity (turtle_view, grav_northwest);
|
||||
Ent_SetComponent (turtle_view.id, canvas_pic, turtle_view.reg, &pic);
|
||||
View_SetVisible (turtle_view, 0);
|
||||
|
||||
Cvar_Register (&scr_showpause_cvar, 0, 0);
|
||||
Cvar_Register (&scr_showram_cvar, 0, 0);
|
||||
Cvar_Register (&scr_showturtle_cvar, 0, 0);
|
||||
|
||||
pic = r_funcs->Draw_PicFromWad ("net");
|
||||
net_view = View_New (vsys, cl_screen_view);
|
||||
View_SetPos (net_view, 64, 0);
|
||||
View_SetLen (net_view, pic->width, pic->height);
|
||||
View_SetGravity (net_view, grav_northwest);
|
||||
Ent_SetComponent (net_view.id, canvas_pic, net_view.reg, &pic);
|
||||
View_SetVisible (net_view, 0);
|
||||
|
||||
timegraph_view = View_New (vsys, cl_screen_view);
|
||||
View_SetPos (timegraph_view, 0, 0);
|
||||
View_SetLen (timegraph_view, r_data->vid->width, 100);
|
||||
View_SetGravity (timegraph_view, grav_southwest);
|
||||
void *rtg = R_TimeGraph;
|
||||
Ent_SetComponent (timegraph_view.id, canvas_func, timegraph_view.reg, &rtg);
|
||||
View_SetVisible (timegraph_view, r_timegraph);
|
||||
|
||||
zgraph_view = View_New (vsys, cl_screen_view);
|
||||
View_SetPos (zgraph_view, 0, 0);
|
||||
View_SetLen (zgraph_view, r_data->vid->width, 100);
|
||||
View_SetGravity (zgraph_view, grav_southwest);
|
||||
void *rzg = R_ZGraph;
|
||||
Ent_SetComponent (zgraph_view.id, canvas_func, zgraph_view.reg, &rzg);
|
||||
View_SetVisible (zgraph_view, r_zgraph);
|
||||
|
||||
const char *name = "gfx/loading.lmp";
|
||||
pic = r_funcs->Draw_CachePic (name, 1);
|
||||
loading_view = View_New (vsys, cl_screen_view);
|
||||
View_SetPos (loading_view, 0, -24);
|
||||
View_SetLen (loading_view, pic->width, pic->height);
|
||||
View_SetGravity (loading_view, grav_center);
|
||||
Ent_SetComponent (loading_view.id, canvas_cachepic,
|
||||
loading_view.reg, &name);
|
||||
View_SetVisible (loading_view, 0);
|
||||
|
||||
name = "gfx/pause.lmp";
|
||||
pic = r_funcs->Draw_CachePic (name, 1);
|
||||
pause_view = View_New (vsys, cl_screen_view);
|
||||
View_SetPos (pause_view, 0, -24);
|
||||
View_SetLen (pause_view, pic->width, pic->height);
|
||||
View_SetGravity (pause_view, grav_center);
|
||||
Ent_SetComponent (pause_view.id, canvas_cachepic, pause_view.reg, &name);
|
||||
View_SetVisible (pause_view, 0);
|
||||
cl_create_views ();
|
||||
|
||||
cvar_t *con_scale = Cvar_FindVar ("con_scale");
|
||||
Cvar_AddListener (con_scale, cl_scale_listener, 0);
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#include "QF/darray.h"
|
||||
#include "QF/msg.h"
|
||||
#include "QF/progs.h" // for PR_RESMAP
|
||||
#include "QF/quakefs.h"
|
||||
|
@ -47,6 +48,7 @@
|
|||
#include "QF/plugin/vid_render.h" //FIXME
|
||||
//
|
||||
#include "QF/scene/entity.h"
|
||||
#include "QF/scene/light.h"
|
||||
#include "QF/scene/scene.h"
|
||||
|
||||
#include "client/effects.h"
|
||||
|
@ -325,15 +327,55 @@ CL_ParseBeam (qmsg_t *net_message, model_t *m, double time, TEntContext_t *ctx)
|
|||
}
|
||||
}
|
||||
|
||||
typedef struct tempent_s DARRAY_TYPE (entity_t) tempent_t;
|
||||
static tempent_t light_entities = DARRAY_STATIC_INIT (32);
|
||||
|
||||
static void
|
||||
free_stale_entities (void)
|
||||
{
|
||||
size_t i, j;
|
||||
for (i = 0, j = 0; i < light_entities.size; i++) {
|
||||
auto ent = light_entities.a[i];
|
||||
if (Ent_HasComponent (ent.id, scene_dynlight, ent.reg)) {
|
||||
if (j != i) {
|
||||
light_entities.a[j] = ent;
|
||||
}
|
||||
j++;
|
||||
} else {
|
||||
ECS_DelEntity (ent.reg, ent.id);
|
||||
}
|
||||
}
|
||||
light_entities.size = j;
|
||||
}
|
||||
|
||||
static void
|
||||
spawn_light (vec4f_t position, vec4f_t color, float radius, float die,
|
||||
float decay)
|
||||
{
|
||||
entity_t ent = {
|
||||
.reg = cl_world.scene->reg,
|
||||
.id = ECS_NewEntity (cl_world.scene->reg),
|
||||
};
|
||||
DARRAY_APPEND (&light_entities, ent);
|
||||
|
||||
Ent_SetComponent (ent.id, scene_dynlight, ent.reg, &(dlight_t) {
|
||||
.origin = position,
|
||||
.color = color,
|
||||
.radius = radius,
|
||||
.die = die,
|
||||
.decay = decay,
|
||||
});
|
||||
Light_LinkLight (cl_world.scene->lights, ent.id);
|
||||
}
|
||||
|
||||
static void
|
||||
parse_tent (qmsg_t *net_message, double time, TEntContext_t *ctx,
|
||||
TE_Effect type)
|
||||
{
|
||||
dlight_t *dl;
|
||||
tent_obj_t *to;
|
||||
explosion_t *ex;
|
||||
int colorStart, colorLength;
|
||||
quat_t color;
|
||||
vec4f_t color;
|
||||
vec4f_t position = {0, 0, 0, 1};
|
||||
int count;
|
||||
const char *name;
|
||||
|
@ -369,23 +411,16 @@ parse_tent (qmsg_t *net_message, double time, TEntContext_t *ctx,
|
|||
renderer_t *renderer = Ent_GetComponent (ex->tent->ent.id, scene_renderer, cl_world.scene->reg);
|
||||
renderer->model = cl_spr_explod;
|
||||
Transform_SetLocalPosition (transform, position);
|
||||
color = (vec4f_t) {0.86, 0.31, 0.24, 0.7};
|
||||
goto TE_Explosion_no_sprite;
|
||||
case TE_Explosion:
|
||||
MSG_ReadCoordV (net_message, (vec_t*)&position);//FIXME
|
||||
color = (vec4f_t) {1.0, 0.5, 0.25, 0.7};
|
||||
TE_Explosion_no_sprite:
|
||||
// particles
|
||||
clp_funcs->ParticleExplosion (position);
|
||||
|
||||
// light
|
||||
dl = R_AllocDlight (0);
|
||||
if (dl) {
|
||||
VectorCopy (position, dl->origin);
|
||||
dl->radius = 350;
|
||||
dl->die = time + 0.5;
|
||||
dl->decay = 300;
|
||||
QuatSet (0.86, 0.31, 0.24, 0.7, dl->color);
|
||||
//FIXME? nq: QuatSet (1.0, 0.5, 0.25, 0.7, dl->color);
|
||||
}
|
||||
spawn_light (position, color, 250, time + 0.5, 300);
|
||||
|
||||
// sound
|
||||
S_StartSound (-1, 0, cl_sfx_r_exp3, position, 1, 1);
|
||||
|
@ -396,32 +431,20 @@ TE_Explosion_no_sprite:
|
|||
colorLength = MSG_ReadByte (net_message);
|
||||
S_StartSound (-1, 0, cl_sfx_r_exp3, position, 1, 1);
|
||||
clp_funcs->ParticleExplosion2 (position, colorStart, colorLength);
|
||||
dl = R_AllocDlight (0);
|
||||
if (!dl)
|
||||
break;
|
||||
VectorCopy (position, dl->origin);
|
||||
dl->radius = 350;
|
||||
dl->die = time + 0.5;
|
||||
dl->decay = 300;
|
||||
|
||||
colorStart = (colorStart + (rand () % colorLength)) * 3;
|
||||
VectorScale (&r_data->vid->palette[colorStart], 1.0 / 255.0,
|
||||
dl->color);
|
||||
dl->color[3] = 0.7;
|
||||
VectorScale (&r_data->vid->palette[colorStart], 1.0 / 255.0, color);
|
||||
color[3] = 0.7;
|
||||
spawn_light (position, color, 350, time + 0.5, 300);
|
||||
break;
|
||||
case TE_Explosion3:
|
||||
MSG_ReadCoordV (net_message, (vec_t*)&position);//FIXME
|
||||
MSG_ReadCoordV (net_message, color); // OUCH!
|
||||
MSG_ReadCoordV (net_message, (vec_t*)&color); //FIXME OUCH!
|
||||
color[3] = 0.7;
|
||||
clp_funcs->ParticleExplosion (position);
|
||||
S_StartSound (-1, 0, cl_sfx_r_exp3, position, 1, 1);
|
||||
dl = R_AllocDlight (0);
|
||||
if (dl) {
|
||||
VectorCopy (position, dl->origin);
|
||||
dl->radius = 350;
|
||||
dl->die = time + 0.5;
|
||||
dl->decay = 300;
|
||||
QuatCopy (color, dl->color);
|
||||
}
|
||||
|
||||
spawn_light (position, color, 350, time + 0.5, 300);
|
||||
break;
|
||||
case TE_Gunshot1:
|
||||
MSG_ReadCoordV (net_message, (vec_t*)&position);//FIXME
|
||||
|
@ -457,15 +480,8 @@ TE_Explosion_no_sprite:
|
|||
case TE_LightningBlood:
|
||||
MSG_ReadCoordV (net_message, (vec_t*)&position);//FIXME
|
||||
|
||||
// light
|
||||
dl = R_AllocDlight (0);
|
||||
if (dl) {
|
||||
VectorCopy (position, dl->origin);
|
||||
dl->radius = 150;
|
||||
dl->die = time + 0.1;
|
||||
dl->decay = 200;
|
||||
QuatSet (0.25, 0.40, 0.65, 1, dl->color);
|
||||
}
|
||||
color = (vec4f_t) {0.25, 0.40, 0.65, 1};
|
||||
spawn_light (position, color, 150, time + 0.1, 200);
|
||||
|
||||
clp_funcs->LightningBloodEffect (position);
|
||||
break;
|
||||
|
@ -650,6 +666,7 @@ CL_UpdateExplosions (double time, TEntContext_t *ctx)
|
|||
void
|
||||
CL_UpdateTEnts (double time, TEntContext_t *ctx)
|
||||
{
|
||||
free_stale_entities ();
|
||||
CL_UpdateBeams (time, ctx);
|
||||
CL_UpdateExplosions (time, ctx);
|
||||
}
|
||||
|
@ -732,3 +749,48 @@ CL_ParseProjectiles (qmsg_t *net_message, bool nail2, TEntContext_t *ctx)
|
|||
*tail = cl_projectiles;
|
||||
cl_projectiles = head;
|
||||
}
|
||||
|
||||
#define c_muzzleflash (effect_system.base + effect_muzzleflash)
|
||||
|
||||
static bool
|
||||
has_muzzleflash (entity_t ent)
|
||||
{
|
||||
return Ent_HasComponent (ent.id, c_muzzleflash, ent.reg);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
get_muzzleflash (entity_t ent)
|
||||
{
|
||||
return *(uint32_t *) Ent_GetComponent (ent.id, c_muzzleflash, ent.reg);
|
||||
}
|
||||
|
||||
static void
|
||||
set_muzzleflash (entity_t ent, uint32_t light)
|
||||
{
|
||||
Ent_SetComponent (ent.id, c_muzzleflash, ent.reg, &light);
|
||||
}
|
||||
|
||||
void
|
||||
CL_MuzzleFlash (entity_t ent, vec4f_t position, vec4f_t fv, float zoffset,
|
||||
double time)
|
||||
{
|
||||
// spawn a new entity so the light doesn't mess with the owner
|
||||
uint32_t light = nullent;
|
||||
if (has_muzzleflash (ent)) {
|
||||
light = get_muzzleflash (ent);
|
||||
}
|
||||
if (!ECS_EntValid (light, ent.reg)) {
|
||||
light = ECS_NewEntity (ent.reg);
|
||||
set_muzzleflash (ent, light);
|
||||
}
|
||||
DARRAY_APPEND (&light_entities, ((entity_t) {.reg = ent.reg, .id = light}));
|
||||
|
||||
Ent_SetComponent (light, scene_dynlight, ent.reg, &(dlight_t) {
|
||||
.origin = position + 18 * fv + zoffset * (vec4f_t) {0, 0, 1, 0},
|
||||
.color = { 0.2, 0.1, 0.05, 0.7 },
|
||||
.radius = 200 + (rand () & 31),
|
||||
.die = time + 0.1,
|
||||
.minlight = 32,
|
||||
});
|
||||
Light_LinkLight (cl_world.scene->lights, light);
|
||||
}
|
||||
|
|
|
@ -932,9 +932,11 @@ void
|
|||
V_RenderView (viewstate_t *vs)
|
||||
{
|
||||
if (!vs->active) {
|
||||
vec4f_t base = { 0, 0, 0, 1 };
|
||||
Transform_SetWorldPosition (vs->camera_transform, base);
|
||||
Transform_SetWorldRotation (vs->camera_transform, base);
|
||||
if (Transform_Valid (vs->camera_transform)) {
|
||||
vec4f_t base = { 0, 0, 0, 1 };
|
||||
Transform_SetWorldPosition (vs->camera_transform, base);
|
||||
Transform_SetWorldRotation (vs->camera_transform, base);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -952,6 +954,13 @@ V_RenderView (viewstate_t *vs)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
V_NewScene (viewstate_t *viewstate, scene_t *scene)
|
||||
{
|
||||
viewstate->camera_transform = Transform_New (cl_world.scene->reg,
|
||||
nulltransform);
|
||||
}
|
||||
|
||||
void
|
||||
V_Init (viewstate_t *viewstate)
|
||||
{
|
||||
|
@ -965,9 +974,6 @@ V_Init (viewstate_t *viewstate)
|
|||
"currently being displayed.\n"
|
||||
"Used when you are underwater, hit, have the Ring of "
|
||||
"Shadows, or Quad Damage. (v_cshift r g b intensity)");
|
||||
|
||||
viewstate->camera_transform = Transform_New (cl_world.scene->reg,
|
||||
nulltransform);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -43,16 +43,12 @@
|
|||
#include "QF/idparse.h"
|
||||
#include "QF/quakefs.h"
|
||||
#include "QF/plist.h"
|
||||
#include "QF/progs.h"
|
||||
#include "QF/msg.h"
|
||||
|
||||
#include "QF/scene/entity.h"
|
||||
#include "QF/scene/light.h"
|
||||
#include "QF/scene/scene.h"
|
||||
#include "QF/simd/vec4f.h"
|
||||
|
||||
#include "QF/plugin/vid_render.h" //FIXME
|
||||
|
||||
#include "client/effects.h"
|
||||
#include "client/entities.h"
|
||||
#include "client/temp_entities.h"
|
||||
#include "client/world.h"
|
||||
|
@ -64,7 +60,13 @@ worldscene_t cl_world = {
|
|||
void
|
||||
CL_World_Init (void)
|
||||
{
|
||||
cl_world.scene = Scene_NewScene ();
|
||||
scene_system_t extra_systems[] = {
|
||||
{ .system = &effect_system,
|
||||
.components = effect_components,
|
||||
.component_count = effect_comp_count },
|
||||
{}
|
||||
};
|
||||
cl_world.scene = Scene_NewScene (extra_systems);
|
||||
cl_world.scene->lights = Light_CreateLightingData (cl_world.scene);
|
||||
}
|
||||
|
||||
|
@ -119,6 +121,7 @@ CL_ParseStatic (qmsg_t *msg, int version)
|
|||
|
||||
// copy it to the current state
|
||||
renderer->model = cl_world.models.a[es.modelindex];
|
||||
renderer->noshadows = renderer->model->shadow_alpha < 0.5;
|
||||
animation->frame = es.frame;
|
||||
renderer->skinnum = es.skinnum;
|
||||
|
||||
|
@ -233,3 +236,10 @@ CL_World_NewMap (const char *mapname, const char *skyname)
|
|||
SCR_NewScene (cl_world.scene);
|
||||
map_cfg (mapname, 1);
|
||||
}
|
||||
|
||||
void
|
||||
CL_World_Clear (void)
|
||||
{
|
||||
Scene_FreeAllEntities (cl_world.scene);
|
||||
CL_ClearTEnts ();
|
||||
}
|
||||
|
|
|
@ -290,7 +290,6 @@ void
|
|||
locs_draw (double time, vec4f_t simorg)
|
||||
{
|
||||
//FIXME custom ent rendering code would be nice
|
||||
dlight_t *dl;
|
||||
location_t *nearloc;
|
||||
vec4f_t trueloc;
|
||||
vec4f_t zero = {};
|
||||
|
@ -298,16 +297,15 @@ locs_draw (double time, vec4f_t simorg)
|
|||
|
||||
nearloc = locs_find (simorg);
|
||||
if (nearloc) {
|
||||
dl = R_AllocDlight (4096);
|
||||
if (dl) {
|
||||
VectorCopy (nearloc->loc, dl->origin);
|
||||
dl->radius = 200;
|
||||
dl->die = time + 0.1;
|
||||
dl->color[0] = 0;
|
||||
dl->color[1] = 1;
|
||||
dl->color[2] = 0;
|
||||
dl->color[3] = 0.7;
|
||||
}
|
||||
#if 0//FIXME
|
||||
Ent_SetComponent (ent.id, scene_dynlight, ent.reg, &(dlight_t) {
|
||||
.origin = nearloc->loc,
|
||||
.color = { 0, 1, 0, 0.7 },
|
||||
.radius = 200,
|
||||
.die = time + 0.1,
|
||||
});
|
||||
Light_LinkLight (cl_world.scene->lights, ent.id);
|
||||
#endif
|
||||
trueloc = nearloc->loc;
|
||||
clp_funcs->Particle_New (pt_smokecloud, part_tex_smoke, trueloc, 2.0,
|
||||
zero, time + 9.0, 254,
|
||||
|
|
|
@ -11,10 +11,13 @@ console_common_sources= \
|
|||
libs/console/console.c \
|
||||
libs/console/list.c \
|
||||
libs/console/filelist.c
|
||||
|
||||
client_sources= \
|
||||
libs/console/bi_inputline.c \
|
||||
libs/console/cl_debug.c \
|
||||
libs/console/client.c \
|
||||
libs/console/menu.c
|
||||
|
||||
server_sources= \
|
||||
libs/console/server.c
|
||||
|
||||
|
|
719
libs/console/cl_debug.c
Normal file
719
libs/console/cl_debug.c
Normal file
|
@ -0,0 +1,719 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "QF/cbuf.h"
|
||||
#include "QF/cvar.h"
|
||||
#include "QF/input.h"
|
||||
#include "QF/keys.h"
|
||||
#include "QF/render.h"
|
||||
#include "QF/screen.h"
|
||||
#include "QF/sys.h"
|
||||
#include "QF/va.h"
|
||||
|
||||
#include "QF/input/event.h"
|
||||
|
||||
#include "QF/scene/scene.h"
|
||||
#include "QF/scene/transform.h"
|
||||
|
||||
#include "QF/ui/canvas.h"
|
||||
#include "QF/ui/imui.h"
|
||||
|
||||
#include "QF/plugin/console.h"
|
||||
#include "QF/plugin/vid_render.h"
|
||||
|
||||
#include "cl_console.h"
|
||||
|
||||
static in_axis_t deb_move_forward = {
|
||||
.mode = ina_set,
|
||||
.name = "debug.move.forward",
|
||||
.description = "[debug] Move forward (negative) or backward (positive)",
|
||||
};
|
||||
static in_axis_t deb_move_side = {
|
||||
.mode = ina_set,
|
||||
.name = "debug.move.side",
|
||||
.description = "[debug] Move right (positive) or left (negative)",
|
||||
};
|
||||
static in_axis_t deb_move_up = {
|
||||
.mode = ina_set,
|
||||
.name = "debug.move.up",
|
||||
.description = "[debug] Move up (negative) or down (positive)",
|
||||
};
|
||||
static in_axis_t deb_move_pitch = {
|
||||
.mode = ina_set,
|
||||
.name = "debug.move.pitch",
|
||||
.description = "[debug] Pitch axis",
|
||||
};
|
||||
static in_axis_t deb_move_yaw = {
|
||||
.mode = ina_set,
|
||||
.name = "debug.move.yaw",
|
||||
.description = "[debug] Yaw axis",
|
||||
};
|
||||
static in_axis_t deb_move_roll = {
|
||||
.mode = ina_set,
|
||||
.name = "debug.move.roll",
|
||||
.description = "[debug] Roll axis",
|
||||
};
|
||||
static in_axis_t deb_mouse_x = {
|
||||
.mode = ina_set,
|
||||
.name = "debug.mouse.x",
|
||||
.description = "[debug] Mouse X",
|
||||
};
|
||||
static in_axis_t deb_mouse_y = {
|
||||
.mode = ina_set,
|
||||
.name = "debug.mouse.y",
|
||||
.description = "[debug] Mouse Y",
|
||||
};
|
||||
static in_button_t deb_left = {
|
||||
.name = "debug.left",
|
||||
.description = "[debug] When active the player is turning left"
|
||||
};
|
||||
static in_button_t deb_right = {
|
||||
.name = "debug.right",
|
||||
.description = "[debug] When active the player is turning right"
|
||||
};
|
||||
static in_button_t deb_forward = {
|
||||
.name = "debug.forward",
|
||||
.description = "[debug] When active the player is moving forward"
|
||||
};
|
||||
static in_button_t deb_back = {
|
||||
.name = "debug.back",
|
||||
.description = "[debug] When active the player is moving backwards"
|
||||
};
|
||||
static in_button_t deb_lookup = {
|
||||
.name = "debug.lookup",
|
||||
.description = "[debug] When active the player's view is looking up"
|
||||
};
|
||||
static in_button_t deb_lookdown = {
|
||||
.name = "debug.lookdown",
|
||||
.description = "[debug] When active the player's view is looking down"
|
||||
};
|
||||
static in_button_t deb_moveleft = {
|
||||
.name = "debug.moveleft",
|
||||
.description = "[debug] When active the player is strafing left"
|
||||
};
|
||||
static in_button_t deb_moveright = {
|
||||
.name = "debug.moveright",
|
||||
.description = "[debug] When active the player is strafing right"
|
||||
};
|
||||
static in_button_t deb_up = {
|
||||
.name = "debug.moveup",
|
||||
.description = "[debug] When active the player is swimming up in a liquid"
|
||||
};
|
||||
static in_button_t deb_down = {
|
||||
.name = "debug.movedown",
|
||||
.description = "[debug] When active the player is swimming down in a liquid"
|
||||
};
|
||||
static in_axis_t *deb_in_axes[] = {
|
||||
&deb_move_forward,
|
||||
&deb_move_side,
|
||||
&deb_move_up,
|
||||
&deb_move_pitch,
|
||||
&deb_move_yaw,
|
||||
&deb_move_roll,
|
||||
&deb_mouse_x,
|
||||
&deb_mouse_y,
|
||||
0
|
||||
};
|
||||
static in_button_t *deb_in_buttons[] = {
|
||||
&deb_left,
|
||||
&deb_right,
|
||||
&deb_forward,
|
||||
&deb_back,
|
||||
&deb_lookup,
|
||||
&deb_lookdown,
|
||||
&deb_moveleft,
|
||||
&deb_moveright,
|
||||
&deb_up,
|
||||
&deb_down,
|
||||
0
|
||||
};
|
||||
|
||||
static int debug_event_id;
|
||||
static int debug_saved_focus;
|
||||
static int debug_context;
|
||||
static int debug_saved_context;
|
||||
static imui_ctx_t *debug_imui;
|
||||
static int64_t debug_enable_time;
|
||||
#define IMUI_context debug_imui
|
||||
|
||||
static scene_t *debug_scene;
|
||||
static transform_t debug_camera_pivot;
|
||||
static transform_t debug_camera;
|
||||
|
||||
bool con_debug;
|
||||
static cvar_t con_debug_cvar = {
|
||||
.name = "con_debug",
|
||||
.description =
|
||||
"Enable the debug interface",
|
||||
.default_value = "false",
|
||||
.flags = CVAR_NONE,
|
||||
.value = { .type = &cexpr_bool, .value = &con_debug },
|
||||
};
|
||||
static char *deb_fontname;
|
||||
static cvar_t deb_fontname_cvar = {
|
||||
.name = "deb_fontname",
|
||||
.description =
|
||||
"Font name/patter for debug interface",
|
||||
.default_value = "Consolas",
|
||||
.flags = CVAR_NONE,
|
||||
.value = { .type = 0, .value = &deb_fontname },
|
||||
};
|
||||
static float deb_fontsize;
|
||||
static cvar_t deb_fontsize_cvar = {
|
||||
.name = "deb_fontsize",
|
||||
.description =
|
||||
"Font size for debug interface",
|
||||
.default_value = "22",
|
||||
.flags = CVAR_NONE,
|
||||
.value = { .type = &cexpr_float, .value = &deb_fontsize },
|
||||
};
|
||||
|
||||
static int deb_xlen = -1;
|
||||
static int deb_ylen = -1;
|
||||
static vec4f_t mouse_start;
|
||||
|
||||
static void
|
||||
con_debug_f (void *data, const cvar_t *cvar)
|
||||
{
|
||||
Con_Show_Mouse (con_debug);
|
||||
if (debug_imui) {
|
||||
IMUI_SetVisible (debug_imui, con_debug);
|
||||
debug_enable_time = Sys_LongTime ();
|
||||
if (!con_debug) {
|
||||
IE_Set_Focus (debug_saved_focus);
|
||||
IMT_SetContext (debug_saved_context);
|
||||
r_override_camera = false;
|
||||
} else {
|
||||
IMUI_SetSize (debug_imui, deb_xlen, deb_ylen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
debug_app_window (const IE_event_t *ie_event)
|
||||
{
|
||||
if (deb_xlen != ie_event->app_window.xlen
|
||||
|| deb_ylen != ie_event->app_window.ylen) {
|
||||
deb_xlen = ie_event->app_window.xlen;
|
||||
deb_ylen = ie_event->app_window.ylen;
|
||||
IMUI_SetSize (debug_imui, deb_xlen, deb_ylen);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
capture_mouse_event (const IE_event_t *ie_event)
|
||||
{
|
||||
static IE_mouse_event_t prev_mouse;
|
||||
static bool dragging;
|
||||
|
||||
if (ie_event->mouse.type == ie_mousedown
|
||||
&& ((ie_event->mouse.buttons ^ prev_mouse.buttons) & 4)) {
|
||||
IN_UpdateGrab (1);
|
||||
dragging = true;
|
||||
mouse_start = (vec4f_t) {
|
||||
ie_event->mouse.x,
|
||||
ie_event->mouse.y,
|
||||
};
|
||||
} else if (ie_event->mouse.type == ie_mouseup
|
||||
&& ((ie_event->mouse.buttons ^ prev_mouse.buttons) & 4)) {
|
||||
IN_UpdateGrab (0);
|
||||
dragging = false;
|
||||
}
|
||||
|
||||
prev_mouse = ie_event->mouse;
|
||||
return !dragging;
|
||||
}
|
||||
|
||||
static int
|
||||
debug_mouse (const IE_event_t *ie_event)
|
||||
{
|
||||
if (!IMUI_ProcessEvent (debug_imui, ie_event)) {
|
||||
return capture_mouse_event (ie_event);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
close_debug (void)
|
||||
{
|
||||
con_debug = false;
|
||||
con_debug_f (0, &con_debug_cvar);
|
||||
}
|
||||
|
||||
static int
|
||||
debug_key (const IE_event_t *ie_event)
|
||||
{
|
||||
int shift = ie_event->key.shift & ~(ies_capslock | ies_numlock);
|
||||
if (ie_event->key.code == QFK_ESCAPE && shift == ies_control) {
|
||||
close_debug ();
|
||||
}
|
||||
IMUI_ProcessEvent (debug_imui, ie_event);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
debug_event_handler (const IE_event_t *ie_event, void *data)
|
||||
{
|
||||
static int (*handlers[ie_event_count]) (const IE_event_t *ie_event) = {
|
||||
[ie_app_window] = debug_app_window,
|
||||
[ie_mouse] = debug_mouse,
|
||||
[ie_key] = debug_key,
|
||||
};
|
||||
if ((unsigned) ie_event->type >= ie_event_count
|
||||
|| !handlers[ie_event->type]) {
|
||||
return IN_Binding_HandleEvent (ie_event);
|
||||
}
|
||||
return handlers[ie_event->type] (ie_event);
|
||||
}
|
||||
|
||||
void
|
||||
Con_Debug_InitCvars (void)
|
||||
{
|
||||
Cvar_Register (&con_debug_cvar, con_debug_f, 0);
|
||||
Cvar_Register (&deb_fontname_cvar, 0, 0);
|
||||
Cvar_Register (&deb_fontsize_cvar, 0, 0);
|
||||
}
|
||||
|
||||
static imui_style_t current_style;
|
||||
void
|
||||
Con_Debug_Init (void)
|
||||
{
|
||||
for (int i = 0; deb_in_axes[i]; i++) {
|
||||
IN_RegisterAxis (deb_in_axes[i]);
|
||||
}
|
||||
for (int i = 0; deb_in_buttons[i]; i++) {
|
||||
IN_RegisterButton (deb_in_buttons[i]);
|
||||
}
|
||||
|
||||
debug_event_id = IE_Add_Handler (debug_event_handler, 0);
|
||||
debug_context = IMT_CreateContext ("debug.context");
|
||||
debug_imui = IMUI_NewContext (*con_data.canvas_sys,
|
||||
deb_fontname, deb_fontsize);
|
||||
IMUI_SetVisible (debug_imui, con_debug);
|
||||
IMUI_Style_Fetch (debug_imui, ¤t_style);
|
||||
|
||||
debug_scene = Scene_NewScene (0);
|
||||
}
|
||||
|
||||
void
|
||||
Con_Debug_Shutdown (void)
|
||||
{
|
||||
IE_Remove_Handler (debug_event_id);
|
||||
|
||||
Scene_DeleteScene (debug_scene);
|
||||
}
|
||||
|
||||
static void
|
||||
color_window (void)
|
||||
{
|
||||
static imui_window_t style_editor = {
|
||||
.name = "Style Colors",
|
||||
.xpos = 75,
|
||||
.ypos = 75,
|
||||
.is_open = false,
|
||||
};
|
||||
static int style_selection;
|
||||
static int style_mode;
|
||||
static int style_color;
|
||||
|
||||
UI_Window (&style_editor) {
|
||||
if (style_editor.is_collapsed) {
|
||||
continue;
|
||||
}
|
||||
UI_Vertical {
|
||||
UI_Horizontal {
|
||||
UI_FlexibleSpace ();
|
||||
UI_Radio (&style_selection, 0, "Background");
|
||||
UI_FlexibleSpace ();
|
||||
UI_Radio (&style_selection, 1, "Foreground");
|
||||
UI_FlexibleSpace ();
|
||||
UI_Radio (&style_selection, 2, "Text");
|
||||
UI_FlexibleSpace ();
|
||||
}
|
||||
|
||||
UI_Horizontal {
|
||||
UI_FlexibleSpace ();
|
||||
UI_Radio (&style_mode, 0, "Normal");
|
||||
UI_FlexibleSpace ();
|
||||
UI_Radio (&style_mode, 1, "Hot");
|
||||
UI_FlexibleSpace ();
|
||||
UI_Radio (&style_mode, 2, "Active");
|
||||
UI_FlexibleSpace ();
|
||||
}
|
||||
|
||||
if (style_selection == 0) {
|
||||
style_color = current_style.background.color[style_mode];
|
||||
} else if (style_selection == 1) {
|
||||
style_color = current_style.foreground.color[style_mode];
|
||||
} else if (style_selection == 2) {
|
||||
style_color = current_style.text.color[style_mode];
|
||||
}
|
||||
|
||||
imui_style_t style;
|
||||
IMUI_Style_Fetch (debug_imui, &style);
|
||||
auto bg_save = style.background.normal;
|
||||
auto fg_save = style.foreground.normal;
|
||||
UI_Style (0) for (int y = 0; y < 16; y++) {
|
||||
UI_Horizontal for (int x = 0; x < 16; x++) {
|
||||
if (!x) UI_FlexibleSpace ();
|
||||
int c = y * 16 + x;
|
||||
int ic = y * 16 + (15-x);
|
||||
style.background.normal = c;
|
||||
style.foreground.normal = c == style_color ? c : ic;
|
||||
IMUI_Style_Update (debug_imui, &style);
|
||||
UI_Radio (&style_color, c, va (0, "##color_%x%x", y, x));
|
||||
if (x == 15) {
|
||||
style.background.normal = bg_save;
|
||||
style.foreground.normal = fg_save;
|
||||
IMUI_Style_Update (debug_imui, &style);
|
||||
UI_FlexibleSpace ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (style_selection == 0) {
|
||||
current_style.background.color[style_mode] = style_color;
|
||||
} else if (style_selection == 1) {
|
||||
current_style.foreground.color[style_mode] = style_color;
|
||||
} else if (style_selection == 2) {
|
||||
current_style.text.color[style_mode] = style_color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static transform_t
|
||||
create_debug_camera (void)
|
||||
{
|
||||
debug_camera_pivot = Transform_New (debug_scene->reg, nulltransform);
|
||||
debug_camera = Transform_New (debug_scene->reg, debug_camera_pivot);
|
||||
return debug_camera;
|
||||
}
|
||||
|
||||
static void
|
||||
camera_mouse_first_person (void)
|
||||
{
|
||||
vec4f_t delta_pos = {};
|
||||
vec4f_t delta_rot = {};
|
||||
|
||||
delta_pos[0] -= IN_UpdateAxis (&deb_move_forward);
|
||||
delta_pos[1] -= IN_UpdateAxis (&deb_move_side);
|
||||
delta_pos[2] -= IN_UpdateAxis (&deb_move_up);
|
||||
|
||||
float dt = *con_data.frametime;
|
||||
|
||||
vec4f_t rot = Transform_GetLocalRotation (debug_camera_pivot);
|
||||
delta_pos = qvmulf (rot, delta_pos) * dt;
|
||||
vec4f_t pos = Transform_GetLocalPosition (debug_camera_pivot);
|
||||
Transform_SetLocalPosition (debug_camera_pivot, pos + delta_pos);
|
||||
|
||||
delta_rot[PITCH] -= IN_UpdateAxis (&deb_move_pitch);
|
||||
delta_rot[YAW] -= IN_UpdateAxis (&deb_move_yaw);
|
||||
delta_rot[ROLL] -= IN_UpdateAxis (&deb_move_roll);
|
||||
delta_rot *= dt;
|
||||
vec4f_t drot;
|
||||
AngleQuat ((vec_t*)&delta_rot, (vec_t*)&drot);
|
||||
vec4f_t r = normalf (qmulf (rot, drot));
|
||||
Transform_SetLocalRotation (debug_camera_pivot, r);
|
||||
}
|
||||
|
||||
static vec4f_t
|
||||
trackball_vector (vec4f_t xy)
|
||||
{
|
||||
// xy is already in -1..1 order of magnitude range (ie, might be a bit
|
||||
// over due to screen aspect)
|
||||
// This is very similar to blender's trackball calculation (based on it,
|
||||
// really)
|
||||
float r = 1;
|
||||
float t = r * r / 2;
|
||||
float d = dotf (xy, xy)[0];
|
||||
vec4f_t vec = xy;
|
||||
if (d < t) {
|
||||
// less than 45 degrees around the sphere from the viewer facing
|
||||
// pole, so map the mouse point to the sphere
|
||||
vec[2] = sqrt (r * r - d);
|
||||
} else {
|
||||
// beyond 45 degrees around the sphere from the veiwer facing
|
||||
// pole, so the slope is rapidly approaching infinity or the mouse
|
||||
// point may miss the sphere entirely, so instead map the mouse
|
||||
// point to the hyperbolic cone pointed towards the viewer. The
|
||||
// cone and sphere are tangential at the 45 degree latitude
|
||||
vec[2] = t / sqrt (d);
|
||||
}
|
||||
return (vec4f_t) { vec[2], vec[0], vec[1] };
|
||||
}
|
||||
static float trackball_sensitivity = 0.1;
|
||||
#define sphere_scale 1.0f
|
||||
static void
|
||||
camera_mouse_trackball (void)
|
||||
{
|
||||
vec4f_t delta = {
|
||||
IN_UpdateAxis (&deb_mouse_x),
|
||||
IN_UpdateAxis (&deb_mouse_y),
|
||||
};
|
||||
float size = min (deb_xlen, deb_ylen) / 2;
|
||||
vec4f_t center = { deb_xlen, deb_ylen }; center /= 2;
|
||||
vec4f_t start = mouse_start - center;
|
||||
vec4f_t end = start + delta;
|
||||
start = trackball_vector (start / (size * sphere_scale));
|
||||
end = trackball_vector (end / (size * sphere_scale));
|
||||
vec4f_t drot = crossf (end, start);
|
||||
float ma = dotf (drot, drot)[0];
|
||||
if (ma < 1e-7) {
|
||||
return;
|
||||
}
|
||||
drot /= sqrtf (ma);
|
||||
float dist = sqrtf (dotf (delta, delta)[0]) * trackball_sensitivity;
|
||||
dist /= size;
|
||||
drot *= sinf (dist);
|
||||
drot[3] = cosf (dist);
|
||||
|
||||
vec4f_t rot = Transform_GetLocalRotation (debug_camera_pivot);
|
||||
vec4f_t r = normalf (qmulf (rot, drot));
|
||||
Transform_SetLocalRotation (debug_camera_pivot, r);
|
||||
}
|
||||
|
||||
static void
|
||||
hs (void)
|
||||
{
|
||||
IMUI_Spacer (debug_imui, imui_size_pixels, 10, imui_size_expand, 100);
|
||||
}
|
||||
|
||||
static imui_window_t system_info_window = {
|
||||
.name = "System Info##window",
|
||||
.xpos = 50,
|
||||
.ypos = 50,
|
||||
};
|
||||
|
||||
static imui_window_t cam_window = {
|
||||
.name = "Debug Camera",
|
||||
};
|
||||
|
||||
static imui_window_t inp_window = {
|
||||
.name = "Debug Input",
|
||||
};
|
||||
|
||||
static imui_window_t debug_menu = {
|
||||
.name = "Debug##menu",
|
||||
.group_offset = 0,
|
||||
.is_open = true,
|
||||
.no_collapse = true,
|
||||
};
|
||||
|
||||
static imui_window_t renderer_menu = {
|
||||
.name = "Renderer##menu",
|
||||
.group_offset = 1,
|
||||
.reference_gravity = grav_northwest,
|
||||
.anchor_gravity = grav_southwest,
|
||||
};
|
||||
|
||||
static void
|
||||
menu_bar (void)
|
||||
{
|
||||
UI_MenuBar (&debug_menu) {
|
||||
if (UI_MenuItem ("System Info##menu_item")) {
|
||||
system_info_window.is_open = true;
|
||||
}
|
||||
hs ();
|
||||
if (UI_MenuItem ("Camera")) {
|
||||
cam_window.is_open = true;
|
||||
}
|
||||
hs ();
|
||||
if (UI_MenuItem ("Input")) {
|
||||
inp_window.is_open = true;
|
||||
}
|
||||
if (r_funcs->debug_ui) {
|
||||
hs ();
|
||||
// create the menu so the renderer can access it
|
||||
UI_Menu (&renderer_menu);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
camera_window (void)
|
||||
{
|
||||
static int cam_state;
|
||||
static int cam_mode;
|
||||
|
||||
int old_mode = cam_mode;
|
||||
UI_Window (&cam_window) {
|
||||
if (cam_window.is_collapsed) {
|
||||
continue;
|
||||
}
|
||||
UI_Horizontal {
|
||||
UI_Radio (&cam_state, 0, "Game##camera");
|
||||
IMUI_Spacer (debug_imui, imui_size_pixels, 10,
|
||||
imui_size_expand, 100);
|
||||
UI_Radio (&cam_state, 1, "Debug##camera");
|
||||
UI_FlexibleSpace ();
|
||||
}
|
||||
if (cam_state) {
|
||||
UI_Horizontal {
|
||||
UI_Radio (&cam_mode, 0, "First Person##camera");
|
||||
IMUI_Spacer (debug_imui, imui_size_pixels, 10,
|
||||
imui_size_expand, 100);
|
||||
UI_Radio (&cam_mode, 1, "Trackball##camera");
|
||||
// IMUI_Spacer (debug_imui, imui_size_pixels, 10,
|
||||
// imui_size_expand, 100);
|
||||
// UI_Radio (&cam_mode, 2, "Turntable##camera");
|
||||
UI_FlexibleSpace ();
|
||||
}
|
||||
UI_Horizontal {
|
||||
UI_Checkbox (&r_lock_viewleaf, "Lock VIS##camera");
|
||||
UI_FlexibleSpace ();
|
||||
}
|
||||
}
|
||||
if (r_override_camera) {
|
||||
if (cam_mode == 0) {
|
||||
camera_mouse_first_person();
|
||||
} else if (cam_mode == 1) {
|
||||
camera_mouse_trackball ();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cam_state) {
|
||||
if (!Transform_Valid (r_camera)) {
|
||||
r_camera = create_debug_camera ();
|
||||
}
|
||||
if (!r_override_camera || old_mode != cam_mode) {
|
||||
// the camera is still whatever the client set it to (or what
|
||||
// the renderer last used if switching modes)
|
||||
static vec4f_t forward = {1, 0, 0, 0};
|
||||
static vec4f_t up = {0, 0, 1, 0};
|
||||
static vec4f_t qident = {0, 0, 0, 1};
|
||||
|
||||
vec4f_t f = r_data->refdef->camera[0]; //X is forward
|
||||
vec4f_t u = r_data->refdef->camera[2]; //Z is up
|
||||
vec4f_t q1 = qrotf (forward, f);
|
||||
vec4f_t up1 = qvmulf (q1, up);
|
||||
u -= dotf (u, f) * f; // ensure orthogonal (should be, but...)
|
||||
vec4f_t q2 = qrotf (up1, u);
|
||||
vec4f_t q = qmulf (q2, q1);
|
||||
|
||||
Transform_SetLocalRotation (debug_camera_pivot, q);
|
||||
|
||||
vec4f_t pos = r_data->refdef->camera[3];
|
||||
float dist = cam_mode == 0 ? 0 : 128;
|
||||
vec4f_t offs = dist * Transform_Forward (debug_camera_pivot);
|
||||
|
||||
Transform_SetLocalPosition (debug_camera_pivot, pos + offs);
|
||||
|
||||
Transform_SetLocalRotation (debug_camera, qident);
|
||||
Transform_SetLocalPosition (debug_camera, (vec4f_t) {-dist,0,0,1});
|
||||
}
|
||||
r_override_camera = true;
|
||||
} else {
|
||||
r_override_camera = false;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
input_window (void)
|
||||
{
|
||||
UI_Window (&inp_window) {
|
||||
if (inp_window.is_collapsed) {
|
||||
continue;
|
||||
}
|
||||
for (int i = 0; deb_in_axes[i]; i++) {
|
||||
auto axis = deb_in_axes[i];
|
||||
UI_Horizontal {
|
||||
UI_Label (axis->name);
|
||||
UI_FlexibleSpace ();
|
||||
UI_Labelf ("%8g", axis->rel_input);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool close_debug_pressed = false;
|
||||
static void
|
||||
system_info (void)
|
||||
{
|
||||
UI_Window (&system_info_window) {
|
||||
if (system_info_window.is_collapsed) {
|
||||
continue;
|
||||
}
|
||||
UI_Vertical {
|
||||
UI_Horizontal {
|
||||
if (UI_Button ("Close Debug")) {
|
||||
close_debug_pressed = true;
|
||||
}
|
||||
IMUI_Spacer (debug_imui, imui_size_pixels, 10,
|
||||
imui_size_expand, 100);
|
||||
if (UI_Button ("Screenshot")) {
|
||||
Cbuf_AddText (con_data.cbuf, "screenshot\n");
|
||||
}
|
||||
UI_FlexibleSpace ();
|
||||
}
|
||||
#if 0
|
||||
for (int i = 0; deb_in_axes[i]; i++) {
|
||||
UI_Horizontal {
|
||||
UI_Label (deb_in_axes[i]->name);
|
||||
UI_FlexibleSpace ();
|
||||
//IN_UpdateAxis (deb_in_axes[i]);
|
||||
UI_Labelf ("%6.3f", deb_in_axes[i]->value);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
static int64_t prev_time;
|
||||
static int64_t min_delta = INT64_MAX;
|
||||
static int64_t max_delta = -INT64_MAX;
|
||||
int64_t cur_time = Sys_LongTime ();
|
||||
int64_t delta = cur_time - prev_time;
|
||||
prev_time = cur_time;
|
||||
min_delta = min (min_delta, delta);
|
||||
max_delta = max (max_delta, delta);
|
||||
UI_Horizontal {
|
||||
UI_Label ("frame: ");
|
||||
UI_FlexibleSpace ();
|
||||
UI_Labelf ("%'7"PRIu64"\u03bcs##frame.time", min_delta);
|
||||
UI_Labelf ("%'7"PRIu64"\u03bcs##frame.time", delta);
|
||||
UI_Labelf ("%'7"PRIu64"\u03bcs##frame.time", max_delta);
|
||||
}
|
||||
UI_Horizontal {
|
||||
UI_FlexibleSpace ();
|
||||
if (UI_Button ("Reset##timings")) {
|
||||
max_delta = -INT64_MAX;
|
||||
min_delta = INT64_MAX;
|
||||
}
|
||||
}
|
||||
UI_Horizontal {
|
||||
UI_Labelf ("mem: %'zd", Sys_CurrentRSS ());
|
||||
UI_FlexibleSpace ();
|
||||
}
|
||||
UI_FlexibleSpace ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Con_Debug_Draw (void)
|
||||
{
|
||||
if (debug_enable_time && Sys_LongTime () - debug_enable_time > 1000) {
|
||||
debug_saved_focus = IE_Get_Focus ();
|
||||
IE_Set_Focus (debug_event_id);
|
||||
debug_saved_context = IMT_GetContext ();
|
||||
IMT_SetContext (debug_context);
|
||||
debug_enable_time = 0;
|
||||
}
|
||||
|
||||
IMUI_BeginFrame (debug_imui);
|
||||
IMUI_Style_Update (debug_imui, ¤t_style);
|
||||
menu_bar ();
|
||||
system_info ();
|
||||
color_window ();
|
||||
camera_window ();
|
||||
input_window ();
|
||||
if (r_funcs->debug_ui) {
|
||||
r_funcs->debug_ui (debug_imui);
|
||||
}
|
||||
|
||||
if (close_debug_pressed) {
|
||||
close_debug_pressed = false;
|
||||
close_debug ();
|
||||
}
|
||||
|
||||
IMUI_Draw (debug_imui);
|
||||
}
|
|
@ -46,6 +46,7 @@
|
|||
#include "QF/console.h"
|
||||
#include "QF/cvar.h"
|
||||
#include "QF/dstring.h"
|
||||
#include "QF/input.h"
|
||||
#include "QF/keys.h"
|
||||
#include "QF/qargs.h"
|
||||
#include "QF/quakefs.h"
|
||||
|
@ -61,6 +62,7 @@
|
|||
#include "QF/ui/inputline.h"
|
||||
#include "QF/ui/view.h"
|
||||
|
||||
#include "cl_console.h"
|
||||
#include "compat.h"
|
||||
|
||||
static con_buffer_t *con;
|
||||
|
@ -155,8 +157,11 @@ static uint32_t canvas_base;
|
|||
static uint32_t view_base;
|
||||
|
||||
static con_state_t con_state;
|
||||
static bool con_hide_mouse; // external requested state
|
||||
static bool con_show_mouse; // local (overrides con_hide_mouse)
|
||||
static bool con_force_mouse_visible;// internal (overrides all for show)
|
||||
static int con_event_id;
|
||||
static int con_saved_focos;
|
||||
static int con_saved_focus;
|
||||
|
||||
static bool con_debuglog;
|
||||
static bool chat_team;
|
||||
|
@ -332,16 +337,37 @@ ClearNotify (void)
|
|||
}
|
||||
|
||||
static void
|
||||
C_SetState (con_state_t state)
|
||||
con_update_mouse (void)
|
||||
{
|
||||
bool show_cursor = (con_force_mouse_visible
|
||||
|| con_show_mouse
|
||||
|| !con_hide_mouse);
|
||||
VID_SetCursor (show_cursor);
|
||||
IN_UpdateGrab (show_cursor ? 0 : in_grab);
|
||||
}
|
||||
|
||||
void
|
||||
Con_Show_Mouse (bool visible)
|
||||
{
|
||||
con_show_mouse = visible;
|
||||
con_update_mouse ();
|
||||
}
|
||||
|
||||
static void
|
||||
C_SetState (con_state_t state, bool hide_mouse)
|
||||
{
|
||||
con_state_t old_state = con_state;
|
||||
con_state = state;
|
||||
con_hide_mouse = hide_mouse;
|
||||
if (con_state == con_inactive) {
|
||||
IE_Set_Focus (con_saved_focos);
|
||||
IE_Set_Focus (con_saved_focus);
|
||||
con_force_mouse_visible = false;
|
||||
} else if (old_state == con_inactive) {
|
||||
con_saved_focos = IE_Get_Focus ();
|
||||
con_saved_focus = IE_Get_Focus ();
|
||||
IE_Set_Focus (con_event_id);
|
||||
con_force_mouse_visible = true;
|
||||
}
|
||||
con_update_mouse ();
|
||||
|
||||
if (state == con_message) {
|
||||
say_line.prompt = "say:";
|
||||
|
@ -369,10 +395,10 @@ ToggleConsole_f (void)
|
|||
case con_message:
|
||||
return;
|
||||
case con_inactive:
|
||||
C_SetState (con_active);
|
||||
C_SetState (con_active, con_hide_mouse);
|
||||
break;
|
||||
case con_active:
|
||||
C_SetState (con_inactive);
|
||||
C_SetState (con_inactive, con_hide_mouse);
|
||||
break;
|
||||
case con_fullscreen:
|
||||
break;
|
||||
|
@ -413,7 +439,7 @@ static void
|
|||
con_end_message (inputline_t *line)
|
||||
{
|
||||
Con_ClearTyping (line, 1);
|
||||
C_SetState (con_inactive);
|
||||
C_SetState (con_inactive, con_hide_mouse);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -545,14 +571,14 @@ draw_input_line (inputline_t *il, draw_charbuffer_t *buffer)
|
|||
char *src = il->lines[il->edit_line] + il->scroll + 1;
|
||||
size_t i;
|
||||
|
||||
*dst++ = il->scroll ? '<' | 0x80 : il->lines[il->edit_line][0];
|
||||
*dst++ = il->scroll ? (char) ('<' | 0x80) : il->lines[il->edit_line][0];
|
||||
for (i = 0; i < il->width - 2 && *src; i++) {
|
||||
*dst++ = *src++;
|
||||
}
|
||||
while (i++ < il->width - 2) {
|
||||
*dst++ = ' ';
|
||||
}
|
||||
*dst++ = *src ? '>' | 0x80 : ' ';
|
||||
*dst++ = *src ? (char) ('<' | 0x80) : ' ';
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -765,6 +791,9 @@ setup_console (void)
|
|||
static void
|
||||
C_DrawConsole (void)
|
||||
{
|
||||
if (con_debug) {
|
||||
Con_Debug_Draw ();
|
||||
}
|
||||
setup_console ();
|
||||
view_pos_t screen_len = View_GetLen (screen_view);
|
||||
|
||||
|
@ -839,8 +868,8 @@ con_set_size (void)
|
|||
int xlen = win_xlen / con_scale;
|
||||
int ylen = win_ylen / con_scale;
|
||||
if (xlen > 0 && ylen > 0) {
|
||||
View_SetLen (screen_view, xlen, ylen);
|
||||
View_UpdateHierarchy (screen_view);
|
||||
Canvas_SetLen (*con_data.canvas_sys, screen_canvas,
|
||||
(view_pos_t) { xlen, ylen });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -979,7 +1008,7 @@ MessageMode_f (void)
|
|||
if (con_state != con_inactive)
|
||||
return;
|
||||
chat_team = false;
|
||||
C_SetState (con_message);
|
||||
C_SetState (con_message, con_hide_mouse);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -988,7 +1017,7 @@ MessageMode2_f (void)
|
|||
if (con_state != con_inactive)
|
||||
return;
|
||||
chat_team = true;
|
||||
C_SetState (con_message);
|
||||
C_SetState (con_message, con_hide_mouse);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1032,6 +1061,7 @@ C_InitCvars (void)
|
|||
Cvar_Register (&con_size_cvar, 0, 0);
|
||||
Cvar_Register (&con_speed_cvar, 0, 0);
|
||||
Cvar_Register (&cl_conmode_cvar, 0, 0);
|
||||
Con_Debug_InitCvars ();
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1053,6 +1083,8 @@ C_Init (void)
|
|||
// The console will get resized, so assume initial size is 320x200
|
||||
ecs_system_t sys = { con_data.canvas_sys->reg, view_base };
|
||||
screen_canvas = Canvas_New (*con_data.canvas_sys);
|
||||
Con_Debug_Init ();
|
||||
|
||||
screen_view = Canvas_GetRootView (*con_data.canvas_sys, screen_canvas);
|
||||
console_view = View_New (sys, screen_view);
|
||||
buffer_view = View_New (sys, console_view);
|
||||
|
@ -1111,6 +1143,8 @@ C_Init (void)
|
|||
con_setfitpic (console_view, conback);
|
||||
}
|
||||
|
||||
con_linewidth = 320 / 8;
|
||||
|
||||
cmd_line.prompt = "";
|
||||
cmd_line.input_line = Con_CreateInputLine (32, MAXCMDLINE, ']');
|
||||
cmd_line.input_line->complete = Con_BasicCompleteCommandLine;
|
||||
|
@ -1137,7 +1171,6 @@ C_Init (void)
|
|||
con_setinput (say_view, &say_line);
|
||||
con_setinput (command_view, &cmd_line);
|
||||
|
||||
|
||||
view_pos_t len;
|
||||
|
||||
len = View_GetLen (buffer_view);
|
||||
|
@ -1193,6 +1226,8 @@ C_Init (void)
|
|||
static void
|
||||
C_shutdown (void)
|
||||
{
|
||||
Con_Debug_Shutdown ();
|
||||
|
||||
r_funcs->Draw_DestroyPic (conback);
|
||||
IE_Remove_Handler (con_event_id);
|
||||
Menu_Shutdown ();
|
||||
|
|
|
@ -175,10 +175,10 @@ Con_Print (const char *fmt, va_list args)
|
|||
}
|
||||
|
||||
VISIBLE void
|
||||
Con_SetState (con_state_t state)
|
||||
Con_SetState (con_state_t state, bool hide_mouse)
|
||||
{
|
||||
if (con_module) {
|
||||
con_module->functions->console->set_state (state);
|
||||
con_module->functions->console->set_state (state, hide_mouse);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -54,6 +54,8 @@
|
|||
#include "QF/plugin/console.h"
|
||||
#include "QF/plugin/vid_render.h"
|
||||
|
||||
#include "cl_console.h"
|
||||
|
||||
typedef struct menu_pic_s {
|
||||
struct menu_pic_s *next;
|
||||
int x, y;
|
||||
|
@ -378,7 +380,7 @@ bi_Menu_SelectMenu (progs_t *pr, void *data)
|
|||
if (name && *name)
|
||||
menu = Hash_Find (menu_hash, name);
|
||||
if (menu) {
|
||||
Con_SetState (con_menu);
|
||||
Con_SetState (con_menu, true);
|
||||
if (menu->enter_hook) {
|
||||
run_menu_pre ();
|
||||
PR_ExecuteProgram (&menu_pr_state, menu->enter_hook);
|
||||
|
@ -387,7 +389,7 @@ bi_Menu_SelectMenu (progs_t *pr, void *data)
|
|||
} else {
|
||||
if (name && *name)
|
||||
Sys_Printf ("no menu \"%s\"\n", name);
|
||||
Con_SetState (con_inactive);
|
||||
Con_SetState (con_inactive, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -472,7 +474,7 @@ bi_Menu_Leave (progs_t *pr, void *data)
|
|||
}
|
||||
menu = menu->parent;
|
||||
if (!menu) {
|
||||
Con_SetState (con_inactive);
|
||||
Con_SetState (con_inactive, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -851,14 +853,14 @@ void
|
|||
Menu_Enter ()
|
||||
{
|
||||
if (!top_menu) {
|
||||
Con_SetState (con_active);
|
||||
Con_SetState (con_active, true);
|
||||
return;
|
||||
}
|
||||
if (!menu) {
|
||||
menu = Hash_Find (menu_hash, top_menu);
|
||||
}
|
||||
if (menu) {
|
||||
Con_SetState (con_menu);
|
||||
Con_SetState (con_menu, true);
|
||||
if (menu->enter_hook) {
|
||||
run_menu_pre ();
|
||||
PR_ExecuteProgram (&menu_pr_state, menu->enter_hook);
|
||||
|
@ -878,7 +880,7 @@ Menu_Leave ()
|
|||
}
|
||||
menu = menu->parent;
|
||||
if (!menu) {
|
||||
Con_SetState (con_inactive);
|
||||
Con_SetState (con_inactive, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -146,11 +146,7 @@ enum {
|
|||
sv_cursor = 8,
|
||||
};
|
||||
|
||||
#ifdef HAVE_NCURSES
|
||||
static int use_curses = 1;
|
||||
#else
|
||||
static int use_curses = 0;
|
||||
#endif
|
||||
|
||||
static view_t sv_view;
|
||||
static view_t output;
|
||||
|
@ -855,12 +851,14 @@ C_ProcessInput (void)
|
|||
static void
|
||||
C_DrawConsole (void)
|
||||
{
|
||||
#ifdef HAVE_NCURSES
|
||||
// only the status bar is drawn because the inputline and output views
|
||||
// take care of themselves
|
||||
if (use_curses) {
|
||||
draw_status (status);
|
||||
sv_refresh_windows ();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -141,13 +141,12 @@ static int
|
|||
test_3 (void)
|
||||
{
|
||||
int ret = 1;
|
||||
static char text[] = R"(01 don't forget this line
|
||||
02 and some more lines here
|
||||
03 adsf
|
||||
04 adfa
|
||||
06 hi there
|
||||
06 don't forget there's line 07
|
||||
)";
|
||||
static char text[] = "01 don't forget this line\n\
|
||||
02 and some more lines here\n\
|
||||
03 adsf\n\
|
||||
04 adfa\n\
|
||||
06 hi there\n\
|
||||
06 don't forget there's line 07\n";
|
||||
static uint32_t lengths[] = { 26, 28, 9, 8, 12, 32, 0 };
|
||||
static uint32_t lengths2[] = { 1, 5, 2 };
|
||||
|
||||
|
|
|
@ -88,12 +88,13 @@ ECS_CreateComponentPools (ecs_registry_t *registry)
|
|||
{
|
||||
uint32_t count = registry->components.size;
|
||||
registry->comp_pools = calloc (count, sizeof (ecs_pool_t));
|
||||
registry->subpools = calloc (count, sizeof (ecs_subpool_t));
|
||||
size_t size = registry->max_entities * sizeof (uint32_t);
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
registry->comp_pools[i].sparse = malloc (size);
|
||||
memset (registry->comp_pools[i].sparse, nullent, size);
|
||||
registry->subpools[i].next = nullent;
|
||||
}
|
||||
registry->subpools = calloc (count, sizeof (ecs_subpool_t));
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -116,7 +116,6 @@ Ent_RemoveComponent (uint32_t ent, uint32_t comp, ecs_registry_t *registry)
|
|||
uint32_t ind = pool->sparse[id];
|
||||
component_t *c = ®istry->components.a[comp];
|
||||
if (ind < pool->count && pool->dense[ind] == ent) {
|
||||
uint32_t last = pool->count - 1;
|
||||
// invalidate the entity for this component to prevent the component
|
||||
// being double-removed due to deletion of the component resulting
|
||||
// in the entity being deleted (happens with hierarchies)
|
||||
|
@ -137,6 +136,7 @@ Ent_RemoveComponent (uint32_t ent, uint32_t comp, ecs_registry_t *registry)
|
|||
}
|
||||
}
|
||||
}
|
||||
uint32_t last = pool->count - 1;
|
||||
if (last > ind) {
|
||||
pool->sparse[Ent_Index (pool->dense[last])] = ind;
|
||||
pool->dense[ind] = pool->dense[last];
|
||||
|
|
|
@ -43,6 +43,10 @@ static component_t ent_component = { .size = sizeof (uint32_t) };
|
|||
static component_t childCount_component = { .size = sizeof (uint32_t) };
|
||||
static component_t childIndex_component = { .size = sizeof (uint32_t) };
|
||||
static component_t parentIndex_component = { .size = sizeof (uint32_t) };
|
||||
static component_t nextIndex_component = { .size = sizeof (uint32_t) };
|
||||
static component_t lastIndex_component = { .size = sizeof (uint32_t) };
|
||||
|
||||
|
||||
|
||||
static void
|
||||
hierarchy_UpdateTransformIndices (hierarchy_t *hierarchy, uint32_t start,
|
||||
|
@ -107,6 +111,10 @@ Hierarchy_Reserve (hierarchy_t *hierarchy, uint32_t count)
|
|||
(void **) &hierarchy->childIndex, new_max);
|
||||
Component_ResizeArray (&parentIndex_component,
|
||||
(void **) &hierarchy->parentIndex, new_max);
|
||||
Component_ResizeArray (&nextIndex_component,
|
||||
(void **) &hierarchy->nextIndex, new_max);
|
||||
Component_ResizeArray (&lastIndex_component,
|
||||
(void **) &hierarchy->lastIndex, new_max);
|
||||
|
||||
if (hierarchy->type) {
|
||||
for (uint32_t i = 0; i < hierarchy->type->num_components; i++) {
|
||||
|
@ -126,6 +134,9 @@ hierarchy_open (hierarchy_t *hierarchy, uint32_t index, uint32_t count)
|
|||
hierarchy->num_objects += count;
|
||||
uint32_t dstIndex = index + count;
|
||||
count = hierarchy->num_objects - index - count;
|
||||
if (!count) {
|
||||
return;
|
||||
}
|
||||
Component_MoveElements (&ent_component,
|
||||
hierarchy->ent, dstIndex, index, count);
|
||||
Component_MoveElements (&childCount_component,
|
||||
|
@ -134,6 +145,10 @@ hierarchy_open (hierarchy_t *hierarchy, uint32_t index, uint32_t count)
|
|||
hierarchy->childIndex, dstIndex, index, count);
|
||||
Component_MoveElements (&parentIndex_component,
|
||||
hierarchy->parentIndex, dstIndex, index, count);
|
||||
Component_MoveElements (&nextIndex_component,
|
||||
hierarchy->nextIndex, dstIndex, index, count);
|
||||
Component_MoveElements (&lastIndex_component,
|
||||
hierarchy->lastIndex, dstIndex, index, count);
|
||||
if (hierarchy->type) {
|
||||
for (uint32_t i = 0; i < hierarchy->type->num_components; i++) {
|
||||
Component_MoveElements (&hierarchy->type->components[i],
|
||||
|
@ -160,6 +175,10 @@ hierarchy_close (hierarchy_t *hierarchy, uint32_t index, uint32_t count)
|
|||
hierarchy->childIndex, index, srcIndex, count);
|
||||
Component_MoveElements (&parentIndex_component,
|
||||
hierarchy->parentIndex, index, srcIndex, count);
|
||||
Component_MoveElements (&nextIndex_component,
|
||||
hierarchy->nextIndex, index, srcIndex, count);
|
||||
Component_MoveElements (&lastIndex_component,
|
||||
hierarchy->lastIndex, index, srcIndex, count);
|
||||
if (hierarchy->type) {
|
||||
for (uint32_t i = 0; i < hierarchy->type->num_components; i++) {
|
||||
Component_MoveElements (&hierarchy->type->components[i],
|
||||
|
@ -210,6 +229,7 @@ hierarchy_init (hierarchy_t *dst, uint32_t index,
|
|||
dst->parentIndex[index + i] = parentIndex;
|
||||
dst->childCount[index + i] = 0;
|
||||
dst->childIndex[index + i] = childIndex;
|
||||
dst->lastIndex[index + i] = nullindex;
|
||||
}
|
||||
if (dst->type) {
|
||||
for (uint32_t i = 0; i < dst->type->num_components; i++) {
|
||||
|
@ -220,8 +240,8 @@ hierarchy_init (hierarchy_t *dst, uint32_t index,
|
|||
}
|
||||
|
||||
static uint32_t
|
||||
hierarchy_insert (hierarchy_t *dst, const hierarchy_t *src,
|
||||
uint32_t dstParent, uint32_t *srcRoot, uint32_t count)
|
||||
hierarchy_insert_flat (hierarchy_t *dst, const hierarchy_t *src,
|
||||
uint32_t dstParent, uint32_t *srcRoot, uint32_t count)
|
||||
{
|
||||
uint32_t insertIndex; // where the objects will be inserted
|
||||
uint32_t childIndex; // where the objects' children will inserted
|
||||
|
@ -271,6 +291,62 @@ hierarchy_insert (hierarchy_t *dst, const hierarchy_t *src,
|
|||
return insertIndex;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
hierarchy_insert_tree (hierarchy_t *dst, const hierarchy_t *src,
|
||||
uint32_t dstParent, uint32_t *srcRoot, uint32_t count)
|
||||
{
|
||||
uint32_t insertIndex;
|
||||
if (dst == src) {
|
||||
// reparenting within the hierarchy, so need only to update indices
|
||||
// of course, easier said than done
|
||||
insertIndex = *srcRoot;
|
||||
uint32_t srcParent = dst->parentIndex[insertIndex];
|
||||
uint32_t *next = &dst->nextIndex[srcParent];
|
||||
while (*next != insertIndex) {
|
||||
next = &dst->nextIndex[*next];
|
||||
}
|
||||
if (dst->lastIndex[srcParent] == insertIndex) {
|
||||
// removing src from the end of srcParent's child chain
|
||||
dst->lastIndex[srcParent] = next - dst->nextIndex;
|
||||
}
|
||||
*next = dst->nextIndex[insertIndex];
|
||||
dst->nextIndex[insertIndex] = nullindex;
|
||||
|
||||
dst->nextIndex[dst->lastIndex[dstParent]] = insertIndex;
|
||||
dst->lastIndex[dstParent] = insertIndex;
|
||||
} else {
|
||||
// new objecs are always appended
|
||||
insertIndex = dst->num_objects;
|
||||
hierarchy_open (dst, insertIndex, count);
|
||||
if (dst->childCount[dstParent]) {
|
||||
dst->nextIndex[dst->lastIndex[dstParent]] = insertIndex;
|
||||
} else {
|
||||
dst->childIndex[dstParent] = insertIndex;
|
||||
}
|
||||
dst->childCount[dstParent] += count;
|
||||
dst->lastIndex[dstParent] = insertIndex;
|
||||
dst->nextIndex[insertIndex] = nullindex;
|
||||
|
||||
if (src) {
|
||||
hierarchy_move (dst, src, insertIndex, *srcRoot, count);
|
||||
} else {
|
||||
hierarchy_init (dst, insertIndex, dstParent, nullindex, count);
|
||||
}
|
||||
}
|
||||
return insertIndex;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
hierarchy_insert (hierarchy_t *dst, const hierarchy_t *src,
|
||||
uint32_t dstParent, uint32_t *srcRoot, uint32_t count)
|
||||
{
|
||||
if (dst->tree_mode) {
|
||||
return hierarchy_insert_tree (dst, src, dstParent, srcRoot, count);
|
||||
} else {
|
||||
return hierarchy_insert_flat (dst, src, dstParent, srcRoot, count);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
hierarchy_insert_children (hierarchy_t *dst, const hierarchy_t *src,
|
||||
uint32_t dstParent, uint32_t *srcRoot)
|
||||
|
@ -297,7 +373,7 @@ hierarchy_insertHierarchy (hierarchy_t *dst, const hierarchy_t *src,
|
|||
{
|
||||
uint32_t insertIndex;
|
||||
|
||||
if (dstParent == nullent) {
|
||||
if (dstParent == nullindex) {
|
||||
if (dst->num_objects) {
|
||||
Sys_Error ("attempt to insert root in non-empty hierarchy");
|
||||
}
|
||||
|
@ -305,7 +381,7 @@ hierarchy_insertHierarchy (hierarchy_t *dst, const hierarchy_t *src,
|
|||
if (src) {
|
||||
hierarchy_move (dst, src, 0, *srcRoot, 1);
|
||||
}
|
||||
dst->parentIndex[0] = nullent;
|
||||
dst->parentIndex[0] = nullindex;
|
||||
dst->childIndex[0] = 1;
|
||||
dst->childCount[0] = 0;
|
||||
insertIndex = 0;
|
||||
|
@ -361,6 +437,9 @@ void
|
|||
Hierarchy_RemoveHierarchy (hierarchy_t *hierarchy, uint32_t index,
|
||||
int delEntities)
|
||||
{
|
||||
if (hierarchy->tree_mode) {
|
||||
Sys_Error ("Hierarchy_RemoveHierarchy tree mode not implemented");
|
||||
}
|
||||
uint32_t parentIndex = hierarchy->parentIndex[index];
|
||||
|
||||
hierarchy_remove_children (hierarchy, index, delEntities);
|
||||
|
@ -371,7 +450,7 @@ Hierarchy_RemoveHierarchy (hierarchy_t *hierarchy, uint32_t index,
|
|||
hierarchy_close (hierarchy, index, 1);
|
||||
|
||||
hierarchy_UpdateTransformIndices (hierarchy, index, -1);
|
||||
if (parentIndex != nullent) {
|
||||
if (parentIndex != nullindex) {
|
||||
hierarchy_UpdateChildIndices (hierarchy, parentIndex + 1, -1);
|
||||
hierarchy->childCount[parentIndex] -= 1;
|
||||
}
|
||||
|
@ -394,20 +473,21 @@ Hierarchy_New (ecs_registry_t *reg, uint32_t href_comp,
|
|||
|
||||
if (createRoot) {
|
||||
hierarchy_open (hierarchy, 0, 1);
|
||||
hierarchy_init (hierarchy, 0, nullent, 1, 1);
|
||||
hierarchy_init (hierarchy, 0, nullindex, 1, 1);
|
||||
}
|
||||
|
||||
return hierarchy;
|
||||
}
|
||||
|
||||
void
|
||||
Hierarchy_Delete (hierarchy_t *hierarchy)
|
||||
static void
|
||||
hierarchy_delete (hierarchy_t *hierarchy)
|
||||
{
|
||||
hierarchy_InvalidateReferences (hierarchy, 0, hierarchy->num_objects);
|
||||
free (hierarchy->ent);
|
||||
free (hierarchy->childCount);
|
||||
free (hierarchy->childIndex);
|
||||
free (hierarchy->parentIndex);
|
||||
free (hierarchy->nextIndex);
|
||||
free (hierarchy->lastIndex);
|
||||
if (hierarchy->type) {
|
||||
for (uint32_t i = 0; i < hierarchy->type->num_components; i++) {
|
||||
free (hierarchy->components[i]);
|
||||
|
@ -419,10 +499,138 @@ Hierarchy_Delete (hierarchy_t *hierarchy)
|
|||
PR_RESFREE (reg->hierarchies, hierarchy);
|
||||
}
|
||||
|
||||
void
|
||||
Hierarchy_Delete (hierarchy_t *hierarchy)
|
||||
{
|
||||
hierarchy_InvalidateReferences (hierarchy, 0, hierarchy->num_objects);
|
||||
hierarchy_delete (hierarchy);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
copy_one_node (hierarchy_t *dst, const hierarchy_t *src,
|
||||
uint32_t dstIndex, uint32_t childIndex)
|
||||
{
|
||||
uint32_t srcIndex = dst->parentIndex[dstIndex];
|
||||
uint32_t childCount = src->childCount[srcIndex];
|
||||
|
||||
dst->childIndex[dstIndex] = childIndex;
|
||||
dst->childCount[dstIndex] = childCount;
|
||||
dst->ent[dstIndex] = src->ent[srcIndex];
|
||||
if (dst->type) {
|
||||
for (uint32_t i = 0; i < dst->type->num_components; i++) {
|
||||
Component_CopyElements (&dst->type->components[i],
|
||||
dst->components[i], dstIndex,
|
||||
src->components[i], srcIndex, 1);
|
||||
}
|
||||
}
|
||||
return srcIndex;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
queue_tree_nodes (hierarchy_t *dst, const hierarchy_t *src,
|
||||
uint32_t queueIndex, uint32_t srcIndex)
|
||||
{
|
||||
uint32_t srcChild = src->childIndex[srcIndex];
|
||||
uint32_t childCount = src->childCount[srcIndex];
|
||||
|
||||
for (uint32_t i = 0; i < childCount; i++) {
|
||||
dst->parentIndex[queueIndex + i] = srcChild;
|
||||
srcChild = src->nextIndex[srcChild];
|
||||
}
|
||||
return childCount;
|
||||
}
|
||||
|
||||
static void
|
||||
copy_tree_nodes (hierarchy_t *dst, const hierarchy_t *src,
|
||||
uint32_t dstIndex, uint32_t *queueIndex)
|
||||
{
|
||||
auto ind = copy_one_node (dst, src, dstIndex, *queueIndex);
|
||||
auto count = queue_tree_nodes (dst, src, *queueIndex, ind);
|
||||
*queueIndex += count;
|
||||
}
|
||||
|
||||
static void
|
||||
swap_pointers (void *a, void *b)
|
||||
{
|
||||
void *t = *(void **)a;
|
||||
*(void **)a = *(void **) b;
|
||||
*(void **)b = t;
|
||||
}
|
||||
|
||||
void
|
||||
Hierarchy_SetTreeMode (hierarchy_t *hierarchy, bool tree_mode)
|
||||
{
|
||||
if (!hierarchy->tree_mode == !tree_mode) {
|
||||
// no change
|
||||
return;
|
||||
}
|
||||
hierarchy->tree_mode = tree_mode;
|
||||
if (tree_mode) {
|
||||
// switching from a cononical hierarchy to tree mode, noed only to
|
||||
// ensure next/last indices are correct
|
||||
|
||||
// root node has no siblings
|
||||
hierarchy->nextIndex[0] = nullindex;
|
||||
for (uint32_t i = 0; i < hierarchy->num_objects; i++) {
|
||||
uint32_t count = hierarchy->childCount[i];
|
||||
uint32_t child = hierarchy->childIndex[i];
|
||||
for (uint32_t j = 0; count && j < count - 1; j++) {
|
||||
hierarchy->nextIndex[child + j] = child + j + 1;
|
||||
}
|
||||
hierarchy->lastIndex[i] = count ? child + count - 1 : nullindex;
|
||||
if (count) {
|
||||
hierarchy->nextIndex[hierarchy->lastIndex[i]] = nullindex;
|
||||
} else {
|
||||
hierarchy->childIndex[i] = nullindex;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
auto src = hierarchy;
|
||||
auto tmp = Hierarchy_New (src->reg, src->href_comp, src->type, 0);
|
||||
Hierarchy_Reserve (tmp, src->num_objects);
|
||||
tmp->num_objects = src->num_objects;
|
||||
|
||||
// treat parentIndex as a queue for breadth-first traversal
|
||||
tmp->parentIndex[0] = 0; // start at root of src
|
||||
uint32_t queueIndex = 1;
|
||||
for (uint32_t i = 0; i < src->num_objects; i++) {
|
||||
copy_tree_nodes (tmp, src, i, &queueIndex);
|
||||
}
|
||||
tmp->parentIndex[0] = nullindex;
|
||||
for (uint32_t i = 0; i < src->num_objects; i++) {
|
||||
for (uint32_t j = 0; j < tmp->childCount[i]; j++) {
|
||||
tmp->parentIndex[tmp->childIndex[i] + j] = i;
|
||||
}
|
||||
}
|
||||
auto href_comp = src->href_comp;
|
||||
for (uint32_t i = 0; i < src->num_objects; i++) {
|
||||
hierref_t *ref = Ent_GetComponent (tmp->ent[i], href_comp, tmp->reg);
|
||||
ref->index = i;
|
||||
}
|
||||
|
||||
swap_pointers (&tmp->ent, &src->ent);
|
||||
swap_pointers (&tmp->childCount, &src->childCount);
|
||||
swap_pointers (&tmp->childIndex, &src->childIndex);
|
||||
swap_pointers (&tmp->parentIndex, &src->parentIndex);
|
||||
swap_pointers (&tmp->nextIndex, &src->nextIndex);
|
||||
swap_pointers (&tmp->lastIndex, &src->lastIndex);
|
||||
if (src->type) {
|
||||
for (uint32_t i = 0; i < src->type->num_components; i++) {
|
||||
swap_pointers (&tmp->components[i], &src->components[i]);
|
||||
}
|
||||
}
|
||||
hierarchy_delete (tmp);
|
||||
}
|
||||
|
||||
hierarchy_t *
|
||||
Hierarchy_Copy (ecs_registry_t *dstReg, uint32_t href_comp,
|
||||
const hierarchy_t *src)
|
||||
{
|
||||
if (src->tree_mode) {
|
||||
Sys_Error ("Hierarchy_Copy tree mode not implemented");
|
||||
}
|
||||
hierarchy_t *dst = Hierarchy_New (dstReg, href_comp, src->type, 0);
|
||||
size_t count = src->num_objects;
|
||||
|
||||
|
@ -441,6 +649,10 @@ Hierarchy_Copy (ecs_registry_t *dstReg, uint32_t href_comp,
|
|||
dst->childIndex, 0, src->childIndex, 0, count);
|
||||
Component_CopyElements (&parentIndex_component,
|
||||
dst->parentIndex, 0, src->parentIndex, 0, count);
|
||||
Component_CopyElements (&nextIndex_component,
|
||||
dst->nextIndex, 0, src->nextIndex, 0, count);
|
||||
Component_CopyElements (&lastIndex_component,
|
||||
dst->lastIndex, 0, src->lastIndex, 0, count);
|
||||
if (dst->type) {
|
||||
for (uint32_t i = 0; i < dst->type->num_components; i++) {
|
||||
Component_CopyElements (&dst->type->components[i],
|
||||
|
@ -455,8 +667,11 @@ hierref_t
|
|||
Hierarchy_SetParent (hierarchy_t *dst, uint32_t dstParent,
|
||||
hierarchy_t *src, uint32_t srcRoot)
|
||||
{
|
||||
if (src->tree_mode) {
|
||||
Sys_Error ("Hierarchy_SetParent tree mode not implemented");
|
||||
}
|
||||
hierref_t r = {};
|
||||
if (dst && dstParent != nullent) {
|
||||
if (dst && dstParent != nullindex) {
|
||||
if (dst->type != src->type) {
|
||||
Sys_Error ("Can't set parent in hierarchy of different type");
|
||||
}
|
||||
|
|
|
@ -77,14 +77,44 @@ ECS_DelSubpoolRange (ecs_registry_t *registry, uint32_t component, uint32_t id)
|
|||
uint32_t next = subpool->next | Ent_NextGen (Ent_Generation (id));
|
||||
uint32_t ind = Ent_Index (id);
|
||||
uint32_t count = subpool->num_ranges - subpool->available;
|
||||
uint32_t range = subpool->sorted[ind];
|
||||
subpool->rangeids[ind] = next;
|
||||
subpool->next = ind;
|
||||
subpool->available++;
|
||||
memmove (subpool->ranges + ind, subpool->ranges + ind + 1,
|
||||
(count - 1 - ind) * sizeof (ecs_range_t));
|
||||
memmove (subpool->ranges + range, subpool->ranges + range + 1,
|
||||
(subpool->num_ranges - 1 - range) * sizeof (ecs_range_t));
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
if (subpool->sorted[i] > ind) {
|
||||
if (subpool->sorted[i] > range) {
|
||||
subpool->sorted[i]--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VISIBLE void
|
||||
ECS_MoveSubpoolLast (ecs_registry_t *registry, uint32_t component, uint32_t id)
|
||||
{
|
||||
ecs_pool_t *pool = ®istry->comp_pools[component];
|
||||
ecs_subpool_t *subpool = ®istry->subpools[component];
|
||||
uint32_t ind = Ent_Index (id);
|
||||
component_t *c = ®istry->components.a[component];
|
||||
uint32_t range = subpool->sorted[ind];
|
||||
uint32_t num_ranges = subpool->num_ranges - subpool->available;
|
||||
uint32_t last_range = num_ranges - 1;
|
||||
|
||||
uint32_t start = range ? subpool->ranges[range - 1] : 0;
|
||||
uint32_t end = subpool->ranges[range];
|
||||
uint32_t last = subpool->ranges[last_range];
|
||||
uint32_t count = end - start;
|
||||
uint32_t srcIndex = start;
|
||||
uint32_t dstIndex = last - count;
|
||||
for (uint32_t i = range; i < last_range; i++) {
|
||||
subpool->ranges[i] = subpool->ranges[i + 1] - count;
|
||||
}
|
||||
for (uint32_t i = 0; i < num_ranges; i++) {
|
||||
if (subpool->sorted[i] > range) {
|
||||
subpool->sorted[i]--;
|
||||
}
|
||||
}
|
||||
subpool->sorted[ind] = last_range;
|
||||
Component_RotateElements (c, pool->data, dstIndex, srcIndex, count);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
libs_ecs_tests = \
|
||||
libs/ecs/test/test-components \
|
||||
libs/ecs/test/test-compops \
|
||||
libs/ecs/test/test-hierarchy \
|
||||
libs/ecs/test/test-registry \
|
||||
libs/ecs/test/test-subpools
|
||||
libs/ecs/test/test-subpools \
|
||||
libs/ecs/test/test-treehierarchy
|
||||
|
||||
TESTS += $(libs_ecs_tests)
|
||||
|
||||
|
@ -19,6 +21,13 @@ libs_ecs_test_test_components_LDADD= \
|
|||
libs_ecs_test_test_components_DEPENDENCIES= \
|
||||
$(libs_ecs_test_libs)
|
||||
|
||||
libs_ecs_test_test_compops_SOURCES= \
|
||||
libs/ecs/test/test-compops.c
|
||||
libs_ecs_test_test_compops_LDADD= \
|
||||
$(libs_ecs_test_libs)
|
||||
libs_ecs_test_test_compops_DEPENDENCIES= \
|
||||
$(libs_ecs_test_libs)
|
||||
|
||||
libs_ecs_test_test_hierarchy_SOURCES= \
|
||||
libs/ecs/test/test-hierarchy.c
|
||||
libs_ecs_test_test_hierarchy_LDADD= \
|
||||
|
@ -39,3 +48,10 @@ libs_ecs_test_test_subpools_LDADD= \
|
|||
$(libs_ecs_test_libs)
|
||||
libs_ecs_test_test_subpools_DEPENDENCIES= \
|
||||
$(libs_ecs_test_libs)
|
||||
|
||||
libs_ecs_test_test_treehierarchy_SOURCES= \
|
||||
libs/ecs/test/test-treehierarchy.c
|
||||
libs_ecs_test_test_treehierarchy_LDADD= \
|
||||
$(libs_ecs_test_libs)
|
||||
libs_ecs_test_test_treehierarchy_DEPENDENCIES= \
|
||||
$(libs_ecs_test_libs)
|
||||
|
|
86
libs/ecs/test/test-compops.c
Normal file
86
libs/ecs/test/test-compops.c
Normal file
|
@ -0,0 +1,86 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "QF/ecs.h"
|
||||
|
||||
enum {
|
||||
test_comp,
|
||||
};
|
||||
|
||||
static int counter = 0;
|
||||
static void
|
||||
create_test_comp (void *comp)
|
||||
{
|
||||
*(int *) comp = counter++;
|
||||
}
|
||||
|
||||
static const component_t test_component[] = {
|
||||
[test_comp] = {
|
||||
.size = sizeof (int),
|
||||
.create = create_test_comp,
|
||||
.name = "position",
|
||||
},
|
||||
};
|
||||
|
||||
static int
|
||||
test_rotation (const component_t *comp, int *array, uint32_t array_count,
|
||||
uint32_t dstIndex, uint32_t srcIndex, uint32_t count,
|
||||
int *expect)
|
||||
{
|
||||
counter = 0;
|
||||
Component_CreateElements (comp, array, 0, array_count);
|
||||
for (uint32_t i = 0; i < array_count; i++) {
|
||||
if (array[i] != (int) i) {
|
||||
printf ("array initialized incorrectly");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
Component_RotateElements (comp, array, dstIndex, srcIndex, count);
|
||||
for (uint32_t i = 0; i < array_count; i++) {
|
||||
printf ("%d ", expect[i]);
|
||||
}
|
||||
puts ("");
|
||||
for (uint32_t i = 0; i < array_count; i++) {
|
||||
printf ("%d ", array[i]);
|
||||
}
|
||||
puts ("");
|
||||
for (uint32_t i = 0; i < array_count; i++) {
|
||||
if (array[i] != expect[i]) {
|
||||
printf ("array rotated incorrectly");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int expect1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
||||
static int expect2[] = { 0, 1, 6, 7, 8, 2, 3, 4, 5, 9 };
|
||||
static int expect3[] = { 0, 1, 4, 5, 6, 7, 8, 2, 3, 9 };
|
||||
static int expect4[] = { 0, 6, 7, 8, 1, 2, 3, 4, 5, 9 };
|
||||
static int expect5[] = { 0, 4, 5, 6, 7, 8, 1, 2, 3, 9 };
|
||||
|
||||
static int *test_array = 0;
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
auto comp = &test_component[test_comp];
|
||||
|
||||
Component_ResizeArray (comp, (void **) &test_array, 10);
|
||||
if (test_rotation (comp, test_array, 10, 2, 2, 3, expect1))
|
||||
return 1;
|
||||
if (test_rotation (comp, test_array, 10, 2, 6, 3, expect2))
|
||||
return 1;
|
||||
if (test_rotation (comp, test_array, 10, 2, 4, 5, expect3))
|
||||
return 1;
|
||||
if (test_rotation (comp, test_array, 10, 4, 1, 5, expect4))
|
||||
return 1;
|
||||
if (test_rotation (comp, test_array, 10, 6, 1, 3, expect5))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
|
@ -10,13 +10,26 @@
|
|||
#include "QF/mathlib.h"
|
||||
#include "QF/ecs.h"
|
||||
|
||||
#define DFL "\e[39;49m"
|
||||
#define BLK "\e[30;40m"
|
||||
#define RED "\e[31;40m"
|
||||
#define GRN "\e[32;40m"
|
||||
#define ONG "\e[33;40m"
|
||||
#define BLU "\e[34;40m"
|
||||
#define MAG "\e[35;40m"
|
||||
#define CYN "\e[36;40m"
|
||||
#define WHT "\e[37;40m"
|
||||
|
||||
enum test_components {
|
||||
test_subpool,
|
||||
test_obj,
|
||||
test_name,
|
||||
|
||||
test_num_components
|
||||
};
|
||||
|
||||
#define prent(e) (Ent_Generation (e) >> ENT_IDBITS), (Ent_Index (e))
|
||||
|
||||
static uint32_t
|
||||
obj_rangeid (ecs_registry_t *reg, uint32_t ent, uint32_t comp)
|
||||
{
|
||||
|
@ -34,8 +47,19 @@ static const component_t test_components[] = {
|
|||
.name = "obj",
|
||||
.rangeid = obj_rangeid,
|
||||
},
|
||||
[test_name] = {
|
||||
.size = sizeof (const char *),
|
||||
.name = "name",
|
||||
},
|
||||
};
|
||||
|
||||
static void
|
||||
set_ent_name (uint32_t ent, uint32_t base, ecs_registry_t *reg,
|
||||
const char *name)
|
||||
{
|
||||
Ent_SetComponent (ent, base + test_name, reg, &name);
|
||||
}
|
||||
|
||||
static void
|
||||
dump_sp_ids (ecs_registry_t *reg, uint32_t comp)
|
||||
{
|
||||
|
@ -44,7 +68,8 @@ dump_sp_ids (ecs_registry_t *reg, uint32_t comp)
|
|||
uint32_t *id = pool->data;
|
||||
|
||||
for (uint32_t i = 0; i < pool->count; i++) {
|
||||
printf ("ent[%d]: %d, %d\n", i, ent[i], id[i]);
|
||||
const char **n = Ent_GetComponent (ent[i], test_name, reg);
|
||||
printf ("ent[%d]: %2d, %2d %s\n", i, ent[i], id[i], *n);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,13 +78,43 @@ check_subpool_ranges (ecs_subpool_t *subpool, uint32_t *expect)
|
|||
{
|
||||
uint32_t count = subpool->num_ranges - subpool->available;
|
||||
uint32_t *range = subpool->ranges;
|
||||
int ret = 0;
|
||||
|
||||
while (count--) {
|
||||
uint32_t *r = range++;
|
||||
uint32_t e = *expect++;
|
||||
printf ("%d: %d %d\n", (int)(r - subpool->ranges), *r, e);
|
||||
printf ("%2d: %2d %2d\n", (int)(r - subpool->ranges), *r, e);
|
||||
if (*r != e++) {
|
||||
return 1;
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
check_subpool_sorted (ecs_subpool_t *subpool)
|
||||
{
|
||||
uint32_t *sorted = subpool->sorted;
|
||||
uint32_t *ranges = subpool->ranges;
|
||||
uint32_t count = subpool->num_ranges - subpool->available;
|
||||
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
printf ("sorted[%d]: %d %d\n", i, sorted[i], ranges[sorted[i]]);
|
||||
}
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
for (uint32_t j = i + 1; j < count; j++) {
|
||||
if (sorted[j] == sorted[i]) {
|
||||
printf ("subpool sorted duplicated\n");
|
||||
return 1;
|
||||
}
|
||||
if (sorted[j] >= count) {
|
||||
printf ("subpool sorted out of bounds\n");
|
||||
return 1;
|
||||
}
|
||||
if (ranges[sorted[j]] > ranges[count - 1]) {
|
||||
printf ("subpool sorted bogus\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -73,7 +128,8 @@ check_obj_comps (ecs_registry_t *reg, uint32_t comp, uint32_t *expect)
|
|||
int fail = 0;
|
||||
|
||||
for (uint32_t i = 0; i < pool->count; i++) {
|
||||
printf ("val[%d]: %d %d\n", i, val[i], expect[i]);
|
||||
const char **n = Ent_GetComponent (pool->dense[i], test_name, reg);
|
||||
printf ("val[%d]: %2d %2d %s\n", i, val[i], expect[i], *n);
|
||||
if (val[i] != expect[i]) {
|
||||
fail = 1;
|
||||
}
|
||||
|
@ -93,7 +149,7 @@ main (void)
|
|||
uint32_t sp2 = ECS_NewSubpoolRange (reg, base + test_obj);
|
||||
uint32_t sp3 = ECS_NewSubpoolRange (reg, base + test_obj);
|
||||
|
||||
printf ("%d %d %d\n", sp1, sp2, sp3);
|
||||
printf ("%d.%d %d.%d %d.%d\n", prent (sp1), prent (sp2), prent (sp3));
|
||||
if (reg->subpools[base + test_subpool].num_ranges != 0
|
||||
|| reg->subpools[base + test_subpool].available != 0) {
|
||||
printf ("subpool not 0 count: %d %d\n",
|
||||
|
@ -134,6 +190,15 @@ main (void)
|
|||
Ent_SetComponent (entg, base + test_subpool, reg, &sp2);
|
||||
Ent_SetComponent (enth, base + test_subpool, reg, &sp1);
|
||||
|
||||
set_ent_name (enta, base, reg, MAG"a"DFL);
|
||||
set_ent_name (entb, base, reg, MAG"b"DFL);
|
||||
set_ent_name (entc, base, reg, ONG"c"DFL);
|
||||
set_ent_name (entd, base, reg, CYN"d"DFL);
|
||||
set_ent_name (ente, base, reg, CYN"e"DFL);
|
||||
set_ent_name (entf, base, reg, ONG"f"DFL);
|
||||
set_ent_name (entg, base, reg, ONG"g"DFL);
|
||||
set_ent_name (enth, base, reg, MAG"h"DFL);
|
||||
|
||||
dump_sp_ids (reg, base + test_subpool);
|
||||
if (check_subpool_ranges (®->subpools[base + test_obj],
|
||||
(uint32_t[]) { 0, 0, 0 })) {
|
||||
|
@ -233,7 +298,7 @@ main (void)
|
|||
}
|
||||
|
||||
sp2 = ECS_NewSubpoolRange (reg, base + test_obj);
|
||||
printf ("sp2: %d\n", sp2);
|
||||
printf ("sp2: %d.%d\n", prent (sp2));
|
||||
if (check_subpool_ranges (®->subpools[base + test_obj],
|
||||
(uint32_t[]) { 2, 4, 4 })) {
|
||||
printf ("oops\n");
|
||||
|
@ -256,6 +321,26 @@ main (void)
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (check_subpool_sorted (®->subpools[base + test_obj])) {
|
||||
printf ("oops\n");
|
||||
return 1;
|
||||
}
|
||||
ECS_MoveSubpoolLast (reg, base + test_obj, sp3);
|
||||
if (check_subpool_sorted (®->subpools[base + test_obj])) {
|
||||
printf ("oops\n");
|
||||
return 1;
|
||||
}
|
||||
if (check_subpool_ranges (®->subpools[base + test_obj],
|
||||
(uint32_t[]) { 2, 5, 7})) {
|
||||
printf ("oops\n");
|
||||
return 1;
|
||||
}
|
||||
if (check_obj_comps (reg, base + test_obj,
|
||||
(uint32_t[]) { 0, 7, 10, 11, 12, 9, 8 })) {
|
||||
printf ("oops\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
ECS_DelRegistry (reg);
|
||||
return 0;
|
||||
}
|
||||
|
|
623
libs/ecs/test/test-treehierarchy.c
Normal file
623
libs/ecs/test/test-treehierarchy.c
Normal file
|
@ -0,0 +1,623 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "QF/ecs.h"
|
||||
|
||||
enum {
|
||||
test_href,
|
||||
test_name,
|
||||
test_highlight,
|
||||
|
||||
test_num_components
|
||||
};
|
||||
|
||||
static const component_t test_components[] = {
|
||||
[test_href] = {
|
||||
.size = sizeof (hierref_t),
|
||||
.create = 0,//create_href,
|
||||
.name = "href",
|
||||
.destroy = Hierref_DestroyComponent,
|
||||
},
|
||||
[test_name] = {
|
||||
.size = sizeof (const char *),
|
||||
.name = "name",
|
||||
},
|
||||
[test_highlight] = {
|
||||
.size = sizeof (byte),
|
||||
.name = "highlight",
|
||||
},
|
||||
};
|
||||
|
||||
ecs_registry_t *test_reg;
|
||||
|
||||
#define DFL "\e[39;49m"
|
||||
#define BLK "\e[30;40m"
|
||||
#define RED "\e[31;40m"
|
||||
#define GRN "\e[32;40m"
|
||||
#define ONG "\e[33;40m"
|
||||
#define BLU "\e[34;40m"
|
||||
#define MAG "\e[35;40m"
|
||||
#define CYN "\e[36;40m"
|
||||
#define WHT "\e[37;40m"
|
||||
|
||||
static int
|
||||
check_hierarchy_size (hierarchy_t *h, uint32_t size)
|
||||
{
|
||||
if (h->num_objects != size) {
|
||||
printf ("hierarchy does not have exactly %u transform\n", size);
|
||||
return 0;
|
||||
}
|
||||
ecs_registry_t *reg = h->reg;
|
||||
for (uint32_t i = 0; i < h->num_objects; i++) {
|
||||
hierref_t *ref = Ent_GetComponent (h->ent[i], test_href, reg);
|
||||
char **name = Ent_GetComponent (h->ent[i], test_name, reg);;
|
||||
if (ref->hierarchy != h) {
|
||||
printf ("transform %d (%s) does not point to hierarchy\n",
|
||||
i, *name);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const char *
|
||||
ref_index_color (uint32_t i, uint32_t rind)
|
||||
{
|
||||
return rind != i ? RED : DFL;
|
||||
}
|
||||
|
||||
static const char *
|
||||
parent_index_color (hierarchy_t *h, uint32_t i)
|
||||
{
|
||||
if (!i && h->parentIndex[i] == nullindex) {
|
||||
return GRN;
|
||||
}
|
||||
if (h->parentIndex[i] >= i) {
|
||||
return RED;
|
||||
}
|
||||
uint32_t ci = h->childIndex[h->parentIndex[i]];
|
||||
uint32_t cc = h->childCount[h->parentIndex[i]];
|
||||
if (i < ci || i >= ci + cc) {
|
||||
return ONG;
|
||||
}
|
||||
return DFL;
|
||||
}
|
||||
|
||||
static const char *
|
||||
child_index_color (hierarchy_t *h, uint32_t i)
|
||||
{
|
||||
if (h->tree_mode) {
|
||||
if ((h->childCount[i] && h->childIndex[i] == nullindex)
|
||||
|| (!h->childCount[i] && h->childIndex[i] != nullindex)) {
|
||||
return RED;
|
||||
}
|
||||
if (h->childIndex[i] != nullindex
|
||||
&& h->childIndex[i] >= h->num_objects) {
|
||||
return RED;
|
||||
}
|
||||
} else {
|
||||
if (h->childIndex[i] > h->num_objects
|
||||
|| h->childCount[i] > h->num_objects
|
||||
|| h->childIndex[i] + h->childCount[i] > h->num_objects) {
|
||||
return RED;
|
||||
}
|
||||
if (h->childIndex[i] <= i) {
|
||||
return ONG;
|
||||
}
|
||||
}
|
||||
return DFL;
|
||||
}
|
||||
|
||||
static const char *
|
||||
child_count_color (hierarchy_t *h, uint32_t i)
|
||||
{
|
||||
if (h->childCount[i] > h->num_objects) {
|
||||
return RED;
|
||||
}
|
||||
if (h->tree_mode) {
|
||||
if ((h->childCount[i] && h->childIndex[i] == nullindex)
|
||||
|| (!h->childCount[i] && h->childIndex[i] != nullindex)) {
|
||||
return RED;
|
||||
}
|
||||
} else {
|
||||
if (h->childIndex[i] > h->num_objects
|
||||
|| h->childIndex[i] + h->childCount[i] > h->num_objects) {
|
||||
return RED;
|
||||
}
|
||||
}
|
||||
return DFL;
|
||||
}
|
||||
|
||||
static bool
|
||||
check_for_loops (hierarchy_t *h)
|
||||
{
|
||||
for (uint32_t i = 0; i < h->num_objects; i++) {
|
||||
if (!h->childCount[i]) {
|
||||
continue;
|
||||
}
|
||||
uint32_t n, c;
|
||||
for (n = h->childIndex[i], c = h->childCount[i];
|
||||
n != nullindex; n = h->nextIndex[n], c--) {
|
||||
if (!c) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!c && n != nullindex) {
|
||||
printf ("too many children at %d\n", i);
|
||||
return false;
|
||||
}
|
||||
if (c && n == nullindex) {
|
||||
printf ("too few children at %d\n", i);
|
||||
return false;
|
||||
}
|
||||
if (c && n != nullindex) {
|
||||
printf ("what the what?!? at %d\n", i);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
check_next_index (hierarchy_t *h, uint32_t i)
|
||||
{
|
||||
if (i == 0) {
|
||||
// root never has siblings
|
||||
if (h->nextIndex[i] != nullindex) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
uint32_t p;
|
||||
if ((p = h->parentIndex[i]) >= h->num_objects
|
||||
|| h->childIndex[p] > h->num_objects
|
||||
|| h->childCount[p] > h->num_objects
|
||||
|| h->childIndex[p] + h->childCount[p] > h->num_objects
|
||||
|| h->lastIndex[p] >= h->num_objects
|
||||
|| (h->nextIndex[i] == nullindex && h->lastIndex[p] != i)
|
||||
|| (h->nextIndex[i] != nullindex && h->lastIndex[p] == i)) {
|
||||
return false;
|
||||
}
|
||||
if (h->nextIndex[i] != nullindex && h->parentIndex[h->nextIndex[i]] != p) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static const char *
|
||||
next_index_color (hierarchy_t *h, uint32_t i)
|
||||
{
|
||||
return check_next_index (h, i) ? DFL : RED;
|
||||
}
|
||||
|
||||
static bool
|
||||
check_last_index (hierarchy_t *h, uint32_t i)
|
||||
{
|
||||
if ((h->childCount[i] && h->childIndex[i] >= h->num_objects)
|
||||
|| h->childCount[i] >= h->num_objects
|
||||
|| (h->childCount[i] && h->lastIndex[i] == nullindex)
|
||||
|| (!h->childCount[i] && h->lastIndex[i] != nullindex)) {
|
||||
return false;
|
||||
}
|
||||
if (h->lastIndex[i] != nullindex && h->parentIndex[h->lastIndex[i]] != i) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static const char *
|
||||
last_index_color (hierarchy_t *h, uint32_t i)
|
||||
{
|
||||
return check_last_index (h, i) ? DFL : RED;
|
||||
}
|
||||
|
||||
static const char *
|
||||
entity_color (hierarchy_t *h, uint32_t i)
|
||||
{
|
||||
return h->ent[i] == nullent ? MAG : DFL;
|
||||
}
|
||||
|
||||
static const char *
|
||||
highlight_color (hierarchy_t *h, uint32_t i)
|
||||
{
|
||||
uint32_t ent = h->ent[i];
|
||||
if (ECS_EntValid (ent, test_reg)
|
||||
&& Ent_HasComponent (ent, test_highlight, test_reg)) {
|
||||
static char color_str[] = "\e[3.;4.m";
|
||||
byte *color = Ent_GetComponent (ent, test_highlight, test_reg);
|
||||
if (*color) {
|
||||
byte fg = *color & 0x0f;
|
||||
byte bg = *color >> 4;
|
||||
color_str[3] = fg < 8 ? '0' + fg : '9';
|
||||
color_str[6] = bg < 8 ? '0' + bg : '9';
|
||||
return color_str;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
static void
|
||||
print_header (hierarchy_t *h)
|
||||
{
|
||||
if (h->tree_mode) {
|
||||
puts ("in: ri pa ci cc ni li en|name");
|
||||
} else {
|
||||
puts ("in: ri pa ci cc en|name");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_line (hierarchy_t *h, uint32_t ind, int level)
|
||||
{
|
||||
ecs_registry_t *reg = h->reg;
|
||||
uint32_t rind = nullindex;
|
||||
static char fake_name[] = ONG "null" DFL;
|
||||
static char *fake_nameptr = fake_name;
|
||||
char **name = &fake_nameptr;
|
||||
if (ECS_EntValid (h->ent[ind], reg)) {
|
||||
hierref_t *ref = Ent_GetComponent (h->ent[ind], test_href, reg);
|
||||
rind = ref->index;
|
||||
if (Ent_HasComponent (h->ent[ind], test_name, reg)) {
|
||||
name = Ent_GetComponent (h->ent[ind], test_name, reg);
|
||||
}
|
||||
}
|
||||
printf ("%2d: %s%2d %s%2d %s%2d %s%2d", ind,
|
||||
ref_index_color (ind, rind), rind,
|
||||
parent_index_color (h, ind), h->parentIndex[ind],
|
||||
child_index_color (h, ind), h->childIndex[ind],
|
||||
child_count_color (h, ind), h->childCount[ind]);
|
||||
if (h->tree_mode) {
|
||||
printf (" %s%2d %s%2d",
|
||||
next_index_color (h, ind), h->nextIndex[ind],
|
||||
last_index_color (h, ind), h->lastIndex[ind]);
|
||||
}
|
||||
printf (" %s%2d"DFL"|%*s%s%s"DFL"\n",
|
||||
entity_color (h, ind), h->ent[ind],
|
||||
level * 3, "", highlight_color (h, ind), *name);
|
||||
}
|
||||
|
||||
static void
|
||||
dump_hierarchy (hierarchy_t *h)
|
||||
{
|
||||
print_header (h);
|
||||
for (uint32_t i = 0; i < h->num_objects; i++) {
|
||||
print_line (h, i, 0);
|
||||
}
|
||||
puts ("");
|
||||
}
|
||||
|
||||
static void
|
||||
dump_tree (hierarchy_t *h, uint32_t ind, int level)
|
||||
{
|
||||
if (ind >= h->num_objects) {
|
||||
printf ("index %d out of bounds (%d)\n", ind, h->num_objects);
|
||||
return;
|
||||
}
|
||||
if (!level) {
|
||||
print_header (h);
|
||||
}
|
||||
print_line (h, ind, level);
|
||||
|
||||
if (h->tree_mode) {
|
||||
uint32_t count = h->childCount[ind];
|
||||
uint32_t child;
|
||||
for (child = h->childIndex[ind]; count && child != nullindex;
|
||||
child = h->nextIndex[child], count--) {
|
||||
dump_tree (h, child, level + 1);
|
||||
}
|
||||
} else {
|
||||
if (h->childIndex[ind] > ind) {
|
||||
for (uint32_t i = 0; i < h->childCount[ind]; i++) {
|
||||
if (h->childIndex[ind] + i >= h->num_objects) {
|
||||
break;
|
||||
}
|
||||
dump_tree (h, h->childIndex[ind] + i, level + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!level) {
|
||||
puts ("");
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
check_indices (uint32_t ent, uint32_t index, uint32_t parentIndex,
|
||||
uint32_t childIndex, uint32_t childCount)
|
||||
{
|
||||
ecs_registry_t *reg = test_reg;
|
||||
char **entname = Ent_GetComponent (ent, test_name, reg);;
|
||||
hierref_t *ref = Ent_GetComponent (ent, test_href, reg);
|
||||
hierarchy_t *h = ref->hierarchy;
|
||||
if (ref->index != index) {
|
||||
char **name = Ent_GetComponent (h->ent[index], test_name, reg);;
|
||||
printf ("%s/%s index incorrect: expect %u got %u\n",
|
||||
*entname, *name,
|
||||
index, ref->index);
|
||||
return 0;
|
||||
}
|
||||
if (h->parentIndex[index] != parentIndex) {
|
||||
printf ("%s parent index incorrect: expect %u got %u\n",
|
||||
*entname, parentIndex, h->parentIndex[index]);
|
||||
return 0;
|
||||
}
|
||||
if (h->childIndex[index] != childIndex) {
|
||||
printf ("%s child index incorrect: expect %u got %u\n",
|
||||
*entname, childIndex, h->childIndex[index]);
|
||||
return 0;
|
||||
}
|
||||
if (h->childCount[index] != childCount) {
|
||||
printf ("%s child count incorrect: expect %u got %u\n",
|
||||
*entname, childCount, h->childCount[index]);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool
|
||||
check_next_last_indices (hierarchy_t *h)
|
||||
{
|
||||
for (uint32_t i = 0; i < h->num_objects; i++) {
|
||||
if (!check_next_index (h, i)) {
|
||||
printf ("incorrect next index at %d: %d\n", i, h->nextIndex[i]);
|
||||
return false;
|
||||
}
|
||||
if (!check_last_index (h, i)) {
|
||||
printf ("incorrect last index at %d: %d\n", i, h->lastIndex[i]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
create_ent (uint32_t parent, const char *name)
|
||||
{
|
||||
uint32_t ent = ECS_NewEntity (test_reg);
|
||||
Ent_SetComponent (ent, test_name, test_reg, &name);
|
||||
hierref_t *ref = Ent_AddComponent (ent, test_href, test_reg);
|
||||
|
||||
if (parent != nullindex) {
|
||||
hierref_t *pref = Ent_GetComponent (parent, test_href, test_reg);
|
||||
ref->hierarchy = pref->hierarchy;
|
||||
ref->index = Hierarchy_InsertHierarchy (pref->hierarchy, 0,
|
||||
pref->index, 0);
|
||||
} else {
|
||||
ref->hierarchy = Hierarchy_New (test_reg, test_href, 0, 1);
|
||||
ref->index = 0;
|
||||
}
|
||||
ref->hierarchy->ent[ref->index] = ent;
|
||||
return ent;
|
||||
}
|
||||
#if 0
|
||||
static void
|
||||
highlight_ent (uint32_t ent, byte color)
|
||||
{
|
||||
Ent_SetComponent (ent, test_highlight, test_reg, &color);
|
||||
}
|
||||
|
||||
static void
|
||||
set_parent (uint32_t child, uint32_t parent)
|
||||
{
|
||||
if (parent != nullindex) {
|
||||
hierref_t *pref = Ent_GetComponent (parent, test_href, test_reg);
|
||||
hierref_t *cref = Ent_GetComponent (child, test_href, test_reg);
|
||||
Hierarchy_SetParent (pref->hierarchy, pref->index,
|
||||
cref->hierarchy, cref->index);
|
||||
} else {
|
||||
hierref_t *cref = Ent_GetComponent (child, test_href, test_reg);
|
||||
Hierarchy_SetParent (0, nullindex, cref->hierarchy, cref->index);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
static int
|
||||
test_build_hierarchy (void)
|
||||
{
|
||||
printf ("test_build_hierarchy\n");
|
||||
|
||||
uint32_t root = create_ent (nullent, "root");
|
||||
uint32_t A = create_ent (root, "A");
|
||||
uint32_t B = create_ent (root, "B");
|
||||
uint32_t C = create_ent (root, "C");
|
||||
|
||||
hierref_t *ref = Ent_GetComponent (root, test_href, test_reg);
|
||||
|
||||
if (!check_indices (root, 0, nullindex, 1, 3)) { return 1; }
|
||||
if (!check_indices (A, 1, 0, 4, 0)) { return 1; }
|
||||
if (!check_indices (B, 2, 0, 4, 0)) { return 1; }
|
||||
if (!check_indices (C, 3, 0, 4, 0)) { return 1; }
|
||||
|
||||
uint32_t B1 = create_ent (B, "B1");
|
||||
|
||||
if (!check_indices (root, 0, nullindex, 1, 3)) { return 1; }
|
||||
if (!check_indices ( A, 1, 0, 4, 0)) { return 1; }
|
||||
if (!check_indices ( B, 2, 0, 4, 1)) { return 1; }
|
||||
if (!check_indices ( C, 3, 0, 5, 0)) { return 1; }
|
||||
if (!check_indices (B1, 4, 2, 5, 0)) { return 1; }
|
||||
|
||||
uint32_t A1 = create_ent (A, "A1");
|
||||
|
||||
if (!check_indices (root, 0, nullindex, 1, 3)) { return 1; }
|
||||
if (!check_indices ( A, 1, 0, 4, 1)) { return 1; }
|
||||
if (!check_indices ( B, 2, 0, 5, 1)) { return 1; }
|
||||
if (!check_indices ( C, 3, 0, 6, 0)) { return 1; }
|
||||
if (!check_indices (A1, 4, 1, 6, 0)) { return 1; }
|
||||
if (!check_indices (B1, 5, 2, 6, 0)) { return 1; }
|
||||
uint32_t A1a = create_ent (A1, "A1a");
|
||||
uint32_t B2 = create_ent (B, "B2");
|
||||
uint32_t A2 = create_ent (A, "A2");
|
||||
uint32_t B3 = create_ent (B, "B3");
|
||||
uint32_t B2a = create_ent (B2, "B2a");
|
||||
|
||||
if (!check_hierarchy_size (ref->hierarchy, 11)) { return 1; }
|
||||
|
||||
if (!check_indices (root, 0, nullindex, 1, 3)) { return 1; }
|
||||
if (!check_indices ( A, 1, 0, 4, 2)) { return 1; }
|
||||
if (!check_indices ( B, 2, 0, 6, 3)) { return 1; }
|
||||
if (!check_indices ( C, 3, 0, 9, 0)) { return 1; }
|
||||
if (!check_indices ( A1, 4, 1, 9, 1)) { return 1; }
|
||||
if (!check_indices ( A2, 5, 1, 10, 0)) { return 1; }
|
||||
if (!check_indices ( B1, 6, 2, 10, 0)) { return 1; }
|
||||
if (!check_indices ( B2, 7, 2, 10, 1)) { return 1; }
|
||||
if (!check_indices ( B3, 8, 2, 11, 0)) { return 1; }
|
||||
if (!check_indices (A1a, 9, 4, 11, 0)) { return 1; }
|
||||
if (!check_indices (B2a, 10, 7, 11, 0)) { return 1; }
|
||||
|
||||
uint32_t D = create_ent (root, "D");
|
||||
|
||||
if (!check_hierarchy_size (ref->hierarchy, 12)) { return 1; }
|
||||
|
||||
if (!check_indices (root, 0, nullindex, 1, 4)) { return 1; }
|
||||
if (!check_indices ( A, 1, 0, 5, 2)) { return 1; }
|
||||
if (!check_indices ( B, 2, 0, 7, 3)) { return 1; }
|
||||
if (!check_indices ( C, 3, 0, 10, 0)) { return 1; }
|
||||
if (!check_indices ( D, 4, 0, 10, 0)) { return 1; }
|
||||
if (!check_indices ( A1, 5, 1, 10, 1)) { return 1; }
|
||||
if (!check_indices ( A2, 6, 1, 11, 0)) { return 1; }
|
||||
if (!check_indices ( B1, 7, 2, 11, 0)) { return 1; }
|
||||
if (!check_indices ( B2, 8, 2, 11, 1)) { return 1; }
|
||||
if (!check_indices ( B3, 9, 2, 12, 0)) { return 1; }
|
||||
if (!check_indices (A1a, 10, 5, 12, 0)) { return 1; }
|
||||
if (!check_indices (B2a, 11, 8, 12, 0)) { return 1; }
|
||||
|
||||
dump_hierarchy (ref->hierarchy);
|
||||
uint32_t C1 = create_ent (C, "C1");
|
||||
dump_hierarchy (ref->hierarchy);
|
||||
if (!check_hierarchy_size (ref->hierarchy, 13)) { return 1; }
|
||||
|
||||
if (!check_indices (root, 0, nullindex, 1, 4)) { return 1; }
|
||||
if (!check_indices ( A, 1, 0, 5, 2)) { return 1; }
|
||||
if (!check_indices ( B, 2, 0, 7, 3)) { return 1; }
|
||||
if (!check_indices ( C, 3, 0, 10, 1)) { return 1; }
|
||||
if (!check_indices ( D, 4, 0, 11, 0)) { return 1; }
|
||||
if (!check_indices ( A1, 5, 1, 11, 1)) { return 1; }
|
||||
if (!check_indices ( A2, 6, 1, 12, 0)) { return 1; }
|
||||
if (!check_indices ( B1, 7, 2, 12, 0)) { return 1; }
|
||||
if (!check_indices ( B2, 8, 2, 12, 1)) { return 1; }
|
||||
if (!check_indices ( B3, 9, 2, 13, 0)) { return 1; }
|
||||
if (!check_indices ( C1, 10, 3, 13, 0)) { return 1; }
|
||||
if (!check_indices (A1a, 11, 5, 13, 0)) { return 1; }
|
||||
if (!check_indices (B2a, 12, 8, 13, 0)) { return 1; }
|
||||
|
||||
dump_tree (ref->hierarchy, 0, 0);
|
||||
Hierarchy_SetTreeMode (ref->hierarchy, true);
|
||||
//ref->hierarchy->tree_mode = true;
|
||||
dump_hierarchy (ref->hierarchy);
|
||||
dump_tree (ref->hierarchy, 0, 0);
|
||||
if (!check_for_loops (ref->hierarchy)) { return 1; }
|
||||
if (!check_next_last_indices (ref->hierarchy)) { return 1; }
|
||||
|
||||
create_ent (root, "E");
|
||||
create_ent (B1, "B1a");
|
||||
create_ent (A2, "A2a");
|
||||
dump_hierarchy (ref->hierarchy);
|
||||
dump_tree (ref->hierarchy, 0, 0);
|
||||
if (!check_for_loops (ref->hierarchy)) { return 1; }
|
||||
if (!check_next_last_indices (ref->hierarchy)) { return 1; }
|
||||
|
||||
// Delete the hierarchy directly as setparent isn't fully tested
|
||||
Hierarchy_Delete (ref->hierarchy);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
test_build_hierarchy2 (void)
|
||||
{
|
||||
printf ("test_build_hierarchy2\n");
|
||||
|
||||
uint32_t root = create_ent (nullent, "root");
|
||||
hierref_t *ref = Ent_GetComponent (root, test_href, test_reg);
|
||||
Hierarchy_SetTreeMode (ref->hierarchy, true);
|
||||
uint32_t A = create_ent (root, "A");
|
||||
uint32_t A1 = create_ent (A, "A1");
|
||||
uint32_t A1a = create_ent (A1, "A1a");
|
||||
uint32_t A2 = create_ent (A, "A2");
|
||||
uint32_t B = create_ent (root, "B");
|
||||
uint32_t B1 = create_ent (B, "B1");
|
||||
uint32_t B2 = create_ent (B, "B2");
|
||||
uint32_t B2a = create_ent (B2, "B2a");
|
||||
uint32_t B3 = create_ent (B, "B3");
|
||||
uint32_t C = create_ent (root, "C");
|
||||
uint32_t C1 = create_ent (C, "C1");
|
||||
uint32_t D = create_ent (root, "D");
|
||||
|
||||
//check_indices (ent, index, parentIndex, childIndex, childCount)
|
||||
#define ni nullindex
|
||||
if (!check_indices (root, 0, ni, 1, 4)) { return 1; }
|
||||
if (!check_indices ( A, 1, 0, 2, 2)) { return 1; }
|
||||
if (!check_indices ( A1, 2, 1, 3, 1)) { return 1; }
|
||||
if (!check_indices (A1a, 3, 2, ni, 0)) { return 1; }
|
||||
if (!check_indices ( A2, 4, 1, ni, 0)) { return 1; }
|
||||
if (!check_indices ( B, 5, 0, 6, 3)) { return 1; }
|
||||
if (!check_indices ( B1, 6, 5, ni, 0)) { return 1; }
|
||||
if (!check_indices ( B2, 7, 5, 8, 1)) { return 1; }
|
||||
if (!check_indices (B2a, 8, 7, ni, 0)) { return 1; }
|
||||
if (!check_indices ( B3, 9, 5, ni, 0)) { return 1; }
|
||||
if (!check_indices ( C, 10, 0, 11, 1)) { return 1; }
|
||||
if (!check_indices ( C1, 11, 10, ni, 0)) { return 1; }
|
||||
if (!check_indices ( D, 12, 0, ni, 0)) { return 1; }
|
||||
if (!check_next_last_indices (ref->hierarchy)) { return 1; }
|
||||
if (!check_for_loops (ref->hierarchy)) { return 1; }
|
||||
|
||||
dump_hierarchy (ref->hierarchy);
|
||||
dump_tree (ref->hierarchy, 0, 0);
|
||||
Hierarchy_SetTreeMode (ref->hierarchy, true);// shouldn't do anything
|
||||
if (!check_indices (root, 0, ni, 1, 4)) { return 1; }
|
||||
if (!check_indices ( A, 1, 0, 2, 2)) { return 1; }
|
||||
if (!check_indices ( A1, 2, 1, 3, 1)) { return 1; }
|
||||
if (!check_indices (A1a, 3, 2, ni, 0)) { return 1; }
|
||||
if (!check_indices ( A2, 4, 1, ni, 0)) { return 1; }
|
||||
if (!check_indices ( B, 5, 0, 6, 3)) { return 1; }
|
||||
if (!check_indices ( B1, 6, 5, ni, 0)) { return 1; }
|
||||
if (!check_indices ( B2, 7, 5, 8, 1)) { return 1; }
|
||||
if (!check_indices (B2a, 8, 7, ni, 0)) { return 1; }
|
||||
if (!check_indices ( B3, 9, 5, ni, 0)) { return 1; }
|
||||
if (!check_indices ( C, 10, 0, 11, 1)) { return 1; }
|
||||
if (!check_indices ( C1, 11, 10, ni, 0)) { return 1; }
|
||||
if (!check_indices ( D, 12, 0, ni, 0)) { return 1; }
|
||||
if (!check_next_last_indices (ref->hierarchy)) { return 1; }
|
||||
if (!check_for_loops (ref->hierarchy)) { return 1; }
|
||||
|
||||
Hierarchy_SetTreeMode (ref->hierarchy, false);
|
||||
puts("Hierarchy_SetTreeMode");
|
||||
dump_hierarchy (ref->hierarchy);
|
||||
dump_tree (ref->hierarchy, 0, 0);
|
||||
|
||||
if (!check_indices (root, 0, nullindex, 1, 4)) { return 1; }
|
||||
if (!check_indices ( A, 1, 0, 5, 2)) { return 1; }
|
||||
if (!check_indices ( B, 2, 0, 7, 3)) { return 1; }
|
||||
if (!check_indices ( C, 3, 0, 10, 1)) { return 1; }
|
||||
if (!check_indices ( D, 4, 0, 11, 0)) { return 1; }
|
||||
if (!check_indices ( A1, 5, 1, 11, 1)) { return 1; }
|
||||
if (!check_indices ( A2, 6, 1, 12, 0)) { return 1; }
|
||||
if (!check_indices ( B1, 7, 2, 12, 0)) { return 1; }
|
||||
if (!check_indices ( B2, 8, 2, 12, 1)) { return 1; }
|
||||
if (!check_indices ( B3, 9, 2, 13, 0)) { return 1; }
|
||||
if (!check_indices ( C1, 10, 3, 13, 0)) { return 1; }
|
||||
if (!check_indices (A1a, 11, 5, 13, 0)) { return 1; }
|
||||
if (!check_indices (B2a, 12, 8, 13, 0)) { return 1; }
|
||||
|
||||
// Delete the hierarchy directly as setparent isn't fully tested
|
||||
Hierarchy_Delete (ref->hierarchy);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
test_reg = ECS_NewRegistry ();
|
||||
ECS_RegisterComponents (test_reg, test_components, test_num_components);
|
||||
ECS_CreateComponentPools (test_reg);
|
||||
|
||||
if (test_build_hierarchy ()) { return 1; }
|
||||
if (test_build_hierarchy2 ()) { return 1; }
|
||||
|
||||
ECS_DelRegistry (test_reg);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
print("""// encoding is teemmm
|
||||
print("""// encoding is rteemmm
|
||||
// r = 0: forward, r = 1: reverse (also reverses component order for 2 and 3)
|
||||
// t = 0: 32-bit, t = 1: 64-bit
|
||||
// e = 00: 0
|
||||
// e = 01: 1.0
|
||||
|
@ -29,9 +30,9 @@ extend = [
|
|||
["0", "INT64_C(0x3ff0000000000000)", "0", "INT64_C(0xbff0000000000000)"],
|
||||
]
|
||||
|
||||
def case_str(type, ext, mode):
|
||||
case = (type << 5) | (ext << 3) | (mode)
|
||||
return f"case {case:03o}:"
|
||||
def case_str(reverse, type, ext, mode):
|
||||
case = (reverse << 6) | (type << 5) | (ext << 3) | (mode)
|
||||
return f"case {case:04o}:"
|
||||
|
||||
def dst_str(type, ext, mode):
|
||||
return f"OPC({types[type][mode]})"
|
||||
|
@ -39,39 +40,61 @@ def dst_str(type, ext, mode):
|
|||
def cast_str(type, ext, mode):
|
||||
return f"(pr_{types[type][mode]}_t)"
|
||||
|
||||
def init_str(type, ext, mode):
|
||||
def init_str(reverse, type, ext, mode):
|
||||
ext_str = extend[type][ext]
|
||||
src = f"OPA({src_types[type][mode]})"
|
||||
if mode == 0:
|
||||
if ext == 2:
|
||||
ext_str = src
|
||||
return f"{src}, {ext_str}"
|
||||
if reverse:
|
||||
return f"{ext_str}, {src}"
|
||||
else:
|
||||
return f"{src}, {ext_str}"
|
||||
elif mode == 1:
|
||||
if ext == 2:
|
||||
ext_str = src
|
||||
return f"{src}, {ext_str}, {ext_str}"
|
||||
if reverse:
|
||||
return f"{ext_str}, {ext_str}, {src}"
|
||||
else:
|
||||
return f"{src}, {ext_str}, {ext_str}"
|
||||
elif mode == 2:
|
||||
if ext == 2:
|
||||
ext_str = src
|
||||
return f"{src}, {ext_str}, {ext_str}, {ext_str}"
|
||||
elif mode == 3:
|
||||
return f"{src}[0], {src}[1], {ext_str}"
|
||||
elif mode == 4:
|
||||
if ext == 2:
|
||||
return f"{src}[0], {src}[1], {src}[0], {src}[1]"
|
||||
if reverse:
|
||||
return f"{ext_str}, {ext_str}, {ext_str}, {src}"
|
||||
else:
|
||||
return f"{src}[0], {src}[1], {ext_str}, {ext_str}"
|
||||
elif mode == 5:
|
||||
return f"{src}[0], {src}[1], {src}[2], {ext_str}"
|
||||
|
||||
for type in range(2):
|
||||
for ext in range(4):
|
||||
for mode in range(6): # 6, 7 are reserved
|
||||
case = case_str(type, ext, mode)
|
||||
dst = dst_str(type, ext, mode)
|
||||
cast = cast_str(type, ext, mode)
|
||||
init = init_str(type, ext, mode)
|
||||
if mode in [1, 3]:
|
||||
print(f"{case} VectorSet({init}, {dst}); break;");
|
||||
return f"{src}, {ext_str}, {ext_str}, {ext_str}"
|
||||
elif mode == 3:
|
||||
if reverse:
|
||||
return f"{ext_str}, {src}[1], {src}[0]"
|
||||
else:
|
||||
return f"{src}[0], {src}[1], {ext_str}"
|
||||
elif mode == 4:
|
||||
if reverse:
|
||||
if ext == 2:
|
||||
return f"{src}[1], {src}[0], {src}[1], {src}[0]"
|
||||
else:
|
||||
print(f"{case} {dst} = {cast} {{ {init} }}; break;");
|
||||
return f"{ext_str}, {ext_str}, {src}[1], {src}[0]"
|
||||
else:
|
||||
if ext == 2:
|
||||
return f"{src}[0], {src}[1], {src}[0], {src}[1]"
|
||||
else:
|
||||
return f"{src}[0], {src}[1], {ext_str}, {ext_str}"
|
||||
elif mode == 5:
|
||||
if reverse:
|
||||
return f"{ext_str}, {src}[2], {src}[1], {src}[0]"
|
||||
else:
|
||||
return f"{src}[0], {src}[1], {src}[2], {ext_str}"
|
||||
|
||||
for reverse in range(2):
|
||||
for type in range(2):
|
||||
for ext in range(4):
|
||||
for mode in range(6): # 6, 7 are reserved
|
||||
case = case_str(reverse, type, ext, mode)
|
||||
dst = dst_str(type, ext, mode)
|
||||
cast = cast_str(type, ext, mode)
|
||||
init = init_str(reverse, type, ext, mode)
|
||||
if mode in [1, 3]:
|
||||
print(f"{case} VectorSet({init}, {dst}); break;");
|
||||
else:
|
||||
print(f"{case} {dst} = {cast} {{ {init} }}; break;");
|
||||
|
|
|
@ -3,6 +3,8 @@ bitmap_txt = """
|
|||
0 0001 mmss store
|
||||
0 0010 mmss push
|
||||
0 0011 mmss pop
|
||||
0 0111 00ts swizzle2
|
||||
0 0111 01t0 wedge2
|
||||
0 1ccc ttss compare
|
||||
0 0000 00nn
|
||||
0 0000 0000 noop
|
||||
|
@ -155,11 +157,12 @@ compare_formats = {
|
|||
"mnemonic": "{op_cmp[ccc]}.{cmp_type[tt]}",
|
||||
"opname": "{op_cmp[ccc]}",
|
||||
"widths": "{ss+1}, {ss+1}, {ss+1}",
|
||||
"types": "{cmp_types[tt]}, {cmp_types[tt]}, ev_int",
|
||||
"types": "{cmp_types[tt]}, {cmp_types[tt]}, {res_types[tt & 2]}",
|
||||
"args": {
|
||||
"op_cmp": compare_ccc,
|
||||
"cmp_type": type_tt,
|
||||
"cmp_types": etype_tt,
|
||||
"res_types": etype_tt,
|
||||
},
|
||||
}
|
||||
compare2_formats = {
|
||||
|
@ -212,7 +215,7 @@ extend_formats = {
|
|||
"opcode": "OP_EXTEND",
|
||||
"mnemonic": "extend",
|
||||
"opname": "extend",
|
||||
"format": "%Ga %Hb %gc",
|
||||
"format": "%Ga%Xb, %gc",
|
||||
"widths": "-1, 0, -1",
|
||||
"types": "ev_void, ev_short, ev_void",
|
||||
}
|
||||
|
@ -220,7 +223,7 @@ hops_formats = {
|
|||
"opcode": "OP_HOPS",
|
||||
"mnemonic": "hops",
|
||||
"opname": "hops",
|
||||
"format": "%Ga %Hb %gc",
|
||||
"format": "%Hb %Ga, %gc",
|
||||
"widths": "-1, 0, 1",
|
||||
"types": "ev_void, ev_short, ev_void",
|
||||
}
|
||||
|
@ -508,15 +511,39 @@ string_formats = {
|
|||
},
|
||||
}
|
||||
swizzle_formats = {
|
||||
"opcode": "OP_SWIZZLE_{swiz_type[t]}",
|
||||
"opcode": "OP_SWIZZLE_{swiz_type[t]}_4",
|
||||
"mnemonic": "swizzle.{swiz_type[t]}",
|
||||
"opname": "swizzle",
|
||||
"format": "%Ga %sb %gc",
|
||||
"format": "%Ga.%Sb %gc",
|
||||
"widths": "4, 0, 4",
|
||||
"types": "{swizzle_types[t]}",
|
||||
"types": "{swizzle_types[t]}, ev_short, {swizzle_types[t]}",
|
||||
"args": {
|
||||
"swiz_type": ['F', 'D'],
|
||||
"swizzle_types": float_t,
|
||||
"swizzle_types": unsigned_t,
|
||||
},
|
||||
}
|
||||
swizzle2_formats = {
|
||||
"opcode": "OP_SWIZZLE_{swiz_type[t]}_{s+2}",
|
||||
"mnemonic": "swizzle.{swiz_type[t]}",
|
||||
"opname": "swizzle",
|
||||
"format": "%Ga.%Sb %gc",
|
||||
"widths": "{s+2}, 0, {s+2}",
|
||||
"types": "{swizzle_types[t]}, ev_short, {swizzle_types[t]}",
|
||||
"args": {
|
||||
"swiz_type": ['F', 'D'],
|
||||
"swizzle_types": unsigned_t,
|
||||
},
|
||||
}
|
||||
wedge2_formats = {
|
||||
"opcode": "OP_WEDGE_{wedge_type[t]}_2",
|
||||
"mnemonic": "wedge.{wedge_type[t]}",
|
||||
"opname": "wedge",
|
||||
"format": "%Ga, %Gb, %gc",
|
||||
"widths": "2, 2, 1",
|
||||
"types": "{wedge_types[t]}",
|
||||
"args": {
|
||||
"wedge_type": ['F', 'D'],
|
||||
"wedge_types": float_t,
|
||||
},
|
||||
}
|
||||
return_formats = {
|
||||
|
@ -551,9 +578,9 @@ vecops_formats = {
|
|||
"vop_type": ['F', 'D'],
|
||||
"vec_widths": [
|
||||
"3, 3, 3",
|
||||
"2, 2, 2",
|
||||
"3, 3, 3",
|
||||
"4, 4, 4",
|
||||
"2, 2, 1",
|
||||
"3, 3, 1",
|
||||
"4, 4, 1",
|
||||
"2, 2, 2",
|
||||
"4, 3, 3",
|
||||
"3, 4, 3",
|
||||
|
@ -614,10 +641,12 @@ group_map = {
|
|||
"store64": store64_formats,
|
||||
"string": string_formats,
|
||||
"swizzle": swizzle_formats,
|
||||
"swizzle2": swizzle2_formats,
|
||||
"return": return_formats,
|
||||
"udivops": udivops_formats,
|
||||
"vecops": vecops_formats,
|
||||
"vecops2": vecops2_formats,
|
||||
"wedge2": wedge2_formats,
|
||||
"with": with_formats,
|
||||
}
|
||||
|
||||
|
|
|
@ -260,6 +260,8 @@ pr_debug_type_size (const progs_t *pr, const qfot_type_t *type)
|
|||
case ty_alias:
|
||||
aux_type = &G_STRUCT (pr, qfot_type_t, type->alias.aux_type);
|
||||
return pr_debug_type_size (pr, aux_type);
|
||||
case ty_algebra:
|
||||
return 1; //FIXME wip
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1053,6 +1055,12 @@ static void
|
|||
value_string (pr_debug_data_t *data, qfot_type_t *type, pr_type_t *value)
|
||||
{
|
||||
switch (type->meta) {
|
||||
case ty_algebra:
|
||||
if (type->type == ev_invalid) {
|
||||
dstring_appendstr (data->dstr, "<?""?>");
|
||||
break;
|
||||
}
|
||||
// fall through
|
||||
case ty_handle:
|
||||
case ty_basic:
|
||||
switch (type->type) {
|
||||
|
@ -1174,6 +1182,65 @@ global_string (pr_debug_data_t *data, pr_ptr_t offset, qfot_type_t *type,
|
|||
return dstr->str;
|
||||
}
|
||||
|
||||
static const char *
|
||||
extend_string (pr_debug_data_t *data, pr_uint_t ext)
|
||||
{
|
||||
progs_t *pr = data->pr;
|
||||
prdeb_resources_t *res = pr->pr_debug_resources;
|
||||
static const char *extend_range[] = {
|
||||
"1>2", "1>3", "1>4",
|
||||
"2>3", "2>4", "3>4",
|
||||
"res1", "res2",
|
||||
};
|
||||
static const char *extend_string[] = {
|
||||
"0", "1", "c", "-1",
|
||||
};
|
||||
return va (res->va, "[%s%s:%s]%d",
|
||||
extend_range[ext & 7],
|
||||
ext & 0100 ? ":r" : "",
|
||||
extend_string[(ext >> 3) & 2],
|
||||
32 << ((ext >> 5) & 1));
|
||||
}
|
||||
|
||||
static const char *
|
||||
hop_string (pr_debug_data_t *data, pr_uint_t hop)
|
||||
{
|
||||
progs_t *pr = data->pr;
|
||||
prdeb_resources_t *res = pr->pr_debug_resources;
|
||||
static const char *hop_string[] = {
|
||||
"and", "or", "xor", "add",
|
||||
"nad", "nor", "xnor", "add",
|
||||
};
|
||||
static const char *type_string[2][8] = {
|
||||
{"I", "I", "I", "I", "I", "I", "I", "F"},
|
||||
{"L", "L", "L", "L", "L", "L", "L", "D"},
|
||||
};
|
||||
return va (res->va, "%s.%s{%d}",
|
||||
hop_string[hop & 7],
|
||||
type_string[(hop >> 5) & 1][hop & 7],
|
||||
((hop >> 3) & 3) + 1);
|
||||
}
|
||||
|
||||
static const char *
|
||||
swizzle_string (pr_debug_data_t *data, pr_uint_t swiz)
|
||||
{
|
||||
progs_t *pr = data->pr;
|
||||
prdeb_resources_t *res = pr->pr_debug_resources;
|
||||
static char swizzle_components[] = "xyzw";
|
||||
const char *swizzle = "";
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (swiz & (0x1000 << i)) {
|
||||
swizzle = va (res->va, "%s0", swizzle);
|
||||
} else {
|
||||
swizzle = va (res->va, "%s%s%c", swizzle,
|
||||
swiz & (0x100 << i) ? "-" : "",
|
||||
swizzle_components[(swiz >> 2 * i) & 3]);
|
||||
}
|
||||
}
|
||||
return swizzle;
|
||||
}
|
||||
|
||||
const char *
|
||||
PR_Debug_ValueString (progs_t *pr, pr_ptr_t offset, qfot_type_t *type,
|
||||
dstring_t *dstr)
|
||||
|
@ -1187,7 +1254,18 @@ static void
|
|||
pr_debug_void_view (qfot_type_t *type, pr_type_t *value, void *_data)
|
||||
{
|
||||
__auto_type data = (pr_debug_data_t *) _data;
|
||||
dasprintf (data->dstr, "<void>");
|
||||
dstring_t *dstr = data->dstr;
|
||||
|
||||
if (!type->basic.width) {
|
||||
dasprintf (dstr, "<void>");
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < type->basic.width; i++, value++) {
|
||||
if (i) {
|
||||
dstring_appendstr (dstr, ", ");
|
||||
}
|
||||
dasprintf (dstr, "<%08x>", PR_PTR (int, value));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1238,12 +1316,23 @@ pr_debug_float_view (qfot_type_t *type, pr_type_t *value, void *_data)
|
|||
__auto_type data = (pr_debug_data_t *) _data;
|
||||
dstring_t *dstr = data->dstr;
|
||||
|
||||
if (data->pr->progs->version == PROG_ID_VERSION
|
||||
&& ISDENORM (PR_PTR (int, value))
|
||||
&& PR_PTR (uint, value) != 0x80000000) {
|
||||
dasprintf (dstr, "<%08x>", PR_PTR (int, value));
|
||||
} else {
|
||||
dasprintf (dstr, "%.9g", PR_PTR (float, value));
|
||||
if (type->basic.width > 1) {
|
||||
dstring_appendstr (dstr, "[");
|
||||
}
|
||||
for (int i = 0; i < type->basic.width; i++, value++) {
|
||||
if (i) {
|
||||
dstring_appendstr (dstr, ", ");
|
||||
}
|
||||
if (data->pr->progs->version == PROG_ID_VERSION
|
||||
&& ISDENORM (PR_PTR (int, value))
|
||||
&& PR_PTR (uint, value) != 0x80000000) {
|
||||
dasprintf (dstr, "<%08x>", PR_PTR (int, value));
|
||||
} else {
|
||||
dasprintf (dstr, "%.9g", PR_PTR (float, value));
|
||||
}
|
||||
}
|
||||
if (type->basic.width > 1) {
|
||||
dstring_appendstr (dstr, "]");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1344,7 +1433,18 @@ pr_debug_int_view (qfot_type_t *type, pr_type_t *value, void *_data)
|
|||
__auto_type data = (pr_debug_data_t *) _data;
|
||||
dstring_t *dstr = data->dstr;
|
||||
|
||||
dasprintf (dstr, "%d", PR_PTR (int, value));
|
||||
if (type->basic.width > 1) {
|
||||
dstring_appendstr (dstr, "[");
|
||||
}
|
||||
for (int i = 0; i < type->basic.width; i++, value++) {
|
||||
if (i) {
|
||||
dstring_appendstr (dstr, ", ");
|
||||
}
|
||||
dasprintf (dstr, "%d", PR_PTR (int, value));
|
||||
}
|
||||
if (type->basic.width > 1) {
|
||||
dstring_appendstr (dstr, "]");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1353,7 +1453,18 @@ pr_debug_uint_view (qfot_type_t *type, pr_type_t *value, void *_data)
|
|||
__auto_type data = (pr_debug_data_t *) _data;
|
||||
dstring_t *dstr = data->dstr;
|
||||
|
||||
dasprintf (dstr, "$%08x", PR_PTR (uint, value));
|
||||
if (type->basic.width > 1) {
|
||||
dstring_appendstr (dstr, "[");
|
||||
}
|
||||
for (int i = 0; i < type->basic.width; i++, value++) {
|
||||
if (i) {
|
||||
dstring_appendstr (dstr, ", ");
|
||||
}
|
||||
dasprintf (dstr, "$%08x", PR_PTR (uint, value));
|
||||
}
|
||||
if (type->basic.width > 1) {
|
||||
dstring_appendstr (dstr, "]");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1371,7 +1482,18 @@ pr_debug_double_view (qfot_type_t *type, pr_type_t *value, void *_data)
|
|||
__auto_type data = (pr_debug_data_t *) _data;
|
||||
dstring_t *dstr = data->dstr;
|
||||
|
||||
dasprintf (dstr, "%.17g", *(double *)value);
|
||||
if (type->basic.width > 1) {
|
||||
dstring_appendstr (dstr, "[");
|
||||
}
|
||||
for (int i = 0; i < type->basic.width; i++, value += 2) {
|
||||
if (i) {
|
||||
dstring_appendstr (dstr, ", ");
|
||||
}
|
||||
dasprintf (dstr, "%.17g", *(double *)value);
|
||||
}
|
||||
if (type->basic.width > 1) {
|
||||
dstring_appendstr (dstr, "]");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1380,7 +1502,18 @@ pr_debug_long_view (qfot_type_t *type, pr_type_t *value, void *_data)
|
|||
__auto_type data = (pr_debug_data_t *) _data;
|
||||
dstring_t *dstr = data->dstr;
|
||||
|
||||
dasprintf (dstr, "%" PRIi64, *(int64_t *)value);
|
||||
if (type->basic.width > 1) {
|
||||
dstring_appendstr (dstr, "[");
|
||||
}
|
||||
for (int i = 0; i < type->basic.width; i++, value += 2) {
|
||||
if (i) {
|
||||
dstring_appendstr (dstr, ", ");
|
||||
}
|
||||
dasprintf (dstr, "%" PRIi64, *(int64_t *)value);
|
||||
}
|
||||
if (type->basic.width > 1) {
|
||||
dstring_appendstr (dstr, "]");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1389,7 +1522,18 @@ pr_debug_ulong_view (qfot_type_t *type, pr_type_t *value, void *_data)
|
|||
__auto_type data = (pr_debug_data_t *) _data;
|
||||
dstring_t *dstr = data->dstr;
|
||||
|
||||
dasprintf (dstr, "%" PRIu64, *(uint64_t *)value);
|
||||
if (type->basic.width > 1) {
|
||||
dstring_appendstr (dstr, "[");
|
||||
}
|
||||
for (int i = 0; i < type->basic.width; i++, value += 2) {
|
||||
if (i) {
|
||||
dstring_appendstr (dstr, ", ");
|
||||
}
|
||||
dasprintf (dstr, "%" PRIx64, *(uint64_t *)value);
|
||||
}
|
||||
if (type->basic.width > 1) {
|
||||
dstring_appendstr (dstr, "]");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1514,17 +1658,26 @@ PR_Debug_Print (progs_t *pr, const char *expr)
|
|||
}
|
||||
|
||||
static const char *
|
||||
print_raw_op (progs_t *pr, pr_ushort_t op, pr_ushort_t base_ind,
|
||||
print_raw_op (progs_t *pr, pr_short_t op, pr_ushort_t base_ind,
|
||||
etype_t op_type, int op_width)
|
||||
{
|
||||
prdeb_resources_t *res = pr->pr_debug_resources;
|
||||
const char *width = va (res->va, "%d", op_width);
|
||||
return va (res->va, "%d:%04x<%08x>%s:%-8s",
|
||||
return va (res->va, "%d:%04hx<%08x>%s:%-8s",
|
||||
base_ind, op, op + pr->pr_bases[base_ind],
|
||||
op_width > 0 ? width : op_width < 0 ? "X" : "?",
|
||||
pr_type_name[op_type]);
|
||||
}
|
||||
|
||||
static pr_uint_t
|
||||
get_opval (progs_t *pr, pr_short_t op)
|
||||
{
|
||||
if (pr->progs->version < PROG_VERSION) {
|
||||
return (pr_ushort_t) op;
|
||||
}
|
||||
return op;
|
||||
}
|
||||
|
||||
VISIBLE void
|
||||
PR_PrintStatement (progs_t *pr, dstatement_t *s, int contents)
|
||||
{
|
||||
|
@ -1591,7 +1744,7 @@ PR_PrintStatement (progs_t *pr, dstatement_t *s, int contents)
|
|||
if (pr_debug > 2) {
|
||||
if (pr->progs->version < PROG_VERSION) {
|
||||
dasprintf (res->line,
|
||||
"%03x %04x(%8s) %04x(%8s) %04x(%8s)\t",
|
||||
"%03x %04hx(%8s) %04hx(%8s) %04hx(%8s)\t",
|
||||
s->op,
|
||||
s->a, pr_type_name[op_type[0]],
|
||||
s->b, pr_type_name[op_type[1]],
|
||||
|
@ -1624,7 +1777,8 @@ PR_PrintStatement (progs_t *pr, dstatement_t *s, int contents)
|
|||
pr_uint_t shift = 0;
|
||||
pr_uint_t opreg;
|
||||
pr_uint_t opval;
|
||||
qfot_type_t *optype = &res->void_type;
|
||||
qfot_type_t basic_type = {};
|
||||
qfot_type_t *optype = &basic_type;
|
||||
pr_func_t func;
|
||||
|
||||
if (mode == 'P') {
|
||||
|
@ -1647,18 +1801,21 @@ PR_PrintStatement (progs_t *pr, dstatement_t *s, int contents)
|
|||
switch (opchar) {
|
||||
case 'a':
|
||||
opreg = PR_BASE_IND (s->op, A);
|
||||
opval = s->a;
|
||||
optype = res->type_encodings[op_type[0]];
|
||||
opval = get_opval (pr, s->a);
|
||||
basic_type = *res->type_encodings[op_type[0]];
|
||||
basic_type.basic.width = op_width[0];
|
||||
break;
|
||||
case 'b':
|
||||
opreg = PR_BASE_IND (s->op, B);
|
||||
opval = s->b;
|
||||
optype = res->type_encodings[op_type[1]];
|
||||
opval = get_opval (pr, s->b);
|
||||
basic_type = *res->type_encodings[op_type[1]];
|
||||
basic_type.basic.width = op_width[1];
|
||||
break;
|
||||
case 'c':
|
||||
opreg = PR_BASE_IND (s->op, C);
|
||||
opval = s->c;
|
||||
optype = res->type_encodings[op_type[2]];
|
||||
opval = get_opval (pr, s->c);
|
||||
basic_type = *res->type_encodings[op_type[2]];
|
||||
basic_type.basic.width = op_width[2];
|
||||
break;
|
||||
case 'o':
|
||||
opreg = 0;
|
||||
|
@ -1719,6 +1876,15 @@ PR_PrintStatement (progs_t *pr, dstatement_t *s, int contents)
|
|||
case 's':
|
||||
str = dsprintf (res->dva, "%d", (short) opval);
|
||||
break;
|
||||
case 'H':
|
||||
str = hop_string (&data, opval);
|
||||
break;
|
||||
case 'S':
|
||||
str = swizzle_string (&data, opval);
|
||||
break;
|
||||
case 'X':
|
||||
str = extend_string (&data, opval);
|
||||
break;
|
||||
case 'O':
|
||||
str = dsprintf (res->dva, "%04x",
|
||||
addr + (short) opval);
|
||||
|
@ -1729,8 +1895,8 @@ PR_PrintStatement (progs_t *pr, dstatement_t *s, int contents)
|
|||
case 'E':
|
||||
{
|
||||
edict_t *ed = 0;
|
||||
opval = G_ENTITY (pr, s->a);
|
||||
param_ind = G_FIELD (pr, s->b);
|
||||
opval = G_ENTITY (pr, (pr_ushort_t) s->a);
|
||||
param_ind = G_FIELD (pr, (pr_ushort_t) s->b);
|
||||
if (param_ind < pr->progs->entityfields
|
||||
&& opval > 0
|
||||
&& opval < pr->pr_edict_area_size) {
|
||||
|
@ -1744,7 +1910,8 @@ PR_PrintStatement (progs_t *pr, dstatement_t *s, int contents)
|
|||
str = global_string (&data, opval, optype,
|
||||
contents & 1);
|
||||
str = dsprintf (res->dva, "$%x $%x %s",
|
||||
s->a, s->b, str);
|
||||
(pr_ushort_t) s->a,
|
||||
(pr_ushort_t) s->b, str);
|
||||
}
|
||||
break;
|
||||
case 'M':
|
||||
|
@ -1761,7 +1928,7 @@ PR_PrintStatement (progs_t *pr, dstatement_t *s, int contents)
|
|||
case 2:
|
||||
ptr = s->a + PR_BASE (pr, s, A);
|
||||
ptr = G_POINTER (pr, ptr);
|
||||
offs = (short) s->b;
|
||||
offs = s->b;
|
||||
break;
|
||||
case 3:
|
||||
ptr = s->a + PR_BASE (pr, s, A);
|
||||
|
|
|
@ -547,9 +547,9 @@ pr_exec_quakec (progs_t *pr, int exitdepth)
|
|||
PR_RunError (pr, "runaway loop error");
|
||||
}
|
||||
|
||||
op_a = pr->pr_globals + st->a;
|
||||
op_b = pr->pr_globals + st->b;
|
||||
op_c = pr->pr_globals + st->c;
|
||||
op_a = pr->pr_globals + (pr_ushort_t) st->a;
|
||||
op_b = pr->pr_globals + (pr_ushort_t) st->b;
|
||||
op_c = pr->pr_globals + (pr_ushort_t) st->c;
|
||||
|
||||
if (pr->pr_trace) {
|
||||
if (pr->debug_handler) {
|
||||
|
@ -888,7 +888,7 @@ pr_exec_quakec (progs_t *pr, int exitdepth)
|
|||
case OP_ADDRESS_I_v6p:
|
||||
case OP_ADDRESS_P_v6p:
|
||||
case OP_ADDRESS_D_v6p:
|
||||
OPC(int) = st->a;
|
||||
OPC(int) = (pr_ushort_t) st->a;
|
||||
break;
|
||||
|
||||
case OP_LOAD_F_v6p:
|
||||
|
@ -990,7 +990,7 @@ pr_exec_quakec (progs_t *pr, int exitdepth)
|
|||
case OP_LOADBI_FN_v6p:
|
||||
case OP_LOADBI_I_v6p:
|
||||
case OP_LOADBI_P_v6p:
|
||||
pointer = OPA(ptr) + (short) st->b;
|
||||
pointer = OPA(ptr) + st->b;
|
||||
if (pr_boundscheck) {
|
||||
PR_BoundsCheck (pr, pointer, ev_int);
|
||||
}
|
||||
|
@ -998,7 +998,7 @@ pr_exec_quakec (progs_t *pr, int exitdepth)
|
|||
OPC(int) = ptr->value;
|
||||
break;
|
||||
case OP_LOADBI_V_v6p:
|
||||
pointer = OPA(ptr) + (short) st->b;
|
||||
pointer = OPA(ptr) + st->b;
|
||||
if (pr_boundscheck) {
|
||||
PR_BoundsCheck (pr, pointer, ev_vector);
|
||||
}
|
||||
|
@ -1006,7 +1006,7 @@ pr_exec_quakec (progs_t *pr, int exitdepth)
|
|||
VectorCopy (G_VECTOR (pr, pointer), &OPC(float));
|
||||
break;
|
||||
case OP_LOADBI_Q_v6p:
|
||||
pointer = OPA(ptr) + (short) st->b;
|
||||
pointer = OPA(ptr) + st->b;
|
||||
if (pr_boundscheck) {
|
||||
PR_BoundsCheck (pr, pointer, ev_quaternion);
|
||||
}
|
||||
|
@ -1014,7 +1014,7 @@ pr_exec_quakec (progs_t *pr, int exitdepth)
|
|||
QuatCopy (G_QUAT (pr, pointer), &OPC(float));
|
||||
break;
|
||||
case OP_LOADBI_D_v6p:
|
||||
pointer = OPA(ptr) + (short) st->b;
|
||||
pointer = OPA(ptr) + st->b;
|
||||
if (pr_boundscheck) {
|
||||
PR_BoundsCheck (pr, pointer, ev_quaternion);
|
||||
}
|
||||
|
@ -1028,7 +1028,7 @@ pr_exec_quakec (progs_t *pr, int exitdepth)
|
|||
break;
|
||||
|
||||
case OP_LEAI_v6p:
|
||||
pointer = OPA(ptr) + (short) st->b;
|
||||
pointer = OPA(ptr) + st->b;
|
||||
OPC(ptr) = pointer;
|
||||
break;
|
||||
|
||||
|
@ -1078,7 +1078,7 @@ pr_exec_quakec (progs_t *pr, int exitdepth)
|
|||
case OP_STOREBI_FN_v6p:
|
||||
case OP_STOREBI_I_v6p:
|
||||
case OP_STOREBI_P_v6p:
|
||||
pointer = OPB(ptr) + (short) st->c;
|
||||
pointer = OPB(ptr) + st->c;
|
||||
if (pr_boundscheck) {
|
||||
PR_BoundsCheck (pr, pointer, ev_int);
|
||||
}
|
||||
|
@ -1086,7 +1086,7 @@ pr_exec_quakec (progs_t *pr, int exitdepth)
|
|||
ptr->value = OPA(int);
|
||||
break;
|
||||
case OP_STOREBI_V_v6p:
|
||||
pointer = OPB(ptr) + (short) st->c;
|
||||
pointer = OPB(ptr) + st->c;
|
||||
if (pr_boundscheck) {
|
||||
PR_BoundsCheck (pr, pointer, ev_vector);
|
||||
}
|
||||
|
@ -1094,7 +1094,7 @@ pr_exec_quakec (progs_t *pr, int exitdepth)
|
|||
VectorCopy (&OPA(float), G_VECTOR (pr, pointer));
|
||||
break;
|
||||
case OP_STOREBI_Q_v6p:
|
||||
pointer = OPB(ptr) + (short) st->c;
|
||||
pointer = OPB(ptr) + st->c;
|
||||
if (pr_boundscheck) {
|
||||
PR_BoundsCheck (pr, pointer, ev_quaternion);
|
||||
}
|
||||
|
@ -1102,7 +1102,7 @@ pr_exec_quakec (progs_t *pr, int exitdepth)
|
|||
QuatCopy (&OPA(float), G_QUAT (pr, pointer));
|
||||
break;
|
||||
case OP_STOREBI_D_v6p:
|
||||
pointer = OPB(ptr) + (short) st->c;
|
||||
pointer = OPB(ptr) + st->c;
|
||||
if (pr_boundscheck) {
|
||||
PR_BoundsCheck (pr, pointer, ev_quaternion);
|
||||
}
|
||||
|
@ -1217,7 +1217,7 @@ pr_exec_quakec (progs_t *pr, int exitdepth)
|
|||
pr_ptr_t stack = *pr->globals.stack - 1;
|
||||
pr_type_t *stk = pr->pr_globals + stack;
|
||||
|
||||
pointer = OPA(ptr) + st->b;
|
||||
pointer = OPA(ptr) + (pr_ushort_t) st->b;
|
||||
ptr = pr->pr_globals + pointer;
|
||||
|
||||
if (pr_boundscheck) {
|
||||
|
@ -1233,7 +1233,7 @@ pr_exec_quakec (progs_t *pr, int exitdepth)
|
|||
{
|
||||
pr_ptr_t stack = *pr->globals.stack - 3;
|
||||
|
||||
pointer = OPA(ptr) + st->b;
|
||||
pointer = OPA(ptr) + (pr_ushort_t) st->b;
|
||||
ptr = pr->pr_globals + pointer;
|
||||
|
||||
if (pr_boundscheck) {
|
||||
|
@ -1249,7 +1249,7 @@ pr_exec_quakec (progs_t *pr, int exitdepth)
|
|||
{
|
||||
pr_ptr_t stack = *pr->globals.stack - 4;
|
||||
|
||||
pointer = OPA(ptr) + st->b;
|
||||
pointer = OPA(ptr) + (pr_ushort_t) st->b;
|
||||
ptr = pr->pr_globals + pointer;
|
||||
|
||||
if (pr_boundscheck) {
|
||||
|
@ -1369,7 +1369,7 @@ pr_exec_quakec (progs_t *pr, int exitdepth)
|
|||
pr_ptr_t stack = *pr->globals.stack;
|
||||
pr_type_t *stk = pr->pr_globals + stack;
|
||||
|
||||
pointer = OPA(ptr) + st->b;
|
||||
pointer = OPA(ptr) + (pr_ushort_t) st->b;
|
||||
ptr = pr->pr_globals + pointer;
|
||||
|
||||
if (pr_boundscheck) {
|
||||
|
@ -1385,7 +1385,7 @@ pr_exec_quakec (progs_t *pr, int exitdepth)
|
|||
{
|
||||
pr_ptr_t stack = *pr->globals.stack;
|
||||
|
||||
pointer = OPA(ptr) + st->b;
|
||||
pointer = OPA(ptr) + (pr_ushort_t) st->b;
|
||||
ptr = pr->pr_globals + pointer;
|
||||
|
||||
if (pr_boundscheck) {
|
||||
|
@ -1401,7 +1401,7 @@ pr_exec_quakec (progs_t *pr, int exitdepth)
|
|||
{
|
||||
pr_ptr_t stack = *pr->globals.stack;
|
||||
|
||||
pointer = OPA(ptr) + st->b;
|
||||
pointer = OPA(ptr) + (pr_ushort_t) st->b;
|
||||
ptr = pr->pr_globals + pointer;
|
||||
|
||||
if (pr_boundscheck) {
|
||||
|
@ -1417,42 +1417,42 @@ pr_exec_quakec (progs_t *pr, int exitdepth)
|
|||
// ==================
|
||||
case OP_IFNOT_v6p:
|
||||
if (!OPA(int)) {
|
||||
pr->pr_xstatement += (short)st->b - 1; // offset the st++
|
||||
pr->pr_xstatement += st->b - 1; // offset the st++
|
||||
st = pr->pr_statements + pr->pr_xstatement;
|
||||
}
|
||||
break;
|
||||
case OP_IF_v6p:
|
||||
if (OPA(int)) {
|
||||
pr->pr_xstatement += (short)st->b - 1; // offset the st++
|
||||
pr->pr_xstatement += st->b - 1; // offset the st++
|
||||
st = pr->pr_statements + pr->pr_xstatement;
|
||||
}
|
||||
break;
|
||||
case OP_IFBE_v6p:
|
||||
if (OPA(int) <= 0) {
|
||||
pr->pr_xstatement += (short)st->b - 1; // offset the st++
|
||||
pr->pr_xstatement += st->b - 1; // offset the st++
|
||||
st = pr->pr_statements + pr->pr_xstatement;
|
||||
}
|
||||
break;
|
||||
case OP_IFB_v6p:
|
||||
if (OPA(int) < 0) {
|
||||
pr->pr_xstatement += (short)st->b - 1; // offset the st++
|
||||
pr->pr_xstatement += st->b - 1; // offset the st++
|
||||
st = pr->pr_statements + pr->pr_xstatement;
|
||||
}
|
||||
break;
|
||||
case OP_IFAE_v6p:
|
||||
if (OPA(int) >= 0) {
|
||||
pr->pr_xstatement += (short)st->b - 1; // offset the st++
|
||||
pr->pr_xstatement += st->b - 1; // offset the st++
|
||||
st = pr->pr_statements + pr->pr_xstatement;
|
||||
}
|
||||
break;
|
||||
case OP_IFA_v6p:
|
||||
if (OPA(int) > 0) {
|
||||
pr->pr_xstatement += (short)st->b - 1; // offset the st++
|
||||
pr->pr_xstatement += st->b - 1; // offset the st++
|
||||
st = pr->pr_statements + pr->pr_xstatement;
|
||||
}
|
||||
break;
|
||||
case OP_GOTO_v6p:
|
||||
pr->pr_xstatement += (short)st->a - 1; // offset the st++
|
||||
pr->pr_xstatement += st->a - 1; // offset the st++
|
||||
st = pr->pr_statements + pr->pr_xstatement;
|
||||
break;
|
||||
case OP_JUMP_v6p:
|
||||
|
@ -1464,7 +1464,7 @@ pr_exec_quakec (progs_t *pr, int exitdepth)
|
|||
st = pr->pr_statements + pr->pr_xstatement;
|
||||
break;
|
||||
case OP_JUMPB_v6p:
|
||||
pointer = st->a + OPB(int);
|
||||
pointer = (pr_ushort_t) st->a + OPB(int);
|
||||
if (pr_boundscheck) {
|
||||
PR_BoundsCheck (pr, pointer, ev_int);
|
||||
}
|
||||
|
@ -1684,7 +1684,7 @@ op_call:
|
|||
break;
|
||||
|
||||
case OP_MOVEI_v6p:
|
||||
memmove (op_c, op_a, st->b * 4);
|
||||
memmove (op_c, op_a, (pr_ushort_t) st->b * 4);
|
||||
break;
|
||||
case OP_MOVEP_v6p:
|
||||
if (pr_boundscheck) {
|
||||
|
@ -1697,15 +1697,15 @@ op_call:
|
|||
break;
|
||||
case OP_MOVEPI_v6p:
|
||||
if (pr_boundscheck) {
|
||||
PR_BoundsCheckSize (pr, OPC(ptr), st->b);
|
||||
PR_BoundsCheckSize (pr, OPA(ptr), st->b);
|
||||
PR_BoundsCheckSize (pr, OPC(ptr), (pr_ushort_t) st->b);
|
||||
PR_BoundsCheckSize (pr, OPA(ptr), (pr_ushort_t) st->b);
|
||||
}
|
||||
memmove (pr->pr_globals + OPC(ptr),
|
||||
pr->pr_globals + OPA(ptr),
|
||||
st->b * 4);
|
||||
(pr_ushort_t) st->b * 4);
|
||||
break;
|
||||
case OP_MEMSETI_v6p:
|
||||
pr_memset (op_c, OPA(ptr), st->b);
|
||||
pr_memset (op_c, OPA(ptr), (pr_ushort_t) st->b);
|
||||
break;
|
||||
case OP_MEMSETP_v6p:
|
||||
if (pr_boundscheck) {
|
||||
|
@ -1716,10 +1716,10 @@ op_call:
|
|||
break;
|
||||
case OP_MEMSETPI_v6p:
|
||||
if (pr_boundscheck) {
|
||||
PR_BoundsCheckSize (pr, OPC(ptr), st->b);
|
||||
PR_BoundsCheckSize (pr, OPC(ptr), (pr_ushort_t) st->b);
|
||||
}
|
||||
pr_memset (pr->pr_globals + OPC(ptr), OPA(int),
|
||||
st->b);
|
||||
(pr_ushort_t) st->b);
|
||||
break;
|
||||
case OP_GE_D_v6p:
|
||||
OPC(float) = OPA(double) >= OPB(double);
|
||||
|
@ -1758,9 +1758,10 @@ op_call:
|
|||
// LordHavoc: to be enabled when Progs version 7 (or whatever it will be numbered) is finalized
|
||||
/*
|
||||
case OP_BOUNDCHECK_v6p:
|
||||
if (OPA(ptr) >= st->b) {
|
||||
if (OPA(ptr) >= (pr_ushort_t) st->b) {
|
||||
PR_RunError (pr, "Progs boundcheck failed at line number "
|
||||
"%d, value is < 0 or >= %d", st->b, st->c);
|
||||
"%d, value is < 0 or >= %d", (pr_ushort_t) st->b,
|
||||
(pr_ushort_t) st->c);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1781,7 +1782,7 @@ op_call:
|
|||
old_val.value = pr->watch->value;
|
||||
}
|
||||
}
|
||||
exit_program:
|
||||
exit_program:;
|
||||
}
|
||||
|
||||
#define MM(type) (*((pr_##type##_t *) (mm)))
|
||||
|
@ -1793,6 +1794,7 @@ pr_address_mode (progs_t *pr, const dstatement_t *st, int mm_ind)
|
|||
pr_type_t *op_a = pr->pr_globals + st->a + PR_BASE (pr, st, A);
|
||||
pr_type_t *op_b = pr->pr_globals + st->b + PR_BASE (pr, st, B);
|
||||
pr_ptr_t mm_offs = 0;
|
||||
pr_ptr_t edict_area = 0;
|
||||
|
||||
switch (mm_ind) {
|
||||
case 0:
|
||||
|
@ -1801,12 +1803,12 @@ pr_address_mode (progs_t *pr, const dstatement_t *st, int mm_ind)
|
|||
break;
|
||||
case 1:
|
||||
// entity.field (equivalent to OP_LOAD_t_v6p)
|
||||
pr_ptr_t edict_area = pr->pr_edict_area - pr->pr_globals;
|
||||
edict_area = pr->pr_edict_area - pr->pr_globals;
|
||||
mm_offs = edict_area + OPA(entity) + OPB(field);
|
||||
break;
|
||||
case 2:
|
||||
// constant indexed pointer: *a + b (supports -ve offset)
|
||||
mm_offs = OPA(ptr) + (short) st->b;
|
||||
mm_offs = OPA(ptr) + st->b;
|
||||
break;
|
||||
case 3:
|
||||
// variable indexed pointer: *a + *b (supports -ve offset)
|
||||
|
@ -1814,7 +1816,7 @@ pr_address_mode (progs_t *pr, const dstatement_t *st, int mm_ind)
|
|||
break;
|
||||
case 4:
|
||||
// global access with constant offset (supports -ve offset)
|
||||
mm_offs = op_a - pr->pr_globals + (short) st->b;
|
||||
mm_offs = op_a - pr->pr_globals + st->b;
|
||||
break;
|
||||
case 5:
|
||||
// global access with variable offset (supports -ve offset)
|
||||
|
@ -1830,6 +1832,7 @@ pr_call_mode (progs_t *pr, const dstatement_t *st, int mm_ind)
|
|||
pr_type_t *op_a = pr->pr_globals + st->a + PR_BASE (pr, st, A);
|
||||
pr_type_t *op_b = pr->pr_globals + st->b + PR_BASE (pr, st, B);
|
||||
pr_ptr_t mm_offs = 0;
|
||||
pr_ptr_t edict_area = 0;
|
||||
|
||||
switch (mm_ind) {
|
||||
case 1:
|
||||
|
@ -1838,7 +1841,7 @@ pr_call_mode (progs_t *pr, const dstatement_t *st, int mm_ind)
|
|||
break;
|
||||
case 2:
|
||||
// constant indexed pointer: *a + b (supports -ve offset)
|
||||
mm_offs = OPA(ptr) + (short) st->b;
|
||||
mm_offs = OPA(ptr) + st->b;
|
||||
break;
|
||||
case 3:
|
||||
// variable indexed pointer: *a + *b (supports -ve offset)
|
||||
|
@ -1846,7 +1849,7 @@ pr_call_mode (progs_t *pr, const dstatement_t *st, int mm_ind)
|
|||
break;
|
||||
case 4:
|
||||
// entity.field (equivalent to OP_LOAD_t_v6p)
|
||||
pr_ptr_t edict_area = pr->pr_edict_area - pr->pr_globals;
|
||||
edict_area = pr->pr_edict_area - pr->pr_globals;
|
||||
mm_offs = edict_area + OPA(entity) + OPB(field);
|
||||
break;
|
||||
}
|
||||
|
@ -1863,7 +1866,7 @@ pr_jump_mode (progs_t *pr, const dstatement_t *st, int jump_ind)
|
|||
switch (jump_ind) {
|
||||
case 0:
|
||||
// instruction relative offset
|
||||
jump_offs = jump_offs + (short) st->a;
|
||||
jump_offs = jump_offs + st->a;
|
||||
break;
|
||||
case 1:
|
||||
// variable indexed array: a + *b (only +ve)
|
||||
|
@ -1871,7 +1874,7 @@ pr_jump_mode (progs_t *pr, const dstatement_t *st, int jump_ind)
|
|||
break;
|
||||
case 2:
|
||||
// constant indexed pointer: *a + b (supports -ve offset)
|
||||
jump_offs = OPA(ptr) + (short) st->b;
|
||||
jump_offs = OPA(ptr) + st->b;
|
||||
break;
|
||||
case 3:
|
||||
// variable indexed pointer: *a + *b (supports -ve offset)
|
||||
|
@ -1936,24 +1939,24 @@ pr_with (progs_t *pr, const dstatement_t *st)
|
|||
// fixed offset
|
||||
case 0:
|
||||
// hard-0 base
|
||||
pr->pr_bases[st->c & 3] = st->b;
|
||||
pr->pr_bases[st->c & 3] = (pr_ushort_t) st->b;
|
||||
return;
|
||||
case 1:
|
||||
// relative to current base (-ve offset)
|
||||
pr->pr_bases[st->c & 3] = PR_BASE (pr, st, B) + (pr_short_t) st->b;
|
||||
pr->pr_bases[st->c & 3] = PR_BASE (pr, st, B) + st->b;
|
||||
return;
|
||||
case 2:
|
||||
// relative to stack (-ve offset)
|
||||
pr->pr_bases[st->c & 3] = *pr->globals.stack + (pr_short_t) st->b;
|
||||
pr->pr_bases[st->c & 3] = *pr->globals.stack + st->b;
|
||||
return;
|
||||
case 3:
|
||||
// relative to edict_area (only +ve)
|
||||
pr->pr_bases[st->c & 3] = edict_area + st->b;
|
||||
pr->pr_bases[st->c & 3] = edict_area + (pr_ushort_t) st->b;
|
||||
return;
|
||||
|
||||
case 4:
|
||||
// hard-0 base
|
||||
pr->pr_bases[st->c & 3] = G_POINTER (pr, st->b);;
|
||||
pr->pr_bases[st->c & 3] = G_POINTER (pr, (pr_ushort_t) st->b);;
|
||||
return;
|
||||
case 5:
|
||||
pr->pr_bases[st->c & 3] = OPB(ptr);
|
||||
|
@ -2148,13 +2151,16 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth)
|
|||
pr_type_t *stk;
|
||||
pr_type_t *mm;
|
||||
pr_func_t function;
|
||||
|
||||
int ret_size = 0;
|
||||
|
||||
pr_opcode_e st_op = st->op & OP_MASK;
|
||||
switch (st_op) {
|
||||
// 0 0000
|
||||
case OP_NOP:
|
||||
break;
|
||||
case OP_ADJSTK:
|
||||
pr_stack_adjust (pr, st->a, (short) st->b);
|
||||
pr_stack_adjust (pr, (pr_ushort_t) st->a, st->b);
|
||||
break;
|
||||
case OP_LDCONST:
|
||||
PR_RunError (pr, "OP_LDCONST not implemented");
|
||||
|
@ -2285,6 +2291,51 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth)
|
|||
// 0 0110
|
||||
// spare
|
||||
// 0 0111
|
||||
case OP_SWIZZLE_F_2:
|
||||
{
|
||||
auto s2 = OPA(ivec2);
|
||||
pr_ivec4_t s4 = { s2[0], s2[1] };
|
||||
s4 = pr_swizzle_f (s4, (pr_ushort_t) st->b);
|
||||
OPC(ivec2) = (pr_ivec2_t) { s4[0], s4[1] };
|
||||
}
|
||||
break;
|
||||
case OP_SWIZZLE_F_3:
|
||||
{
|
||||
auto s4 = loadvec3i (&OPA(int));
|
||||
s4 = pr_swizzle_f (s4, (pr_ushort_t) st->b);
|
||||
storevec3i (&OPA(int), s4);
|
||||
}
|
||||
break;
|
||||
case OP_SWIZZLE_D_2:
|
||||
{
|
||||
auto s2 = OPA(lvec2);
|
||||
pr_lvec4_t s4 = { s2[0], s2[1] };
|
||||
s4 = pr_swizzle_d (s4, (pr_ushort_t) st->b);
|
||||
OPC(lvec2) = (pr_lvec2_t) { s4[0], s4[1] };
|
||||
}
|
||||
break;
|
||||
case OP_SWIZZLE_D_3:
|
||||
{
|
||||
auto s4 = loadvec3l (&OPA(long));
|
||||
s4 = pr_swizzle_d (s4, (pr_ushort_t) st->b);
|
||||
storevec3l (&OPC(long), s4);
|
||||
}
|
||||
break;
|
||||
case OP_WEDGE_F_2:
|
||||
{
|
||||
auto a = OPA(vec2);
|
||||
auto b = OPB(vec2);
|
||||
OPC(float) = a[0] * b[1] - a[1] * b[0];
|
||||
}
|
||||
break;
|
||||
// spare
|
||||
case OP_WEDGE_D_2:
|
||||
{
|
||||
auto a = OPA(dvec2);
|
||||
auto b = OPB(dvec2);
|
||||
OPC(double) = a[0] * b[1] - a[1] * b[0];
|
||||
}
|
||||
break;
|
||||
// spare
|
||||
|
||||
#define OP_cmp_1(OP, T, rt, cmp, ct) \
|
||||
|
@ -2547,16 +2598,16 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth)
|
|||
break;
|
||||
OP_cmp_T (LT, U, long, lvec2, lvec4, <, ulong, ulvec2, ulvec4);
|
||||
case OP_RETURN:
|
||||
int ret_size = (st->c & 0x1f) + 1; // up to 32 words
|
||||
if (st->c != 0xffff) {
|
||||
mm = pr_address_mode (pr, st, st->c >> 5);
|
||||
ret_size = (st->c & 0x1f) + 1; // up to 32 words
|
||||
if ((pr_ushort_t) st->c != 0xffff) {
|
||||
mm = pr_address_mode (pr, st, ((pr_ushort_t) st->c) >> 5);
|
||||
memcpy (&R_INT (pr), mm, ret_size * sizeof (*op_a));
|
||||
}
|
||||
pr->pr_xfunction->profile += profile - startprofile;
|
||||
startprofile = profile;
|
||||
PR_LeaveFunction (pr, pr->pr_depth == exitdepth);
|
||||
st = pr->pr_statements + pr->pr_xstatement;
|
||||
if (pr->pr_depth== exitdepth) {
|
||||
if (pr->pr_depth == exitdepth) {
|
||||
if (pr->pr_trace && pr->pr_depth <= pr->pr_trace_depth) {
|
||||
pr->pr_trace = false;
|
||||
}
|
||||
|
@ -2577,8 +2628,8 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth)
|
|||
break;
|
||||
// 1 1010
|
||||
OP_cmp_T (GT, u, int, ivec2, ivec4, >, uint, uivec2, uivec4);
|
||||
case OP_SWIZZLE_F:
|
||||
OPC(ivec4) = pr_swizzle_f (OPA(ivec4), st->b);
|
||||
case OP_SWIZZLE_F_4:
|
||||
OPC(ivec4) = pr_swizzle_f (OPA(ivec4), (pr_ushort_t) st->b);
|
||||
break;
|
||||
case OP_SCALE_F_2:
|
||||
OPC(vec2) = OPA(vec2) * OPB(float);
|
||||
|
@ -2590,8 +2641,8 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth)
|
|||
OPC(vec4) = OPA(vec4) * OPB(float);
|
||||
break;
|
||||
OP_cmp_T (GT, U, long, lvec2, lvec4, >, ulong, ulvec2, ulvec4);
|
||||
case OP_SWIZZLE_D:
|
||||
OPC(lvec4) = pr_swizzle_d (OPA(lvec4), st->b);
|
||||
case OP_SWIZZLE_D_4:
|
||||
OPC(lvec4) = pr_swizzle_d (OPA(lvec4), (pr_ushort_t) st->b);
|
||||
break;
|
||||
case OP_SCALE_D_2:
|
||||
OPC(dvec2) = OPA(dvec2) * OPB(double);
|
||||
|
@ -2612,17 +2663,13 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth)
|
|||
}
|
||||
break;
|
||||
case OP_CDOT_F:
|
||||
OPC(vec2) = dot2f (OPA(vec2), OPB(vec2));
|
||||
OPC(float) = dot2f (OPA(vec2), OPB(vec2))[0];
|
||||
break;
|
||||
case OP_VDOT_F:
|
||||
{
|
||||
vec_t d = DotProduct (&OPA(float),
|
||||
&OPB(float));
|
||||
VectorSet (d, d, d, &OPC(float));
|
||||
}
|
||||
OPC(float) = DotProduct (&OPA(float), &OPB(float));
|
||||
break;
|
||||
case OP_QDOT_F:
|
||||
OPC(vec4) = dotf (OPA(vec4), OPB(vec4));
|
||||
OPC(float) = dotf (OPA(vec4), OPB(vec4))[0];
|
||||
break;
|
||||
case OP_CMUL_F:
|
||||
OPC(vec2) = cmulf (OPA(vec2), OPB(vec2));
|
||||
|
@ -2653,17 +2700,13 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth)
|
|||
}
|
||||
break;
|
||||
case OP_CDOT_D:
|
||||
OPC(dvec2) = dot2d (OPA(dvec2), OPB(dvec2));
|
||||
OPC(double) = dot2d (OPA(dvec2), OPB(dvec2))[0];
|
||||
break;
|
||||
case OP_VDOT_D:
|
||||
{
|
||||
double d = DotProduct (&OPA(double),
|
||||
&OPB(double));
|
||||
VectorSet (d, d, d, &OPC(double));
|
||||
}
|
||||
OPC(double) = DotProduct (&OPA(double), &OPB(double));
|
||||
break;
|
||||
case OP_QDOT_D:
|
||||
OPC(dvec4) = dotd (OPA(dvec4), OPB(dvec4));
|
||||
OPC(double) = dotd (OPA(dvec4), OPB(dvec4))[0];
|
||||
break;
|
||||
case OP_CMUL_D:
|
||||
OPC(dvec2) = cmuld (OPA(dvec2), OPB(dvec2));
|
||||
|
@ -2693,7 +2736,7 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth)
|
|||
// 1 1101
|
||||
OP_cmp_T (GE, u, int, ivec2, ivec4, >=, uint, uivec2, uivec4);
|
||||
case OP_MOVE_I:
|
||||
memmove (op_c, op_a, st->b * sizeof (pr_type_t));
|
||||
memmove (op_c, op_a, (pr_ushort_t) st->b * sizeof (pr_type_t));
|
||||
break;
|
||||
case OP_MOVE_P:
|
||||
memmove (pr->pr_globals + OPC(ptr), pr->pr_globals + OPA(ptr),
|
||||
|
@ -2701,7 +2744,7 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth)
|
|||
break;
|
||||
case OP_MOVE_PI:
|
||||
memmove (pr->pr_globals + OPC(ptr), pr->pr_globals + OPA(ptr),
|
||||
st->b * sizeof (pr_type_t));
|
||||
(pr_ushort_t) st->b * sizeof (pr_type_t));
|
||||
break;
|
||||
case OP_STATE_ft:
|
||||
{
|
||||
|
@ -2717,13 +2760,14 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth)
|
|||
break;
|
||||
OP_cmp_T (GE, U, long, lvec2, lvec4, >=, ulong, ulvec2, ulvec4);
|
||||
case OP_MEMSET_I:
|
||||
pr_memset (op_c, OPA(int), st->b);
|
||||
pr_memset (op_c, OPA(int), (pr_ushort_t) st->b);
|
||||
break;
|
||||
case OP_MEMSET_P:
|
||||
pr_memset (pr->pr_globals + OPC(ptr), OPA(int), OPB(uint));
|
||||
break;
|
||||
case OP_MEMSET_PI:
|
||||
pr_memset (pr->pr_globals + OPC(ptr), OPA(int), st->b);
|
||||
pr_memset (pr->pr_globals + OPC(ptr), OPA(int),
|
||||
(pr_ushort_t) st->b);
|
||||
break;
|
||||
case OP_STATE_ftt:
|
||||
{
|
||||
|
@ -2833,35 +2877,37 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth)
|
|||
OPC(float) = ~ (int) OPA(float);
|
||||
break;
|
||||
case OP_CONV:
|
||||
switch (st->b) {
|
||||
switch ((pr_ushort_t) st->b) {
|
||||
#include "libs/gamecode/pr_convert.cinc"
|
||||
default:
|
||||
PR_RunError (pr, "invalid conversion code: %04o",
|
||||
st->b);
|
||||
(pr_ushort_t) st->b);
|
||||
}
|
||||
break;
|
||||
case OP_WITH:
|
||||
pr_with (pr, st);
|
||||
break;
|
||||
case OP_EXTEND:
|
||||
switch (st->b) {
|
||||
switch ((pr_ushort_t) st->b) {
|
||||
#include "libs/gamecode/pr_extend.cinc"
|
||||
default:
|
||||
PR_RunError (pr, "invalid extend code: %04o", st->b);
|
||||
PR_RunError (pr, "invalid extend code: %04o",
|
||||
(pr_ushort_t) st->b);
|
||||
}
|
||||
break;
|
||||
#define OP_hop2(vec, op) ((vec)[0] op (vec)[1])
|
||||
#define OP_hop3(vec, op) ((vec)[0] op (vec)[1] op (vec)[2])
|
||||
#define OP_hop4(vec, op) ((vec)[0] op (vec)[1] op (vec)[2] op (vec)[3])
|
||||
case OP_HOPS:
|
||||
switch (st->b) {
|
||||
switch ((pr_ushort_t) st->b) {
|
||||
#include "libs/gamecode/pr_hops.cinc"
|
||||
default:
|
||||
PR_RunError (pr, "invalid hops code: %04o", st->b);
|
||||
PR_RunError (pr, "invalid hops code: %04o",
|
||||
(pr_ushort_t) st->b);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
PR_RunError (pr, "Bad opcode o%03o", st->op & OP_MASK);
|
||||
PR_RunError (pr, "Bad opcode x%03x", st->op & OP_MASK);
|
||||
}
|
||||
if (pr->watch && pr->watch->value != old_val.value) {
|
||||
if (!pr->wp_conditional
|
||||
|
@ -2876,7 +2922,7 @@ pr_exec_ruamoko (progs_t *pr, int exitdepth)
|
|||
old_val.value = pr->watch->value;
|
||||
}
|
||||
}
|
||||
exit_program:
|
||||
exit_program:;
|
||||
}
|
||||
/*
|
||||
PR_ExecuteProgram
|
||||
|
|
|
@ -269,7 +269,7 @@ PR_LoadProgsFile (progs_t *pr, QFile *file, int size)
|
|||
pr->pr_statements = (dstatement_t *) (base + pr->progs->statements.offset);
|
||||
|
||||
pr->pr_globals = (pr_type_t *) (base + pr->progs->globals.offset);
|
||||
pr->stack = (pr_type_t *) ((byte *) pr->zone + pr->zone_size);
|
||||
pr->stack = (pr_type_t *) (heap + pr->zone_size);
|
||||
pr->stack_bottom = pr->stack - pr->pr_globals;
|
||||
pr->globals_size = (pr_type_t *) ((byte *) pr->stack + pr->stack_size)
|
||||
- pr->pr_globals;
|
||||
|
|
|
@ -219,6 +219,9 @@ ED_ParseEpair (progs_t *pr, pr_type_t *base, pr_def_t *key, const char *s)
|
|||
pr_type_t *d;
|
||||
dfunction_t *func;
|
||||
|
||||
vec3_t vec = {};
|
||||
char *str = 0;
|
||||
|
||||
d = &base[key->ofs];
|
||||
|
||||
switch (key->type & ~DEF_SAVEGLOBAL) {
|
||||
|
@ -231,8 +234,7 @@ ED_ParseEpair (progs_t *pr, pr_type_t *base, pr_def_t *key, const char *s)
|
|||
break;
|
||||
|
||||
case ev_vector:
|
||||
vec3_t vec = {};
|
||||
char *str = alloca (strlen (s) + 1);
|
||||
str = alloca (strlen (s) + 1);
|
||||
strcpy (str, s);
|
||||
for (char *v = str; *v; v++) {
|
||||
if (*v == ',') {
|
||||
|
@ -446,7 +448,6 @@ static void
|
|||
ED_SpawnEntities (progs_t *pr, plitem_t *entity_list)
|
||||
{
|
||||
edict_t *ent;
|
||||
int inhibit = 0;
|
||||
plitem_t *entity;
|
||||
plitem_t *item;
|
||||
int i;
|
||||
|
@ -479,7 +480,6 @@ ED_SpawnEntities (progs_t *pr, plitem_t *entity_list)
|
|||
// remove things from different skill levels or deathmatch
|
||||
if (pr->prune_edict && pr->prune_edict (pr, ent)) {
|
||||
ED_Free (pr, ent);
|
||||
inhibit++;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -1058,7 +1058,8 @@ fmt_state_modifiers (fmt_state_t *state)
|
|||
// no modifiers supported
|
||||
if (state->c[0] == 'l'
|
||||
&& (state->c[1] == 'i' || state->c[1] == 'd' || state->c[1] == 'x'
|
||||
|| state->c[1] == 'u')) {
|
||||
|| state->c[1] == 'u'
|
||||
|| state->c[1] == 'v' || state->c[1] == 'q')) {
|
||||
(*state->fi)->flags |= FMT_LONG;
|
||||
state->c++;
|
||||
}
|
||||
|
@ -1070,10 +1071,11 @@ fmt_state_conversion (fmt_state_t *state)
|
|||
{
|
||||
progs_t *pr = state->pr;
|
||||
char conv;
|
||||
pr_ptr_t at_param;
|
||||
switch ((conv = *state->c++)) {
|
||||
case '@':
|
||||
// object
|
||||
pr_ptr_t at_param = P_UINT (pr, state->fmt_count);
|
||||
at_param = P_UINT (pr, state->fmt_count);
|
||||
if (state->at_handler) {
|
||||
const char *at_str = state->at_handler (pr, at_param,
|
||||
state->at_handler_data);
|
||||
|
@ -1182,8 +1184,13 @@ fmt_state_conversion (fmt_state_t *state)
|
|||
(*state->fi)->precision = precision;
|
||||
(*state->fi)->minFieldWidth = minWidth;
|
||||
(*state->fi)->type = 'g';
|
||||
(*state->fi)->data.float_var =
|
||||
P_VECTOR (pr, state->fmt_count)[i];
|
||||
if (flags & FMT_LONG) {
|
||||
(*state->fi)->data.double_var
|
||||
= (&P_var (pr, state->fmt_count, double))[i];
|
||||
} else {
|
||||
(*state->fi)->data.float_var =
|
||||
P_VECTOR (pr, state->fmt_count)[i];
|
||||
}
|
||||
|
||||
fmt_append_item (state);
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ static void
|
|||
test_debug_handler (prdebug_t event, void *param, void *data)
|
||||
{
|
||||
progs_t *pr = data;
|
||||
dstatement_t *st = 0;
|
||||
|
||||
switch (event) {
|
||||
case prd_breakpoint:
|
||||
|
@ -44,7 +45,7 @@ test_debug_handler (prdebug_t event, void *param, void *data)
|
|||
case prd_subexit:
|
||||
break;
|
||||
case prd_trace:
|
||||
dstatement_t *st = test_pr.pr_statements + test_pr.pr_xstatement;
|
||||
st = test_pr.pr_statements + test_pr.pr_xstatement;
|
||||
if (verbose > 1) {
|
||||
printf ("---\n");
|
||||
printf ("debug: trace %05x %04x %04x %04x %04x%s\n",
|
||||
|
|
|
@ -67,13 +67,13 @@ static dstatement_t callret_statements[] = {
|
|||
#define c 20 // in locals int
|
||||
{ OP(2, 0, 1, OP_STORE_A_1), xn+1,0, x }, // init xn to [1, x, 0, 0]
|
||||
{ OP(2, 0, 0, OP_STORE_A_1), xn, 0, 4 },
|
||||
{ OP(2, 0, 2, OP_SWIZZLE_F), xn, 0x0044, xn }, // xn -> [1, x, 1, x]
|
||||
{ OP(2, 0, 2, OP_SWIZZLE_F_4), xn, 0x0044, xn },// xn -> [1, x, 1, x]
|
||||
{ OP(1, 1, 2, OP_MUL_F_1), x, x, x2 }, // x2 -> [x*x, ?, ?, ?]
|
||||
{ OP(2, 0, 2, OP_SWIZZLE_F), x2, 0x0300, x2},//x2 -> [-x*x, -x*x, x*x, x*x]
|
||||
{ OP(2, 0, 2, OP_SWIZZLE_F_4), x2, 0x0300, x2},//x2 -> [-x*x, -x*x, x*x, x*x]
|
||||
{ OP(2, 0, 0, OP_STORE_A_1), fa, 0, 4 }, // init factorial
|
||||
{ OP(2, 0, 0, OP_STORE_A_1), fa+1,0, 5 },
|
||||
{ OP(2, 0, 2, OP_SWIZZLE_F), fa, 0x0044, fa }, // fa -> [1, 2, 1, 2]
|
||||
{ OP(2, 0, 2, OP_SWIZZLE_F), fa, 0x0000, fi }, // init fi -> [1, 1, 1, 1]
|
||||
{ OP(2, 0, 2, OP_SWIZZLE_F_4), fa, 0x0044, fa },// fa -> [1, 2, 1, 2]
|
||||
{ OP(2, 0, 2, OP_SWIZZLE_F_4), fa, 0x0000, fi },// init fi -> [1, 1, 1, 1]
|
||||
{ OP(2, 2, 2, OP_SUB_F_4), ac, ac, ac }, // init acc (output) to 0
|
||||
{ OP(0, 0, 2, OP_LEA_A), 25, 0, c }, // init count
|
||||
// loop:
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue