From 991fd0cd4a75753db62c901766eb634767c18d5e Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Mon, 29 May 2023 04:56:39 +0300 Subject: [PATCH 01/12] Fix being able to break scripted_sequence by +using friendly NPCs to make them follow player (#375) --- dlls/talkmonster.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/talkmonster.cpp b/dlls/talkmonster.cpp index 2b3ac14f..83100466 100644 --- a/dlls/talkmonster.cpp +++ b/dlls/talkmonster.cpp @@ -1344,7 +1344,7 @@ void CTalkMonster::StartFollowing( CBaseEntity *pLeader ) BOOL CTalkMonster::CanFollow( void ) { - if( m_MonsterState == MONSTERSTATE_SCRIPT ) + if( m_MonsterState == MONSTERSTATE_SCRIPT || m_IdealMonsterState == MONSTERSTATE_SCRIPT ) { if( !m_pCine ) return FALSE; From 31790c101af30ca9571c6923d3c3dccc8e3e5f0a Mon Sep 17 00:00:00 2001 From: Bohdan Shulyar Date: Tue, 30 May 2023 15:43:37 +0300 Subject: [PATCH 02/12] cmake: LibraryNaming: fix Android check --- cmake/LibraryNaming.cmake | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cmake/LibraryNaming.cmake b/cmake/LibraryNaming.cmake index e233a7de..0ffae76f 100644 --- a/cmake/LibraryNaming.cmake +++ b/cmake/LibraryNaming.cmake @@ -36,12 +36,14 @@ endmacro() # grep '^#undef XASH' build.h | grep "XASH_RISCV_" | awk '{ print "check_build_target(" $2 ")"}' # echo "endif()" +# NOTE: Android must have priority over Linux to work correctly! + set(CMAKE_REQUIRED_INCLUDES "${PROJECT_SOURCE_DIR}/public/") check_build_target(XASH_64BIT) check_group_build_target(XASH_WIN32 XASH_PLATFORM) +check_group_build_target(XASH_ANDROID XASH_PLATFORM) check_group_build_target(XASH_LINUX XASH_PLATFORM) check_group_build_target(XASH_FREEBSD XASH_PLATFORM) -check_group_build_target(XASH_ANDROID XASH_PLATFORM) check_group_build_target(XASH_APPLE XASH_PLATFORM) check_group_build_target(XASH_NETBSD XASH_PLATFORM) check_group_build_target(XASH_OPENBSD XASH_PLATFORM) From ef7b4a9015080fc3c70b5220bc6446373d3a83da Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Mon, 12 Jun 2023 01:30:13 +0300 Subject: [PATCH 03/12] Replace copyright symbol with (c) in game_shared/ and common/com_model.h to avoid problems with encoding (#378) --- common/com_model.h | 2 +- game_shared/bitvec.h | 2 +- game_shared/vgui_checkbutton2.cpp | 2 +- game_shared/vgui_checkbutton2.h | 2 +- game_shared/vgui_defaultinputsignal.h | 2 +- game_shared/vgui_grid.cpp | 2 +- game_shared/vgui_grid.h | 2 +- game_shared/vgui_helpers.cpp | 2 +- game_shared/vgui_helpers.h | 2 +- game_shared/vgui_listbox.cpp | 2 +- game_shared/vgui_listbox.h | 2 +- game_shared/vgui_loadtga.cpp | 2 +- game_shared/vgui_loadtga.h | 2 +- game_shared/vgui_scrollbar2.cpp | 2 +- game_shared/vgui_scrollbar2.h | 2 +- game_shared/vgui_slider2.cpp | 2 +- game_shared/vgui_slider2.h | 2 +- game_shared/voice_banmgr.cpp | 2 +- game_shared/voice_banmgr.h | 2 +- game_shared/voice_common.h | 2 +- game_shared/voice_gamemgr.h | 2 +- game_shared/voice_status.cpp | 2 +- game_shared/voice_vgui_tweakdlg.cpp | 2 +- game_shared/voice_vgui_tweakdlg.h | 2 +- 24 files changed, 24 insertions(+), 24 deletions(-) diff --git a/common/com_model.h b/common/com_model.h index 61c0434a..a2b8e8bc 100644 --- a/common/com_model.h +++ b/common/com_model.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/game_shared/bitvec.h b/game_shared/bitvec.h index d77796fb..effd6249 100644 --- a/game_shared/bitvec.h +++ b/game_shared/bitvec.h @@ -1,4 +1,4 @@ -//========= Copyright � 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/game_shared/vgui_checkbutton2.cpp b/game_shared/vgui_checkbutton2.cpp index bb67f31a..977a0a98 100644 --- a/game_shared/vgui_checkbutton2.cpp +++ b/game_shared/vgui_checkbutton2.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/game_shared/vgui_checkbutton2.h b/game_shared/vgui_checkbutton2.h index d04fc182..79fd025b 100644 --- a/game_shared/vgui_checkbutton2.h +++ b/game_shared/vgui_checkbutton2.h @@ -1,4 +1,4 @@ -//========= Copyright � 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/game_shared/vgui_defaultinputsignal.h b/game_shared/vgui_defaultinputsignal.h index cd55b76c..11cba53a 100644 --- a/game_shared/vgui_defaultinputsignal.h +++ b/game_shared/vgui_defaultinputsignal.h @@ -1,4 +1,4 @@ -//========= Copyright � 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/game_shared/vgui_grid.cpp b/game_shared/vgui_grid.cpp index f94e1cef..57717895 100644 --- a/game_shared/vgui_grid.cpp +++ b/game_shared/vgui_grid.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/game_shared/vgui_grid.h b/game_shared/vgui_grid.h index 0e45ac4a..1d37cf36 100644 --- a/game_shared/vgui_grid.h +++ b/game_shared/vgui_grid.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/game_shared/vgui_helpers.cpp b/game_shared/vgui_helpers.cpp index 79c4e378..429910f3 100644 --- a/game_shared/vgui_helpers.cpp +++ b/game_shared/vgui_helpers.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/game_shared/vgui_helpers.h b/game_shared/vgui_helpers.h index 91c24343..603b1a30 100644 --- a/game_shared/vgui_helpers.h +++ b/game_shared/vgui_helpers.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/game_shared/vgui_listbox.cpp b/game_shared/vgui_listbox.cpp index 77b7689b..dfea03a3 100644 --- a/game_shared/vgui_listbox.cpp +++ b/game_shared/vgui_listbox.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/game_shared/vgui_listbox.h b/game_shared/vgui_listbox.h index a97c780d..30281ba6 100644 --- a/game_shared/vgui_listbox.h +++ b/game_shared/vgui_listbox.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/game_shared/vgui_loadtga.cpp b/game_shared/vgui_loadtga.cpp index bfd8ee7a..37b69483 100644 --- a/game_shared/vgui_loadtga.cpp +++ b/game_shared/vgui_loadtga.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/game_shared/vgui_loadtga.h b/game_shared/vgui_loadtga.h index 26505b18..2e4db263 100644 --- a/game_shared/vgui_loadtga.h +++ b/game_shared/vgui_loadtga.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/game_shared/vgui_scrollbar2.cpp b/game_shared/vgui_scrollbar2.cpp index 805bb191..ccba4aa8 100644 --- a/game_shared/vgui_scrollbar2.cpp +++ b/game_shared/vgui_scrollbar2.cpp @@ -1,4 +1,4 @@ -//========= Copyright � 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/game_shared/vgui_scrollbar2.h b/game_shared/vgui_scrollbar2.h index 71cd965b..3d3ab23a 100644 --- a/game_shared/vgui_scrollbar2.h +++ b/game_shared/vgui_scrollbar2.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/game_shared/vgui_slider2.cpp b/game_shared/vgui_slider2.cpp index d7e2c564..3b1cf311 100644 --- a/game_shared/vgui_slider2.cpp +++ b/game_shared/vgui_slider2.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: New version of the slider bar // diff --git a/game_shared/vgui_slider2.h b/game_shared/vgui_slider2.h index 9f9388c8..291a39e9 100644 --- a/game_shared/vgui_slider2.h +++ b/game_shared/vgui_slider2.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/game_shared/voice_banmgr.cpp b/game_shared/voice_banmgr.cpp index f8241bf3..8e8b18cb 100644 --- a/game_shared/voice_banmgr.cpp +++ b/game_shared/voice_banmgr.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/game_shared/voice_banmgr.h b/game_shared/voice_banmgr.h index 64c0c2bb..41c8e0fc 100644 --- a/game_shared/voice_banmgr.h +++ b/game_shared/voice_banmgr.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/game_shared/voice_common.h b/game_shared/voice_common.h index c32011a3..e10856e0 100644 --- a/game_shared/voice_common.h +++ b/game_shared/voice_common.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/game_shared/voice_gamemgr.h b/game_shared/voice_gamemgr.h index cdbb8815..75b3e003 100644 --- a/game_shared/voice_gamemgr.h +++ b/game_shared/voice_gamemgr.h @@ -1,4 +1,4 @@ -//========= Copyright � 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/game_shared/voice_status.cpp b/game_shared/voice_status.cpp index cbc81e81..1099fb8c 100644 --- a/game_shared/voice_status.cpp +++ b/game_shared/voice_status.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/game_shared/voice_vgui_tweakdlg.cpp b/game_shared/voice_vgui_tweakdlg.cpp index ea61f509..cca316c2 100644 --- a/game_shared/voice_vgui_tweakdlg.cpp +++ b/game_shared/voice_vgui_tweakdlg.cpp @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // diff --git a/game_shared/voice_vgui_tweakdlg.h b/game_shared/voice_vgui_tweakdlg.h index 21af03ae..5e820173 100644 --- a/game_shared/voice_vgui_tweakdlg.h +++ b/game_shared/voice_vgui_tweakdlg.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // From 8da76a8c3fb5246fb08526673f79f9a8d5498336 Mon Sep 17 00:00:00 2001 From: Xiaobaibai <824395314@qq.com> Date: Mon, 12 Jun 2023 11:37:20 +0800 Subject: [PATCH 04/12] ARMv8 neon support --- cl_dll/neon_mathfun.h | 356 +++++++++++++++++++++++++++++++++++++++++ cl_dll/studio_util.cpp | 235 +++++++++++++++++++++++++++ 2 files changed, 591 insertions(+) create mode 100644 cl_dll/neon_mathfun.h diff --git a/cl_dll/neon_mathfun.h b/cl_dll/neon_mathfun.h new file mode 100644 index 00000000..e45b92c1 --- /dev/null +++ b/cl_dll/neon_mathfun.h @@ -0,0 +1,356 @@ +/* NEON implementation of sin, cos, exp and log + + Inspired by Intel Approximate Math library, and based on the + corresponding algorithms of the cephes math library +*/ + +/* Copyright (C) 2011 Julien Pommier + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + (this is the zlib license) +*/ + +#include + +typedef float32x4_t v4sf; // vector of 4 float +typedef uint32x4_t v4su; // vector of 4 uint32 +typedef int32x4_t v4si; // vector of 4 uint32 + +#define s4f_x(s4f) vgetq_lane_f32(s4f, 0) +#define s4f_y(s4f) vgetq_lane_f32(s4f, 1) +#define s4f_z(s4f) vgetq_lane_f32(s4f, 2) +#define s4f_w(s4f) vgetq_lane_f32(s4f, 3) + +#define c_inv_mant_mask ~0x7f800000u +#define c_cephes_SQRTHF 0.707106781186547524 +#define c_cephes_log_p0 7.0376836292E-2 +#define c_cephes_log_p1 - 1.1514610310E-1 +#define c_cephes_log_p2 1.1676998740E-1 +#define c_cephes_log_p3 - 1.2420140846E-1 +#define c_cephes_log_p4 + 1.4249322787E-1 +#define c_cephes_log_p5 - 1.6668057665E-1 +#define c_cephes_log_p6 + 2.0000714765E-1 +#define c_cephes_log_p7 - 2.4999993993E-1 +#define c_cephes_log_p8 + 3.3333331174E-1 +#define c_cephes_log_q1 -2.12194440e-4 +#define c_cephes_log_q2 0.693359375 + +/* natural logarithm computed for 4 simultaneous float + return NaN for x <= 0 +*/ +inline v4sf log_ps(v4sf x) { + v4sf one = vdupq_n_f32(1); + + x = vmaxq_f32(x, vdupq_n_f32(0)); /* force flush to zero on denormal values */ + v4su invalid_mask = vcleq_f32(x, vdupq_n_f32(0)); + + v4si ux = vreinterpretq_s32_f32(x); + + v4si emm0 = vshrq_n_s32(ux, 23); + + /* keep only the fractional part */ + ux = vandq_s32(ux, vdupq_n_s32(c_inv_mant_mask)); + ux = vorrq_s32(ux, vreinterpretq_s32_f32(vdupq_n_f32(0.5f))); + x = vreinterpretq_f32_s32(ux); + + emm0 = vsubq_s32(emm0, vdupq_n_s32(0x7f)); + v4sf e = vcvtq_f32_s32(emm0); + + e = vaddq_f32(e, one); + + /* part2: + if( x < SQRTHF ) { + e -= 1; + x = x + x - 1.0; + } else { x = x - 1.0; } + */ + v4su mask = vcltq_f32(x, vdupq_n_f32(c_cephes_SQRTHF)); + v4sf tmp = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(x), mask)); + x = vsubq_f32(x, one); + e = vsubq_f32(e, vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(one), mask))); + x = vaddq_f32(x, tmp); + + v4sf z = vmulq_f32(x,x); + + v4sf y = vdupq_n_f32(c_cephes_log_p0); + y = vmulq_f32(y, x); + y = vaddq_f32(y, vdupq_n_f32(c_cephes_log_p1)); + y = vmulq_f32(y, x); + y = vaddq_f32(y, vdupq_n_f32(c_cephes_log_p2)); + y = vmulq_f32(y, x); + y = vaddq_f32(y, vdupq_n_f32(c_cephes_log_p3)); + y = vmulq_f32(y, x); + y = vaddq_f32(y, vdupq_n_f32(c_cephes_log_p4)); + y = vmulq_f32(y, x); + y = vaddq_f32(y, vdupq_n_f32(c_cephes_log_p5)); + y = vmulq_f32(y, x); + y = vaddq_f32(y, vdupq_n_f32(c_cephes_log_p6)); + y = vmulq_f32(y, x); + y = vaddq_f32(y, vdupq_n_f32(c_cephes_log_p7)); + y = vmulq_f32(y, x); + y = vaddq_f32(y, vdupq_n_f32(c_cephes_log_p8)); + y = vmulq_f32(y, x); + + y = vmulq_f32(y, z); + + + tmp = vmulq_f32(e, vdupq_n_f32(c_cephes_log_q1)); + y = vaddq_f32(y, tmp); + + + tmp = vmulq_f32(z, vdupq_n_f32(0.5f)); + y = vsubq_f32(y, tmp); + + tmp = vmulq_f32(e, vdupq_n_f32(c_cephes_log_q2)); + x = vaddq_f32(x, y); + x = vaddq_f32(x, tmp); + x = vreinterpretq_f32_u32(vorrq_u32(vreinterpretq_u32_f32(x), invalid_mask)); // negative arg will be NAN + return x; +} + +#define c_exp_hi 88.3762626647949f +#define c_exp_lo -88.3762626647949f + +#define c_cephes_LOG2EF 1.44269504088896341 +#define c_cephes_exp_C1 0.693359375 +#define c_cephes_exp_C2 -2.12194440e-4 + +#define c_cephes_exp_p0 1.9875691500E-4 +#define c_cephes_exp_p1 1.3981999507E-3 +#define c_cephes_exp_p2 8.3334519073E-3 +#define c_cephes_exp_p3 4.1665795894E-2 +#define c_cephes_exp_p4 1.6666665459E-1 +#define c_cephes_exp_p5 5.0000001201E-1 + +/* exp() computed for 4 float at once */ +inline v4sf exp_ps(v4sf x) { + v4sf tmp, fx; + + v4sf one = vdupq_n_f32(1); + x = vminq_f32(x, vdupq_n_f32(c_exp_hi)); + x = vmaxq_f32(x, vdupq_n_f32(c_exp_lo)); + + /* express exp(x) as exp(g + n*log(2)) */ + fx = vmlaq_f32(vdupq_n_f32(0.5f), x, vdupq_n_f32(c_cephes_LOG2EF)); + + /* perform a floorf */ + tmp = vcvtq_f32_s32(vcvtq_s32_f32(fx)); + + /* if greater, substract 1 */ + v4su mask = vcgtq_f32(tmp, fx); + mask = vandq_u32(mask, vreinterpretq_u32_f32(one)); + + + fx = vsubq_f32(tmp, vreinterpretq_f32_u32(mask)); + + tmp = vmulq_f32(fx, vdupq_n_f32(c_cephes_exp_C1)); + v4sf z = vmulq_f32(fx, vdupq_n_f32(c_cephes_exp_C2)); + x = vsubq_f32(x, tmp); + x = vsubq_f32(x, z); + + static const float cephes_exp_p[6] = { c_cephes_exp_p0, c_cephes_exp_p1, c_cephes_exp_p2, c_cephes_exp_p3, c_cephes_exp_p4, c_cephes_exp_p5 }; + v4sf y = vld1q_dup_f32(cephes_exp_p+0); + v4sf c1 = vld1q_dup_f32(cephes_exp_p+1); + v4sf c2 = vld1q_dup_f32(cephes_exp_p+2); + v4sf c3 = vld1q_dup_f32(cephes_exp_p+3); + v4sf c4 = vld1q_dup_f32(cephes_exp_p+4); + v4sf c5 = vld1q_dup_f32(cephes_exp_p+5); + + y = vmulq_f32(y, x); + z = vmulq_f32(x,x); + y = vaddq_f32(y, c1); + y = vmulq_f32(y, x); + y = vaddq_f32(y, c2); + y = vmulq_f32(y, x); + y = vaddq_f32(y, c3); + y = vmulq_f32(y, x); + y = vaddq_f32(y, c4); + y = vmulq_f32(y, x); + y = vaddq_f32(y, c5); + + y = vmulq_f32(y, z); + y = vaddq_f32(y, x); + y = vaddq_f32(y, one); + + /* build 2^n */ + int32x4_t mm; + mm = vcvtq_s32_f32(fx); + mm = vaddq_s32(mm, vdupq_n_s32(0x7f)); + mm = vshlq_n_s32(mm, 23); + v4sf pow2n = vreinterpretq_f32_s32(mm); + + y = vmulq_f32(y, pow2n); + return y; +} + +#define c_minus_cephes_DP1 -0.78515625 +#define c_minus_cephes_DP2 -2.4187564849853515625e-4 +#define c_minus_cephes_DP3 -3.77489497744594108e-8 +#define c_sincof_p0 -1.9515295891E-4 +#define c_sincof_p1 8.3321608736E-3 +#define c_sincof_p2 -1.6666654611E-1 +#define c_coscof_p0 2.443315711809948E-005 +#define c_coscof_p1 -1.388731625493765E-003 +#define c_coscof_p2 4.166664568298827E-002 +#define c_cephes_FOPI 1.27323954473516 // 4 / M_PI + +/* evaluation of 4 sines & cosines at once. + + The code is the exact rewriting of the cephes sinf function. + Precision is excellent as long as x < 8192 (I did not bother to + take into account the special handling they have for greater values + -- it does not return garbage for arguments over 8192, though, but + the extra precision is missing). + + Note that it is such that sinf((float)M_PI) = 8.74e-8, which is the + surprising but correct result. + + Note also that when you compute sin(x), cos(x) is available at + almost no extra price so both sin_ps and cos_ps make use of + sincos_ps.. + */ +inline void sincos_ps(v4sf x, v4sf *ysin, v4sf *ycos) { // any x + v4sf y; + + v4su emm2; + + v4su sign_mask_sin, sign_mask_cos; + sign_mask_sin = vcltq_f32(x, vdupq_n_f32(0)); + x = vabsq_f32(x); + + /* scale by 4/Pi */ + y = vmulq_n_f32(x, c_cephes_FOPI); + + /* store the integer part of y in mm0 */ + emm2 = vcvtq_u32_f32(y); + /* j=(j+1) & (~1) (see the cephes sources) */ + emm2 = vaddq_u32(emm2, vdupq_n_u32(1)); + emm2 = vandq_u32(emm2, vdupq_n_u32(~1)); + y = vcvtq_f32_u32(emm2); + + /* get the polynom selection mask + there is one polynom for 0 <= x <= Pi/4 + and another one for Pi/4 +#include "neon_mathfun.h" +#endif /* ==================== @@ -17,8 +23,59 @@ AngleMatrix ==================== */ +#if XASH_SIMD_NEON +const uint32x4_t AngleMatrix_sign0 = vreinterpretq_f32_u32(vsetq_lane_u32(0x80000000, vdupq_n_u32(0), 0)); +const uint32x4_t AngleMatrix_sign1 = vreinterpretq_f32_u32(vsetq_lane_u32(0x80000000, vdupq_n_u32(0), 1)); +const uint32x4_t AngleMatrix_sign2 = vreinterpretq_f32_u32(vsetq_lane_u32(0x80000000, vdupq_n_u32(0), 2)); +#endif void AngleMatrix( const float *angles, float (*matrix)[4] ) { +#if XASH_SIMD_NEON + float32x4x3_t out_reg; + float32x4_t angles_reg = {}; + memcpy(&angles_reg, angles, sizeof(float) * 3); + + float32x4x2_t sp_sy_sr_0_cp_cy_cr_1; + sincos_ps(vmulq_n_f32(angles_reg, (M_PI * 2 / 360)), &sp_sy_sr_0_cp_cy_cr_1.val[0], &sp_sy_sr_0_cp_cy_cr_1.val[1]); + + float32x4x2_t sp_sr_cp_cr_sy_0_cy_1 = vuzpq_f32(sp_sy_sr_0_cp_cy_cr_1.val[0], sp_sy_sr_0_cp_cy_cr_1.val[1]); + float32x4x2_t sp_cp_sy_cy_sr_cr_0_1 = vzipq_f32(sp_sy_sr_0_cp_cy_cr_1.val[0], sp_sy_sr_0_cp_cy_cr_1.val[1]); + + float32x4_t _0_sr_cr_0 = vextq_f32(sp_sy_sr_0_cp_cy_cr_1.val[0], sp_cp_sy_cy_sr_cr_0_1.val[1], 3); + float32x4_t cp_cr_sr_0 = vcombine_f32(vget_high_f32(sp_sr_cp_cr_sy_0_cy_1.val[0]), vget_high_f32(sp_sy_sr_0_cp_cy_cr_1.val[0])); + float32x4_t cy_sy_sy_0 = vcombine_f32(vrev64_f32(vget_high_f32(sp_cp_sy_cy_sr_cr_0_1.val[0])), vget_low_f32(sp_sr_cp_cr_sy_0_cy_1.val[1])); + float32x4_t sy_cy_cy_1 = vcombine_f32(vget_high_f32(sp_cp_sy_cy_sr_cr_0_1.val[0]), vget_high_f32(sp_sr_cp_cr_sy_0_cy_1.val[1])); + + float32x4_t _0_srsp_crsp_0 = vmulq_laneq_f32(_0_sr_cr_0, sp_sy_sr_0_cp_cy_cr_1.val[0], 0); // *sp + out_reg.val[0] = vmulq_laneq_f32(_0_srsp_crsp_0, sp_sy_sr_0_cp_cy_cr_1.val[1], 1); // *cy + out_reg.val[1] = vmulq_laneq_f32(_0_srsp_crsp_0, sp_sy_sr_0_cp_cy_cr_1.val[0], 1); // *sy + + cy_sy_sy_0 = vreinterpretq_f32_u32(veorq_u32(vreinterpretq_u32_f32(cy_sy_sy_0), AngleMatrix_sign1)); + sy_cy_cy_1 = vreinterpretq_f32_u32(veorq_u32(vreinterpretq_u32_f32(sy_cy_cy_1), AngleMatrix_sign2)); + out_reg.val[0] = vfmaq_f32(out_reg.val[0], cp_cr_sr_0, cy_sy_sy_0); + out_reg.val[1] = vfmaq_f32(out_reg.val[1], cp_cr_sr_0, sy_cy_cy_1); + + float32x4_t cp_cr_0_1 = vcombine_f32(vget_high_f32(sp_sr_cp_cr_sy_0_cy_1.val[0]), vget_high_f32(sp_cp_sy_cy_sr_cr_0_1.val[1])); + float32x4_t _1_cp_cr_0 = vextq_f32(cp_cr_0_1, cp_cr_0_1, 3); + out_reg.val[2] = vmulq_f32(sp_sr_cp_cr_sy_0_cy_1.val[0], _1_cp_cr_0); + out_reg.val[2] = vreinterpretq_f32_u32(veorq_u32(vreinterpretq_u32_f32(out_reg.val[2]), AngleMatrix_sign0)); + + memcpy(matrix, &out_reg, sizeof(float) * 3 * 4); +/* + matrix[0][0] = cp*cy; + matrix[0][1] = sr*sp*cy-cr*sy; + matrix[0][2] = cr*sp*cy+sr*sy; + matrix[0][3] = 0.0; + matrix[1][0] = cp*sy; + matrix[1][1] = sr*sp*sy+cr*cy; + matrix[1][2] = cr*sp*sy-sr*cy; + matrix[1][3] = 0.0; + matrix[2][0] = -sp*1; + matrix[2][1] = sr*cp; + matrix[2][2] = cp*cr; + matrix[2][3] = cr*0; +*/ +#else float angle; float sr, sp, sy, cr, cp, cy; @@ -45,6 +102,7 @@ void AngleMatrix( const float *angles, float (*matrix)[4] ) matrix[0][3] = 0.0f; matrix[1][3] = 0.0f; matrix[2][3] = 0.0f; +#endif } /* @@ -55,6 +113,13 @@ VectorCompare */ int VectorCompare( const float *v1, const float *v2 ) { +#if XASH_SIMD_NEON + // is this really works? + float32x4_t v1_reg = {}, v2_reg = {}; + memcpy(&v1_reg, v1, sizeof(float) * 3); + memcpy(&v2_reg, v2, sizeof(float) * 3); + return !vaddvq_u32(vceqq_f32(v1_reg, v2_reg)); +#else int i; for( i = 0; i < 3; i++ ) @@ -62,6 +127,7 @@ int VectorCompare( const float *v1, const float *v2 ) return 0; return 1; +#endif } /* @@ -72,9 +138,23 @@ CrossProduct */ void CrossProduct( const float *v1, const float *v2, float *cross ) { +#if XASH_SIMD_NEON + float32x4_t v1_reg = {}, v2_reg = {}; + memcpy(&v1_reg, v1, sizeof(float) * 3); + memcpy(&v2_reg, v2, sizeof(float) * 3); + + float32x4_t yzxy_a = vextq_f32(vextq_f32(v1_reg, v1_reg, 3), v1_reg, 2); // [aj, ak, ai, aj] + float32x4_t yzxy_b = vextq_f32(vextq_f32(v2_reg, v2_reg, 3), v2_reg, 2); // [bj, bk, bi, bj] + float32x4_t zxyy_a = vextq_f32(yzxy_a, yzxy_a, 1); // [ak, ai, aj, aj] + float32x4_t zxyy_b = vextq_f32(yzxy_b, yzxy_b, 1); // [bk, ai, bj, bj] + float32x4_t cross_reg = vfmsq_f32(vmulq_f32(yzxy_a, zxyy_b), zxyy_a, yzxy_b); // [ajbk-akbj, akbi-aibk, aibj-ajbi, 0] + + memcpy(cross, &v2_reg, sizeof(float) * 3); +#else cross[0] = v1[1] * v2[2] - v1[2] * v2[1]; cross[1] = v1[2] * v2[0] - v1[0] * v2[2]; cross[2] = v1[0] * v2[1] - v1[1] * v2[0]; +#endif } /* @@ -85,9 +165,26 @@ VectorTransform */ void VectorTransform( const float *in1, float in2[3][4], float *out ) { +#if XASH_SIMD_NEON + float32x4_t in1_reg = {}; + memcpy(&in1_reg, &in1, sizeof(float) * 3); + + float32x4x4_t in_t; + memcpy(&in_t, &in2, sizeof(float) * 3 * 4); + //memset(&in_t.val[3], 0, sizeof(in_t.val[3])); + in_t = vld4q_f32((const float*)&in_t); + + float32x4_t out_reg = in_t.val[3]; + out_reg = vfmaq_laneq_f32(out_reg, in_t.val[0], in1_reg, 0); + out_reg = vfmaq_laneq_f32(out_reg, in_t.val[1], in1_reg, 1); + out_reg = vfmaq_laneq_f32(out_reg, in_t.val[2], in1_reg, 2); + + memcpy(out, &out_reg, sizeof(float) * 3); +#else out[0] = DotProduct(in1, in2[0]) + in2[0][3]; out[1] = DotProduct(in1, in2[1]) + in2[1][3]; out[2] = DotProduct(in1, in2[2]) + in2[2][3]; +#endif } /* @@ -98,6 +195,29 @@ ConcatTransforms */ void ConcatTransforms( float in1[3][4], float in2[3][4], float out[3][4] ) { +#if XASH_SIMD_NEON + float32x4x3_t in1_reg, in2_reg; + memcpy(&in1_reg, in1, sizeof(float) * 3 * 4); + memcpy(&in2_reg, in2, sizeof(float) * 3 * 4); + float32x4x3_t out_reg = {}; + + out_reg.val[0] = vcopyq_laneq_f32(out_reg.val[0], 3, in1_reg.val[0], 3); // out[0][3] = in[0][3] + out_reg.val[0] = vfmaq_laneq_f32(out_reg.val[0], in2_reg.val[0], in1_reg.val[0], 0); // out[0][n] += in2[0][n] * in1[0][0] + out_reg.val[0] = vfmaq_laneq_f32(out_reg.val[0], in2_reg.val[1], in1_reg.val[0], 1); // out[0][n] += in2[1][n] * in1[0][1] + out_reg.val[0] = vfmaq_laneq_f32(out_reg.val[0], in2_reg.val[2], in1_reg.val[0], 2); // out[0][n] += in2[2][n] * in1[0][2] + + out_reg.val[1] = vcopyq_laneq_f32(out_reg.val[1], 3, in1_reg.val[1], 3); + out_reg.val[1] = vfmaq_laneq_f32(out_reg.val[1], in2_reg.val[0], in1_reg.val[1], 0); + out_reg.val[1] = vfmaq_laneq_f32(out_reg.val[1], in2_reg.val[1], in1_reg.val[1], 1); + out_reg.val[1] = vfmaq_laneq_f32(out_reg.val[1], in2_reg.val[2], in1_reg.val[1], 2); + + out_reg.val[2] = vcopyq_laneq_f32(out_reg.val[2], 3, in1_reg.val[2], 3); + out_reg.val[2] = vfmaq_laneq_f32(out_reg.val[2], in2_reg.val[0], in1_reg.val[2], 0); + out_reg.val[2] = vfmaq_laneq_f32(out_reg.val[2], in2_reg.val[1], in1_reg.val[2], 1); + out_reg.val[2] = vfmaq_laneq_f32(out_reg.val[2], in2_reg.val[2], in1_reg.val[2], 2); + + memcpy(&out, &out_reg, sizeof(out)); +#else out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] + in1[0][2] * in2[2][0]; out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] + @@ -122,6 +242,7 @@ void ConcatTransforms( float in1[3][4], float in2[3][4], float out[3][4] ) in1[2][2] * in2[2][2]; out[2][3] = in1[2][0] * in2[0][3] + in1[2][1] * in2[1][3] + in1[2][2] * in2[2][3] + in1[2][3]; +#endif } // angles index are not the same as ROLL, PITCH, YAW @@ -132,8 +253,36 @@ AngleQuaternion ==================== */ +#if XASH_SIMD_NEON +const float32x4_t AngleQuaternion_sign2 = vzipq_f32(vdupq_n_u32(0x80000000), vdupq_n_u32(0x00000000)).val[0]; // { 0x80000000, 0x00000000, 0x80000000, 0x00000000 }; +#endif void AngleQuaternion( float *angles, vec4_t quaternion ) { +#if XASH_SIMD_NEON + float32x4_t angles_reg = {}; + memcpy(&angles_reg, angles, sizeof(float) * 3); + float32x4x2_t sr_sp_sy_0_cr_cp_cy_1; + sincos_ps(vmulq_n_f32(angles_reg, 0.5), &sr_sp_sy_0_cr_cp_cy_1.val[0], &sr_sp_sy_0_cr_cp_cy_1.val[1]); + + float32x4x2_t sr_sy_cr_cy_sp_0_cp_1 = vuzpq_f32(sr_sp_sy_0_cr_cp_cy_1.val[0], sr_sp_sy_0_cr_cp_cy_1.val[1]); + float32x4_t cp_cp_cp_cp = vdupq_laneq_f32(sr_sp_sy_0_cr_cp_cy_1.val[1], 1); + float32x4_t sp_sp_sp_sp = vdupq_laneq_f32(sr_sp_sy_0_cr_cp_cy_1.val[0], 1); + + float32x4_t sr_sy_cr_cy = sr_sy_cr_cy_sp_0_cp_1.val[0]; + float32x4_t sy_cr_cy_sr = vextq_f32(sr_sy_cr_cy_sp_0_cp_1.val[0], sr_sy_cr_cy_sp_0_cp_1.val[0], 1); + float32x4_t cr_cy_sr_sy = vextq_f32(sr_sy_cr_cy_sp_0_cp_1.val[0], sr_sy_cr_cy_sp_0_cp_1.val[0], 2); + float32x4_t cy_sr_sy_cr = vextq_f32(sr_sy_cr_cy_sp_0_cp_1.val[0], sr_sy_cr_cy_sp_0_cp_1.val[0], 3); + float32x4_t sp_sp_sp_sp_signed = veorq_u32(sp_sp_sp_sp, AngleQuaternion_sign2); + + float32x4_t left = vmulq_f32(vmulq_f32(sr_sy_cr_cy, cp_cp_cp_cp), cy_sr_sy_cr); + + float32x4_t out_reg = vfmaq_f32(left, vmulq_f32(cr_cy_sr_sy, sp_sp_sp_sp_signed), sy_cr_cy_sr); + memcpy(quaternion, &out_reg, sizeof(float) * 4); + //quaternion[0] = sr * cp * cy - cr * sp * sy; // X + //quaternion[1] = sy * cp * sr + cy * sp * cr; // Y + //quaternion[2] = cr * cp * sy - sr * sp * cy; // Z + //quaternion[3] = cy * cp * cr + sy * sp * sr; // W +#else float angle; float sr, sp, sy, cr, cp, cy; @@ -152,6 +301,7 @@ void AngleQuaternion( float *angles, vec4_t quaternion ) quaternion[1] = cr * sp * cy + sr * cp * sy; // Y quaternion[2] = cr * cp * sy - sr * sp * cy; // Z quaternion[3] = cr * cp * cy + sr * sp * sy; // W +#endif } /* @@ -162,6 +312,37 @@ QuaternionSlerp */ void QuaternionSlerp( vec4_t p, vec4_t q, float t, vec4_t qt ) { +#if XASH_SIMD_NEON + float32x4_t p_reg = {}, q_reg = {}; + memcpy(&p_reg, p, sizeof(float) * 4); + memcpy(&q_reg, q, sizeof(float) * 4); + + // q = (cos(a/2), xsin(a/2), ysin(a/2), zsin(a/2)) + // cos(a-b) = cosacosb+sinasinb + const uint32x4_t signmask = vdupq_n_u32(0x80000000); + const float32x4_t one_minus_epsilon = vdupq_n_f32(1.0f - 0.00001f); + + float32x4_t vcosom = vdupq_n_f32(DotProduct(p, q)); + uint32x4_t sign = vandq_u32(vreinterpretq_u32_f32(vcosom), signmask); + q_reg = vreinterpretq_f32_u32(veorq_u32(vreinterpretq_u32_f32(p_reg), sign)); + vcosom = vreinterpretq_f32_u32(veorq_u32(vreinterpretq_u32_f32(vcosom), sign)); + + float x[4] = {(1.0f - t), t, 1, 0}; // cosom -> 1, sinom -> 0, sinx ~ x + float32x4_t x_reg; + memcpy(&x_reg, x, sizeof(float) * 4); + + // if ((1.0 - cosom) > 0.000001) x = sin(x * omega) + uint32x4_t cosom_less_then_one = vcltq_f32(vcosom, one_minus_epsilon); + float32x4_t vomega = acos_ps(vcosom); + x_reg = vbslq_f32(cosom_less_then_one, x_reg, sin_ps(vmulq_f32(x_reg, vomega))); + + // qt = (x[0] * p + x[1] * q) / x[2]; + float32x4_t qt_reg = vmulq_laneq_f32(p_reg, x_reg, 0); + qt_reg = vfmaq_laneq_f32(qt_reg, q_reg, x_reg, 1); + qt_reg = vdivq_f32(qt_reg, vdupq_laneq_f32(x_reg, 2)); // vdivq_laneq_f32 ? + + memcpy(qt, &qt_reg, sizeof(float) * 4); +#else int i; float omega, cosom, sinom, sclp, sclq; @@ -216,6 +397,7 @@ void QuaternionSlerp( vec4_t p, vec4_t q, float t, vec4_t qt ) qt[i] = sclp * p[i] + sclq * qt[i]; } } +#endif } /* @@ -224,8 +406,60 @@ QuaternionMatrix ==================== */ +#if XASH_SIMD_NEON +const uint32x4_t QuaternionMatrix_sign1 = vsetq_lane_u32(0x80000000, vdupq_n_u32(0x00000000), 0); // { 0x80000000, 0x00000000, 0x00000000, 0x00000000 }; +const uint32x4_t QuaternionMatrix_sign2 = vsetq_lane_u32(0x80000000, vdupq_n_u32(0x00000000), 1); // { 0x00000000, 0x80000000, 0x00000000, 0x00000000 }; +const uint32x4_t QuaternionMatrix_sign3 = vsetq_lane_u32(0x00000000, vdupq_n_u32(0x80000000), 2); // { 0x80000000, 0x80000000, 0x00000000, 0x80000000 }; +const float32x4_t matrix3x4_identity_0 = vsetq_lane_f32(1, vdupq_n_f32(0), 0); // { 1, 0, 0, 0 } +const float32x4_t matrix3x4_identity_1 = vsetq_lane_f32(1, vdupq_n_f32(0), 1); // { 0, 1, 0, 0 } +const float32x4_t matrix3x4_identity_2 = vsetq_lane_f32(1, vdupq_n_f32(0), 2); // { 0, 0, 1, 0 } +#endif + void QuaternionMatrix( vec4_t quaternion, float (*matrix)[4] ) { +#if XASH_SIMD_NEON + float32x4_t quaternion_reg; + memcpy(&quaternion_reg, quaternion, sizeof(float) * 4); + + float32x4_t q1032 = vrev64q_f32(quaternion_reg); + float32x4_t q1032_signed = vreinterpretq_f32_u32(veorq_u32(vreinterpretq_u32_f32(q1032), QuaternionMatrix_sign1)); + float32x4_t q2301 = vextq_f32(quaternion_reg, quaternion_reg, 2); + float32x4_t q2301_signed = vreinterpretq_f32_u32(veorq_u32(vreinterpretq_u32_f32(q2301), QuaternionMatrix_sign3)); + float32x4_t q3210 = vrev64q_f32(q2301); + float32x4_t q3210_signed = vreinterpretq_f32_u32(veorq_u32(vreinterpretq_u32_f32(q3210), QuaternionMatrix_sign2)); + + float32x4x3_t out_reg; + + out_reg.val[0] = vmulq_laneq_f32(q2301_signed, quaternion_reg, 2); + out_reg.val[0] = vfmaq_laneq_f32(out_reg.val[0], q1032_signed, quaternion_reg, 1); + out_reg.val[0] = vfmaq_n_f32(matrix3x4_identity_0, out_reg.val[0], 2.0f); + + out_reg.val[1] = vmulq_laneq_f32(q3210_signed, quaternion_reg, 2); + out_reg.val[1] = vfmsq_laneq_f32(out_reg.val[1], q1032_signed, quaternion_reg, 0); + out_reg.val[1] = vfmaq_n_f32(matrix3x4_identity_1, out_reg.val[1], 2.0f); + + out_reg.val[2] = vmulq_laneq_f32(q3210_signed, quaternion_reg, 1); + out_reg.val[2] = vfmaq_laneq_f32(out_reg.val[2], q2301_signed, quaternion_reg, 0); + out_reg.val[2] = vfmsq_n_f32(matrix3x4_identity_2, out_reg.val[2], 2.0f); + + memcpy(matrix, &out_reg, sizeof(float) * 3 * 4); +/* + matrix[0][0] = 1.0 + 2.0 * ( quaternion[1] * -quaternion[1] + -quaternion[2] * quaternion[2] ); + matrix[0][1] = 0.0 + 2.0 * ( quaternion[1] * quaternion[0] + -quaternion[3] * quaternion[2] ); + matrix[0][2] = 0.0 + 2.0 * ( quaternion[1] * quaternion[3] + quaternion[0] * quaternion[2] ); + matrix[0][3] = 0.0 + 2.0 * ( quaternion[1] * quaternion[2] + -quaternion[1] * quaternion[2] ); + + matrix[1][0] = 0.0 + 2.0 * ( -quaternion[0] * -quaternion[1] + quaternion[3] * quaternion[2] ); + matrix[1][1] = 1.0 + 2.0 * ( -quaternion[0] * quaternion[0] + -quaternion[2] * quaternion[2] ); + matrix[1][2] = 0.0 + 2.0 * ( -quaternion[0] * quaternion[3] + quaternion[1] * quaternion[2] ); + matrix[1][3] = 0.0 + 2.0 * ( -quaternion[0] * quaternion[2] + quaternion[0] * quaternion[2] ); + + matrix[2][0] = 0.0 + 2.0 * ( -quaternion[0] * -quaternion[2] + -quaternion[3] * quaternion[1] ); + matrix[2][1] = 0.0 + 2.0 * ( -quaternion[0] * -quaternion[3] + quaternion[2] * quaternion[1] ); + matrix[2][2] = 1.0 + 2.0 * ( -quaternion[0] * quaternion[0] + -quaternion[1] * quaternion[1] ); + matrix[2][3] = 0.0 + 2.0 * ( -quaternion[0] * -quaternion[1] + -quaternion[0] * quaternion[1] ); +*/ +#else matrix[0][0] = 1.0f - 2.0f * quaternion[1] * quaternion[1] - 2.0f * quaternion[2] * quaternion[2]; matrix[1][0] = 2.0f * quaternion[0] * quaternion[1] + 2.0f * quaternion[3] * quaternion[2]; matrix[2][0] = 2.0f * quaternion[0] * quaternion[2] - 2.0f * quaternion[3] * quaternion[1]; @@ -237,6 +471,7 @@ void QuaternionMatrix( vec4_t quaternion, float (*matrix)[4] ) matrix[0][2] = 2.0f * quaternion[0] * quaternion[2] + 2.0f * quaternion[3] * quaternion[1]; matrix[1][2] = 2.0f * quaternion[1] * quaternion[2] - 2.0f * quaternion[3] * quaternion[0]; matrix[2][2] = 1.0f - 2.0f * quaternion[0] * quaternion[0] - 2.0f * quaternion[1] * quaternion[1]; +#endif } /* From efa83646e4c33d6dc9eea744c9b91bb7fdf356c9 Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Wed, 21 Jun 2023 01:04:55 +0300 Subject: [PATCH 05/12] Fix skipping the m249 submodel 1 when updating the cartridge belt --- dlls/gearbox/m249.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/gearbox/m249.cpp b/dlls/gearbox/m249.cpp index 553560cc..630263a8 100644 --- a/dlls/gearbox/m249.cpp +++ b/dlls/gearbox/m249.cpp @@ -295,7 +295,7 @@ int CM249::BodyFromClip(int clip) { if (clip == 0) { return 8; - } else if (clip > 0 && clip < 8) { + } else if (clip > 0 && clip <= 8) { return 9 - clip; } else { return 0; From 5e722bfabab61d870d50e8cfdb15a85c34af66d5 Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Wed, 21 Jun 2023 01:20:30 +0300 Subject: [PATCH 06/12] Alternate between shell and link ejection in M249 --- cl_dll/ev_hldm.cpp | 3 ++- dlls/gearbox/m249.cpp | 5 ++++- dlls/weapons.h | 2 ++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/cl_dll/ev_hldm.cpp b/cl_dll/ev_hldm.cpp index 1a8a7187..543d093c 100644 --- a/cl_dll/ev_hldm.cpp +++ b/cl_dll/ev_hldm.cpp @@ -1984,7 +1984,8 @@ void EV_FireM249( event_args_t *args ) AngleVectors( angles, forward, right, up ); - shell = gEngfuncs.pEventAPI->EV_FindModelIndex( "models/saw_shell.mdl" );// brass shell + const bool bAlternatingEject = args->bparam1 != 0; + shell = bAlternatingEject ? gEngfuncs.pEventAPI->EV_FindModelIndex("models/saw_link.mdl") : gEngfuncs.pEventAPI->EV_FindModelIndex( "models/saw_shell.mdl" );// brass shell if( EV_IsLocal( idx ) ) { diff --git a/dlls/gearbox/m249.cpp b/dlls/gearbox/m249.cpp index 630263a8..c9ae9068 100644 --- a/dlls/gearbox/m249.cpp +++ b/dlls/gearbox/m249.cpp @@ -51,6 +51,7 @@ void CM249::Spawn() m_iDefaultAmmo = M249_DEFAULT_GIVE; m_fInSpecialReload = 0; + m_bAlternatingEject = false; FallInit();// get ready to fall down. } @@ -63,6 +64,7 @@ void CM249::Precache(void) PRECACHE_MODEL("models/p_saw.mdl"); m_iShell = PRECACHE_MODEL("models/saw_shell.mdl");// brass shellTE_MODEL + m_iLink = PRECACHE_MODEL("models/saw_link.mdl"); PRECACHE_MODEL("models/w_saw_clip.mdl"); PRECACHE_SOUND("items/9mmclip1.wav"); @@ -146,6 +148,7 @@ void CM249::PrimaryAttack() m_iClip--; UpdateTape(); + m_bAlternatingEject = !m_bAlternatingEject; m_pPlayer->pev->effects = (int)(m_pPlayer->pev->effects) | EF_MUZZLEFLASH; // player "shoot" animation @@ -177,7 +180,7 @@ void CM249::PrimaryAttack() flags = 0; #endif - PLAYBACK_EVENT_FULL(flags, m_pPlayer->edict(), m_usM249, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, vecDir.x, vecDir.y, 0, pev->body, 0, 0); + PLAYBACK_EVENT_FULL(flags, m_pPlayer->edict(), m_usM249, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, vecDir.x, vecDir.y, 0, pev->body, m_bAlternatingEject ? 1 : 0, 0); #if !CLIENT_DLL diff --git a/dlls/weapons.h b/dlls/weapons.h index 9e0fc901..7dd9b3b0 100644 --- a/dlls/weapons.h +++ b/dlls/weapons.h @@ -1252,6 +1252,8 @@ public: virtual BOOL ShouldWeaponIdle(void) { return TRUE; } float m_flNextAnimTime; int m_iShell; + int m_iLink; + bool m_bAlternatingEject; virtual BOOL UseDecrement(void) { From 6259156cb194f3d5e73319c8548c22ac69ea5016 Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Wed, 21 Jun 2023 01:23:24 +0300 Subject: [PATCH 07/12] Remove usage of redundant m249 fire sounds (they are all the same and only one is used in opfor) --- cl_dll/ev_hldm.cpp | 13 +------------ dlls/gearbox/m249.cpp | 2 -- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/cl_dll/ev_hldm.cpp b/cl_dll/ev_hldm.cpp index 543d093c..a98e3878 100644 --- a/cl_dll/ev_hldm.cpp +++ b/cl_dll/ev_hldm.cpp @@ -2000,18 +2000,7 @@ void EV_FireM249( event_args_t *args ) EV_EjectBrass( ShellOrigin, ShellVelocity, angles[YAW], shell, TE_BOUNCE_SHELL ); - switch( gEngfuncs.pfnRandomLong( 0, 2 ) ) - { - case 0: - gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/saw_fire1.wav", 1, ATTN_NORM, 0, PITCH_NORM); - break; - case 1: - gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/saw_fire2.wav", 1, ATTN_NORM, 0, PITCH_NORM); - break; - case 2: - gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/saw_fire3.wav", 1, ATTN_NORM, 0, PITCH_NORM); - break; - } + gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/saw_fire1.wav", 1, ATTN_NORM, 0, PITCH_NORM); EV_GetGunPosition( args, vecSrc, origin ); VectorCopy( forward, vecAiming ); diff --git a/dlls/gearbox/m249.cpp b/dlls/gearbox/m249.cpp index c9ae9068..b2ba4a0e 100644 --- a/dlls/gearbox/m249.cpp +++ b/dlls/gearbox/m249.cpp @@ -70,8 +70,6 @@ void CM249::Precache(void) PRECACHE_SOUND("items/9mmclip1.wav"); PRECACHE_SOUND("weapons/saw_fire1.wav"); - PRECACHE_SOUND("weapons/saw_fire2.wav"); - PRECACHE_SOUND("weapons/saw_fire3.wav"); PRECACHE_SOUND("weapons/saw_reload.wav"); PRECACHE_SOUND("weapons/saw_reload2.wav"); From f0f4e55c489de6ff6da5e99efdc4328fe5770359 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Mon, 3 Jul 2023 01:45:28 +0300 Subject: [PATCH 08/12] Add PowerPC to library naming scheme --- cmake/LibraryNaming.cmake | 10 ++++++++++ public/build.h | 13 ++++++++++++- scripts/waifulib/library_naming.py | 17 ++++++++++++----- 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/cmake/LibraryNaming.cmake b/cmake/LibraryNaming.cmake index 0ffae76f..724349bd 100644 --- a/cmake/LibraryNaming.cmake +++ b/cmake/LibraryNaming.cmake @@ -59,6 +59,7 @@ check_group_build_target(XASH_X86 XASH_ARCHITECTURE) check_group_build_target(XASH_AMD64 XASH_ARCHITECTURE) check_group_build_target(XASH_ARM XASH_ARCHITECTURE) check_group_build_target(XASH_MIPS XASH_ARCHITECTURE) +check_group_build_target(XASH_PPC XASH_ARCHITECTURE) check_group_build_target(XASH_JS XASH_ARCHITECTURE) check_group_build_target(XASH_E2K XASH_ARCHITECTURE) check_group_build_target(XASH_RISCV XASH_ARCHITECTURE) @@ -168,6 +169,15 @@ elseif(XASH_JS) set(BUILDARCH "javascript") elseif(XASH_E2K) set(BUILDARCH "e2k") +elseif(XASH_PPC) + set(BUILDARCH "ppc") + if(XASH_64BIT) + set(BUILDARCH "${BUILDARCH}64") + endif() + + if(XASH_LITTLE_ENDIAN) + set(BUILDARCH "${BUILDARCH}el") + endif() else() message(SEND_ERROR "Place your architecture name here! If this is a mistake, try to fix conditions above and report a bug") endif() diff --git a/public/build.h b/public/build.h index 636d97a4..2f8fffae 100644 --- a/public/build.h +++ b/public/build.h @@ -76,6 +76,7 @@ Then you can use another oneliner to query all variables: #undef XASH_NETBSD #undef XASH_OPENBSD #undef XASH_POSIX +#undef XASH_PPC #undef XASH_RISCV #undef XASH_RISCV_DOUBLEFP #undef XASH_RISCV_SINGLEFP @@ -138,7 +139,12 @@ Then you can use another oneliner to query all variables: #endif #endif -#if XASH_ANDROID || defined XASH_IOS || defined XASH_NSWITCH || defined XASH_PSVITA +// XASH_SAILFISH is special: SailfishOS by itself is a normal GNU/Linux platform +// It doesn't make sense to split it to separate platform +// but we still need XASH_MOBILE_PLATFORM for the engine. +// So this macro is defined entirely in build-system: see main wscript +// HLSDK/PrimeXT/other SDKs users note: you may ignore this macro +#if XASH_ANDROID || XASH_IOS || XASH_NSWITCH || XASH_PSVITA || XASH_SAILFISH #define XASH_MOBILE_PLATFORM 1 #endif @@ -190,6 +196,11 @@ Then you can use another oneliner to query all variables: #elif defined __e2k__ #define XASH_64BIT 1 #define XASH_E2K 1 +#elif defined __PPC__ || defined __powerpc__ + #define XASH_PPC 1 + #if defined __PPC64__ || defined __powerpc64__ + #define XASH_64BIT 1 + #endif #elif defined _M_ARM // msvc #define XASH_ARM 7 #define XASH_ARM_HARDFP 1 diff --git a/scripts/waifulib/library_naming.py b/scripts/waifulib/library_naming.py index 78acafe9..4369b3b6 100644 --- a/scripts/waifulib/library_naming.py +++ b/scripts/waifulib/library_naming.py @@ -51,6 +51,7 @@ DEFINES = [ 'XASH_NETBSD', 'XASH_OPENBSD', 'XASH_POSIX', +'XASH_PPC', 'XASH_RISCV', 'XASH_RISCV_DOUBLEFP', 'XASH_RISCV_SINGLEFP', @@ -126,7 +127,7 @@ def configure(conf): buildarch += "4" else: raise conf.fatal('Unknown ARM') - + if conf.env.XASH_ARM_HARDFP: buildarch += "hf" else: @@ -143,7 +144,7 @@ def configure(conf): buildarch += "64" else: buildarch += "32" - + if conf.env.XASH_RISCV_DOUBLEFP: buildarch += "d" elif conf.env.XASH_RISCV_SINGLEFP: @@ -152,12 +153,18 @@ def configure(conf): buildarch = "javascript" elif conf.env.XASH_E2K: buildarch = "e2k" + elif conf.env.XASH_PPC: + buildarch = "ppc" + if conf.env.XASH_64BIT: + buildarch += "64" + if conf.env.XASH_LITTLE_ENDIAN: + buildarch += "el" else: raise conf.fatal("Place your architecture name in build.h and library_naming.py!\n" "If this is a mistake, try to fix conditions above and report a bug") - + conf.env.revert() - + if buildos == 'android': # force disable for Android, as Android ports aren't distributed in normal way and doesn't follow library naming conf.env.POSTFIX = '' @@ -167,5 +174,5 @@ def configure(conf): conf.env.POSTFIX = '_%s' % buildarch else: conf.env.POSTFIX = '' - + conf.end_msg(conf.env.POSTFIX) From fa03ed3bce89e16c86b28b8419e1b540f8d1d627 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Mon, 3 Jul 2023 02:36:40 +0300 Subject: [PATCH 09/12] wscript: fix mod_options.txt parsing under Python2 --- wscript | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/wscript b/wscript index 71f485f0..02efd884 100644 --- a/wscript +++ b/wscript @@ -214,18 +214,19 @@ def configure(conf): with open('mod_options.txt') as fd: lines = fd.readlines() for line in lines: - p = regex.match(line.strip()) - if p: - conf.start_msg("* " + p[3]) - if p[2] == 'ON': - conf.env[p[1]] = True - conf.define(p[1], 1) - elif p[2] == 'OFF': - conf.env[p[1]] = False - conf.undefine(p[1]) + m = regex.match(line.strip()) + if m: + p = m.groups() + conf.start_msg("* " + p[2]) + if p[1] == 'ON': + conf.env[p[0]] = True + conf.define(p[0], 1) + elif p[1] == 'OFF': + conf.env[p[0]] = False + conf.undefine(p[0]) else: - conf.env[p[1]] = p[2] - conf.end_msg(p[2]) + conf.env[p[0]] = p[1] + conf.end_msg(p[1]) if conf.env.HLDEMO_BUILD and conf.env.OEM_BUILD: conf.fatal('Don\'t mix Demo and OEM builds!') From d8e4ec04e4927c7050e0bb10fe63d53e54e9e787 Mon Sep 17 00:00:00 2001 From: Xiaobaibai <824395314@qq.com> Date: Fri, 14 Jul 2023 10:17:31 +0800 Subject: [PATCH 10/12] fix typo ( no xref at all? ) --- cl_dll/studio_util.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cl_dll/studio_util.cpp b/cl_dll/studio_util.cpp index 3b9af7de..2d4bad80 100644 --- a/cl_dll/studio_util.cpp +++ b/cl_dll/studio_util.cpp @@ -149,7 +149,7 @@ void CrossProduct( const float *v1, const float *v2, float *cross ) float32x4_t zxyy_b = vextq_f32(yzxy_b, yzxy_b, 1); // [bk, ai, bj, bj] float32x4_t cross_reg = vfmsq_f32(vmulq_f32(yzxy_a, zxyy_b), zxyy_a, yzxy_b); // [ajbk-akbj, akbi-aibk, aibj-ajbi, 0] - memcpy(cross, &v2_reg, sizeof(float) * 3); + memcpy(cross, &cross_reg, sizeof(float) * 3); #else cross[0] = v1[1] * v2[2] - v1[2] * v2[1]; cross[1] = v1[2] * v2[0] - v1[0] * v2[2]; From a898d773a175760def16c61847a6fd17f5a2abf5 Mon Sep 17 00:00:00 2001 From: Andrey Akhmichin <15944199+nekonomicon@users.noreply.github.com> Date: Mon, 17 Jul 2023 22:49:24 +0500 Subject: [PATCH 11/12] Revert "Always change view rolling on client side." This reverts commit 1ed4c1d899c083a494b4ca0de41d02d6f043d7fa. --- cl_dll/hud.cpp | 14 ++++++++++++-- cl_dll/view.cpp | 12 +++++++++--- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/cl_dll/hud.cpp b/cl_dll/hud.cpp index bc87f630..5155993e 100644 --- a/cl_dll/hud.cpp +++ b/cl_dll/hud.cpp @@ -95,6 +95,7 @@ float g_hud_text_color[3]; extern client_sprite_t *GetSpriteList( client_sprite_t *pList, const char *psz, int iRes, int iCount ); extern cvar_t *sensitivity; +qboolean bIsXash; cvar_t *cl_lw = NULL; cvar_t *cl_viewbob = NULL; cvar_t *cl_rollspeed; @@ -383,8 +384,17 @@ void CHud::Init( void ) m_pCvarDraw = CVAR_CREATE( "hud_draw", "1", FCVAR_ARCHIVE ); cl_lw = gEngfuncs.pfnGetCvarPointer( "cl_lw" ); cl_viewbob = CVAR_CREATE( "cl_viewbob", "0", FCVAR_ARCHIVE ); - cl_rollangle = gEngfuncs.pfnRegisterVariable( "cl_rollangle", "0", FCVAR_CLIENTDLL | FCVAR_ARCHIVE ); - cl_rollspeed = gEngfuncs.pfnRegisterVariable( "cl_rollspeed", "200", FCVAR_CLIENTDLL | FCVAR_ARCHIVE ); +#if GOLDSOURCE_SUPPORT + if( gEngfuncs.pfnGetCvarPointer( "build" )) + { + bIsXash = true; + } + else + { + cl_rollangle = gEngfuncs.pfnRegisterVariable( "cl_rollangle", "0", FCVAR_CLIENTDLL | FCVAR_ARCHIVE ); + cl_rollspeed = gEngfuncs.pfnRegisterVariable( "cl_rollspeed", "200", FCVAR_CLIENTDLL | FCVAR_ARCHIVE ); + } +#endif m_pSpriteList = NULL; // Clear any old HUD list diff --git a/cl_dll/view.cpp b/cl_dll/view.cpp index f0a5deef..5c6316a5 100644 --- a/cl_dll/view.cpp +++ b/cl_dll/view.cpp @@ -313,6 +313,7 @@ void V_AddIdle( struct ref_params_s *pparams ) pparams->viewangles[YAW] += v_idlescale * sin( pparams->time * v_iyaw_cycle.value ) * v_iyaw_level.value; } +extern qboolean bIsXash; extern cvar_t *cl_rollspeed; extern cvar_t *cl_rollangle; @@ -331,9 +332,14 @@ void V_CalcViewRoll( struct ref_params_s *pparams ) viewentity = gEngfuncs.GetEntityByIndex( pparams->viewentity ); if( !viewentity ) return; - - side = V_CalcRoll( viewentity->angles, pparams->simvel, cl_rollangle->value, cl_rollspeed->value ); - +#if GOLDSOURCE_SUPPORT + if( bIsXash ) + side = V_CalcRoll( viewentity->angles, pparams->simvel, pparams->movevars->rollangle, pparams->movevars->rollspeed ); + else + side = V_CalcRoll( viewentity->angles, pparams->simvel, cl_rollangle->value, cl_rollspeed->value ); +#else + side = V_CalcRoll( viewentity->angles, pparams->simvel, pparams->movevars->rollangle, pparams->movevars->rollspeed ); +#endif pparams->viewangles[ROLL] += side; if( pparams->health <= 0 && ( pparams->viewheight[2] != 0 ) ) From 8180cf60c270b933096506f61d07ed03ba3619af Mon Sep 17 00:00:00 2001 From: Andrey Akhmichin <15944199+nekonomicon@users.noreply.github.com> Date: Mon, 17 Jul 2023 22:50:16 +0500 Subject: [PATCH 12/12] Revert "Change view rolling via separate cvars under GoldSource." This reverts commit 5cca1eb971ad177ddeb65b14defc845a95b8bec6. --- cl_dll/hud.cpp | 15 +-------------- cl_dll/view.cpp | 13 ++----------- 2 files changed, 3 insertions(+), 25 deletions(-) diff --git a/cl_dll/hud.cpp b/cl_dll/hud.cpp index 5155993e..f16e30b9 100644 --- a/cl_dll/hud.cpp +++ b/cl_dll/hud.cpp @@ -95,11 +95,8 @@ float g_hud_text_color[3]; extern client_sprite_t *GetSpriteList( client_sprite_t *pList, const char *psz, int iRes, int iCount ); extern cvar_t *sensitivity; -qboolean bIsXash; cvar_t *cl_lw = NULL; cvar_t *cl_viewbob = NULL; -cvar_t *cl_rollspeed; -cvar_t *cl_rollangle; void ShutdownInput( void ); @@ -384,17 +381,7 @@ void CHud::Init( void ) m_pCvarDraw = CVAR_CREATE( "hud_draw", "1", FCVAR_ARCHIVE ); cl_lw = gEngfuncs.pfnGetCvarPointer( "cl_lw" ); cl_viewbob = CVAR_CREATE( "cl_viewbob", "0", FCVAR_ARCHIVE ); -#if GOLDSOURCE_SUPPORT - if( gEngfuncs.pfnGetCvarPointer( "build" )) - { - bIsXash = true; - } - else - { - cl_rollangle = gEngfuncs.pfnRegisterVariable( "cl_rollangle", "0", FCVAR_CLIENTDLL | FCVAR_ARCHIVE ); - cl_rollspeed = gEngfuncs.pfnRegisterVariable( "cl_rollspeed", "200", FCVAR_CLIENTDLL | FCVAR_ARCHIVE ); - } -#endif + m_pSpriteList = NULL; // Clear any old HUD list diff --git a/cl_dll/view.cpp b/cl_dll/view.cpp index 5c6316a5..4c93fb87 100644 --- a/cl_dll/view.cpp +++ b/cl_dll/view.cpp @@ -313,10 +313,6 @@ void V_AddIdle( struct ref_params_s *pparams ) pparams->viewangles[YAW] += v_idlescale * sin( pparams->time * v_iyaw_cycle.value ) * v_iyaw_level.value; } -extern qboolean bIsXash; -extern cvar_t *cl_rollspeed; -extern cvar_t *cl_rollangle; - /* ============== V_CalcViewRoll @@ -332,14 +328,9 @@ void V_CalcViewRoll( struct ref_params_s *pparams ) viewentity = gEngfuncs.GetEntityByIndex( pparams->viewentity ); if( !viewentity ) return; -#if GOLDSOURCE_SUPPORT - if( bIsXash ) - side = V_CalcRoll( viewentity->angles, pparams->simvel, pparams->movevars->rollangle, pparams->movevars->rollspeed ); - else - side = V_CalcRoll( viewentity->angles, pparams->simvel, cl_rollangle->value, cl_rollspeed->value ); -#else + side = V_CalcRoll( viewentity->angles, pparams->simvel, pparams->movevars->rollangle, pparams->movevars->rollspeed ); -#endif + pparams->viewangles[ROLL] += side; if( pparams->health <= 0 && ( pparams->viewheight[2] != 0 ) )