Compare commits

...

403 Commits

Author SHA1 Message Date
Alibek Omarov
3f81af50af engine: platform: allow querying window type through R_GetWindowHandle 2025-05-24 21:28:09 +05:00
TheEVolk
735f4e2bcb ref_api: make handle as argument and use type request input 2025-05-24 20:47:28 +05:00
TheEVolk
9ebeb520fa engine: platform: refactor R_GetWindowHandle to return a struct instead of a pointer 2025-05-24 20:47:28 +05:00
TheEVolk
dd52840a97 ref_api: update REF_API_VERSION to 10 and document R_GetWindowHandle addition 2025-05-24 20:47:28 +05:00
TheEVolk
4ce03662d9 ref_api: R_GetWindowHandle method 2025-05-24 20:47:28 +05:00
Andrey Akhmichin
20320d8dfa Documentation: not-supported-mod-list-and-reasons-why.md: update. 2025-05-24 20:45:28 +05:00
Alibek Omarov
f2ecdad5bb engine: disable clipnodes remapping for non-extended formats and QBSP2 2025-05-24 20:43:44 +05:00
Alibek Omarov
298842be32 engine: fix clipnodes limit check based on BSP version 2025-05-24 17:43:01 +05:00
Alibek Omarov
15544cde26 engine: common: fix typo in aguirRe nickname [skip ci] 2025-05-21 17:43:05 +05:00
Alibek Omarov
a4ad537e59 engine: server: minor refactoring 2025-05-20 20:24:42 +05:00
Alibek Omarov
7ba48e00bc 3rdparty: libbacktrace: sort entries in config.h to keep it the same between reconfigurations
Multicheck parallel nature caused config.h entries to be sorted randomly and
libbacktrace recompiled on every occasion.
2025-05-20 15:25:39 +05:00
Alibek Omarov
bb620d1265 engine: client: set cl_upmax to 508 by default 2025-05-20 14:35:29 +05:00
SNMetamorph
32e6f37c7e engine: server: fixed incorrect printing of IPv6 address in "status" command 2025-05-12 14:11:09 +03:00
Alibek Omarov
8f95535390 engine: server: fix a typo that prevented "status" command from executing by spawned player 2025-05-12 11:37:11 +03:00
Alibek Omarov
b2444f2480 engine: restore SDL2 include path 2025-05-11 18:01:17 +03:00
Alibek Omarov
37d6d75e69 engine: platform: sdl3: add system and input SDL3 platform implementation 2025-05-11 17:35:13 +03:00
Alibek Omarov
97bdd9dba0 engine: port occasional SDL2 calls to SDL3, no platform yet 2025-05-11 16:18:10 +03:00
Alibek Omarov
ffc8bf30d7 engine: platform: make most input platform functions optional, patch fbdev/evdev to compile 2025-05-11 16:14:36 +03:00
Alibek Omarov
8209a8a681 engine: platform: move mouse grab enabling and querying functions to SDL platform code 2025-05-11 16:09:57 +03:00
Alibek Omarov
34beb9666b engine: soundlib: drop SDL-based resampler 2025-05-11 15:27:50 +03:00
Alibek Omarov
6ccafbe297 engine: platform: move Host_Minimize_f into platform code 2025-05-11 15:24:52 +03:00
Andrey Akhmichin
a479099804 utils: mdldec: write all GoldSource-compatible motion-types with "-m" option. 2025-05-11 03:40:57 +03:00
Alibek Omarov
94791d3cb6 engine: allow downloading files that have multiple dots in filename. Also disallow everything that has nonprintable characters. 2025-05-06 21:16:06 +03:00
Alibek Omarov
6555562e78 engine: common: fix building tests 2025-05-06 21:15:28 +03:00
Alibek Omarov
de790d6f59 Revert "engine: server: increased sv_connect_timeout to a half a minute"
This reverts commit 3fca1bb4d5.
2025-05-06 20:22:20 +03:00
Alibek Omarov
cff0df60a9 engine: server: also bump timeouts for connected clients during changelevel in server activation 2025-05-06 20:19:17 +03:00
Alibek Omarov
c8b8e19ed3 engine: server: fix time out on change level 2025-05-06 20:11:41 +03:00
Alibek Omarov
2106556dec engine: server: limit status and build info commands only to spawned clients 2025-05-06 19:50:51 +03:00
Alibek Omarov
7221bd6049 engine: server: small refactoring 2025-05-06 19:50:26 +03:00
Alibek Omarov
ded38020d3 engine: server: add new client state cs_spawning, to ensure that client cannot spawn before it has an entity 2025-05-06 19:37:54 +03:00
Alibek Omarov
c6251174df engine: server: don't let unspawned player execute ent tools commands or send voice data 2025-05-06 19:02:32 +03:00
Alibek Omarov
177c132969 engine: common: fix incorrect argument name, which also fixes build with compilers that enforce C23 2025-05-06 19:00:18 +03:00
Alibek Omarov
3fca1bb4d5 engine: server: increased sv_connect_timeout to a half a minute 2025-05-06 16:28:29 +03:00
Alibek Omarov
321e28c810 scripts: waifulib: sdl2: fix SDL3 sanity test 2025-05-05 18:51:01 +03:00
Alibek Omarov
7fda58561f engine: platform: sdl2: remove SDL1.2 code, as it's now moved into it's own separate directory 2025-05-05 05:56:23 +03:00
Alibek Omarov
0cbb62b329 engine: platform: try to restore SDL1.2 support (only ref_soft is tested, ref_gl doesn't work) 2025-05-05 05:44:31 +03:00
Alibek Omarov
aa2e5eb3cc engine: platform: move SDL2 support code into sdl2 subdirectory. Change XASH_SDL macro value from 12 to 1 for SDL1.2 2025-05-05 05:15:10 +03:00
Alibek Omarov
3d26ba1ed8 engine: client: always pass a valid pointer to usercmd_t in ref_params_t to prevent crassh when client.dll reads them during demo playback 2025-05-05 03:40:18 +03:00
Alibek Omarov
47c4844024 engine: platform: sdl: enable building with SDL as old as 2.0.8, it should satisfy everybody masturbating to old software 2025-04-30 17:45:05 +03:00
Alibek Omarov
d457d7d093 filesystem: archive mounting refactoring 2025-04-28 22:28:30 +03:00
Vladimir
43364ec2e9 defaults: enable touch for psvita & nswitch (#2143) 2025-04-27 14:39:58 +03:00
Alibek Omarov
14127c26f5 scripts: gha: don't put dedicated binary in full client tarballs 2025-04-24 23:41:26 +03:00
Alibek Omarov
291f24a611 scripts: cirrus: build dedicated server alongside full client for slightly faster builds 2025-04-24 23:33:59 +03:00
Alibek Omarov
1abb16638f scripts: gha: build dedicated server alongside full client for slightly faster builds 2025-04-24 23:33:59 +03:00
Alibek Omarov
3e41e389c5 engine: lib_common: do not take generic GNU/Linux rules for library naming on Android 2025-04-24 21:53:03 +03:00
Alibek Omarov
5aca143eba engine: disable Android-specific library loader under Termux 2025-04-24 21:46:43 +03:00
Alibek Omarov
60fa855d47 filesystem: wscript: strip lib prefix on Termux too 2025-04-24 21:42:20 +03:00
Alibek Omarov
22661fd446 public: define XASH_TERMUX if __TERMUX__ is defined. Do not enable XASH_MOBILE_PLATFORM for it 2025-04-24 21:40:35 +03:00
Alibek Omarov
61d8d5e12b wscript: detect if we're compiling from Termux 2025-04-24 21:39:46 +03:00
Alibek Omarov
a7f3c04baa engine: platform: android: hide SDL calls under XASH_SDL macro 2025-04-24 21:39:46 +03:00
Alibek Omarov
296e642f09 wscript: look for libm when compiling for Android on Android device itself (e.g. Termux) 2025-04-24 20:52:55 +03:00
Alibek Omarov
75eb1f1e8b filesystem: android: make failing to find JNI env non-fatal 2025-04-24 20:52:18 +03:00
Alibek Omarov
8f4a45baaa engine: platform: win32: set IMAGEHLP_LINE64 structure size as required in dbghelp docs on MSDN 2025-04-21 20:33:30 +03:00
Alibek Omarov
18aac5fd3d readme: update 2025-04-21 20:12:55 +03:00
Alibek Omarov
ca6ca8450b engine: platform: sdl: load .ico file with wide function allowing for icons to be loaded from non-latin game directory 2025-04-21 20:09:39 +03:00
Alibek Omarov
6ecaea3102 engine: system: convert Windows username to utf8 2025-04-21 19:56:49 +03:00
Alibek Omarov
fa47ca0d2d engine: system: make a copy of pw_name just in case 2025-04-21 19:56:23 +03:00
Alibek Omarov
8ce3b4ac93 engine: client: identification: use wide CreateProcess call, ensure that process terminated and it's handles are closed 2025-04-21 19:38:10 +03:00
Alibek Omarov
a7ba705277 engine: platform: win32: make output similar to libbacktrace-based crashhandler, general improvements and refactoring 2025-04-21 18:54:39 +03:00
Alibek Omarov
85a4d296f5 Documentation: not-supported-mod-list-and-reasons-why: clarify that we don't know why Arrange Mod doesn't work on Xash yet [skip ci] 2025-04-21 17:06:11 +03:00
Andrey Akhmichin
4dd8d89459 Documentation: not-supported-mod-list-and-reasons-why.md: update [skip ci] 2025-04-21 17:04:19 +03:00
Alibek Omarov
c564cc96c7 engine: get rid of host.crashed field, as it's a complete duplicate of host.status 2025-04-21 16:59:44 +03:00
Alibek Omarov
0e54200f34 engine: platform: win32: move saving minidumps before showing stacktrace messagebox 2025-04-21 16:58:43 +03:00
Alibek Omarov
fa75c33390 engine: platform: win32: do not set parent window for stacktrace print window 2025-04-21 16:57:27 +03:00
Alibek Omarov
36cb3b2d89 engine: fix incompatible int size when casting pointer to int 2025-04-21 15:54:32 +03:00
Andrey Akhmichin
2f3b03d27a Documentation: opensource-mods.md: add "Counter-Life". 2025-04-20 10:23:53 +03:00
SNMetamorph
f0deac206b Documentation: added initial revision of touch controls configuring guide
Thanks to VladislavKZ and archer for helping with information gathering.
2025-04-18 17:24:44 +03:00
Alibek Omarov
5d0e473cf1 3rdparty: maintui: update 2025-04-16 14:52:46 +03:00
Alibek Omarov
2174fe6d21 ci: update to ubuntu-22.04 2025-04-15 21:04:48 +03:00
Alibek Omarov
5d1e207337 3rdparty: maintui: update 2025-04-15 21:00:38 +03:00
Alibek Omarov
87c209f1f9 engine: server: drop clients that do not continue connecting after smaller timeout 2025-04-15 20:54:27 +03:00
SNMetamorph
ed5ea002d7 Documentation: donate: updated details, changed layout 2025-04-15 18:07:59 +03:00
Alibek Omarov
149593fea5 engine: server: hide Cmd_ForwardToServer call under XASH_DEDICATED just in case, fixes build with debug 2025-04-11 00:34:10 +03:00
Alibek Omarov
8c0f1d65ba 3rdparty: maintui: update 2025-04-10 23:56:55 +03:00
Alibek Omarov
bbf6f1c7b8 scripts: gha: fix generating sources.list on different ubuntu version 2025-04-10 23:37:36 +03:00
Alibek Omarov
3b61e0bbd6 ci: thanks github, ubuntu-latest isn't actually latest 2025-04-10 23:07:39 +03:00
Alibek Omarov
8d2986bc74 3rdparty: maintui: update 2025-04-10 23:02:48 +03:00
Alibek Omarov
27a8adad22 ci: compile risc-v port on ubuntu-latest for newer compilers 2025-04-10 22:48:41 +03:00
Alibek Omarov
64e774377b scripts: gha: fix ppc64el rust target 2025-04-10 22:48:17 +03:00
Alibek Omarov
8ff469d466 3rdparty: maintui: update 2025-04-10 22:26:13 +03:00
Alibek Omarov
a20e961892 scripts: gha: install i686-pc-windows-msvc rust target for cross-compiling 32-bit maintui 2025-04-10 22:02:13 +03:00
Alibek Omarov
8ba30a1c09 scripts: gha: add Rust target for crosscompiling 2025-04-10 20:01:03 +03:00
Alibek Omarov
d570d6d6da scripts: gha: enable building maintui on supported platforms (win32, linux and apple) 2025-04-10 19:21:09 +03:00
Alibek Omarov
882b573e70 wscript: build maintui alongside mainui_cpp, so both could be used and shipped 2025-04-10 19:21:09 +03:00
Andrey Akhmichin
54657c149b utils: mdldec: use separate options for sequences and textures. 2025-04-10 14:57:11 +05:00
Alibek Omarov
9054b11ebd engine: client: let loading custom menu dll with -menulib command line switch 2025-04-09 17:35:36 +03:00
Alibek Omarov
71d31330f9 filesystem: dir: fix possible null dereference 2025-04-05 14:03:24 +05:00
SNMetamorph
ea29699633 scripts: gha: psvita: pinned cmake version to 3.28.3 2025-04-05 12:45:45 +05:00
Andrey Akhmichin
ccb8d611c6 public: add getopt implementation from NetBSD libc. 2025-04-02 12:07:41 +03:00
Andrey Akhmichin
f4d98c056e utils: mdldec: handle unknown options. 2025-04-02 12:07:41 +03:00
Andrey Akhmichin
779adcd838 utils: mdldec: bump version to 1.2. 2025-04-02 12:07:41 +03:00
Andrey Akhmichin
16e2ce0aeb utils: mdldec: avoid brackets. 2025-04-02 12:07:41 +03:00
Andrey Akhmichin
7bfcd4cef0 utils: mdldec: add options to:
- disable log output.
 - use separate directories for smd and texture files.
 - avoid to write paranoia 2 motion types.
 - ignore filesize checks.
 - enable UV coords shifting.
 - show decompiler version.
 - show help.
2025-04-02 12:07:41 +03:00
Andrey Akhmichin
c298635728 utils: mdldec: Makefile: update. 2025-04-02 12:07:41 +03:00
Andrey Akhmichin
92e976952e utils: mdldec: fix UV coords shifting yet again. 2025-04-02 12:07:41 +03:00
Denis Drakhnia
a85bd0c864 maintui: first blood 2025-04-01 14:46:27 +03:00
Alibek Omarov
0a5f175431 mainui: update 2025-03-31 19:18:39 +03:00
Alibek Omarov
da6402ccc2 common: xash3d_types: disable PFN_RETURNS_NONNULL attribute for MCST lcc 2025-03-31 19:14:22 +03:00
Alibek Omarov
9d1b03d119 scripts: gha: build for e2k-8c on GitHub Actions machines 2025-03-31 19:07:47 +03:00
Alibek Omarov
6cf0d7a871 scripts: gha: linux: fix enabling stb_truetype in mainui_cpp 2025-03-31 18:20:23 +03:00
SNMetamorph
d5a6a7ae60 scripts: gha: made voice chat enabled by default for PS Vita platform 2025-03-30 20:24:38 +03:00
SNMetamorph
185374f99f engine: platform: psvita: explicitly exported symbol rintf
This is required for cs16client port for PS Vita.
2025-03-30 20:24:38 +03:00
SNMetamorph
b9072e4642 Documentation: slightly updated PS Vita port installation instructions 2025-03-30 20:24:38 +03:00
yumirak
06e5895d7a engine: client: fix TE_BLOODSPRITE behaviour to GoldSrc 2025-03-26 22:00:10 +03:00
Alibek Omarov
ac5be8156b Revert "wscript: force -Wuninitialized to error"
This reverts commit e615ff0e7f.
2025-03-25 19:10:13 +03:00
Alibek Omarov
8c12a8baed mainui: update 2025-03-25 19:02:00 +03:00
Alibek Omarov
e615ff0e7f wscript: force -Wuninitialized to error 2025-03-25 17:11:51 +03:00
Alibek Omarov
2e8fa60e96 engine: client: don't allow downscaling HUD when using hud_scale's fixed resolution mode 2025-03-25 17:07:05 +03:00
Alibek Omarov
a8ba9124dd engine: server: fix -Wmaybe-uninitialized 2025-03-25 17:07:05 +03:00
Alibek Omarov
f6e8a68b22 engine: imagelib: img_png: fix -Wmaybe-uninitialized 2025-03-25 17:07:05 +03:00
Alibek Omarov
706cc16a86 ref: fix -Wmaybe-uninitialized 2025-03-25 17:06:59 +03:00
Alibek Omarov
a9fd508e47 engine: common: fix reading maybe uninitialized crt_tm variable 2025-03-25 17:04:35 +03:00
Alibek Omarov
90bd72d481 ref: gl: disable blend after we're done drawing sprite "lightmap"
Fixes translucent brush model on renderfx2.bsp (https://twhl.info/vault/view/6933)
which so happened to draw after agrunt sprite, that has "lightmap" enabled
2025-03-25 00:52:11 +03:00
Alibek Omarov
a2a3978de7 engine: server: fix erasing physinfo on client connect, when it was already set by game logic on save restore
Fixes issue when player loses long-jump in Half-Life on save load or level transition.
2025-03-24 23:22:19 +03:00
Andrey Akhmichin
ea70989fd2 utils: mdldec: Fix resource names validity checks. 2025-03-24 01:24:31 +03:00
Andrey Akhmichin
091228bcb3 Documentation: supported-mod-list.md: update. 2025-03-24 01:24:25 +03:00
Alibek Omarov
9c49253388 filesystem: allow symlinks when using listdirectory with dirs_only = true
Should fix special setups when game directories are actually symlinks
2025-03-20 20:31:44 +03:00
Alibek Omarov
eea804a4bf engine: server: improve server op status command output 2025-03-20 05:47:24 +03:00
Alibek Omarov
ecbfdb82f4 engine: server: add requested server command status. Only expose client input devices for now, as everything else might be considered sensitive information 2025-03-20 05:46:49 +03:00
Alibek Omarov
a1950ec7b0 engine: server: tiny refactoring, make SV_CalcPing pointer to client const 2025-03-20 05:44:23 +03:00
Alibek Omarov
6b56e13b60 engine: make local ipv4 address private to net_ws, acquire local addresses with GetLocalAddress function 2025-03-20 05:39:02 +03:00
Alibek Omarov
d93bee0cbc engine: minor refactoring, rename ref_state_t fields to snake case, rename readable names to shorter (no pun intended) long names 2025-03-20 03:11:17 +03:00
Alibek Omarov
5009db6aac engine: client: make renderer loading failure less scary for the user 2025-03-20 03:06:05 +03:00
Alibek Omarov
c389736c2f android: do not crash on Browse button if activity wasn't found 2025-03-20 02:44:37 +03:00
Alibek Omarov
66bdca63ee ref: gl: upload skybox texture object with >= 5800 name only with GL compatibility context, it's not needed on GLES 2025-03-17 08:32:06 +03:00
SNMetamorph
d3f455649e engine: client: implemented xashid for PS Vita platform 2025-03-16 21:34:32 +03:00
SNMetamorph
17ff80d85d engine: platform: psvita: implemented function for getting PSID 2025-03-16 21:34:32 +03:00
SNMetamorph
407d0aa291 engine: wscript: enabled linking library SceLibKernel_stub on PS Vita 2025-03-16 21:34:32 +03:00
Alibek Omarov
d13429a287 game_launch: explicitly call wide or ascii Win32 API function calls 2025-03-16 20:41:57 +03:00
Alibek Omarov
a84204fc75 engine: partial fix to explicitly call ascii or wide Win32 API function calls 2025-03-16 20:41:57 +03:00
SNMetamorph
292ace2d26 engine: client: fixed SQB in CL_ParseEvent & CL_ParseReliableEvent 2025-03-16 20:31:14 +03:00
Alibek Omarov
68a1fbdc2b engine: platform: win32: use widechar versions of LoadLibrary, which fixes loading engine if path contains non-latin characters 2025-03-16 03:16:02 +03:00
Alibek Omarov
d68f29737a public: crtlib: use Q_rint instead of round in Q_pretifymem, so we don't have to link libm when we don't need it 2025-03-16 01:01:13 +03:00
Alibek Omarov
a34edbd8e8 wscript: ok, let's disable format-nonliteral for now 2025-03-15 20:01:47 +03:00
Alibek Omarov
71e2d4ecd4 engine: client: fix another case of format-nonliteral 2025-03-15 19:52:24 +03:00
Alibek Omarov
25656b532a engine: platform: posix: fix a typo 2025-03-15 19:52:00 +03:00
Alibek Omarov
1a791e8556 engine: soundlib: get rid of useless formatstring, which is always the same for all types 2025-03-15 19:36:34 +03:00
Alibek Omarov
ccd31c6b27 engine: imagelib: get rid of useless formatstring, which is always the same for all types 2025-03-15 19:29:11 +03:00
Alibek Omarov
6aeedf201c ref: gl: update dlight texture in case if BLOCK_SIZE changes between maps (going from QBSP to BSP2 or toggling r_large_lightmaps cvar) 2025-03-15 19:23:49 +03:00
Alibek Omarov
c9f8bdfcb0 ref: gl: allow updating texture with NULL data by calling TexImage instead of TexSubImage 2025-03-15 19:20:36 +03:00
Alibek Omarov
3cf4901ad2 engine: fix another case of format-nonliteral 2025-03-15 18:23:38 +03:00
Alibek Omarov
92de3ebc58 wscript: disable format-nonliteral for Clang, it's buggy there 2025-03-15 14:20:11 +03:00
Alibek Omarov
7aa9f23590 public: crtlib: fix Q_pretifymem so it compiles with -Wformat-nonliteral 2025-03-15 14:19:47 +03:00
Alibek Omarov
3d999269eb engine: net_ws: make net6_local global static, as it's not used outside of this translation unit 2025-03-15 01:24:59 +03:00
Alibek Omarov
1e8e4825fa engine: fix remaining -Wformat=2 and force it to -Werror 2025-03-15 01:24:59 +03:00
Alibek Omarov
91bc372811 mainui: update 2025-03-15 01:24:59 +03:00
Alibek Omarov
f9df96d70e engine: server: fix server strings deduplication on 64-bit systems 2025-03-15 01:24:59 +03:00
Alibek Omarov
8af0e2c8b4 readme: add missing system dependencies on Linux systems [skip ci] 2025-03-08 02:42:28 +03:00
Alibek Omarov
a5191d8948 engine: client: console: simplify Field_DrawInputLine, try to make it safer 2025-03-08 02:35:32 +03:00
Alibek Omarov
b2d8239829 engine: common: net_http: fix decompression for compressed but not chunked files 2025-03-06 19:10:48 +03:00
Alibek Omarov
34322f025b engine: client: limit ticket generator choices to revemu2013 only 2025-03-06 12:35:32 +03:00
Alibek Omarov
3e6b434733 mainui: update 2025-03-05 22:36:41 +03:00
Alibek Omarov
8359cbe76c scripts: waifulib: add flag --enable-limited-debuginfo which enables -gline-tables-only on GCC and Clang compilers
This saves ~30mb of APK size on Android.
2025-03-05 02:19:39 +03:00
Alibek Omarov
0e90e6285e engine: host: use #if instead of #ifdef when checking for extended hl25 structs compile option 2025-03-03 22:59:44 +03:00
Alibek Omarov
2f5840f650 engine: host: add a cvar that indicates whether engine was built with --enable-hl25-extended-structs or not 2025-03-03 22:53:20 +03:00
Alibek Omarov
3b51a554dd mainui: update 2025-03-02 20:20:54 +03:00
Alibek Omarov
5f0880d4a2 engine: client: lower the bandwidth test fragment sizes to 1400 and less, as using 64k, 32k and more is unreliable 2025-03-02 20:20:40 +03:00
Bohdan Shulyar
884a3c66ac client: touch: fix minor typo that prevented editing touch buttons commands 2025-03-02 20:19:58 +03:00
Alibek Omarov
c76752cc5f engine: server: validate uuid in protinfo, it's an md5 string 2025-03-01 22:45:01 +03:00
Alibek Omarov
fc2888e107 engine: server: fix incorrect ID string generation, hashedcdkey is already an MD5 string 2025-03-01 22:27:22 +03:00
Alibek Omarov
674b4c1506 engine: server: reorder sv_client_t struct for better memory efficiency, remove unused fields 2025-03-01 22:07:05 +03:00
Alibek Omarov
cddd50f1e9 engine: server: completely erase sv_client_t on client connect, so we always start from scratch for every user 2025-03-01 22:07:05 +03:00
Alibek Omarov
6c9d5bc1fb engine: server: cleanup penalties and warns for new players 2025-03-01 16:03:39 +03:00
Alibek Omarov
ec23860238 gitmodules: use github mirrors instead of xiph.org's git
It's not really a good idea to hammer upstream git servers with cloning same
data over and over. Besides, it's down right now.
2025-03-01 15:28:55 +03:00
Alibek Omarov
14a2e34b7e mainui: update 2025-03-01 15:21:20 +03:00
Alibek Omarov
29c8818557 engine: server: do not continue processing command if the player was kicked during it (for example, by speedhack prevention) 2025-03-01 14:58:15 +03:00
Andrey Akhmichin
7222830b28 Documentation: supported-mod-list.md: a little remark. 2025-02-28 23:56:28 +03:00
Alibek Omarov
9b0ad7daf0 engine: common: register forgotten net_clockwindow cvar 2025-02-28 22:44:44 +03:00
Alibek Omarov
73729827f4 engine: platform: win32: add forgotten SDL.h include 2025-02-28 21:55:26 +03:00
Alibek Omarov
97fa395a3b engine: platform: win32: fix build by restoring previous win32 header inclusion order 2025-02-28 21:44:22 +03:00
Alibek Omarov
1cef8ea7af Revert "ref: gl: check OES NPOT texture extension in BigGL mode"
This breaks mipmaps on PSVita

This reverts commit 54b0cf9991.
2025-02-28 17:08:27 +03:00
Alibek Omarov
eda4e95607 engine: client: draw version at bottom right in menu, regardless if dev_overview or net_graph are enabled (those only used in-game) 2025-02-28 15:11:24 +03:00
Alibek Omarov
a5f0ca38f1 engine: remove inclusion of SDL headers globally, helps to cleanup code before SDL3 migration 2025-02-28 13:14:47 +03:00
Alibek Omarov
bbbd7711c1 engine: platform: cleanup remnants of disabling vsync while loading mechanism for linux fbdev and dos ports 2025-02-28 12:33:30 +03:00
Alibek Omarov
38e922557d engine: platform: sdl: remove disabling vsync while we're not in game, as this is something users have been complaining a lot
It's not a big deal if level loading will take a few milliseconds more.
2025-02-28 08:27:38 +03:00
Alibek Omarov
4dec1785ed engine: client: touch: fix inverted file extension check 2025-02-28 06:44:21 +03:00
Alibek Omarov
9f77b7dc46 scripts: waifulib: enable HLSDK -mtune only on GCC and Clang, and not on Android 2025-02-26 17:11:10 +03:00
Alibek Omarov
5061a29f86 scripts: waifulib: enable asynchronous-unwind-tables for better stacktraces 2025-02-26 17:10:30 +03:00
Alibek Omarov
cb5dffd554 engine: server: don't bother printing about unsupported connectionless packets if sv_log_outofband is set to 0 2025-02-26 17:06:33 +03:00
Alibek Omarov
4eaa8ab40f android: bump minimum CMake version, so disabling unneeded features in SDL actually works 2025-02-26 14:21:58 +03:00
Alibek Omarov
2a82d265d6 scripts: waifulib: xcompile: add support for Android NDK r27 as well 2025-02-26 12:40:22 +03:00
Alibek Omarov
f2392b5709 scripts: waifulib: xcompile: add support for building on Windows. Drop using shortcut target clang symlinks, as those don't work on Windows at all (they are wrapped into batch files, which can't be invoked like exes) 2025-02-26 12:40:22 +03:00
Alibek Omarov
5620e7ab4c android: fixup CMAKE_LIBRARY_OUTPUT_DIRECTORY on Win32, merge stdout and stderr for waf output 2025-02-26 12:40:22 +03:00
Alibek Omarov
a76236ac5a scripts: waifulib: xcompile: add support for NDK 28, remove setting up custom PREFIX to not mess up installation path 2025-02-26 12:40:22 +03:00
Alibek Omarov
d1c5862bab android: bump NDK version to 28 2025-02-26 12:40:22 +03:00
Alibek Omarov
81400d0b01 android: use xcompile.py's support for Android NDK, fix tabs 2025-02-26 12:40:22 +03:00
Alibek Omarov
a129f13e25 android: enable verbose output for CMake running from Gradle 2025-02-26 12:40:22 +03:00
Alibek Omarov
ec8b4c0a84 android: rework how engine is built, instead of generating CMakeLists, just use included in CMake ExternalProject feature 2025-02-26 12:40:22 +03:00
Alibek Omarov
f1f726822c engine: client: restore cl_cmdrate default value at 30. It wasn't an intentional change. 2025-02-25 19:52:48 +03:00
Alibek Omarov
8982d55392 engine: client: set default rate value to 25000
3500 is barely playable these days. Those who have worse than usual internet
connection, should set appropriate value themselves.
2025-02-25 17:36:43 +03:00
Alibek Omarov
f499286a87 engine: platform: sdl: don't call SDL_GL_SetSwapInterval each frame while we're not in game 2025-02-25 11:52:03 +03:00
Alibek Omarov
a3aaa87147 ref: gl: enable polygon offset for fullbright textures when rendering them in separate from VBO pass 2025-02-25 11:49:31 +03:00
Alibek Omarov
15a6971aca engine: platform: posix: strip path from filename in backtrace 2025-02-25 11:46:57 +03:00
Alibek Omarov
b1eb3390e3 engine: server: let server dll to register it's own showtriggers cvar 2025-02-24 06:41:11 +03:00
Alibek Omarov
74ad504377 engine: client: console: do not let color strings contribute to line length in console 2025-02-24 03:55:13 +03:00
Alibek Omarov
8a0c2577ed engine: platform: sdl: exclude fake game controller found on Android emulator 2025-02-24 03:42:03 +03:00
Alibek Omarov
a060d7aefd wscript: disable large file for 32-bit Android 2025-02-23 16:07:51 +03:00
Alibek Omarov
ccf342f4fe engine: client: fix inconsistent mouse state caused by mis-use of touch_emulate by cs16-client 2025-02-23 07:13:39 +03:00
Alibek Omarov
8b9a40ff1f engine: client: completely refactor touch code, protect button color, improve config output 2025-02-23 07:00:20 +03:00
Alibek Omarov
425cc61c4c engine: client: handle K_ESCAPE in Key_Console, remove special case for it in Key_Event 2025-02-23 06:47:44 +03:00
Alibek Omarov
fe1fd5b024 engine: client: make color array of DrawString functions const 2025-02-23 06:46:22 +03:00
Alibek Omarov
0c8da36a0b filesystem: disallow path traversal in FS_Delete and FS_Rename 2025-02-23 03:13:46 +03:00
Alibek Omarov
2c5030ab45 engine: client: do not save touch_emulate cvar 2025-02-23 02:04:33 +03:00
Alibek Omarov
9decba873b engine: platform: sdl: try to save and restore mouse position during showing or hiding cursor 2025-02-23 02:04:03 +03:00
Alibek Omarov
bda4c45504 engine: client: simplify CL_EDICT_NUM and it's sister, non throwing error, function CL_GetEntityByIndex 2025-02-23 01:51:05 +03:00
Alibek Omarov
f7aa8a0c90 ci: bump SDL2 to 2.32.0. This is the last major upgrade to SDL2 dependency, we should migrate to SDL3 (with sdl2-compat for GoldSrc mods) after that 2025-02-22 18:48:41 +03:00
Alibek Omarov
4c15cceb32 engine: client: deprecate custom id, it is not used meaningfully by anyone 2025-02-20 15:41:17 +03:00
Alibek Omarov
3e4c5beb25 ref: fix another typo made after R_StudioCalcBones refactor 2025-02-18 19:22:06 +03:00
Alibek Omarov
f84d865f4a engine: client: fix crash if server sends new movevars before entities were created
Nothing bad will happen if we skip wave height for world entity for now, but
we might need to handle this situation somehow in the future.
2025-02-17 13:02:21 +03:00
SNMetamorph
2465782a3e engine: platform: sys_win: fixed compiling error 2025-02-15 13:45:22 +03:00
Alibek Omarov
7ba2209124 engine: platform: sdl: set requested timer delay in units of 100ns according to the documentation 2025-02-15 13:08:05 +03:00
Alibek Omarov
af6b434b71 engine: platform: win32: implement nanosleep using waitable timers with high precision 2025-02-15 11:57:41 +03:00
Alibek Omarov
052ea6a8bd engine: platform: introduce for Platform_NanoSleep, to be used for better sleeping in between frames for lowering CPU usage 2025-02-15 10:11:17 +03:00
Alibek Omarov
448dc720ed engine: server: immediately exit from SV_GetChallenge on unknown type addresses 2025-02-15 09:31:20 +03:00
Alibek Omarov
75b15696f8 engine: zone: ensure memheader_t size is always expected 2025-02-15 09:31:20 +03:00
Andrey Akhmichin
7fb113f610 Documentation: opensource-mods.md: add "Delta Particles". 2025-02-15 08:02:44 +03:00
Andrey Akhmichin
0497e00ad2 Documentation: supported-mod-list.md: update. 2025-02-15 08:02:35 +03:00
Alibek Omarov
9c50288bbb engine: server: rewrite challenge generator to something more simple: salted MD5 of an IP address
The idea was taken from ReHLDS project.
2025-02-15 08:01:44 +03:00
Alibek Omarov
c5d4af802c engine: server: even if user set non-integer value for cl_updaterate, clamp it to sv_minupdaterate 2025-02-15 08:01:44 +03:00
Alibek Omarov
340a8b5e0c engine: server: fixes for userinfo change ratelimiting
* Add pentalty earlier
* Increase disallowed timewindow according to penality multiplier
* Allow first change even if it falls into ignore timewindow
2025-02-15 08:01:44 +03:00
Alibek Omarov
bc1b86c19c engine: server: refactor SV_ConnectClient, simplify LAN IP check 2025-02-15 08:01:44 +03:00
Alibek Omarov
b605cf603e common: xash3d_types: make it more compatible for inclusion in SDK 2025-02-15 08:01:44 +03:00
xiaodo
fdc2ed8093 engine: server: pfnClientCommand and pfnQueryClientCvarValue should execute on unspawned player 2025-02-14 20:52:45 +03:00
xiaodo
a27375d1f5 engine: server: cmds: fix kick command incorrect argc 2025-02-14 20:52:45 +03:00
Alibek Omarov
0e2abf9040 engine: platform: always create zeroed buffer for audio 2025-02-14 05:20:40 +03:00
Alibek Omarov
89430400d9 engine: sys_con: only allow names that start with either alphabetic or numerical character for a log file 2025-02-14 01:51:50 +03:00
Alibek Omarov
f1a9d408bf engine: sys_con: check if the next argument after -log starts with minus and ignore it if it does 2025-02-14 00:50:01 +03:00
Alibek Omarov
6529692244 engine: disable timestamps in log file by default, allow changing log file name with -log argument 2025-02-14 00:28:00 +03:00
Alibek Omarov
51d11f8e86 engine: platform: win32: remove unused log variables and checks from Win32 console, sys_con does the job 2025-02-14 00:28:00 +03:00
Alibek Omarov
c5397191e5 engine: client: touch: limit usage of touch_set_stroke and touch_setclientonly only for privileged mode 2025-02-13 20:55:49 +03:00
Alibek Omarov
44426709f7 engine: platform: posix: skip first stack frame when printing stack trace with libbacktrace 2025-02-13 20:43:32 +03:00
Alibek Omarov
2d8f747e84 wscript: disable using system-wide libbacktrace, as it might not support features we need 2025-02-13 19:21:07 +03:00
Alibek Omarov
0dd5a60410 3rdparty: gl4es: update submodule 2025-02-13 02:32:28 +03:00
Alibek Omarov
eec8129be4 3rdparty: extras: update submodule 2025-02-13 02:31:30 +03:00
Alibek Omarov
934c5e018d readme: clarify that chat is for russian speaking people [ci skip] 2025-02-12 18:08:10 +03:00
Alibek Omarov
d658d8cc78 readme: remove builds.sr.ht status, add Telegram chat link, remove stable build link (it's very outdated and not recommended to use) [skip ci] 2025-02-12 17:58:51 +03:00
Alibek Omarov
ca9a3f0491 engine: server: fix out of bounds write in SV_FindTouchedLeafs 2025-02-11 21:15:54 +03:00
Alibek Omarov
1510cb458f public: fix another typo 2025-02-11 21:12:50 +03:00
Andrey Akhmichin
30cabb8107 Documentation: supported-mod-list.md: fix branch name. 2025-02-11 21:10:59 +03:00
Alibek Omarov
64ee956618 engine: fix a typo 2025-02-11 20:06:15 +03:00
Alibek Omarov
39659644bf public: merge calc bone quaternion and position into single function
Expect that only adj and output quaternion can be NULL.
2025-02-11 18:57:08 +03:00
Alibek Omarov
eb09af0b08 ref: gl: avoid generating GL_INVALID_OPERATION if gl_vbo_dlightmode is set to 0 2025-02-11 18:57:08 +03:00
Andrey Akhmichin
91a4ace12c Documentation: supported-mod-list.md: update. 2025-02-11 16:28:40 +03:00
Alibek Omarov
2ad2e46b30 mainui: update 2025-02-10 13:18:59 +03:00
Alibek Omarov
627444279f Revert "common: cvar: make auto descriptions private to cvar subsystem, use them when Cvar_Get is called with NULL description"
This reverts commit ade560c601.
2025-02-10 12:49:05 +03:00
Alibek Omarov
3550bdb30d 3rdparty: mainui: update 2025-02-09 23:14:24 +03:00
Alibek Omarov
c201b895eb common: netadr: force cast uint16_t type to netadrtype_t
So it compiles in C++
2025-02-09 23:13:29 +03:00
Alibek Omarov
72f1ac3780 wscript: ensure system-wide libbacktrace supports threads 2025-02-09 18:29:02 +03:00
Alibek Omarov
d7dc3192de 3rdparty: libbacktrace: fix applying uselib 2025-02-09 18:25:40 +03:00
Alibek Omarov
43ea65fffc ci: upgrade freebsd tasks. 2025-02-09 17:41:01 +03:00
Alibek Omarov
a72d921c12 wscript: add system-wide libbacktrace detection 2025-02-09 17:41:01 +03:00
Alibek Omarov
99b7d71824 wscript: set DEST_SIZEOF_VOID_P with allow 64bit flag 2025-02-09 17:16:17 +03:00
Alibek Omarov
67c73bdcbe engine: server: remove impulse 204, it's not used anywhere
Thanks @tyabus for reminding me about this feature.
2025-02-09 17:16:05 +03:00
Alibek Omarov
8b1dbcf166 ci: remove extra 20s of wait before removing current release and downloading artifacts 2025-02-09 17:02:31 +03:00
Alibek Omarov
5f60095dc4 scripts: flatpak: disable separate debuginfo 2025-02-09 16:54:51 +03:00
Alibek Omarov
c7282b488b 3rdparty: libbacktrace: disable linking zlib, lzma and zstd for now, figure this out later 2025-02-09 16:49:43 +03:00
Alibek Omarov
afa829d996 3rdparty: libbacktrace: don't define POSIX_SOURCE, it breaks build on Mac 2025-02-09 16:41:26 +03:00
Alibek Omarov
c06ea8d915 engine: platform: posix: add printing backtrace to stderr and logfile for libbacktrace backend 2025-02-09 16:41:26 +03:00
Alibek Omarov
bf344282ec android: explicitly set Waf output directory so it doesn't mess with current configuration and places generated files where CMake expects them to be 2025-02-09 16:20:38 +03:00
Alibek Omarov
21f62910ac engine: platform: posix: fix build when glibc execinfo.h is not available, but libbacktrace is still used 2025-02-09 16:20:38 +03:00
Alibek Omarov
54552d93ef Documentation: goldsrc-protocol-support: I am not going to support Dproto 2025-02-09 16:18:21 +03:00
Alibek Omarov
97455e7fd4 engine: platform: sdl: fix build after last PR 2025-02-09 15:56:16 +03:00
Alibek Omarov
6087d43043 3rdparty: libbacktrace: properly disable it on win32, nswitch and psvita 2025-02-09 15:55:12 +03:00
Alibek Omarov
c1a96d3ff1 engine: platform: posix: fix build 2025-02-09 15:51:25 +03:00
Alibek Omarov
e27d20dfa3 android: enable debug symbols for native libraries 2025-02-09 15:49:28 +03:00
Alibek Omarov
890e12ec76 engine: platform: posix: flush stdout/stderr before everything, include build branch 2025-02-09 15:45:44 +03:00
Alibek Omarov
774d2ac28a engine: platform: posix: add libbacktrace support for crash handler 2025-02-09 15:42:28 +03:00
Alibek Omarov
960d724828 3rdparty: libbacktrace: add submodule 2025-02-09 15:40:07 +03:00
Alibek Omarov
32aa1f91bf engine: pass argv0 to crash handler setup, which is required for libbacktrace integration
Fix indentation in crash_posix.c
2025-02-09 15:36:49 +03:00
Alibek Omarov
bd3634c815 wscript: add sanity test for opusfile because some distros don't ship 32-bit binary 2025-02-09 15:34:30 +03:00
Oleg
eda0ac92cc engine: platform: sdl: change behavior when window position is not set 2025-02-09 08:54:31 +03:00
Oleg
546903ea05 engine: platform: sdl: write windows position changes even in fullscreen 2025-02-09 08:54:31 +03:00
Oleg
4975001795 engine: platform: sdl: enumerate video modes for display where window located is instead of display zero 2025-02-09 08:54:31 +03:00
Oleg
a078ad1f51 engine: platform: sdl: fix windows save position for multiple monitors 2025-02-09 08:54:31 +03:00
Oleg
8307f671d4 engine: platform: sdl: let platform decide where to put our fullscreen window 2025-02-09 08:54:31 +03:00
Alibek Omarov
241fab02b1 ref: gl: don't try to free luma and detail texture of water texture, as these fields used by r_ripple 2025-02-08 16:57:20 +03:00
Alibek Omarov
1bfee70477 engine: con_utils: add autocompletion for cvar commands like set, reset and toggle 2025-02-08 16:45:52 +03:00
Alibek Omarov
eb51d17cd2 engine: server: enable sv_zmax clamping back to avoid overflowing zmax value encoded in delta 2025-02-08 16:38:11 +03:00
Alibek Omarov
b5cb0b9f10 ref: gl: add r_dlight_virtual_radius. It potentially fixes ugly dlight cut off on largely scaled textures (or at least allows to tune it)
It also adds a fix found in JoeQuake (which traces back to FitzQuake, in which
it is attributed to LadyHavoc, Darkplaces author) to exactly calculate whether
the light hits the surface, so we don't wrongly enable lighting on a surface by
an increased radius.
2025-02-07 23:07:08 +03:00
Alibek Omarov
a955d1e957 ref: gl: make GL_BuildPolygonFromSurface static, remove one global variable usage (which is unused anyway) 2025-02-07 22:55:38 +03:00
Alibek Omarov
2b2c967e85 engine: add ms3.mentality.rip master server 2025-02-07 19:32:37 +03:00
Alibek Omarov
c48d93e3ce public: use last Git commit date (committer date, to be exact) as more predictable source for build num 2025-02-07 17:51:10 +03:00
Alibek Omarov
8f257cc331 public: add parsing build date from ISO-8601 alike format 2025-02-07 17:47:23 +03:00
Alibek Omarov
151e7fe37b public: crtlib: check for empty buffer in Q_vsnprintf 2025-02-06 21:19:10 +03:00
Alibek Omarov
add02dc6f9 engine: fix potential UB in netadr_t 2025-02-06 20:54:18 +03:00
Alibek Omarov
d4c34abd6e engine: enable writing log even if console hasn't been enabled at the engine startup (it might be enabled later, it might also contain crash data) 2025-02-06 20:03:07 +03:00
Alibek Omarov
1d81e611f0 scripts: gha: use N+1 job count when building PSVita dependencies 2025-02-06 00:32:42 +03:00
Alibek Omarov
6a0038e26a ref: gl: always set texture env mode to GL_MODULATE in TriAPI's RenderMode call
Not sure if this is correct, but it's generally a good idea to restore it to an
expected value.
2025-02-06 00:30:32 +03:00
Alibek Omarov
1d99f65e86 filesystem: when shutting down, clean up gameinfo pointers and total games count 2025-02-05 21:14:08 +03:00
Alibek Omarov
5e524bca60 engine: client: enable half-texel hack for nearest filtering too, if the scaling factor isn't an integer 2025-02-05 20:16:16 +03:00
Alibek Omarov
cf3e56e275 engine: client: add alternative mode for hud_scale, where it scales HUD down to selected resolution with preserving aspect ratio 2025-02-05 19:47:59 +03:00
Alibek Omarov
ade560c601 common: cvar: make auto descriptions private to cvar subsystem, use them when Cvar_Get is called with NULL description
It allows us to not lose engine-side description when client or gameui registers cvar with the same name. In case of
menu it's the only way to get cvar pointer.
2025-02-05 19:11:16 +03:00
Alibek Omarov
62e3ba2126 engine: add cvars to control mounting additional directories
Use existing ui_language cvar for mounting localization folders.
2025-02-05 18:54:28 +03:00
Alibek Omarov
674a4e5883 filesystem: add ability to mount HD, LV, addon and language folders by engine request 2025-02-05 18:24:36 +03:00
Alibek Omarov
f911210b81 public: simplify ctype.h is* functions wrappers for null-terminated strings, add Q_isalpha 2025-02-05 18:21:18 +03:00
Alibek Omarov
14eb07653c engine: client: fix incorrect format in error message in CL_SetLightStyle 2025-02-05 17:41:01 +03:00
Alibek Omarov
54b0cf9991 ref: gl: check OES NPOT texture extension in BigGL mode 2025-02-05 14:00:44 +03:00
Alibek Omarov
3ebcb08a97 ref: gl: add cvar r_large_lightmaps to enable larger lightmap sizes, opt-in, yields better performance with VBO renderer 2025-02-05 13:02:37 +03:00
Alibek Omarov
23940f8590 readme: remove fontconfig from dependencies list, we aren't using it anymore [skip ci] 2025-02-04 21:00:42 +03:00
Alibek Omarov
687fb0123f engine: implement basic gamepad gyroscope calibration
Called on game controller becoming active or by user request.
Exposes current calibration state by read-only console variable.
2025-02-03 13:14:51 +03:00
Alibek Omarov
6c91fdb0cd ref: gl: gl2_shim: fix int vs GLuint 2025-02-02 20:57:37 +03:00
Alibek Omarov
4832232fd6 ci: attempt to fix flatpak upload 2025-02-02 20:31:51 +03:00
Alibek Omarov
185bce0489 engine: common: remove unused D_ enum used for MsgDev in old engine. Make sure all enums and structs here are not anonymous 2025-02-02 20:26:07 +03:00
Alibek Omarov
f460aa63b0 engine: platform: posix: don't forget to print backtrace to stderr too 2025-02-02 19:20:54 +03:00
Alibek Omarov
22f8b6f9c3 engine: platform: enable crash handler for macOS 2025-02-02 18:30:41 +03:00
Alibek Omarov
0cb034afc2 engine: wscript: improve execinfo and GNU backtrace() check 2025-02-02 18:18:26 +03:00
Alibek Omarov
d0464ef602 engine: platform: posix: use glibc-based backtrace implementation for crash handling, if execinfo.h can be found 2025-02-02 18:06:18 +03:00
Alibek Omarov
c3ebb84b97 ci: bump SDL2 to 2.30.12 2025-02-02 08:14:24 +03:00
Alibek Omarov
11742efbc3 engine: fix player move on dedicated servers 2025-02-02 08:08:15 +03:00
Alibek Omarov
95af635ab4 engine: client: add command replaybufferdat to aid in debugging protocol errors by parsing buffer.dat 2025-02-02 05:22:46 +03:00
Alibek Omarov
1abec80191 engine: client: set codepage to 0 if con_charset value is unknown 2025-02-02 02:34:08 +03:00
Alibek Omarov
93ebddfba3 public: utflib: simplify Q_EncodeUTF8 2025-02-02 02:31:56 +03:00
Alibek Omarov
5378494199 wscript: enable main() function for Android port, which was forgotten after last refactoring 2025-02-01 18:26:20 +03:00
Alibek Omarov
1b44d7733e engine: platform: add improved Platform_Vibrate2 function, that allows to control vibration strength 2025-02-01 18:08:53 +03:00
Alibek Omarov
694c630b44 engine: zone: don't error when trying to free NULL pointer, like standard C free() and C++ delete 2025-02-01 17:51:02 +03:00
Alibek Omarov
7df1d4b9e2 engine: platform: sdl: remove useless for us game controller events 2025-01-31 19:48:33 +03:00
Alibek Omarov
b16037eabf engine: drop raw SDL joystick API, always use GameController instead. Implement actually working rumble, ensure we're freeing up all resources related to gamepads 2025-01-31 17:50:19 +03:00
Alibek Omarov
bff7299f9b gha: publish binaries even if flatpak fails 2025-01-31 10:37:41 +03:00
Alibek Omarov
de196b1c58 common: xash3d_types: avoid defining true and false in C23 2025-01-31 10:36:27 +03:00
Alibek Omarov
a0eec8b85d scripts: waifulib: add special_install_path for platform-specific executable formats that create post link stage (was nro_install_path) 2025-01-31 10:25:02 +03:00
Alibek Omarov
c7e8ea2ffa scripts: gha: linux: build smaller SDL2 (without 2D renderer) for Linux as well 2025-01-31 10:02:19 +03:00
Alibek Omarov
1c1cf3d646 scripts: waifulib: psvita: make sce_sys truly optional in apply_vpk 2025-01-31 10:02:19 +03:00
Alibek Omarov
9759b80b78 scripts: waifulib: psvita: set default title id and app name to just test 2025-01-31 09:10:39 +03:00
Alibek Omarov
94b2c0b443 scripts: gha: build render-less SDL2 for PSVita 2025-01-31 09:10:09 +03:00
Alibek Omarov
ff8d17a5a8 scripts: waifulib: psvita: add missing cprogram attributes 2025-01-31 09:04:40 +03:00
Alibek Omarov
aa23196a55 scripts: waifulib: support vpk and nro pass for pure C programs, just in case 2025-01-30 20:51:01 +03:00
Alibek Omarov
83b488c37e wscript: let building client and dedicated server in the same configuration 2025-01-30 20:23:12 +03:00
Alibek Omarov
77abf621d7 ref: gl: make GL_Support and GL_MaxTextureUnits functions inlined 2025-01-30 19:02:53 +03:00
Alibek Omarov
f9d4ac2771 ref: gl: fix ugly seam at the skybox, thanks Spoike for help 2025-01-30 18:53:31 +03:00
Alibek Omarov
f076d84975 engine: platform: android: move dlsym-weak hack from C++ to C 2025-01-30 18:07:35 +03:00
Alibek Omarov
faf0b32a94 ref: gl: fix massive frame drop caused by ripples code rendering same texture multiple times in the frame 2025-01-29 20:15:21 +03:00
Alibek Omarov
feb80e5997 engine: platform: sdl: read gamecontrollerdb.txt from extras.pk3 2025-01-29 13:43:10 +03:00
Alibek Omarov
578a77518f engine: client: fix clearing keyboard buttons caused by typical brain fart 2025-01-29 10:04:47 +03:00
Alibek Omarov
2457ecf226 filesystem: fix recursive basedir possible cyclic dependency when default game directory uses a basedir that's base directory is undefined
That could happen when default game directory depends on base directory that don't have gameinfo.txt.
Because all game directories with liblist.gam automatically have dependency on default game directory, it causes cyclic dependency.
2025-01-29 09:49:29 +03:00
Alibek Omarov
8cd99885f1 filesystem: clean added status for game folders when purging search paths 2025-01-29 09:46:18 +03:00
Alibek Omarov
684e229ac8 engine: client: get rid of absolutely useless bitfields 2025-01-26 23:34:04 +03:00
SNMetamorph
c0f1d8c647 engine: model: fixed incorrect check in Mod_LoadModel 2025-01-26 23:27:18 +03:00
SNMetamorph
c3b8696957 engine: platform: win32: disable initializing console in case of regular game startup 2025-01-26 23:02:24 +03:00
Tom Kidd
3ca413dbab Fixed path calc for extras on Mac 2025-01-26 22:25:08 +03:00
Alibek Omarov
92dc04ff3c engine: client: minor change, add forgotten newline in CL_DeltaEntityGS Host_Error call 2025-01-25 17:51:48 +03:00
Alibek Omarov
ad6db91285 engine: move xashid stuff onto client 2025-01-25 17:51:48 +03:00
David DeGraw
90a0f74087 undo change to mod link 2025-01-25 08:23:04 +03:00
David DeGraw
4f7f5288a1 more nits 2025-01-25 08:23:04 +03:00
David DeGraw
c23b4bfe61 nits 2025-01-25 08:23:04 +03:00
David DeGraw
4780f70ea2 Improve mod installation instructions
Also improved uplink setup and used a better source for mod files.
2025-01-25 08:23:04 +03:00
NightFox
98a04c7764 FIx Matrix*x4_LoadIdentity (xash3d_mathlib.h) 2025-01-25 08:21:21 +03:00
Alibek Omarov
7da9772143 engine: check for macOS bundle in SDL_GetBasePath, and fallback to SDL_GetPrefPath for our directory 2025-01-23 22:58:19 +03:00
Alibek Omarov
f0b29bac1b engine: client: add cl_trace_consistency used to print which resources server wants to check 2025-01-23 13:57:17 +03:00
Alibek Omarov
7b5ff606bd 3rdparty: extras: enable compression of extras.pk3 2025-01-23 13:08:53 +03:00
Alibek Omarov
3e22ee64ae scripts: waifulib: zip: add support for passing compression level on Python 3.7. Exclude PNG files from compression 2025-01-23 13:08:21 +03:00
Alibek Omarov
c86c45503f engine: replace few more Xash3D strings by XASH_ENGINE_NAME macro 2025-01-23 10:33:22 +03:00
Alibek Omarov
ef75a4c28d engine: rename pref path on Mac to Xash3D FWGS by allowing for custom branding through XASH_ENGINE_NAME macro 2025-01-23 10:24:55 +03:00
Alibek Omarov
bccd3f2271 engine: pass launcher's default game directory all the way down to Platform_Init, so we mount correct extras.pk3 on Mac 2025-01-23 10:22:53 +03:00
Tom Kidd
7bbc3e8238 Made modifications for Mac App Bundle
- Looks for game data in SDL pref path (Application Support)
- Sets XASH3D_EXTRAS_PAK1 to SDL base path (Resources dir in App Bundle
- Added option to force search for SDL dylib via pkgconfig on Darwin instead of Framework (option for Mac Source Ports build process)
2025-01-23 10:15:47 +03:00
Alibek Omarov
c34e0c66d9 engine: add fuzzing target for Mod_LoadModel 2025-01-23 10:12:32 +03:00
Alibek Omarov
e5d80878b8 scripts: waifulib: add asan-only build type 2025-01-23 10:11:56 +03:00
Alibek Omarov
1e075d25b7 engine: make LZSS compression optional for 49 protocol, disable it for local clients (singleplayer) 2025-01-22 21:18:19 +03:00
Alibek Omarov
d29e53481d engine: client: remove unused S_StreamAviSamples 2025-01-22 20:01:11 +03:00
Alibek Omarov
d23a2fd2df engine: client: stub AVI_StreamSound RenderAPI call, it is not used in ffmpeg-based video playback code 2025-01-22 20:00:50 +03:00
Alibek Omarov
f6f15cc204 engine: mod_studio: validate studio self-reported length before loading model 2025-01-22 20:00:13 +03:00
Alibek Omarov
4f2249ed8e ref: support loading sprites with truncated palette 2025-01-22 19:24:00 +03:00
Alibek Omarov
9f322df498 engine: imagelib: handle loading truncated palette files, by filling remaining bytes with zeros 2025-01-22 19:21:51 +03:00
Alibek Omarov
b554d7e215 ref: properly handle unloading sprites that aren't loaded completely 2025-01-22 19:20:20 +03:00
Alibek Omarov
719093c10b ref: properly return false to the engine if renderer refuses to load the model for some reason 2025-01-22 19:13:23 +03:00
Alibek Omarov
c2da140ccc engine: model: do not crash if renderer refused to load this model 2025-01-22 19:12:43 +03:00
Alibek Omarov
375998dffb Cleanup xash3d_types.h from engine-specific macros and types 2025-01-22 15:10:18 +03:00
Alibek Omarov
787444f63d engine: simplify sound fx allocation 2025-01-22 14:46:40 +03:00
Alibek Omarov
0c50076ff0 engine: zone: ensure poolcount is zero on Memory_Init 2025-01-22 13:49:51 +03:00
Alibek Omarov
8ce01c38c7 engine: http: ensure we don't write broken decompressed files 2025-01-22 13:49:24 +03:00
Alibek Omarov
cac6206984 engine: client: allocate everything related to sounds in the sound pool 2025-01-22 13:49:02 +03:00
Alibek Omarov
a5c88bdda9 engine: touch: allow smoother migration from old engine touch configs by stripping .tga extension 2025-01-22 13:40:47 +03:00
Alibek Omarov
fc017286a6 engine: base_cmd: slightly faster search based on assumption that list is always ordered 2025-01-22 05:41:52 +03:00
Alibek Omarov
20d4e3e719 engine: fix flexible array member usage in case of null terminated strings
(woops)
2025-01-22 05:41:52 +03:00
Alibek Omarov
4eaa32fc10 engine: whereami: sync with upstream 2025-01-21 20:03:20 +03:00
Alibek Omarov
b7c025b167 filesystem: android: request buffer for Android asset LoadFile implementation
Might be better than asking for random access and then only reading forward.
2025-01-21 19:50:14 +03:00
Alibek Omarov
f29c588e0f filesystem: take code from DarkPlaces to properly read compressed files 2025-01-21 18:47:42 +03:00
Alibek Omarov
2065ef143a engine: server: fix ent_create under PrimeXT 2025-01-21 16:09:56 +03:00
Alibek Omarov
a5c02c85f0 filesystem: wad: get rid of sentinel value at the end of wad_types array 2025-01-21 15:26:06 +03:00
Alibek Omarov
9a8761f1d8 engine: client: remove unused NetAPI_ValueForKey function 2025-01-21 15:17:03 +03:00
Alibek Omarov
273990d292 engine: cmd: store command description in flexible array member 2025-01-21 15:06:08 +03:00
Alibek Omarov
0e27d8717c ref: remove servercount from texture struct, Xash don't use it (and it's also harmful anyway) 2025-01-21 14:36:42 +03:00
Alibek Omarov
8a9b209db0 engine: zone: optimize memory usage a bit by compressing memheader_t better while keeping it efficient
It saves about 40 kilobytes of memory.
2025-01-21 14:04:33 +03:00
Alibek Omarov
232d1f8583 engine: make separate mempools for cmds, cvars and basecmd 2025-01-21 11:26:35 +03:00
Alibek Omarov
6cfa5877a4 engine: base_cmd: decrease base cmd hash size 2025-01-21 11:25:33 +03:00
Alibek Omarov
154df00f94 filesystem: don't create full path to rwdir, as cwd is always equal to rwdir
Fixes updating gameinfo.txt.
2025-01-20 19:53:04 +03:00
Alibek Omarov
c5649c94d5 engine: client: fix delta entity packet flush on GoldSrc protocol
Implement counting playerbytes for more accurate net_graph, even if we're
skipping this delta frame.
2025-01-20 19:38:44 +03:00
Alibek Omarov
a1da10fe38 filesystem: set default values for quick/autosave aged count 2025-01-20 16:06:57 +03:00
Andrey Akhmichin
17a71ffc96 ci: upgrade freebsd tasks. 2025-01-19 04:36:07 +03:00
Andrey Akhmichin
4609fbc0c5 Documentation: supported-mod-list.md: update links. 2025-01-19 04:35:17 +03:00
Andrey Akhmichin
d278d3bdd7 engine: common: fix clang build. 2025-01-19 04:33:06 +03:00
Alibek Omarov
7811b60292 engine: common: fix build for apple and freebsd-15 2025-01-18 10:40:12 +03:00
Alibek Omarov
870fad5606 public: tests: remove Q_colorstr tests 2025-01-18 10:36:11 +03:00
Alibek Omarov
3e93aa459d engine: net_buffer: turn bit write and read masks into predefined arrays, so we don't have to call InitMasks
In future, net_buffer might get moved to libpublic.

Also, get rid of 32-th bit write mask, it's only get used when we're trying to
write zero bits value which is nonsense.
2025-01-18 09:54:11 +03:00
Alibek Omarov
626c5e44f6 engine: client: use existing engine functions for some client API functions 2025-01-18 09:44:21 +03:00
Alibek Omarov
c906aa0106 ref: gl: make DrawGLPoly and R_TextureAnimation private to brush rendering code 2025-01-18 08:39:31 +03:00
Alibek Omarov
0a41b70e44 ref: gl: store ripple texture in texture's fb_texturenum as it's only used for water and water don't have luma 2025-01-18 08:38:43 +03:00
Alibek Omarov
ea338adc46 ref: gl: make GL_FrustumSetPlanme private to the frustum implementation 2025-01-18 08:34:25 +03:00
Alibek Omarov
5fa777578b ref: gl: fix detail texture leak, fix texture leak when texture have default texture set (in which case it still might have other textures set) 2025-01-18 08:33:20 +03:00
Alibek Omarov
5b9db5940b engine: mod_bmodel: don't try to load luma/fullbright texture for water, as no renderers support it anyway, and instead we will use that field for rippletexture 2025-01-18 08:30:59 +03:00
Alibek Omarov
4b1b3aa13c public: remove Q_colorstr, as it's completely useless and checking for color string is easy actually 2025-01-18 08:29:36 +03:00
Alibek Omarov
2d51d23d89 engine: client: don't send commands until ca_active on Xash protocol 2025-01-17 15:06:59 +03:00
Alibek Omarov
b5b6dad39c engine: fix a typo in scroll lock (missing L) 2025-01-15 23:49:13 +03:00
Alibek Omarov
a5619e9960 engine: take keydefs header from Quake-2 source code (client/keys.h) 2025-01-15 23:47:55 +03:00
232 changed files with 9866 additions and 5883 deletions

View File

@@ -1,14 +1,13 @@
task:
name: freebsd-14-amd64
freebsd_instance:
image_family: freebsd-14-0
image_family: freebsd-14-2
setup_script:
- pkg update
- pkg install -y pkgconf git sdl2 python fontconfig opus
- pkg install -y pkgconf git sdl2 python fontconfig libvorbis opusfile bzip2 libbacktrace
- git submodule update --init --recursive
test_script:
- ./scripts/cirrus/build_freebsd.sh dedicated
- ./scripts/cirrus/build_freebsd.sh full
- ./scripts/cirrus/build_freebsd.sh
task:
name: freebsd-15-amd64
@@ -16,8 +15,7 @@ task:
image_family: freebsd-15-0-snap
setup_script:
- pkg update
- pkg install -y pkgconf git sdl2 python fontconfig opus
- pkg install -y pkgconf git sdl2 python fontconfig libvorbis opusfile bzip2 libbacktrace
- git submodule update --init --recursive
test_script:
- ./scripts/cirrus/build_freebsd.sh dedicated
- ./scripts/cirrus/build_freebsd.sh full
- ./scripts/cirrus/build_freebsd.sh

View File

@@ -15,35 +15,39 @@ jobs:
include:
# Linux build specifically want oldest Ubuntu as possible
# to be crossdistribution compatible, otherwise use ubuntu-latest
- os: ubuntu-20.04
- os: ubuntu-22.04
targetos: linux
targetarch: amd64
- os: ubuntu-20.04
- os: ubuntu-22.04
targetos: linux
targetarch: i386
- os: ubuntu-20.04
- os: ubuntu-22.04
targetos: linux
targetarch: arm64
cross: true
- os: ubuntu-20.04
- os: ubuntu-22.04
targetos: linux
targetarch: armhf
cross: true
- os: ubuntu-20.04
- os: ubuntu-24.04 # riscv64 would benefit from having latest compilers
targetos: linux
targetarch: riscv64
cross: true
- os: ubuntu-20.04
- os: ubuntu-22.04
targetos: linux
targetarch: ppc64el
cross: true
# - os: ubuntu-aarch64-20.04
# - os: ubuntu-aarch64-22.04
# targetos: linux
# targetarch: aarch64
- os: ubuntu-20.04
- os: ubuntu-latest
targetos: linux
targetarch: e2k-8c
cross: true
- os: ubuntu-latest
targetos: android
targetarch: multiarch
# - os: ubuntu-20.04
# - os: ubuntu-22.04
# targetos: motomagx
# targetarch: armv6
@@ -66,7 +70,7 @@ jobs:
targetos: apple
targetarch: amd64
env:
SDL_VERSION: 2.30.11
SDL_VERSION: 2.32.0
GH_CPU_ARCH: ${{ matrix.targetarch }}
GH_CROSSCOMPILING: ${{ matrix.cross }}
steps:
@@ -87,6 +91,7 @@ jobs:
path: artifacts/*
flatpak:
runs-on: ubuntu-latest
continue-on-error: true
strategy:
matrix:
include:
@@ -100,7 +105,7 @@ jobs:
with:
submodules: recursive
- name: Build flatpak (Compat.i386)
uses: FWGS/flatpak-github-actions/flatpak-builder@v6.3
uses: FWGS/flatpak-github-actions/flatpak-builder@v6.3-fix
with:
bundle: ${{ matrix.app }}.flatpak
manifest-path: scripts/flatpak/${{ matrix.app }}.yml
@@ -119,7 +124,6 @@ jobs:
--yes \
--cleanup-tag \
--repo "$GITHUB_REPOSITORY" || true
sleep 20s
gh run download "$GITHUB_RUN_ID" \
--dir artifacts/ \
--repo "$GITHUB_REPOSITORY"

12
.gitmodules vendored
View File

@@ -27,10 +27,16 @@
url = https://github.com/FWGS/MultiEmulator
[submodule "3rdparty/libogg/libogg"]
path = 3rdparty/libogg/libogg
url = https://gitlab.xiph.org/xiph/ogg.git
url = https://github.com/xiph/ogg.git
[submodule "3rdparty/vorbis/vorbis-src"]
path = 3rdparty/vorbis/vorbis-src
url = https://gitlab.xiph.org/xiph/vorbis.git
url = https://github.com/xiph/vorbis.git
[submodule "3rdparty/opusfile/opusfile"]
path = 3rdparty/opusfile/opusfile
url = https://gitlab.xiph.org/xiph/opusfile.git
url = https://github.com/xiph/opusfile.git
[submodule "3rdparty/libbacktrace/libbacktrace"]
path = 3rdparty/libbacktrace/libbacktrace
url = https://github.com/ianlancetaylor/libbacktrace
[submodule "3rdparty/maintui"]
path = 3rdparty/maintui
url = https://github.com/numas13/xash3d-maintui.git

View File

@@ -25,5 +25,4 @@ def build(bld):
name = 'extras.pk3',
files = srcdir.ant_glob('**/*'),
relative_to = srcdir,
compresslevel = 0,
install_path = install_path)

188
3rdparty/libbacktrace/wscript vendored Normal file
View File

@@ -0,0 +1,188 @@
#! /usr/bin/env python
# encoding: utf-8
from waflib import TaskGen
from waflib.Tools.c_config import DEFKEYS
FRAGMENT_ATOMIC='''int i;
int main(void) {
__atomic_load_n(&i, __ATOMIC_ACQUIRE);
__atomic_store_n(&i, 1, __ATOMIC_RELEASE);
return 0;
}'''
FRAGMENT_SYNC='''int i;
int main (void) {
__sync_bool_compare_and_swap (&i, i, i);
__sync_lock_test_and_set (&i, 1);
__sync_lock_release (&i);
return 0;
}'''
FRAGMENT_GETPAGESIZE='''#include <unistd.h>
int main(void) { return getpagesize() }'''
FRAGMENT_GETEXECNAME='''#include <stdlib.h>
int main(void) { return getexecname() != 0 }'''
FRAGMENT_STRNLEN='''#include <string.h>
int main(int argc, char **argv) { return (int)strnlen(argv[0], 10); }'''
FRAGMENT_DL_ITERATE_PHDR='''#include <%s>
int main(void) { return dl_iterate_phdr(0, 0); }'''
FRAGMENT_FCNTL='''#include <fcntl.h>
int main(void) { return fcntl(0, 0, 0); }'''
FRAGMENT_GETIPINFO='''#include "unwind.h"
struct _Unwind_Context *context;
int ip_before_insn = 0;
int main(void) { return _Unwind_GetIPInfo(context, &ip_before_insn); }'''
FRAGMENT_LOADQUERY='''#include <sys/ldr.h>
#include <sys/debug.h>
int main(void) { return loadquery(0, 0, 0); }'''
FRAGMENT_KERN_PROC='''#include <sys/sysctl.h>
#if !defined(%s) || !defined(KERN_PROC_PATHNAME)
#error
#endif
int main(void) { return 0; }'''
FRAGMENT_LSTAT='''#include <sys/stat.h>
struct stat st;
int main(int argc, char **argv) { return lstat(argv[0], &st); }'''
FRAGMENT_READLINK='''#include <unistd.h>
char buf[100];
int main(int argc, char **argv) { return readlink(argv[0], buf, sizeof(buf)); }'''
def options(opt):
pass
def configure(conf):
# add unsupported platforms here
if conf.env.DEST_OS in ['nswitch', 'psvita', 'dos']:
conf.env.DISABLE_LIBBACKTRACE = True
return
# win32 has it's own dbghelp-based backtrace, that's why we ship PDBs
if conf.env.COMPILER_CC == 'msvc':
conf.env.DISABLE_LIBBACKTRACE = True
return
if not conf.path.find_dir('libbacktrace') or not conf.path.find_dir('libbacktrace/config'):
conf.fatal('Can\'t find libbacktrace submodule. Run `git submodule update --init --recursive`.')
return
if conf.env.DEST_SIZEOF_VOID_P == 8:
conf.define('BACKTRACE_ELF_SIZE', 64)
conf.define('BACKTRACE_XCOFF_SIZE', 64)
else:
conf.define('BACKTRACE_ELF_SIZE', 32)
conf.define('BACKTRACE_XCOFF_SIZE', 32)
conf.define('_ALL_SOURCE', 1)
conf.define('_GNU_SOURCE', 1)
conf.define('_POSIX_PTHREAD_SEMANTICS', 1)
conf.define('_TANDEM_SOURCE', 1)
conf.define('__EXTENSIONS__', 1)
conf.define('_DARWIN_USE_64_BIT_INODE', 1)
conf.define('_LARGE_FILES', 1)
conf.check_large_file(compiler='c', execute=False, mandatory=False) # sets _FILE_OFFSET_BITS
conf.env.CFLAGS_EXTRAFLAGS = conf.filter_cflags(['-funwind-tables', '-g'], [])
if conf.filter_cflags(['-frandom-seed=test'], []):
conf.env.HAVE_FRANDOM_SEED = True
def check_header(hdr):
return {'header_name':hdr, 'msg':'... %s header' % hdr, 'mandatory':False, 'id':hdr}
conf.multicheck(
check_header('dlfcn.h'),
check_header('inttypes.h'),
check_header('link.h'),
check_header('sys/link.h'),
check_header('mach-o/dyld.h'),
check_header('memory.h'),
check_header('stdint.h'),
check_header('stdlib.h'),
check_header('strings.h'),
check_header('string.h'),
check_header('sys/ldr.h'),
check_header('sys/mman.h'),
check_header('sys/stat.h'),
check_header('sys/types.h'),
check_header('tlhelp32.h'),
check_header('unistd.h'),
check_header('windows.h'),
{'fragment':FRAGMENT_ATOMIC, 'msg':'... __atomic extensions', 'define_name':'HAVE_ATOMIC_FUNCTIONS', 'mandatory':False},
{'fragment':FRAGMENT_SYNC, 'msg':'... __sync extensions', 'define_name':'HAVE_SYNC_FUNCTIONS', 'mandatory':False},
{'fragment':FRAGMENT_GETPAGESIZE, 'msg':'... getpagesize function', 'define_name':'HAVE_DECL_GETPAGESIZE', 'mandatory':False},
{'fragment':FRAGMENT_STRNLEN, 'msg':'... strnlen function', 'define_name':'HAVE_DECL_STRNLEN', 'mandatory':False},
{'fragment':FRAGMENT_DL_ITERATE_PHDR % 'link.h', 'msg':'... dl_iterate_phdr function in link.h', 'define_name':'HAVE_DL_ITERATE_PHDR', 'after_tests': ['link.h'], 'mandatory':False},
{'fragment':FRAGMENT_DL_ITERATE_PHDR % 'sys/link.h', 'msg':'... dl_iterate_phdr function in sys/link.h', 'define_name':'HAVE_DL_ITERATE_PHDR', 'after_tests': ['sys/link.h'], 'mandatory':False},
{'fragment':FRAGMENT_FCNTL,'msg':'... fnctl function', 'define_name':'HAVE_FCNTL', 'mandatory':False},
{'fragment':FRAGMENT_GETEXECNAME,'msg':'... getexecname function','define_name':'HAVE_GETEXECNAME', 'mandatory':False},
{'fragment':FRAGMENT_GETIPINFO, 'msg':'... _Unwind_GetIPInfo function', 'define_name':'HAVE_GETIPINFO', 'mandatory':False},
{'fragment':FRAGMENT_KERN_PROC % 'KERN_PROC', 'msg': '... KERN_PROC and KERN_PROC_PATHNAME defines', 'define_name':'HAVE_KERN_PROC', 'mandatory':False},
{'fragment':FRAGMENT_KERN_PROC % 'KERN_PROC_ARGS', 'msg': '... KERN_PROC_ARGS and KERN_PROC_PATHNAME defines', 'define_name':'HAVE_KERN_PROC_ARGS', 'mandatory':False},
{'fragment':FRAGMENT_LOADQUERY, 'msg': '... loadquery function', 'define_name':'HAVE_LOADQUERY', 'mandatory':False},
{'fragment':FRAGMENT_LSTAT, 'msg': '... lstat function', 'define_name':'HAVE_LSTAT', 'mandatory':False},
{'fragment':FRAGMENT_READLINK, 'msg': '... readlink function', 'define_name':'HAVE_READLINK', 'mandatory':False},
# {'lib':'lzma', 'define_name':'HAVE_LIBLZMA', 'uselib_store':'lzma', 'msg':'... lzma library', 'mandatory':False},
# {'lib':'z', 'define_name':'HAVE_ZLIB', 'uselib_store':'z', 'msg':'... zlib library', 'mandatory':False},
# {'lib':'zstd', 'define_name':'HAVE_ZSTD', 'uselib_store':'zstd', 'msg':'... zstd library', 'mandatory':False},
msg='Checking for in parallel'
)
conf.env[DEFKEYS].sort()
conf.write_config_header()
conf.define('BACKTRACE_SUPPORTED', 1)
conf.define('BACKTRACE_USES_MALLOC', 0)
conf.define('BACKTRACE_SUPPORTS_THREADS', 1)
conf.define('BACKTRACE_SUPPORTS_DATA', conf.env.DEST_BINFMT in ['elf', 'mac-o'])
conf.write_config_header('backtrace-supported.h')
@TaskGen.feature('frandomseed')
@TaskGen.after_method('propagate_uselib_vars')
def process_frandom_seed(ctx):
tasks = getattr(ctx, 'compiled_tasks', [])
for task in tasks:
out = task.outputs[0]
task.env.CFLAGS = list(task.env.CFLAGS) # need a copy
task.env.CFLAGS += ['-frandom-seed=%s' % out.path_from(out.ctx.bldnode)]
def build(bld):
if bld.env.DISABLE_LIBBACKTRACE:
return
# we specifically only want mmap-based allocators because calling malloc is not safe from signal handlers
sources = ['atomic.c', 'dwarf.c', 'fileline.c', 'posix.c', 'print.c', 'sort.c', 'state.c', 'backtrace.c', 'simple.c', 'mmap.c', 'mmapio.c']
if bld.env.DEST_BINFMT == 'pe':
sources += ['pecoff.c']
elif bld.env.DEST_BINFMT == 'mac-o':
sources += ['macho.c']
elif bld.env.DEST_BINFMT == 'elf':
sources += ['elf.c']
else:
sources += ['unknown.c']
task = bld.stlib(
source = ['libbacktrace/' + i for i in sources],
target = 'backtrace',
features = 'frandomseed' if bld.env.HAVE_FRANDOM_SEED else '',
use = 'EXTRAFLAGS lzma z zstd',
includes = '. libbacktrace/',
export_defines = 'HAVE_LIBBACKTRACE=1',
export_includes = 'libbacktrace/'
)

1
3rdparty/maintui vendored Submodule

Submodule 3rdparty/maintui added at 0b6ee5b2d8

View File

@@ -2,23 +2,27 @@
On this page you can find links where you can support each developer individually, who has provided public sponsorship information.
### [a1batross](https://github.com/a1batross)
## [a1batross](https://github.com/a1batross)
* Initial Xash3D SDL2/Linux port author, Xash3D FWGS engine maintainer, creator of non-commercial Flying With Gauss organization.
* Boosty page: https://boosty.to/a1ba
Initial Xash3D SDL2/Linux port author, Xash3D FWGS engine maintainer, creator of non-commercial Flying With Gauss organization.
### [nekonomicon](https://github.com/nekonomicon)
* [Boosty page](https://boosty.to/a1ba)
* [hlsdk-portable](https://github.com/FWGS/hlsdk-portable), [mdldec](../utils/mdldec), [opensource-mods.md](opensource-mods.md) maintainer and Xash3D FWGS [contributor](https://github.com/FWGS/xash3d-fwgs/commits?author=nekonomicon) (*BSD/clang port, PNG support, etc).
* Boosty page: https://boosty.to/nekonomicon
## [nekonomicon](https://github.com/nekonomicon)
### [Velaron](https://github.com/Velaron)
* [cs16-client](https://github.com/Velaron/cs16-client) & [tf15-client](https://github.com/Velaron/tf15-client) maintainer and Xash3D FWGS [contributor](https://github.com/FWGS/xash3d-fwgs/commits?author=Velaron) (Android port, voice chat, etc).
* BuyMeACoffee page: https://www.buymeacoffee.com/velaron
[hlsdk-portable](https://github.com/FWGS/hlsdk-portable), [mdldec](../utils/mdldec), [opensource-mods.md](opensource-mods.md) maintainer and Xash3D FWGS [contributor](https://github.com/FWGS/xash3d-fwgs/commits?author=nekonomicon) (*BSD/clang port, PNG support, etc).
### [SNMetamorph](https://github.com/SNMetamorph)
* [PrimeXT](https://github.com/SNMetamorph/PrimeXT) & [GoldSrc Monitor](https://github.com/SNMetamorph/goldsrc-monitor) maintainer and Xash3D FWGS [contributor](https://github.com/FWGS/xash3d-fwgs/commits?author=SNMetamorph) (Windows port, voice chat, etc).
* BTC: `16GAzK3qei5AwBW7sggXp3yNcFHBtdpxXj`
* ETH (ERC20): `0xb580eeca9756e3881f9d6d026e28db28eb72a383`
* USDT (ERC20): `0xb580eeca9756e3881f9d6d026e28db28eb72a383`
* USDC (ERC20): `0xb580eeca9756e3881f9d6d026e28db28eb72a383`
* [Boosty page](https://boosty.to/nekonomicon)
## [Velaron](https://github.com/Velaron)
[cs16-client](https://github.com/Velaron/cs16-client) & [tf15-client](https://github.com/Velaron/tf15-client) maintainer and Xash3D FWGS [contributor](https://github.com/FWGS/xash3d-fwgs/commits?author=Velaron) (Android port, voice chat, etc).
* [BuyMeACoffee page](https://www.buymeacoffee.com/velaron)
## [SNMetamorph](https://github.com/SNMetamorph)
[PrimeXT](https://github.com/SNMetamorph/PrimeXT) & [GoldSrc Monitor](https://github.com/SNMetamorph/goldsrc-monitor) maintainer and Xash3D FWGS [contributor](https://github.com/FWGS/xash3d-fwgs/commits?author=SNMetamorph) (Windows port, voice chat, etc).
* [Boosty page](https://boosty.to/snmetamorph)
* [Other donation methods](https://snmetamorph.github.io/donate)

View File

@@ -6,7 +6,7 @@ For connecting to GoldSrc-based servers, use this command:
connect ip:port gs
```
But keep in mind, there are requirement for server to be able to accept connections from Xash3D-based clients: it should use Reunion or Dproto.
But keep in mind, there are requirement for server to be able to accept connections from Xash3D-based clients: it should use Reunion.
Without this requirement, you will just get "Steam validation rejected" error on connecting.
That is because proper authorization with Steam API is not implemented in engine yet (but we have plans on it).

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 400 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

@@ -2,10 +2,19 @@
|Name |Version |Why not working |What was made for that
|---- |------- |--------------- |----------------------
|Blue Shift |The latest steam release |Uses vgui2 library which xash3d does not support |Recreated source code here: https://github.com/FWGS/hlsdk-xash3d/tree/bshift
|Counter Strike |1.6(The latest steam release) |Uses vgui2 library which xash3d does not support |Some work on vgui2 support was made here: https://github.com/FWGS/xash3d/tree/vinterface
|Counter Strike: Condition Zero |The latest steam release |Uses vgui2 library which xash3d does not support |Some work on vgui2 support was made here: https://github.com/FWGS/xash3d/tree/vinterface
|Counter Strike: Condition Zero - Deleted scenes |The latest steam release |Uses vgui2 library which xash3d does not support |Some work on vgui2 support was made here: https://github.com/FWGS/xash3d/tree/vinterface
|Day of Defeat |The latest steam release |Uses vgui2 library which xash3d does not support |Some work on vgui2 support was made here: https://github.com/FWGS/xash3d/tree/vinterface
|Sven-Coop |5.0+ |Uses custom GoldSrc engine |
|Area 51 |Update 1 |Uses outdated BSP31 map format and custom HLFX SDK libraries. |You can try [this tool](https://hlfx.ru/forum/showthread.php?threadid=5250) to convert maps but there no warranty if it works.
|Arrange Mod: Rebirth |v150 |No idea yet. |
|Blue Shift |The latest steam release |Uses vgui2 library which xash3d does not support. |Recreated source code here: https://github.com/FWGS/hlsdk-xash3d/tree/bshift.
|Counter Strike |Beta 6.5- |Uses an old WON HL 1.0.0.16- interface. |
| |1.4 |Has encrypted blob instead of normal client.dll. |You can try [this tool](https://aluigi.altervista.org/papers/hldlldec.zip) to decrypt client.dll but there no warranty if it works.
| |1.5 |Has encrypted blob instead of normal client.dll. |Decrypted blob here: https://csm.dev/threads/cs-1-5-client-dll-decrypted-patched-for-usage.38845.
| |1.6(The latest steam release) |Uses vgui2 library which xash3d does not support. |Some work on vgui2 support was made here: https://github.com/FWGS/xash3d/tree/vinterface. Recreated Client Source Code here: https://github.com/Velaron/cs16-client.
|Counter Strike: Condition Zero |The latest steam release |Uses vgui2 library which xash3d does not support. |Some work on vgui2 support was made here: https://github.com/FWGS/xash3d/tree/vinterface. Recreated Client Source Code here: https://github.com/Velaron/cs16-client.
|Counter Strike: Condition Zero - Deleted scenes |The latest steam release |Uses vgui2 library which xash3d does not support. Uses new sequences code on engine-side that was never used in any other mods before. |Some work on vgui2 support was made here: https://github.com/FWGS/xash3d/tree/vinterface.
|Day of Defeat |The latest steam release |Uses vgui2 library which xash3d does not support. |Some work on vgui2 support was made here: https://github.com/FWGS/xash3d/tree/vinterface.
|Half-Life: Extended |Day One demo |Uses many hooks to GoldSource engine and version check. |Just wait new version or use more old version.
|Icon of Hell |Beta 0.99 |Uses outdated BSP31 map format and paranoia 2 libraries. |You can try [this tool](https://hlfx.ru/forum/showthread.php?threadid=5250) to convert maps and use Paranoia 2: The Savior 1.51 libraries but there no warranty if it works.
|Paranoia 2: The Savior |All builds older 1.51 |Uses an old renderer interface and engine features. |
|Rebellion |1.0 |Uses an old WON HL 1.0.0.16- interface. |Recreated source code here: https://github.com/FWGS/hlsdk-xash3d/tree/rebellion.
|Sven-Coop |5.0+ |Uses custom GoldSrc engine. |
|Time Shadows |Beta 0.1 |Uses Direct3D renderer. |

View File

@@ -32,12 +32,18 @@ Version 1.9 mirrored on github - https://github.com/solidi/hl-mods/tree/master/c
## Cold Ice Ressurection
Mirrored on github - https://github.com/solidi/hl-mods/tree/master/cir
## Counter-Life
Available on ModDB - https://www.moddb.com/mods/counter-life/downloads/cl-version-1-source-code
## Cthulhu
Uploaded to github by Oleg Cherkasky - https://github.com/gunrunners-paradise/Cthulhu-HLmod-SDK
## Deathmatch Classic
Available in Valve's Half-Life repository - https://github.com/ValveSoftware/halflife/tree/master/dmc
## Delta Particles
Available on ModDB - https://www.moddb.com/mods/half-life-delta/downloads/delta-particles-full-sources-maps-and-c-code
## Earth Special Forces
Alpha 2.0 - https://www.gamers-desire.de/details/2830

View File

@@ -2,11 +2,14 @@
### Prerequisites
1. Make sure your PSVita is [set up to run homebrew applications](https://vita.hacks.guide/).
2. Install [kubridge](https://github.com/TheOfficialFloW/kubridge/releases/) by copying `kubridge.suprx` to your taiHEN plugins folder (usually `ux0:/tai`) and add it to your `config.txt`, for example:
2. Install [kubridge](https://github.com/TheOfficialFloW/kubridge/releases/). It is recommended to use kubridge version `0.1`, because other versions aren't tested, we don't know are they suitable or not.
Worth to notice, we got reports that automatic plugins management app EasyPlugin have issues with installing kubridge plugin, so it's better to install it manually: by copying `kubridge.suprx` to your taiHEN plugins folder (usually `ux0:/tai`, but could be `ur0:/tai`) and add it to your `config.txt`, for example:
```
*KERNEL
ux0:tai/kubridge.skprx
```
3. Install `libshacccg.suprx` by following [this guide](https://cimmerian.gitbook.io/vita-troubleshooting-guide/shader-compiler/extract-libshacccg.suprx).
### Installation

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,149 @@
# Touch controls configuring
## Introduction
Thanks to mittorn, we have the ability to fully customize the controls in Xash3D. The new config allows you to not only add and change control buttons, but also create custom menus. There is also a built-in visual editor available, which simplifies the customization process without the need for manual file editing.
## Editor mode usage
1. Launch Xash3D and start the game.
2. To enter the edit mode, click on the gear icon (command `touch_enableedit`).
3. In the edit mode, the grid is displayed. The number of cells can be changed with the command `touch_grid_count` (default is 50). The grid can be disabled with the command `touch_grid_enable 0`.
*Touch controls layout editor*
![](images/editor.jpg)
*Touch profiles window*
![](images/touch-profiles.jpg)
*Touch buttons parameters window*
![](images/touch-buttons.jpg)
## Layout editor features
* **Moving buttons**: click on a button, drag it to the desired location, and release.
* **Resizing buttons**: place your first finger on the top left corner of the button, and use your second finger to resize it.
* **Hiding/showing buttons**: select the button (it will turn red), then use the menu:
* **Close**: closes the editing mode (`touch_disableedit`).
* **Reset**: resets the button to its default values.
* **Hide/Show**: hides or shows the button (`touch_hide <name>` / `touch_show <name>`).
## Working with configuration files / console
All changes made in the visual editor are automatically saved to the touch profile file. The files are located in the `touch_profiles` folder inside game directory. The file name depends on the selected profile.
### Common commands in configuration files
```
// Comment: lines starting with // are ignored.
// Swipe zones for movement. Specify how far you need to swipe to speed up.
// The default values are set to be optimal for a small swipe to immediately walk quickly.
touch_forwardzone "0.060000" ; touch_sidezone "0.060000"
// Sensitivity settings (pitch - horizontal, yaw - vertical).
touch_pitch ; touch_yaw
// Grid settings (see above).
touch_grid_count ; touch_grid_enable
// Draws a border around the button.
touch_set_stroke <thickness> <c> <v> <e> <t>
(<r> - red; <g> - green; <b> - blue; <a> - alpha/transparency)
// Show (1) or hide (0) client buttons.
touch_setclientonly
// Removes all buttons from the screen.
touch_removeall
// Shows all available buttons in the configuration file.
touch_list
// Saves the config after editing. You can specify a new file name.
touch_config_file command.cfg
```
*The full list of buttons in the standard `touch.cfg` file, displayed in the console when using `touch_list`.*
![](images/example2.jpg)
## Adding new buttons
To add a new button, use the console command:
```
touch_addbutton "digits" "touch/key_1.png" "toggle_digits" 0.340000 0.782222 0.400000 0.888889 255 255 255 100 0
```
### Parameters of `touch_addbutton` command
| Parameter | Description |
| --- | --- |
| `"digits"` | Unique name of the button. |
| `"touch/key_1.png"` | Path to the icon file (`.png` format). If the icon is not needed, leave `""`. |
| `"toggle_digits"` | Command to execute after clicking (for example, `"buy"` for purchase). |
| `0.340000` | X coordinate of the upper-left corner of the button. |
| `0.782222` | Y coordinate of the upper-left corner of the button. |
| `0.400000` | X coordinate of the lower-right corner of the button. |
| `0.888889` | Y coordinate of the lower-right corner of the button. |
| `255 255 255` | Button color in RGB format. |
| `100` | Button transparency (0 - fully transparent, 255 - fully opaque). |
| `0` | Flags (see next section). |
## List of flags
Flags define the behavior of the button. Their values are powers of two:
| Flag | Value | Description |
| --- | --- | --- |
| `TOUCH_FL_HIDE` | 1 | Hides the button (not displayed in the game, but visible in the editor). |
| `TOUCH_FL_NOEDIT` | 2 | Disables editing of the button in the editor. |
| `TOUCH_FL_CLIENT` | 4 | The button is client-side (not saved in the main control file). |
| `TOUCH_FL_MP` | 8 | The button is displayed only in multiplayer. |
| `TOUCH_FL_SP` | 16 | The button is displayed only in singleplayer. |
| `TOUCH_FL_DEF_SHOW` | 32 | The button is always displayed on startup. |
| `TOUCH_FL_DEF_HIDE` | 64 | The button is always hidden on startup. |
| `TOUCH_FL_DRAW_ADDITIVE` | 128 | The button colors are added together in blend mode. |
| `TOUCH_FL_STROKE` | 256 | Enables outline stroke around the button. |
Flags can be combined by adding their values together. For example, `5 = 1 + 4` is the combination of `TOUCH_FL_HIDE` and `TOUCH_FL_CLIENT` flags, which is a hidden client button.
*In the image below, the `spray`, `scores`, `messagemode` buttons are displayed simultaneously with the flag 8 and `loadquick`, `savequick` with the flag 16, and each is displayed in the corresponding game mode.*
![](images/example1.jpg)
## Useful commands
* `touch_hide <pattern>`: hides buttons by pattern.
* `touch_setcommand`: changes the command bound to a button.
* `touch_settexture`: quickly changes the button image.
* `touch_setcolor`: sets the button color.
* `touch_exportconfig`: exports the current configuration, including aspect ratio.
## Usage examples
* `touch_hide menu*` hides all buttons with names starting with `menu`.
* `touch_setcolor "attack" 255 160 0 128` changes the color of the primary fire button from opaque white to translucent orange, similar to the color of the HUD in Half-Life.
*Result of executing this command*
![](images/example3.jpg)
* Example of adding a new button with a custom icon (the `lastinv` command is used - quick change between weapons)
![](images/example4.jpg)
*View of this button in layout editor*
![](images/example5.jpg)
## Tips
* To prevent the `look` and `move` buttons from interfering with editing other elements, place them before the others in the configuration file.
* And vice versa, to make a button appear on top of others, place it at the end of the configuration file.
* You can assign commands to buttons that change other buttons, see the previous section "Usage examples".
* After editing each parameter of each individual button in the Touch Buttons section, do not forget to press Save, otherwise the applied parameters will not be saved.
* To create your own icon for the button, you can use any graphics editor (for Android, Photo Editor by iudesk is suitable). Saving conditions:
* Image format - `.png` with transparency (e.g. alpha channel)
* Aspect ratio / size - 1:1 / 256x256
* Path to the icons location - `touch/gfx` inside game directory.
### Additional links
* [Handy palette for selecting color in RGB format](https://www.rapidtables.com/web/color/RGB_Color.html)

View File

@@ -1,6 +1,7 @@
# Xash3D FWGS Engine <img align="right" width="128" height="128" src="https://github.com/FWGS/xash3d-fwgs/raw/master/game_launch/icon-xash-material.png" alt="Xash3D FWGS icon" />
[![builds.sr.ht status](https://builds.sr.ht/~a1batross/xash3d-fwgs.svg)](https://builds.sr.ht/~a1batross/xash3d-fwgs?) [![GitHub Actions Status](https://github.com/FWGS/xash3d-fwgs/actions/workflows/c-cpp.yml/badge.svg)](https://github.com/FWGS/xash3d-fwgs/actions/workflows/c-cpp.yml) [![FreeBSD Build Status](https://img.shields.io/cirrus/github/FWGS/xash3d-fwgs?label=freebsd%20build)](https://cirrus-ci.com/github/FWGS/xash3d-fwgs) [![Discord Server](https://img.shields.io/discord/355697768582610945.svg)](http://fwgsdiscord.mentality.rip/) \
[![Download Stable](https://img.shields.io/badge/download-stable-yellow)](https://github.com/FWGS/xash3d-fwgs/releases/latest) [![Download Testing](https://img.shields.io/badge/downloads-testing-orange)](https://github.com/FWGS/xash3d-fwgs/releases/tag/continuous)
[![GitHub Actions Status](https://github.com/FWGS/xash3d-fwgs/actions/workflows/c-cpp.yml/badge.svg)](https://github.com/FWGS/xash3d-fwgs/actions/workflows/c-cpp.yml) [![FreeBSD Build Status](https://img.shields.io/cirrus/github/FWGS/xash3d-fwgs?label=freebsd%20build)](https://cirrus-ci.com/github/FWGS/xash3d-fwgs) \
[![Discord Server](https://img.shields.io/discord/355697768582610945?logo=Discord&label=International%20Discord%20chat)](http://fwgsdiscord.mentality.rip/) [![Russian speakers Telegram Chat](https://img.shields.io/badge/Russian_speakers_Telegram_chat-gray?logo=Telegram)](https://t.me/flyingwithgauss) \
[![Download Daily Build](https://img.shields.io/badge/downloads-testing-orange)](https://github.com/FWGS/xash3d-fwgs/releases/tag/continuous)
Xash3D ([pronounced](https://ipa-reader.com/?text=ks%C9%91%CA%82) `[ksɑʂ]`) FWGS is a game engine, aimed to provide compatibility with Half-Life Engine and extend it, as well as to give game developers well known workflow.
@@ -43,7 +44,7 @@ For additional info, run Xash3D with `-help` command line key.
## Build instructions
We are using Waf build system. If you have some Waf-related questions, I recommend you to read [Waf Book](https://waf.io/book/).
NOTE: NEVER USE GitHub's ZIP ARCHIVES. GitHub doesn't include external dependencies we're using!
**NOTE: NEVER USE GitHub's ZIP ARCHIVES. GitHub doesn't include external dependencies we're using!**
### Prerequisites
If your CPU is x86 compatible and you're on Windows or Linux, we are building 32-bit code by default. This was done to maintain compatibility with Steam releases of Half-Life and based on it's engine games.
@@ -65,21 +66,21 @@ This repository contains our fork of HLSDK and restored source code for Half-Lif
* Only for 32-bit engine on 64-bit x86 operating system:
* Enable i386 on your system: `$ sudo dpkg --add-architecture i386`.
* Install `aptitude` ([why?](https://github.com/FWGS/xash3d-fwgs/issues/1828#issuecomment-2415131759)): `$ sudo apt update && sudo apt upgrade && sudo apt install aptitude`
* Install development tools: `$ sudo aptitude --without-recommends install git build-essential gcc-multilib g++-multilib libsdl2-dev:i386 libfontconfig-dev:i386 libfreetype-dev:i386 libopus-dev:i386 libbz2-dev:i386`.
* Install development tools: `$ sudo aptitude --without-recommends install git build-essential gcc-multilib g++-multilib libsdl2-dev:i386 libfreetype-dev:i386 libopus-dev:i386 libbz2-dev:i386 libvorbis-dev:i386 libopusfile-dev:i386 libogg-dev:i386`.
* Set PKG_CONFIG_PATH environment variable to point at 32-bit libraries: `$ export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig`.
* For 64-bit engine on 64-bit x86 and other non-x86 systems:
* Install development tools: `$ sudo apt install git build-essential python libsdl2-dev libfontconfig-dev libfreetype6-dev libopus-dev libbz2-dev`.
* Install development tools: `$ sudo apt install git build-essential python libsdl2-dev libfreetype6-dev libopus-dev libbz2-dev libvorbis-dev libopusfile-dev libogg-dev`.
* Clone this repostory: `$ git clone --recursive https://github.com/FWGS/xash3d-fwgs`.
##### RedHat/Fedora
* Only for 32-bit engine on 64-bit x86 operating system:
* Install development tools: `$ sudo dnf install git gcc gcc-c++ glibc-devel.i686 SDL2-devel.i686 opus-devel.i686 fontconfig-devel.i686 freetype-devel.i686 bzip2-devel.i686`.
* Install development tools: `$ sudo dnf install git gcc gcc-c++ glibc-devel.i686 SDL2-devel.i686 opus-devel.i686 freetype-devel.i686 bzip2-devel.i686 libvorbis-devel.i686 opusfile-devel.i686 libogg-devel.i686`.
* Set PKG_CONFIG_PATH environment variable to point at 32-bit libraries: `$ export PKG_CONFIG_PATH=/usr/lib/pkgconfig`.
* For 64-bit engine on 64-bit x86 and other non-x86 systems:
* Install development tools: `$ sudo dnf install git gcc gcc-c++ SDL2-devel opus-devel fontconfig-devel freetype-devel bzip2-devel`.
* Install development tools: `$ sudo dnf install git gcc gcc-c++ SDL2-devel opus-devel freetype-devel bzip2-devel libvorbis-devel opusfile-devel libogg-devel`.
* Clone this repostory: `$ git clone --recursive https://github.com/FWGS/xash3d-fwgs`.

View File

@@ -1,49 +1,39 @@
cmake_minimum_required(VERSION 3.6)
cmake_minimum_required(VERSION 3.22)
# Only used to build Android project
project(XASH_ANDROID)
# armeabi-v7a requires cpufeatures library
include(AndroidNdkModules)
android_ndk_import_module_cpufeatures()
if(ANDROID)
include_directories(${ANDROID_NDK}/sources/android/cpufeatures)
add_library(cpufeatures ${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c)
target_link_libraries(cpufeatures dl)
endif()
find_package(PythonInterp 2.7 REQUIRED)
get_filename_component(C_COMPILER_ID ${CMAKE_C_COMPILER} NAME_WE)
get_filename_component(CXX_COMPILER_ID ${CMAKE_CXX_COMPILER} NAME_WE)
include(FindPython)
if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
set(BUILD_TYPE "debug")
else()
set(BUILD_TYPE "release")
list(APPEND WAF_EXTRA_ARGS --enable-poly-opt --enable-lto)
list(APPEND WAF_EXTRA_ARGS --enable-poly-opt --enable-lto --enable-limited-debuginfo)
endif()
if(CMAKE_SIZEOF_VOID_P MATCHES "8")
set(64BIT ON CACHE BOOL "" FORCE)
list(APPEND WAF_EXTRA_ARGS -8) # only required for x86 when testing this cmakelist under linux
if(ANDROID_ABI STREQUAL "x86")
# HACKHACK: I don't know why but engine gets built as 64-bit binary here
list(APPEND WAF_EXTRA_ARGS -4)
endif()
set(CMAKE_VERBOSE_MAKEFILE ON)
set(WAF_CC "${CMAKE_C_COMPILER} --target=${CMAKE_C_COMPILER_TARGET}")
set(WAF_CXX "${CMAKE_CXX_COMPILER} --target=${CMAKE_CXX_COMPILER_TARGET}")
# not cleanest way to get upper directory
set(ENGINE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../")
execute_process(
COMMAND ${CMAKE_COMMAND} -E env
CC=${WAF_CC} CXX=${WAF_CXX}
AR=${CMAKE_AR} STRIP=${CMAKE_STRIP}
${PYTHON_EXECUTABLE} waf configure -T ${BUILD_TYPE} ${WAF_EXTRA_ARGS} cmake
--check-c-compiler=${C_COMPILER_ID} --check-cxx-compiler=${CXX_COMPILER_ID}
-s "${ENGINE_SOURCE_DIR}/SDL" --skip-sdl2-sanity-check --enable-bundled-deps
WORKING_DIRECTORY "${ENGINE_SOURCE_DIR}"
)
add_subdirectory("${ENGINE_SOURCE_DIR}/3rdparty/hlsdk-portable" hlsdk-portable)
set(WAF_CC "${CMAKE_C_COMPILER} --target=${CMAKE_C_COMPILER_TARGET}")
set(WAF_CXX "${CMAKE_CXX_COMPILER} --target=${CMAKE_CXX_COMPILER_TARGET}")
set(WAF ${Python_EXECUTABLE} ${ENGINE_SOURCE_DIR}waf -t ${ENGINE_SOURCE_DIR} -o ${CMAKE_CURRENT_BINARY_DIR}/xash3d-fwgs)
# try to build minimal SDL. Enable features as we're gonna use them
set(SDL_RENDER OFF)
@@ -56,5 +46,50 @@ set(SDL_VULKAN OFF)
set(SDL_OFFSCREEN OFF)
set(SDL_STATIC OFF)
add_subdirectory("${ENGINE_SOURCE_DIR}/3rdparty/SDL" SDL)
add_subdirectory("${ENGINE_SOURCE_DIR}/" xash3d-fwgs)
add_subdirectory("${ENGINE_SOURCE_DIR}/3rdparty/mainui" mainui)
include(ExternalProject)
# gradle passes backslashes to cmake, how does this even work for everybody else?
string(REPLACE "\\" "/" CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
ExternalProject_Add(
Xash3DFWGS
SOURCE_DIR ${ENGINE_SOURCE_DIR}
INSTALL_DIR ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}
BUILD_IN_SOURCE TRUE
DEPENDS SDL2
BUILD_ALWAYS TRUE
LOG_CONFIGURE TRUE
LOG_BUILD TRUE
LOG_INSTALL TRUE
LOG_OUTPUT_ON_FAILURE TRUE
LOG_MERGED_STDOUTERR TRUE
# USES_TERMINAL_CONFIGURE TRUE
# USES_TERMINAL_BUILD TRUE
# USES_TERMINAL_INSTALL TRUE
# NOTE: setting up WAFLOCK is important to avoid possible race conditions
CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env
ANDROID_NDK=${ANDROID_NDK}
BUILD_CMAKE_LIBRARY_OUTPUT_DIRECTORY=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}
WAFLOCK=.lock-waf_android_${ANDROID_ABI}_build
${WAF} configure -T ${BUILD_TYPE} --android=${ANDROID_ABI},,${CMAKE_SYSTEM_VERSION}
-s "${ENGINE_SOURCE_DIR}/3rdparty/SDL" --enable-bundled-deps ${WAF_EXTRA_ARGS}
BUILD_COMMAND ${CMAKE_COMMAND} -E env
WAFLOCK=.lock-waf_android_${ANDROID_ABI}_build
${WAF} build -v
INSTALL_COMMAND ${CMAKE_COMMAND} -E env
WAFLOCK=.lock-waf_android_${ANDROID_ABI}_build
${WAF} install --destdir=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}
)
add_subdirectory("${ENGINE_SOURCE_DIR}/3rdparty/hlsdk-portable" hlsdk-portable)
# a1ba: without this, xash3d target will be ignored as nothing depends on it
add_dependencies(client Xash3DFWGS)
add_dependencies(server Xash3DFWGS)

View File

@@ -9,7 +9,7 @@ plugins {
android {
namespace = "su.xash.engine"
ndkVersion = "27.2.12479018"
ndkVersion = "28.0.13004108"
defaultConfig {
applicationId = "su.xash"
@@ -96,6 +96,7 @@ android {
packaging {
jniLibs {
useLegacyPackaging = true
keepDebugSymbols.add("**/*.so")
}
}
}
@@ -112,7 +113,7 @@ dependencies {
implementation("androidx.preference:preference-ktx:1.2.1")
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
implementation("androidx.work:work-runtime-ktx:2.9.0")
// implementation "androidx.legacy:legacy-support-v4:1.0.0"
// implementation "androidx.legacy:legacy-support-v4:1.0.0"
implementation("com.madgag.spongycastle:prov:1.58.0.0")
implementation("in.dragonbra:javasteam:1.2.0")

View File

@@ -2,6 +2,7 @@ package su.xash.engine.ui.library
import android.annotation.SuppressLint
import android.content.Intent
import android.content.ActivityNotFoundException
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
@@ -10,6 +11,7 @@ import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.core.view.MenuProvider
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
@@ -73,11 +75,16 @@ class LibraryFragment : Fragment(), MenuProvider {
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
when (menuItem.itemId) {
R.id.action_browse -> {
startActivity(
Intent(Intent.ACTION_VIEW).setDataAndType(
null, "vnd.android.document/directory"
try {
startActivity(
Intent(Intent.ACTION_VIEW).setDataAndType(
null, "vnd.android.document/directory"
)
)
)
}
catch(e: ActivityNotFoundException) {
Toast.makeText(getActivity(), R.string.library_fragment_no_file_manager, Toast.LENGTH_LONG).show()
}
}
R.id.action_install -> {
@@ -91,4 +98,4 @@ class LibraryFragment : Fragment(), MenuProvider {
return false
}
}
}

View File

@@ -33,4 +33,5 @@
<string name="preferences_client_package">Client package</string>
<string name="preferences_server_package">Server package</string>
<string name="preferences_use_icons">Use icons instead of backgrounds</string>
</resources>
<string name="library_fragment_no_file_manager">File manager is missing</string>
</resources>

View File

@@ -20,4 +20,7 @@ kotlin.code.style=official
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true
android.nonTransitiveRClass=true
# Enable verbose output for CMake
android.native.buildOutput=verbose

View File

@@ -140,13 +140,13 @@ Default build-depended cvar and constant values
// Platform overrides
#if XASH_NSWITCH
#define DEFAULT_TOUCH_ENABLE "0"
#define DEFAULT_TOUCH_ENABLE "1"
#define DEFAULT_M_IGNORE "1"
#define DEFAULT_MODE_WIDTH 1280
#define DEFAULT_MODE_HEIGHT 720
#define DEFAULT_ALLOWCONSOLE 1
#elif XASH_PSVITA
#define DEFAULT_TOUCH_ENABLE "0"
#define DEFAULT_TOUCH_ENABLE "1"
#define DEFAULT_M_IGNORE "1"
#define DEFAULT_MODE_WIDTH 960
#define DEFAULT_MODE_HEIGHT 544
@@ -158,7 +158,7 @@ Default build-depended cvar and constant values
#define DEFAULT_M_IGNORE "1"
#endif // !XASH_MOBILE_PLATFORM && !XASH_NSWITCH
#if XASH_ANDROID || XASH_IOS || XASH_EMSCRIPTEN
#if (XASH_ANDROID && !XASH_TERMUX) || XASH_IOS || XASH_EMSCRIPTEN
// this means that libraries are provided with engine, but not in game data
// You need add library loading code to library.c when adding new platform
#define XASH_INTERNAL_GAMELIBS

View File

@@ -28,7 +28,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define PORT_ANY -1
typedef enum {NA_LOOPBACK = 1, NA_BROADCAST, NA_IP, NA_IPX, NA_BROADCAST_IPX, NA_IP6, NA_MULTICAST_IP6} netadrtype_t;
typedef enum netadrtype_e
{
NA_UNDEFINED = 0,
NA_LOOPBACK,
NA_BROADCAST,
NA_IP,
NA_IPX,
NA_BROADCAST_IPX,
NA_IP6,
NA_MULTICAST_IP6
} netadrtype_t;
/*
Original Quake-2 structure:
@@ -46,29 +56,60 @@ typedef struct
#pragma pack( push, 1 )
typedef struct netadr_s
{
// the reason we do this evil thing, is that when this struct contains IPv6
// address the `type` is 2-byte wide, but when it doesn't `type` must 4-byte
// wide _and_ ip6_0 must be zeroed, to keep it binary compatible.
#if XASH_LITTLE_ENDIAN
uint16_t type;
uint8_t ip6_0[2];
#elif XASH_BIG_ENDIAN
uint8_t ip6_0[2];
uint16_t type;
#else
#error
#endif
union
{
// IPv6 struct
uint8_t ip6_1[14];
struct
{
uint16_t type6;
uint8_t ip6[16];
};
struct
{
uint32_t type; // must be netadrtype_t but will break with short enums
union
{
uint8_t ip[4];
uint32_t ip4; // for easier conversions
uint8_t ip[4];
uint32_t ip4; // for easier conversions
};
uint8_t ipx[10];
};
};
uint16_t port;
uint16_t port;
} netadr_t;
#pragma pack( pop )
static inline netadrtype_t NET_NetadrType( const netadr_t *a )
{
if( a->type == NA_IP6 || a->type == NA_MULTICAST_IP6 )
return (netadrtype_t)a->type;
if( a->ip6_0[0] || a->ip6_0[1] )
return NA_UNDEFINED;
return (netadrtype_t)a->type;
}
static inline void NET_NetadrSetType( netadr_t *a, netadrtype_t type )
{
if( type == NA_IP6 || type == NA_MULTICAST_IP6 )
{
a->type = type;
return;
}
a->ip6_0[0] = a->ip6_0[1] = 0;
a->type = type;
}
STATIC_CHECK_SIZEOF( netadr_t, 20, 20 );
#endif // NET_ADR_H

View File

@@ -86,8 +86,4 @@ GNU General Public License for more details.
#include <string.h>
#include <limits.h>
#if defined XASH_SDL && !defined REF_DLL
#include <SDL.h>
#endif
#endif // PORT_H

View File

@@ -13,47 +13,44 @@
#endif // _WIN32
#include <sys/types.h> // off_t
#ifdef STDINT_H
#include STDINT_H
#else // !STDINT_H
#include <stdint.h>
#endif // !STDINT_H
#include <assert.h>
typedef unsigned char byte;
typedef int sound_t;
typedef float vec_t;
typedef vec_t vec2_t[2];
typedef vec_t vec3_t[3];
typedef vec_t vec4_t[4];
typedef vec_t quat_t[4];
typedef byte rgba_t[4]; // unsigned byte colorpack
typedef byte rgb_t[3]; // unsigned byte colorpack
typedef vec_t matrix3x4[3][4];
typedef vec_t matrix4x4[4][4];
typedef uint32_t poolhandle_t;
typedef uint8_t byte;
typedef float vec_t;
typedef vec_t vec2_t[2];
#ifndef vec3_t // SDK renames it to Vector
typedef vec_t vec3_t[3];
#endif
typedef vec_t vec4_t[4];
typedef vec_t quat_t[4];
typedef byte rgba_t[4]; // unsigned byte colorpack
typedef byte rgb_t[3]; // unsigned byte colorpack
typedef vec_t matrix3x4[3][4];
typedef vec_t matrix4x4[4][4];
typedef uint32_t poolhandle_t;
#undef true
#undef false
#ifndef __cplusplus
typedef enum { false, true } qboolean;
#else
typedef int qboolean;
// true and false are keywords in C++ and C23
#if !__cplusplus && __STDC_VERSION__ < 202311L
enum { false, true };
#endif
typedef int qboolean;
typedef uint64_t longtime_t;
#define MAX_STRING 256 // generic string
#define MAX_INFO_STRING 256 // infostrings are transmitted across network
#define MAX_SERVERINFO_STRING 512 // server handles too many settings. expand to 1024?
#define MAX_LOCALINFO_STRING 32768 // localinfo used on server and not sended to the clients
#define MAX_SYSPATH 1024 // system filepath
#define MAX_VA_STRING 1024 // string length returned by va()
#define MAX_PRINT_MSG 8192 // how many symbols can handle single call of Con_Printf or Con_DPrintf
#define MAX_TOKEN 2048 // parse token length
#define MAX_MODS 512 // environment games that engine can keep visible
#define MAX_USERMSG_LENGTH 2048 // don't modify it's relies on a client-side definitions
#define MAX_STRING 256 // generic string
#define MAX_VA_STRING 1024 // compatibility macro
#define MAX_SYSPATH 1024 // system filepath
#define MAX_MODS 512 // environment games that engine can keep visible
#define BIT( n ) ( 1U << ( n ))
#define BIT64( n ) ( 1ULL << ( n ))
#define SetBits( iBitVector, bits ) ((iBitVector) = (iBitVector) | (bits))
#define ClearBits( iBitVector, bits ) ((iBitVector) = (iBitVector) & ~(bits))
#define FBitSet( iBitVector, bit ) ((iBitVector) & (bit))
@@ -70,6 +67,8 @@ typedef uint64_t longtime_t;
#define IsColorString( p ) ( p && *( p ) == '^' && *(( p ) + 1) && *(( p ) + 1) >= '0' && *(( p ) + 1 ) <= '9' )
#define ColorIndex( c ) ((( c ) - '0' ) & 7 )
#undef EXPORT
#if defined( __GNUC__ )
#if defined( __i386__ )
#define EXPORT __attribute__(( visibility( "default" ), force_align_arg_pointer ))
@@ -92,8 +91,10 @@ typedef uint64_t longtime_t;
#define NORETURN __attribute__(( noreturn ))
#define NONNULL __attribute__(( nonnull ))
#define RETURNS_NONNULL __attribute__(( returns_nonnull ))
#if __clang__
#define PFN_RETURNS_NONNULL // clang has bugged returns_nonnull for functions pointers, it's ignored and generates a warning about objective-c? O_o
#if __clang__ || __MCST__
// clang has bugged returns_nonnull for functions pointers, it's ignored and generates a warning about objective-c? O_o
// lcc doesn't support it at all
#define PFN_RETURNS_NONNULL
#else
#define PFN_RETURNS_NONNULL RETURNS_NONNULL
#endif
@@ -209,35 +210,16 @@ _inline float LittleFloat( float f )
#endif
typedef unsigned int dword;
typedef unsigned int uint;
typedef unsigned long ulong;
typedef char string[MAX_STRING];
typedef struct file_s file_t; // normal file
typedef struct stream_s stream_t; // sound stream for background music playing
typedef off_t fs_offset_t;
typedef unsigned int dword;
typedef unsigned int uint;
typedef char string[MAX_STRING];
typedef off_t fs_offset_t;
#if XASH_WIN32
typedef int fs_size_t; // return type of _read, _write funcs
typedef int fs_size_t; // return type of _read, _write funcs
#else /* !XASH_WIN32 */
typedef ssize_t fs_size_t;
typedef ssize_t fs_size_t;
#endif /* !XASH_WIN32 */
typedef struct dllfunc_s
{
const char *name;
void **func;
} dllfunc_t;
typedef struct dll_info_s
{
const char *name; // name of library
const dllfunc_t *fcts; // list of dll exports
const size_t num_fcts;
qboolean crash; // crash if dll not found
void *link; // hinstance of loading library
} dll_info_t;
typedef void (*setpair_t)( const char *key, const void *value, const void *buffer, void *numpairs );
typedef void *(*pfnCreateInterface_t)( const char *, int * );
// config strings are a general means of communication from

View File

@@ -152,19 +152,6 @@ void CL_PlayCDTrack_f( void )
else Con_Printf( "%s: unknown command %s\n", Cmd_Argv( 0 ), command );
}
/*
==================
CL_ScreenshotGetName
==================
*/
static qboolean CL_ScreenshotGetName( const char *fmt, int lastnum, char *filename, size_t size )
{
if( lastnum < 0 || lastnum > 9999 )
return false;
return Q_snprintf( filename, size, fmt, clgame.mapname, lastnum ) > 0;
}
/*
==============================================================================
@@ -270,7 +257,6 @@ void CL_GenericShot_f( void )
case scrshot_normal:
case scrshot_snapshot:
{
const char *fmt;
string checkname;
int i;
@@ -282,15 +268,18 @@ void CL_GenericShot_f( void )
}
if( type == scrshot_snapshot )
{
fmt = "../%s_%04d.png";
FS_AllowDirectPaths( true );
}
else fmt = "scrshots/%s_shot%04d.png";
for( i = 0; i < 9999; i++ )
{
if( !CL_ScreenshotGetName( fmt, i, checkname, sizeof( checkname )))
int ret;
if( type == scrshot_snapshot )
ret = Q_snprintf( checkname, sizeof( checkname ), "../%s_%04d.png", clgame.mapname, i );
else
ret = Q_snprintf( checkname, sizeof( checkname ), "scrshots/%s_shot%04d.png", clgame.mapname, i );
if( ret <= 0 )
{
Con_Printf( S_ERROR "unable to write %s\n", argv0 );
FS_AllowDirectPaths( false );

View File

@@ -198,3 +198,44 @@ void CL_WriteMessageHistory( void )
CL_WriteErrorMessage( old->starting_offset, msg );
cls_message_debug.parsing = false;
}
void CL_ReplayBufferDat_f( void )
{
file_t *f = FS_Open( Cmd_Argv( 1 ), "rb", true );
sizebuf_t msg;
char buffer[NET_MAX_MESSAGE];
int starting_count, current_count, protocol;
fs_offset_t len;
if( !f )
return;
FS_Read( f, &starting_count, sizeof( starting_count ));
FS_Read( f, &current_count, sizeof( current_count ));
FS_Read( f, &protocol, sizeof( protocol ));
cls.legacymode = protocol;
len = FS_Read( f, buffer, sizeof( buffer ));
FS_Close( f );
MSG_Init( &msg, __func__, buffer, len );
Delta_Shutdown();
Delta_Init();
clgame.maxEntities = MAX_EDICTS;
clgame.entities = Mem_Calloc( clgame.mempool, sizeof( *clgame.entities ) * clgame.maxEntities );
// ad-hoc implement
#if 0
{
const int message_pos = 12; // put real number here
MSG_SeekToBit( &msg, ( message_pos - 12 + 1 ) << 3, SEEK_SET );
CL_ParseYourMom( &msg, protocol );
}
#endif
Sys_Quit( __func__ );
}

View File

@@ -373,7 +373,7 @@ CL_WriteDemoUserMessage
Dumps the user message (demoaction)
====================
*/
void CL_WriteDemoUserMessage( const byte *buffer, size_t size )
void GAME_EXPORT CL_WriteDemoUserMessage( int size, byte *buffer )
{
if( !cls.demorecording || cls.demowaiting )
return;
@@ -642,9 +642,7 @@ static void CL_ReadDemoUserCmd( qboolean discard )
pcmd->sendsize = 1;
// always delta'ing from null
cl.cmd = &pcmd->cmd;
MSG_ReadDeltaUsercmd( &buf, &nullcmd, cl.cmd );
MSG_ReadDeltaUsercmd( &buf, &nullcmd, &pcmd->cmd );
// make sure what interp info contain angles from different frames
// or lerping will stop working
@@ -656,13 +654,16 @@ static void CL_ReadDemoUserCmd( qboolean discard )
// record update
a->starttime = demo.timestamp;
VectorCopy( cl.cmd->viewangles, a->viewangles );
VectorCopy( pcmd->cmd.viewangles, a->viewangles );
demo.lasttime = demo.timestamp;
}
// NOTE: we need to have the current outgoing sequence correct
// so we can do prediction correctly during playback
cls.netchan.outgoing_sequence = outgoing_sequence;
// save last usercmd
cl.cmd = pcmd->cmd;
}
}
@@ -1145,8 +1146,7 @@ void CL_DemoInterpolateAngles( void )
QuaternionSlerp( q2, q1, frac, q );
QuaternionAngle( q, cl.viewangles );
}
else if( cl.cmd != NULL )
VectorCopy( cl.cmd->viewangles, cl.viewangles );
else VectorCopy( cl.cmd.viewangles, cl.viewangles );
}
/*

View File

@@ -2229,4 +2229,3 @@ void CL_ThinkParticle( double frametime, particle_t *p )
break;
}
}

View File

@@ -405,7 +405,11 @@ void CL_ParseReliableEvent( sizebuf_t *msg, connprotocol_t proto )
}
if( args.entindex > 0 && args.entindex <= cl.maxclients )
args.angles[PITCH] *= -3.0f;
{
args.angles[PITCH] *= 3.0f;
if( !FBitSet( host.features, ENGINE_COMPENSATE_QUAKE_BUG ))
args.angles[PITCH] = -args.angles[PITCH];
}
CL_QueueEvent( FEV_RELIABLE|FEV_SERVER, event_index, delay, &args );
}
@@ -477,7 +481,9 @@ void CL_ParseEvent( sizebuf_t *msg, connprotocol_t proto )
if( state->number > 0 && state->number <= cl.maxclients )
{
args.angles[PITCH] *= -3.0f;
args.angles[PITCH] *= 3.0f;
if( !FBitSet( host.features, ENGINE_COMPENSATE_QUAKE_BUG ))
args.angles[PITCH] = -args.angles[PITCH];
CL_CalcPlayerVelocity( state->number, args.velocity );
args.ducking = ( state->usehull == 1 );
}
@@ -487,7 +493,11 @@ void CL_ParseEvent( sizebuf_t *msg, connprotocol_t proto )
if( args.entindex != 0 )
{
if( args.entindex > 0 && args.entindex <= cl.maxclients )
args.angles[PITCH] /= -3.0f;
{
args.angles[PITCH] /= 3.0f;
if( !FBitSet( host.features, ENGINE_COMPENSATE_QUAKE_BUG ))
args.angles[PITCH] = -args.angles[PITCH];
}
}
}

View File

@@ -173,7 +173,7 @@ static int CL_CalcTabStop( const cl_font_t *font, int x )
return stop;
}
int CL_DrawCharacter( float x, float y, int number, rgba_t color, cl_font_t *font, int flags )
int CL_DrawCharacter( float x, float y, int number, const rgba_t color, cl_font_t *font, int flags )
{
wrect_t *rc;
float w, h;
@@ -231,7 +231,7 @@ int CL_DrawCharacter( float x, float y, int number, rgba_t color, cl_font_t *fon
return font->charWidths[number];
}
int CL_DrawString( float x, float y, const char *s, rgba_t color, cl_font_t *font, int flags )
int CL_DrawString( float x, float y, const char *s, const rgba_t color, cl_font_t *font, int flags )
{
rgba_t current_color;
int draw_len = 0;
@@ -287,7 +287,7 @@ int CL_DrawString( float x, float y, const char *s, rgba_t color, cl_font_t *fon
return draw_len;
}
int CL_DrawStringf( cl_font_t *font, float x, float y, rgba_t color, int flags, const char *fmt, ... )
int CL_DrawStringf( cl_font_t *font, float x, float y, const rgba_t color, int flags, const char *fmt, ... )
{
va_list va;
char buf[MAX_VA_STRING];

View File

@@ -13,6 +13,12 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#if XASH_SDL == 2
#include <SDL.h> // SDL_GetWindowPosition
#elif XASH_SDL == 3
#include <SDL3/SDL.h> // SDL_GetWindowPosition
#endif // XASH_SDL
#include "common.h"
#include "client.h"
#include "const.h"
@@ -306,21 +312,22 @@ void SPR_AdjustSize( float *x, float *y, float *w, float *h )
static void SPR_AdjustTexCoords( int texnum, float width, float height, float *s1, float *t1, float *s2, float *t2 )
{
if( REF_GET_PARM( PARM_TEX_FILTERING, texnum ))
{
if( refState.width != clgame.scrInfo.iWidth )
{
// align to texel if scaling
*s1 += 0.5f;
*s2 -= 0.5f;
}
const qboolean filtering = REF_GET_PARM( PARM_TEX_FILTERING, texnum );
const int xremainder = refState.width % clgame.scrInfo.iWidth;
const int yremainder = refState.height % clgame.scrInfo.iHeight;
if( refState.height != clgame.scrInfo.iHeight )
{
// align to texel if scaling
*t1 += 0.5f;
*t2 -= 0.5f;
}
if(( filtering || xremainder ) && refState.width != clgame.scrInfo.iWidth )
{
// align to texel if scaling
*s1 += 0.5f;
*s2 -= 0.5f;
}
if(( filtering || yremainder ) && refState.height != clgame.scrInfo.iHeight )
{
// align to texel if scaling
*t1 += 0.5f;
*t2 -= 0.5f;
}
*s1 /= width;
@@ -556,7 +563,7 @@ static void CL_InitTitles( const char *filename )
Q_snprintf( name, sizeof( name ), TEXT_MSGNAME, i );
cl_textmessage[i].pName = _copystring( clgame.mempool, name, __FILE__, __LINE__ );
cl_textmessage[i].pName = copystringpool( clgame.mempool, name );
cl_textmessage[i].pMessage = cl_textbuffer[i];
}
@@ -1683,7 +1690,7 @@ get actual screen info
*/
int GAME_EXPORT CL_GetScreenInfo( SCREENINFO *pscrinfo )
{
qboolean apply_scale_factor = false;
qboolean apply_scale_factor = false; // we don't want floating point inaccuracies
float scale_factor = hud_scale.value;
if( FBitSet( hud_fontscale.flags, FCVAR_CHANGED ))
@@ -1698,7 +1705,12 @@ int GAME_EXPORT CL_GetScreenInfo( SCREENINFO *pscrinfo )
clgame.scrInfo.iSize = sizeof( clgame.scrInfo );
clgame.scrInfo.iFlags = SCRINFO_SCREENFLASH;
if( scale_factor && scale_factor != 1.0f )
if( hud_scale.value >= 320.0f && hud_scale.value >= hud_scale_minimal_width.value )
{
scale_factor = refState.width / hud_scale.value;
apply_scale_factor = scale_factor > 1.0f;
}
else if( scale_factor && scale_factor != 1.0f )
{
float scaled_width = (float)refState.width / scale_factor;
if( scaled_width >= hud_scale_minimal_width.value )
@@ -2073,6 +2085,7 @@ GetWindowCenterX
static int GAME_EXPORT pfnGetWindowCenterX( void )
{
int x = 0;
#if XASH_WIN32
if( m_ignore.value )
{
@@ -2082,7 +2095,7 @@ static int GAME_EXPORT pfnGetWindowCenterX( void )
}
#endif
#if XASH_SDL == 2
#if XASH_SDL >= 2
SDL_GetWindowPosition( host.hWnd, &x, NULL );
#endif
@@ -2098,6 +2111,7 @@ GetWindowCenterY
static int GAME_EXPORT pfnGetWindowCenterY( void )
{
int y = 0;
#if XASH_WIN32
if( m_ignore.value )
{
@@ -2107,7 +2121,7 @@ static int GAME_EXPORT pfnGetWindowCenterY( void )
}
#endif
#if XASH_SDL == 2
#if XASH_SDL >= 2
SDL_GetWindowPosition( host.hWnd, NULL, &y );
#endif
@@ -3348,28 +3362,6 @@ DemoApi implementation
=================
*/
/*
=================
Demo_IsRecording
=================
*/
static int GAME_EXPORT Demo_IsRecording( void )
{
return cls.demorecording;
}
/*
=================
Demo_IsPlayingback
=================
*/
static int GAME_EXPORT Demo_IsPlayingback( void )
{
return cls.demoplayback;
}
/*
=================
Demo_IsTimeDemo
@@ -3381,17 +3373,6 @@ static int GAME_EXPORT Demo_IsTimeDemo( void )
return cls.timedemo;
}
/*
=================
Demo_WriteBuffer
=================
*/
static void GAME_EXPORT Demo_WriteBuffer( int size, byte *buffer )
{
CL_WriteDemoUserMessage( buffer, size );
}
/*
=================
NetworkApi implementation
@@ -3433,7 +3414,7 @@ static void GAME_EXPORT NetAPI_Status( net_status_t *status )
status->latency = (connected) ? cl.frames[cl.parsecountmod].latency : 0.0;
status->remote_address = cls.netchan.remote_address;
status->packet_loss = packet_loss;
status->local_address = net_local;
NET_GetLocalAddress( &status->local_address, NULL ); // NetAPI doesn't know about IPv6
status->rate = rate.value;
}
@@ -3454,7 +3435,7 @@ static void GAME_EXPORT NetAPI_SendRequest( int context, int request, int flags,
return;
}
if( remote_address->type == NA_IPX || remote_address->type == NA_BROADCAST_IPX )
if( NET_NetadrType( remote_address ) == NA_IPX || NET_NetadrType( remote_address ) == NA_BROADCAST_IPX )
return; // IPX no longer support
if( request == NETAPI_REQUEST_SERVERLIST )
@@ -3577,28 +3558,6 @@ static int GAME_EXPORT NetAPI_CompareAdr( netadr_t *a, netadr_t *b )
return NET_CompareAdr( *a, *b );
}
/*
=================
NetAPI_StringToAdr
=================
*/
static int GAME_EXPORT NetAPI_StringToAdr( char *s, netadr_t *a )
{
return NET_StringToAdr( s, a );
}
/*
=================
NetAPI_ValueForKey
=================
*/
static const char * GAME_EXPORT NetAPI_ValueForKey( const char *s, const char *key )
{
return Info_ValueForKey( s, key );
}
/*
=================
NetAPI_RemoveKey
@@ -3795,10 +3754,10 @@ static event_api_t gEventApi =
static demo_api_t gDemoApi =
{
Demo_IsRecording,
Demo_IsPlayingback,
(void *)CL_IsRecordDemo,
(void *)CL_IsPlaybackDemo,
Demo_IsTimeDemo,
Demo_WriteBuffer,
CL_WriteDemoUserMessage,
};
net_api_t gNetApi =
@@ -3810,8 +3769,8 @@ net_api_t gNetApi =
NetAPI_CancelAllRequests,
NetAPI_AdrToString,
NetAPI_CompareAdr,
NetAPI_StringToAdr,
NetAPI_ValueForKey,
(void *)NET_StringToAdr,
Info_ValueForKey,
NetAPI_RemoveKey,
NetAPI_SetValueForKey,
};

View File

@@ -1273,16 +1273,16 @@ static void pfnEnableTextInput( int enable )
Key_EnableTextInput( enable, false );
}
static int pfnGetRenderers( unsigned int num, char *shortName, size_t size1, char *readableName, size_t size2 )
static int pfnGetRenderers( unsigned int num, char *short_name, size_t size1, char *long_name, size_t size2 )
{
if( num >= ref.numRenderers )
if( num >= ref.num_renderers )
return 0;
if( shortName && size1 )
Q_strncpy( shortName, ref.shortNames[num], size1 );
if( short_name && size1 )
Q_strncpy( short_name, ref.short_names[num], size1 );
if( readableName && size2 )
Q_strncpy( readableName, ref.readableNames[num], size2 );
if( long_name && size2 )
Q_strncpy( long_name, ref.long_names[num], size2 );
return 1;
}

View File

@@ -68,14 +68,15 @@ CVAR_DEFINE_AUTO( hud_scale_minimal_width, "640", FCVAR_ARCHIVE|FCVAR_LATCH, "if
CVAR_DEFINE_AUTO( cl_solid_players, "1", 0, "Make all players not solid (can't traceline them)" );
CVAR_DEFINE_AUTO( cl_updaterate, "20", FCVAR_USERINFO|FCVAR_ARCHIVE, "refresh rate of server messages" );
CVAR_DEFINE_AUTO( cl_showevents, "0", FCVAR_ARCHIVE, "show events playback" );
CVAR_DEFINE_AUTO( cl_cmdrate, "60", FCVAR_ARCHIVE, "Max number of command packets sent to server per second" );
CVAR_DEFINE_AUTO( cl_cmdrate, "30", FCVAR_ARCHIVE, "Max number of command packets sent to server per second" );
CVAR_DEFINE( cl_interp, "ex_interp", "0.1", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "Interpolate object positions starting this many seconds in past" );
CVAR_DEFINE_AUTO( cl_nointerp, "0", 0, "disable interpolation of entities and players" );
static CVAR_DEFINE_AUTO( cl_dlmax, "0", FCVAR_USERINFO|FCVAR_ARCHIVE, "max allowed outcoming fragment size" );
static CVAR_DEFINE_AUTO( cl_upmax, "1200", FCVAR_ARCHIVE, "max allowed incoming fragment size" );
static CVAR_DEFINE_AUTO( cl_upmax, "508", FCVAR_ARCHIVE, "max allowed incoming fragment size" );
CVAR_DEFINE_AUTO( cl_lw, "1", FCVAR_ARCHIVE|FCVAR_USERINFO, "enable client weapon predicting" );
CVAR_DEFINE_AUTO( cl_charset, "utf-8", FCVAR_ARCHIVE, "1-byte charset to use (iconv style)" );
CVAR_DEFINE_AUTO( cl_trace_consistency, "0", FCVAR_ARCHIVE, "enable consistency info tracing (good for developers)" );
CVAR_DEFINE_AUTO( cl_trace_stufftext, "0", FCVAR_ARCHIVE, "enable stufftext (server-to-client console commands) tracing (good for developers)" );
CVAR_DEFINE_AUTO( cl_trace_messages, "0", FCVAR_ARCHIVE|FCVAR_CHEAT, "enable message names tracing (good for developers)" );
CVAR_DEFINE_AUTO( cl_trace_events, "0", FCVAR_ARCHIVE|FCVAR_CHEAT, "enable events tracing (good for developers)" );
@@ -93,11 +94,10 @@ static CVAR_DEFINE_AUTO( name, username, FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_PRIN
static CVAR_DEFINE_AUTO( model, "", FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_FILTERABLE, "player model ('player' is a singleplayer model)" );
static CVAR_DEFINE_AUTO( topcolor, "0", FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_FILTERABLE, "player top color" );
static CVAR_DEFINE_AUTO( bottomcolor, "0", FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_FILTERABLE, "player bottom color" );
CVAR_DEFINE_AUTO( rate, "3500", FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_FILTERABLE, "player network rate" );
CVAR_DEFINE_AUTO( rate, "25000", FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_FILTERABLE, "player network rate" );
static CVAR_DEFINE_AUTO( cl_ticket_generator, "revemu2013", FCVAR_ARCHIVE, "you wouldn't steal a car" );
client_t cl;
client_static_t cls;
clgame_static_t clgame;
@@ -673,7 +673,7 @@ static void CL_CreateCmd( void )
}
// demo always have commands so don't overwrite them
if( !cls.demoplayback ) cl.cmd = &pcmd->cmd;
if( !cls.demoplayback ) cl.cmd = pcmd->cmd;
// predict all unacknowledged movements
CL_PredictMovement( false );
@@ -717,11 +717,20 @@ static void CL_WritePacket( void )
int numbackup, maxbackup, maxcmds;
const connprotocol_t proto = cls.legacymode;
// FIXME: on Xash protocol we don't send move commands until ca_active
// to prevent outgoing_command outrun incoming_acknowledged
// which is fatal for some buggy mods like TFC
//
// ... but GoldSrc don't have (real) ca_validate state, so we consider
// ca_validate the same as ca_active, otherwise we don't pass validation
// of server-side mods like ReAuthCheck
const connstate_t min_state = proto == PROTO_GOLDSRC ? ca_validate : ca_active;
// don't send anything if playing back a demo
if( cls.demoplayback || cls.state < ca_connected || cls.state == ca_cinematic )
return;
if( cls.state <= ca_connected )
if( cls.state < min_state )
{
Netchan_TransmitBits( &cls.netchan, 0, "" );
return;
@@ -999,7 +1008,7 @@ static void CL_WriteSteamTicket( sizebuf_t *send )
const char *s;
uint32_t crc;
char buf[768] = { 0 }; // setti and steamemu return 768
size_t i = sizeof( buf );
int i = sizeof( buf );
if( !Q_strcmp( cl_ticket_generator.string, "null" ))
{
@@ -1018,24 +1027,7 @@ static void CL_WriteSteamTicket( sizebuf_t *send )
CRC32_Init( &crc );
CRC32_ProcessBuffer( &crc, s, Q_strlen( s ));
crc = CRC32_Final( crc );
if( !Q_stricmp( cl_ticket_generator.string, "revemu2013" ))
i = GenerateRevEmu2013( buf, crc );
else if( !Q_stricmp( cl_ticket_generator.string, "sc2009" ))
i = GenerateSC2009( buf, crc );
else if( !Q_stricmp( cl_ticket_generator.string, "oldrevemu" ))
i = GenerateOldRevEmu( buf, crc );
else if( !Q_stricmp( cl_ticket_generator.string, "steamemu" ))
i = GenerateSteamEmu( buf, crc );
else if( !Q_stricmp( cl_ticket_generator.string, "revemu" ))
i = GenerateRevEmu( buf, crc );
else if( !Q_stricmp( cl_ticket_generator.string, "setti" ))
i = GenerateSetti( buf );
else if( !Q_stricmp( cl_ticket_generator.string, "avsmp" ))
i = GenerateAVSMP( buf, crc, true );
else
Con_Printf( "%s: unknown generator %s, supported are: null, revemu2003, sc2009, oldrevemu, steamemu, revemu, setti, avsmp\n", __func__, cl_ticket_generator.string );
i = GenerateRevEmu2013( buf, s, crc );
MSG_WriteBytes( send, buf, i );
}
@@ -1053,6 +1045,7 @@ static void CL_SendConnectPacket( connprotocol_t proto, int challenge )
const char *key = ID_GetMD5();
netadr_t adr = { 0 };
int input_devices;
netadrtype_t adrtype;
protinfo[0] = 0;
@@ -1063,14 +1056,16 @@ static void CL_SendConnectPacket( connprotocol_t proto, int challenge )
return;
}
adrtype = NET_NetadrType( &adr );
if( adr.port == 0 ) adr.port = MSG_BigShort( PORT_SERVER );
input_devices = IN_CollectInputDevices();
IN_LockInputDevices( adr.type != NA_LOOPBACK ? true : false );
IN_LockInputDevices( adrtype != NA_LOOPBACK ? true : false );
// GoldSrc doesn't need sv_cheats set to 0, it's handled by svc_goldsrc_sendextrainfo
// it also doesn't need useragent string
if( adr.type != NA_LOOPBACK && proto != PROTO_GOLDSRC )
if( adrtype != NA_LOOPBACK && proto != PROTO_GOLDSRC )
{
Cvar_SetCheatState();
Cvar_FullSet( "sv_cheats", "0", FCVAR_READ_ONLY | FCVAR_SERVER );
@@ -1170,7 +1165,11 @@ Returns bandwidth test fragment size
*/
static int CL_GetTestFragmentSize( void )
{
const int fragmentSizes[CL_TEST_RETRIES] = { 64000, 32000, 10666, 5200, 1400 };
// const int fragmentSizes[CL_TEST_RETRIES] = { 64000, 32000, 10666, 5200, 1400 };
// it turns out, even if we pass the bandwidth test, it doesn't mean we can use such large fragments
// as a temporary solution, use smaller fragment sizes
const int fragmentSizes[CL_TEST_RETRIES] = { 1400, 1200, 1000, 800, 508 };
if( cls.connect_retry >= 0 && cls.connect_retry < CL_TEST_RETRIES )
return bound( FRAGMENT_MIN_SIZE, fragmentSizes[cls.connect_retry], FRAGMENT_MAX_SIZE );
else
@@ -1208,7 +1207,7 @@ static void CL_CheckForResend( void )
cls.signon = 0;
cls.state = ca_connecting;
Q_strncpy( cls.servername, "localhost", sizeof( cls.servername ));
cls.serveradr.type = NA_LOOPBACK;
NET_NetadrSetType( &cls.serveradr, NA_LOOPBACK );
cls.legacymode = PROTO_CURRENT;
// we don't need a challenge on the localhost
@@ -1544,8 +1543,8 @@ static void CL_SendDisconnectMessage( connprotocol_t proto )
MSG_WriteString( &buf, "dropclient\n" );
else MSG_WriteString( &buf, "disconnect" );
if( !cls.netchan.remote_address.type )
cls.netchan.remote_address.type = NA_LOOPBACK;
if( NET_NetadrType( &cls.netchan.remote_address ) == NA_UNDEFINED )
NET_NetadrSetType( &cls.netchan.remote_address, NA_LOOPBACK );
// make sure message will be delivered
Netchan_TransmitBits( &cls.netchan, MSG_GetNumBitsWritten( &buf ), MSG_GetData( &buf ));
@@ -1588,6 +1587,9 @@ void CL_SetupNetchanForProtocol( connprotocol_t proto )
}
break;
default:
if( !Host_IsLocalClient( ))
SetBits( flags, NETCHAN_USE_LZSS );
cls.extensions = Q_atoi( Info_ValueForKey( Cmd_Argv( 1 ), "ext" ));
if( FBitSet( cls.extensions, NET_EXT_SPLITSIZE ))
@@ -1711,19 +1713,17 @@ CL_LocalServers_f
*/
static void CL_LocalServers_f( void )
{
netadr_t adr;
memset( &adr, 0, sizeof( adr ));
netadr_t adr = { 0 };
Con_Printf( "Scanning for servers on the local network area...\n" );
NET_Config( true, true ); // allow remote
// send a broadcast packet
adr.type = NA_BROADCAST;
NET_NetadrSetType( &adr, NA_BROADCAST );
adr.port = MSG_BigShort( PORT_SERVER );
Netchan_OutOfBandPrint( NS_CLIENT, adr, A2A_INFO" %i", PROTOCOL_VERSION );
adr.type = NA_MULTICAST_IP6;
NET_NetadrSetType( &adr, NA_MULTICAST_IP6 );
Netchan_OutOfBandPrint( NS_CLIENT, adr, A2A_INFO" %i", PROTOCOL_VERSION );
}
@@ -2467,18 +2467,18 @@ static void CL_ServerList( netadr_t from, sizebuf_t *msg )
while( MSG_GetNumBitsLeft( msg ) > 8 )
{
uint8_t addr[16];
netadr_t servadr;
netadr_t servadr = { 0 };
if( from.type6 == NA_IP6 ) // IPv6 master server only sends IPv6 addresses
if( NET_NetadrType( &from ) == NA_IP6 ) // IPv6 master server only sends IPv6 addresses
{
MSG_ReadBytes( msg, addr, sizeof( addr ));
NET_IP6BytesToNetadr( &servadr, addr );
servadr.type6 = NA_IP6;
NET_NetadrSetType( &servadr, NA_IP6 );
}
else
{
MSG_ReadBytes( msg, servadr.ip, sizeof( servadr.ip )); // 4 bytes for IP
servadr.type = NA_IP;
NET_NetadrSetType( &servadr, NA_IP );
}
servadr.port = MSG_ReadShort( msg ); // 2 bytes for Port
@@ -3126,6 +3126,9 @@ static qboolean CL_ShouldRescanFilesystem( void )
}
}
if( FBitSet( fs_mount_lv.flags|fs_mount_hd.flags|fs_mount_addon.flags|fs_mount_l10n.flags|ui_language.flags, FCVAR_CHANGED ))
retval = true;
return retval;
}
@@ -3135,7 +3138,7 @@ qboolean CL_PrecacheResources( void )
// if we downloaded new WAD files or any other archives they must be added to searchpath
if( CL_ShouldRescanFilesystem( ))
g_fsapi.Rescan();
FS_Rescan_f();
// NOTE: world need to be loaded as first model
for( pRes = cl.resourcesonhand.pNext; pRes && pRes != &cl.resourcesonhand; pRes = pRes->pNext )
@@ -3381,6 +3384,7 @@ static void CL_InitLocal( void )
Cvar_RegisterVariable( &rcon_address );
Cvar_RegisterVariable( &cl_trace_consistency );
Cvar_RegisterVariable( &cl_trace_stufftext );
Cvar_RegisterVariable( &cl_trace_messages );
Cvar_RegisterVariable( &cl_trace_events );
@@ -3475,6 +3479,8 @@ static void CL_InitLocal( void )
Cmd_AddCommand ("fullserverinfo", CL_FullServerinfo_f, "sent by server when serverinfo changes" );
Cmd_AddCommand ("upload", CL_BeginUpload_f, "uploading file to the server" );
Cmd_AddRestrictedCommand( "replaybufferdat", CL_ReplayBufferDat_f, "development and debugging tool" );
Cmd_AddRestrictedCommand ("quit", CL_Quit_f, "quit from game" );
Cmd_AddRestrictedCommand ("exit", CL_Quit_f, "quit from game" );
@@ -3652,6 +3658,8 @@ void CL_Init( void )
if( !CL_LoadProgs( libpath ))
Host_Error( "can't initialize %s: %s\n", libpath, COM_GetLibraryError( ));
ID_Init();
cls.build_num = 0;
cls.initialized = true;
cl.maxclients = 1; // allow to drawing player in menu
@@ -3669,7 +3677,7 @@ void CL_Shutdown( void )
{
Con_Printf( "%s()\n", __func__ );
if( !host.crashed && cls.initialized )
if( host.status != HOST_CRASHED && cls.initialized )
{
Host_WriteOpenGLConfig ();
Host_WriteVideoConfig ();

View File

@@ -92,6 +92,11 @@ static char *pfnParseFileSafe( char *data, char *buf, const int size, unsigned i
return COM_ParseFileSafe( data, buf, size, flags, len, NULL );
}
static void GAME_EXPORT pfnSetCustomClientID( const char *id )
{
// deprecated
}
static const mobile_engfuncs_t gMobileEngfuncs =
{
MOBILITY_API_VERSION,
@@ -106,7 +111,7 @@ static const mobile_engfuncs_t gMobileEngfuncs =
pfnDrawScaledCharacter,
Sys_Warn,
Sys_GetNativeObject,
ID_SetCustomClientID,
pfnSetCustomClientID,
pfnParseFileSafe
};

View File

@@ -1614,6 +1614,23 @@ void CL_UpdateUserPings( sizebuf_t *msg )
}
}
static const char *CL_CheckTypeToString( int check_type )
{
// renamed so they have same width and look better in console output
switch( check_type )
{
case force_exactfile:
return "exactfile";
case force_model_samebounds:
return "samebounds";
case force_model_specifybounds:
return "specbounds";
case force_model_specifybounds_if_avail:
return "specbounds2";
}
return "unknown";
}
static void CL_SendConsistencyInfo( sizebuf_t *msg, connprotocol_t proto )
{
qboolean user_changed_diskfile;
@@ -1879,6 +1896,9 @@ static void CL_ParseConsistencyInfo( sizebuf_t *msg, connprotocol_t proto )
return;
}
if( cl_trace_consistency.value )
Con_Printf( "Server wants consistency of the following resources:\n" );
skip_crc_change = NULL;
lastcheck = 0;
@@ -1910,7 +1930,7 @@ static void CL_ParseConsistencyInfo( sizebuf_t *msg, connprotocol_t proto )
pc = &cl.consistency_list[cl.num_consistency];
cl.num_consistency++;
memset( pc, 0, sizeof( consistency_t ));
memset( pc, 0, sizeof( *pc ));
pc->filename = pResource->szFileName;
pc->issound = (pResource->type == t_sound);
pc->orig_index = delta;
@@ -1923,6 +1943,9 @@ static void CL_ParseConsistencyInfo( sizebuf_t *msg, connprotocol_t proto )
pc->check_type = pResource->rguc_reserved[0];
}
if( cl_trace_consistency.value )
Con_Printf( "%s\t%s\t%s\n", COM_ResourceTypeFromIndex( pResource->type ), CL_CheckTypeToString( pc->check_type ), pc->filename );
skip_crc_change = pResource;
lastcheck = delta;
}

View File

@@ -83,7 +83,10 @@ static void CL_ParseNewMovevars( sizebuf_t *msg )
R_SetupSky( clgame.movevars.skyName );
clgame.oldmovevars = clgame.movevars;
clgame.entities->curstate.scale = clgame.movevars.waveHeight;
// FIXME: set world wave height when entities will be allocated
if( clgame.entities )
clgame.entities->curstate.scale = clgame.movevars.waveHeight;
// keep features an actual!
clgame.oldmovevars.features = clgame.movevars.features = host.features;
@@ -91,11 +94,11 @@ static void CL_ParseNewMovevars( sizebuf_t *msg )
typedef struct delta_header_t
{
qboolean remove : 1;
qboolean custom : 1;
qboolean instanced : 1;
uint instanced_baseline_index : 6;
uint offset : 6;
qboolean remove;
qboolean custom;
qboolean instanced;
uint16_t instanced_baseline_index;
uint16_t offset;
} delta_header_t;
static int CL_ParseDeltaHeader( sizebuf_t *msg, qboolean delta, int oldnum, struct delta_header_t *hdr )
@@ -160,33 +163,47 @@ static int CL_GetEntityDelta( const struct delta_header_t *hdr, int entnum )
return DT_ENTITY_STATE_T;
}
static void CL_FlushEntityPacketGS( frame_t *frame, sizebuf_t *msg )
static int CL_FlushEntityPacketGS( frame_t *frame, sizebuf_t *msg )
{
int playerbytes = 0, numbase = 0;
frame->valid = false;
cl.validsequence = 0; // can't render a frame
// read it all but ignore it
while( 1 )
{
int num = 0;
int newnum, bufstart;
entity_state_t from = { 0 }, to;
delta_header_t hdr;
qboolean player;
if( MSG_ReadWord( msg ) != 0 )
{
MSG_SeekToBit( msg, -16, SEEK_CUR );
num = CL_ParseDeltaHeader( msg, false, num, &hdr );
numbase = newnum = CL_ParseDeltaHeader( msg, true, numbase, &hdr );
}
else break;
if( MSG_CheckOverflow( msg ))
Host_Error( "%s: overflow\n", __func__ );
player = CL_IsPlayerIndex( newnum );
bufstart = MSG_GetNumBytesRead( msg );
if( hdr.remove )
continue;
Delta_ReadGSFields( msg, CL_GetEntityDelta( &hdr, num ), &from, &to, cl.mtime[0] );
Delta_ReadGSFields( msg, CL_GetEntityDelta( &hdr, newnum ), &from, &to, cl.mtime[0] );
if( player )
playerbytes += MSG_GetNumBytesRead( msg ) - bufstart;
}
if( MSG_CheckOverflow( msg ))
Host_Error( "%s: overflow\n", __func__ );
return playerbytes;
}
static void CL_DeltaEntityGS( const delta_header_t *hdr, sizebuf_t *msg, frame_t *frame, int newnum, const entity_state_t *from )
@@ -203,7 +220,7 @@ static void CL_DeltaEntityGS( const delta_header_t *hdr, sizebuf_t *msg, frame_t
if(( newnum < 0 ) || ( newnum >= clgame.maxEntities ))
{
Con_DPrintf( S_ERROR "CL_DeltaEntity: invalid newnum: %d\n", newnum );
Host_Error( "%s: bad delta entity number: %i", __func__, newnum );
Host_Error( "%s: bad delta entity number: %i\n", __func__, newnum );
return;
}
@@ -267,7 +284,7 @@ static void CL_CopyPacketEntity( frame_t *frame, int num, const entity_state_t *
static int CL_ParsePacketEntitiesGS( sizebuf_t *msg, qboolean delta )
{
frame_t *frame, *oldframe;
int oldindex, newnum, oldnum, numbase = 0;
int oldindex, oldnum, numbase = 0;
entity_state_t *oldent;
int count;
int playerbytes = 0;
@@ -314,7 +331,7 @@ static int CL_ParsePacketEntitiesGS( sizebuf_t *msg, qboolean delta )
// read it all but ignore it
while( 1 )
{
int bufstart;
int bufstart, newnum;
qboolean player;
delta_header_t hdr;
int val = MSG_ReadWord( msg );

View File

@@ -973,7 +973,7 @@ void CL_MoveSpectatorCamera( void )
CL_SetUpPlayerPrediction( false, true );
CL_SetSolidPlayers( cl.playernum );
CL_RunUsercmd( &cls.spectator_state, &cls.spectator_state, cl.cmd, true, &time, (uint)( time * 100.0 ));
CL_RunUsercmd( &cls.spectator_state, &cls.spectator_state, &cl.cmd, true, &time, (uint)( time * 100.0 ));
VectorCopy( cls.spectator_state.client.velocity, cl.simvel );
VectorCopy( cls.spectator_state.client.origin, cl.simorg );

View File

@@ -233,6 +233,11 @@ static intptr_t pfnRenderGetParm( int parm, int arg )
return CL_RenderGetParm( parm, arg, true );
}
static void pfnAVI_StreamSound( void *avi, int entnum, float fvol, float attn, float synctime )
{
return; // stub, use AVI_SetParm and AVI_Think to stream AVI sound
}
static render_api_t gRenderAPI =
{
pfnRenderGetParm, // GL_RenderGetParm,
@@ -265,7 +270,7 @@ static render_api_t gRenderAPI =
NULL, // R_UploadStretchRaw,
(void*)AVI_FreeVideo,
(void*)AVI_IsActive,
S_StreamAviSamples,
(void*)pfnAVI_StreamSound,
NULL,
NULL,
NULL, // GL_Bind,

View File

@@ -955,7 +955,6 @@ void GAME_EXPORT R_BloodSprite( const vec3_t org, int colorIndex, int modelIndex
if( pTemp->entity.curstate.frame > 8.0f )
pTemp->entity.curstate.frame = pTemp->frameMax;
pTemp->entity.baseline.origin[2] += COM_RandomFloat( 4.0f, 16.0f ) * size;
pTemp->entity.angles[2] = COM_RandomFloat( 0.0f, 360.0f );
pTemp->bounceFactor = 0.0f;
}
@@ -2429,7 +2428,7 @@ void CL_SetLightstyle( int style, const char *s, float f )
if( unlikely( style < 0 || style >= MAX_LIGHTSTYLES ))
{
Con_Printf( S_WARN "%s: ignored invalid lightstyle id %d\n", style );
Con_Printf( S_WARN "%s: ignored invalid lightstyle id %d\n", __func__, style );
return;
}

View File

@@ -165,7 +165,7 @@ static void V_SetRefParams( ref_params_t *fd )
// get pointers to movement vars and user cmd
fd->movevars = &clgame.movevars;
fd->cmd = cl.cmd;
fd->cmd = &cl.cmd;
// setup viewport
fd->viewport[0] = clgame.viewport[0];

View File

@@ -234,7 +234,7 @@ typedef struct
cl_local_data_t local;
// player final info
usercmd_t *cmd; // cl.commands[outgoing_sequence].cmd
usercmd_t cmd; // cl.commands[outgoing_sequence].cmd
vec3_t viewangles;
vec3_t viewheight;
vec3_t punchangle;
@@ -688,6 +688,7 @@ extern convar_t r_showtextures;
extern convar_t cl_bmodelinterp;
extern convar_t cl_lw; // local weapons
extern convar_t cl_charset;
extern convar_t cl_trace_consistency;
extern convar_t cl_trace_stufftext;
extern convar_t cl_trace_messages;
extern convar_t cl_trace_events;
@@ -736,6 +737,7 @@ void CL_ClearResourceLists( void );
//
// cl_debug.c
//
void CL_ReplayBufferDat_f( void );
void CL_Parse_Debug( qboolean enable );
void CL_Parse_RecordCommand( int cmd, int startoffset );
void CL_ResetFrame( frame_t *frame );
@@ -767,7 +769,7 @@ void CL_StartupDemoHeader( void );
void CL_DrawDemoRecording( void );
void CL_WriteDemoUserCmd( int cmdnumber );
void CL_WriteDemoMessage( qboolean startup, int start, sizebuf_t *msg );
void CL_WriteDemoUserMessage( const byte *buffer, size_t size );
void CL_WriteDemoUserMessage( int size, byte *buffer );
qboolean CL_DemoReadMessage( byte *buffer, size_t *length );
void CL_DemoInterpolateAngles( void );
void CL_CheckStartupDemos( void );
@@ -805,11 +807,11 @@ qboolean Con_LoadFixedWidthFont( const char *fontname, cl_font_t *font, float sc
qboolean Con_LoadVariableWidthFont( const char *fontname, cl_font_t *font, float scale, convar_t *rendermode, uint texFlags );
void CL_FreeFont( cl_font_t *font );
void CL_SetFontRendermode( cl_font_t *font );
int CL_DrawCharacter( float x, float y, int number, rgba_t color, cl_font_t *font, int flags );
int CL_DrawString( float x, float y, const char *s, rgba_t color, cl_font_t *font, int flags );
int CL_DrawCharacter( float x, float y, int number, const rgba_t color, cl_font_t *font, int flags );
int CL_DrawString( float x, float y, const char *s, const rgba_t color, cl_font_t *font, int flags );
void CL_DrawCharacterLen( cl_font_t *font, int number, int *width, int *height );
void CL_DrawStringLen( cl_font_t *font, const char *s, int *width, int *height, int flags );
int CL_DrawStringf( cl_font_t *font, float x, float y, rgba_t color, int flags, const char *fmt, ... ) FORMAT_CHECK( 6 );
int CL_DrawStringf( cl_font_t *font, float x, float y, const rgba_t color, int flags, const char *fmt, ... ) FORMAT_CHECK( 6 );
//
@@ -842,19 +844,21 @@ void CL_EnableScissor( scissor_state_t *scissor, int x, int y, int width, int he
void CL_DisableScissor( scissor_state_t *scissor );
qboolean CL_Scissor( const scissor_state_t *scissor, float *x, float *y, float *width, float *height, float *u0, float *v0, float *u1, float *v1 );
static inline cl_entity_t *CL_EDICT_NUM( int n )
static inline cl_entity_t *CL_EDICT_NUM( int index )
{
if( !clgame.entities )
if( !clgame.entities ) // not in game yet
{
Host_Error( "%s: clgame.entities is NULL\n", __func__ );
return NULL;
}
if(( n >= 0 ) && ( n < clgame.maxEntities ))
return clgame.entities + n;
if( index < 0 || index >= clgame.maxEntities )
{
Host_Error( "%s: bad number %i\n", __func__, index );
return NULL;
}
Host_Error( "%s: bad number %i\n", __func__, n );
return NULL;
return clgame.entities + index;
}
static inline cl_entity_t *CL_GetEntityByIndex( int index )
@@ -865,10 +869,7 @@ static inline cl_entity_t *CL_GetEntityByIndex( int index )
if( index < 0 || index >= clgame.maxEntities )
return NULL;
if( index == 0 )
return clgame.entities;
return CL_EDICT_NUM( index );
return clgame.entities + index;
}
static inline model_t *CL_ModelHandle( int modelindex )
@@ -878,7 +879,7 @@ static inline model_t *CL_ModelHandle( int modelindex )
static inline qboolean CL_IsThirdPerson( void )
{
return clgame.dllFuncs.CL_IsThirdPerson() ? true : false;
return clgame.dllFuncs.CL_IsThirdPerson();
}
static inline cl_entity_t *CL_GetLocalPlayer( void )
@@ -1106,7 +1107,7 @@ int Con_UtfMoveRight( char *str, int pos, int length );
void Con_DefaultColor( int r, int g, int b, qboolean gameui );
cl_font_t *Con_GetCurFont( void );
cl_font_t *Con_GetFont( int num );
int Con_DrawString( int x, int y, const char *string, rgba_t setColor ); // legacy, use cl_font.c
int Con_DrawString( int x, int y, const char *string, const rgba_t setColor ); // legacy, use cl_font.c
void GAME_EXPORT Con_DrawStringLen( const char *pText, int *length, int *height ); // legacy, use cl_font.c
void Con_CharEvent( int key );
void Key_Console( int key );
@@ -1119,7 +1120,7 @@ void Con_PageUp( int lines );
//
// s_main.c
//
void S_StreamAviSamples( void *Avi, int entnum, float fvol, float attn, float synctime );
typedef int sound_t;
void S_StartBackgroundTrack( const char *intro, const char *loop, int position, qboolean fullpath );
void S_StopBackgroundTrack( void );
void S_StreamSetPause( int pause );
@@ -1208,6 +1209,12 @@ void Key_EnableTextInput( qboolean enable, qboolean force );
int Key_ToUpper( int key );
void OSK_Draw( void );
//
// identification.c
//
void ID_Init( void );
const char *ID_GetMD5( void );
extern rgba_t g_color_table[8];
extern triangleapi_t gTriApi;
extern net_api_t gNetApi;

View File

@@ -622,7 +622,7 @@ int Con_UtfProcessCharForce( int in )
// TODO: get rid of global state where possible
static utfstate_t state = { 0 };
int ch = Q_DecodeUTF8( &state, in );
uint32_t ch = Q_DecodeUTF8( &state, in );
if( g_codepage == 1251 )
return Q_UnicodeToCP1251( ch );
@@ -759,7 +759,7 @@ Con_DrawString
client version of routine
====================
*/
int Con_DrawString( int x, int y, const char *string, rgba_t setColor )
int Con_DrawString( int x, int y, const char *string, const rgba_t setColor )
{
return CL_DrawString( x, y, string, setColor, con.curFont, FONT_DRAW_UTF8 );
}
@@ -843,11 +843,14 @@ If no console is visible, the notify window will pop up.
*/
void Con_Print( const char *txt )
{
static int cr_pending = 0;
static char buf[MAX_PRINT_MSG];
qboolean norefresh = false;
static int lastlength = 0;
static int bufpos = 0;
static qboolean cr_pending = false;
static qboolean colorstring = false;
static char buf[MAX_PRINT_MSG];
static int lastlength = 0;
static int bufpos = 0;
static int charpos = 0;
qboolean norefresh = false;
int c, mask = 0;
// client not running
@@ -873,7 +876,7 @@ void Con_Print( const char *txt )
if( cr_pending )
{
Con_DeleteLastLine();
cr_pending = 0;
cr_pending = false;
}
c = *txt;
@@ -886,23 +889,42 @@ void Con_Print( const char *txt )
{
Con_AddLine( buf, bufpos, true );
lastlength = CON_LINES_LAST().length;
cr_pending = 1;
cr_pending = true;
bufpos = 0;
charpos = 0;
}
break;
case '\n':
Con_AddLine( buf, bufpos, true );
lastlength = CON_LINES_LAST().length;
bufpos = 0;
charpos = 0;
break;
default:
buf[bufpos++] = c | mask;
if(( bufpos >= sizeof( buf ) - 1 ) || bufpos >= ( con.linewidth - 1 ))
if( IsColorString( txt ))
{
// first color string character
colorstring = true;
}
else if( colorstring )
{
// second color string character
colorstring = false;
}
else
{
// not a color string, move char counter
charpos++;
}
if(( bufpos >= sizeof( buf ) - 1 ) || charpos >= ( con.linewidth - 1 ))
{
Con_AddLine( buf, bufpos, true );
lastlength = CON_LINES_LAST().length;
bufpos = 0;
charpos = 0;
}
break;
}
@@ -918,6 +940,7 @@ void Con_Print( const char *txt )
Con_AddLine( buf, bufpos, lastlength != 0 );
lastlength = 0;
bufpos = 0;
charpos = 0;
}
// pump messages to avoid window hanging
@@ -1244,45 +1267,16 @@ static void Field_CharEvent( field_t *edit, int ch )
Field_DrawInputLine
==================
*/
static void Field_DrawInputLine( int x, int y, field_t *edit )
static void Field_DrawInputLine( int x, int y, const field_t *edit )
{
int len, cursorChar;
int drawLen;
int prestep, curPos;
char str[MAX_SYSPATH];
byte *colorDefault;
int curPos;
char str[MAX_SYSPATH];
const byte *colorDefault = g_color_table[ColorIndex( COLOR_DEFAULT )];
const int prestep = bound( 0, edit->scroll, sizeof( edit->buffer ) - 1 );
const int drawLen = bound( 0, edit->widthInChars, sizeof( str ));
const int cursorCharPos = bound( 0, edit->cursor - prestep, sizeof( str ));
drawLen = edit->widthInChars;
len = Q_strlen( edit->buffer ) + 1;
colorDefault = g_color_table[ColorIndex( COLOR_DEFAULT )];
// guarantee that cursor will be visible
if( len <= drawLen )
{
prestep = 0;
}
else
{
if( edit->scroll + drawLen > len )
{
edit->scroll = len - drawLen;
if( edit->scroll < 0 ) edit->scroll = 0;
}
prestep = edit->scroll;
}
if( prestep + drawLen > len )
drawLen = len - prestep;
// extract <drawLen> characters from the field at <prestep>
drawLen = Q_min( drawLen, MAX_SYSPATH - 1 );
memcpy( str, edit->buffer + prestep, drawLen );
str[drawLen] = 0;
// save char for overstrike
cursorChar = str[edit->cursor - prestep];
Q_strncpy( str, edit->buffer + prestep, drawLen );
// draw it
CL_DrawString( x, y, str, colorDefault, con.curFont, FONT_DRAW_UTF8 );
@@ -1291,7 +1285,7 @@ static void Field_DrawInputLine( int x, int y, field_t *edit )
if((int)( host.realtime * 4 ) & 1 ) return; // off blink
// calc cursor position
str[edit->cursor - prestep] = 0;
str[cursorCharPos] = 0;
CL_DrawStringLen( con.curFont, str, &curPos, NULL, FONT_DRAW_UTF8 );
if( host.key_overstrike )
@@ -1467,6 +1461,16 @@ Handles history and console scrollback
*/
void Key_Console( int key )
{
// exit the console by pressing MINUS on NSwitch
// or both Back(Select)/Start buttons for everyone else
if( key == K_BACK_BUTTON || key == K_START_BUTTON || key == K_ESCAPE )
{
if( cls.state == ca_active && !cl.background )
Key_SetKeyDest( key_game );
else UI_SetActiveMenu( true );
return;
}
// ctrl-L clears screen
if( key == 'l' && Key_IsDown( K_CTRL ))
{
@@ -1575,16 +1579,6 @@ void Key_Console( int key )
return;
}
// exit the console by pressing MINUS on NSwitch
// or both Back(Select)/Start buttons for everyone else
if( key == K_BACK_BUTTON || key == K_START_BUTTON )
{
if( cls.state == ca_active && !cl.background )
Key_SetKeyDest( key_game );
else UI_SetActiveMenu( true );
return;
}
// pass to the normal editline routine
Field_KeyDownEvent( &con.input, key );
}
@@ -2008,7 +2002,7 @@ void Con_DrawVersion( void )
int start, height = refState.height;
string curbuild;
if( !scr_drawversion.value || CL_IsDevOverviewMode() == 2 || net_graph.value )
if( !scr_drawversion.value )
return;
if( cls.key_dest == key_menu )
@@ -2020,6 +2014,9 @@ void Con_DrawVersion( void )
{
qboolean draw_version;
if( CL_IsDevOverviewMode() == 2 || net_graph.value )
return;
draw_version = cls.scrshot_action == scrshot_normal
|| cls.scrshot_action == scrshot_snapshot
|| host.force_draw_version_time > host.realtime;
@@ -2092,10 +2089,7 @@ void Con_RunConsole( void )
}
else
{
Con_Printf( S_WARN "Unknown charset %s, defaulting to cp1252", con_charset.string );
Cvar_DirectSet( &con_charset, "cp1252" );
g_codepage = 1252;
g_codepage = 0;
}
cls.accept_utf8 = !Q_stricmp( cl_charset.string, "utf-8" );
@@ -2138,20 +2132,31 @@ void Con_CharEvent( int key )
static int Con_LoadSimpleConback( const char *name, int flags )
{
const char *paths[] = {
"gfx/shell/%s.dds",
"gfx/shell/%s.bmp",
"gfx/shell/%s.tga",
"cached/%s640",
"cached/%s",
};
size_t i;
int i;
for( i = 0; i < ARRAYSIZE( paths ); i++ )
for( i = 0; i < 5; i++ )
{
string path;
Q_snprintf( path, sizeof( path ), paths[i], name );
switch( i )
{
case 0:
Q_snprintf( path, sizeof( path ), "gfx/shell/%s.dds", name );
break;
case 1:
Q_snprintf( path, sizeof( path ), "gfx/shell/%s.bmp", name );
break;
case 2:
Q_snprintf( path, sizeof( path ), "gfx/shell/%s.tga", name );
break;
case 3:
Q_snprintf( path, sizeof( path ), "cached/%s640", name );
break;
case 4:
Q_snprintf( path, sizeof( path ), "cached/%s", name );
break;
}
if( g_fsapi.FileExists( path, false ))
{
int gl_texturenum = ref.dllFuncs.GL_LoadTexture( path, NULL, 0, flags );

View File

@@ -19,8 +19,8 @@ GNU General Public License for more details.
#if !XASH_WIN32
#include <dirent.h>
#endif
static char id_md5[33];
static char id_customid[MAX_STRING];
/*
==========================================================
@@ -365,10 +365,10 @@ static int ID_GetKeyData( HKEY hRootKey, char *subKey, char *value, LPBYTE data,
{
HKEY hKey;
if( RegOpenKeyEx( hRootKey, subKey, 0, KEY_QUERY_VALUE, &hKey ) != ERROR_SUCCESS )
if( RegOpenKeyExA( hRootKey, subKey, 0, KEY_QUERY_VALUE, &hKey ) != ERROR_SUCCESS )
return 0;
if( RegQueryValueEx( hKey, value, NULL, NULL, data, &cbData ) != ERROR_SUCCESS )
if( RegQueryValueExA( hKey, value, NULL, NULL, data, &cbData ) != ERROR_SUCCESS )
{
RegCloseKey( hKey );
return 0;
@@ -377,13 +377,14 @@ static int ID_GetKeyData( HKEY hRootKey, char *subKey, char *value, LPBYTE data,
RegCloseKey( hKey );
return 1;
}
static int ID_SetKeyData( HKEY hRootKey, char *subKey, DWORD dwType, char *value, LPBYTE data, DWORD cbData)
static int ID_SetKeyData( HKEY hRootKey, char *subKey, DWORD dwType, char *value, LPBYTE data, DWORD cbData )
{
HKEY hKey;
if( RegCreateKey( hRootKey, subKey, &hKey ) != ERROR_SUCCESS )
if( RegCreateKeyA( hRootKey, subKey, &hKey ) != ERROR_SUCCESS )
return 0;
if( RegSetValueEx( hKey, value, 0, dwType, data, cbData ) != ERROR_SUCCESS )
if( RegSetValueExA( hKey, value, 0, dwType, data, cbData ) != ERROR_SUCCESS )
{
RegCloseKey( hKey );
return 0;
@@ -395,7 +396,7 @@ static int ID_SetKeyData( HKEY hRootKey, char *subKey, DWORD dwType, char *value
#define BUFSIZE 4096
static int ID_RunWMIC(char *buffer, const char *cmdline)
static int ID_RunWMIC( char *buffer, const wchar_t *cmdline )
{
HANDLE g_IN_Rd = NULL;
HANDLE g_IN_Wr = NULL;
@@ -403,75 +404,92 @@ static int ID_RunWMIC(char *buffer, const char *cmdline)
HANDLE g_OUT_Wr = NULL;
DWORD dwRead;
BOOL bSuccess = FALSE;
SECURITY_ATTRIBUTES saAttr;
wchar_t *cmdline_copy;
STARTUPINFO si = {0};
PROCESS_INFORMATION pi = {0};
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
PROCESS_INFORMATION pi = { 0 };
SECURITY_ATTRIBUTES saAttr =
{
.nLength = sizeof( SECURITY_ATTRIBUTES ),
.bInheritHandle = TRUE,
.lpSecurityDescriptor = NULL,
};
CreatePipe( &g_IN_Rd, &g_IN_Wr, &saAttr, 0 );
CreatePipe( &g_OUT_Rd, &g_OUT_Wr, &saAttr, 0 );
SetHandleInformation( g_IN_Wr, HANDLE_FLAG_INHERIT, 0 );
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdInput = g_IN_Rd;
si.hStdOutput = g_OUT_Wr;
si.hStdError = g_OUT_Wr;
si.wShowWindow = SW_HIDE;
si.dwFlags |= STARTF_USESTDHANDLES;
STARTUPINFO si =
{
.cb = sizeof( STARTUPINFO ),
.dwFlags = STARTF_USESTDHANDLES,
.hStdInput = g_IN_Rd,
.hStdOutput = g_OUT_Wr,
.hStdError = g_OUT_Wr,
.wShowWindow = SW_HIDE,
.dwFlags = STARTF_USESTDHANDLES,
};
CreateProcess( NULL, (char*)cmdline, NULL, NULL, true, CREATE_NO_WINDOW , NULL, NULL, &si, &pi );
cmdline_copy = malloc( wcslen( cmdline ) * sizeof( *cmdline_copy ));
CloseHandle( g_OUT_Wr );
CloseHandle( g_IN_Wr );
if( !CreateProcessW( NULL, cmdline_copy, NULL, NULL, true, CREATE_NO_WINDOW, NULL, NULL, &si, &pi ))
goto err;
WaitForSingleObject( pi.hProcess, 500 );
bSuccess = ReadFile( g_OUT_Rd, buffer, BUFSIZE, &dwRead, NULL );
buffer[BUFSIZE-1] = 0;
TerminateProcess( pi.hProcess, 0 );
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
err:
CloseHandle( g_IN_Wr );
CloseHandle( g_OUT_Wr );
CloseHandle( g_IN_Rd );
CloseHandle( g_OUT_Rd );
free( cmdline_copy );
return bSuccess;
}
static int ID_ProcessWMIC( bloomfilter_t *value, const char *cmdline )
static int ID_ProcessWMIC( bloomfilter_t *value, const wchar_t *cmdline )
{
char buffer[BUFSIZE], token[BUFSIZE], *pbuf;
int count = 0;
if( !ID_RunWMIC( buffer, cmdline ) )
if( !ID_RunWMIC( buffer, cmdline ))
return 0;
pbuf = COM_ParseFile( buffer, token, sizeof( token )); // Header
while( pbuf = COM_ParseFile( pbuf, token, sizeof( token ) ) )
while( pbuf = COM_ParseFile( pbuf, token, sizeof( token )))
{
if( !ID_VerifyHEX( token ) )
if( !ID_VerifyHEX( token ))
continue;
*value |= BloomFilter_ProcessStr( token );
count ++;
count++;
}
return count;
}
static int ID_CheckWMIC( bloomfilter_t value, const char *cmdline )
static int ID_CheckWMIC( bloomfilter_t value, const wchar_t *cmdline )
{
char buffer[BUFSIZE], token[BUFSIZE], *pbuf;
int count = 0;
if( !ID_RunWMIC( buffer, cmdline ) )
if( !ID_RunWMIC( buffer, cmdline ))
return 0;
pbuf = COM_ParseFile( buffer, token, sizeof( token )); // Header
while( pbuf = COM_ParseFile( pbuf, token, sizeof( token ) ) )
while( pbuf = COM_ParseFile( pbuf, token, sizeof( token )))
{
bloomfilter_t filter;
if( !ID_VerifyHEX( token ) )
if( !ID_VerifyHEX( token ))
continue;
filter = BloomFilter_ProcessStr( token );
@@ -487,6 +505,10 @@ static int ID_CheckWMIC( bloomfilter_t value, const char *cmdline )
char *IOS_GetUDID( void );
#endif
#if XASH_PSVITA
int PSVita_GetPSID( char *buf, const size_t buflen );
#endif
static bloomfilter_t ID_GenerateRawId( void )
{
bloomfilter_t value = 0;
@@ -508,14 +530,22 @@ static bloomfilter_t ID_GenerateRawId( void )
count += ID_ProcessNetDevices( &value );
#endif
#if XASH_WIN32
count += ID_ProcessWMIC( &value, "wmic path win32_physicalmedia get SerialNumber " );
count += ID_ProcessWMIC( &value, "wmic bios get serialnumber " );
count += ID_ProcessWMIC( &value, L"wmic path win32_physicalmedia get SerialNumber " );
count += ID_ProcessWMIC( &value, L"wmic bios get serialnumber " );
#endif
#if XASH_IOS
{
value |= BloomFilter_ProcessStr(IOS_GetUDID());
count ++;
}
#endif
#if XASH_PSVITA
{
char data[16];
PSVita_GetPSID( data, sizeof( data ));
value |= BloomFilter_Process( data, sizeof( data ));
count ++;
}
#endif
return value;
}
@@ -544,8 +574,8 @@ static uint ID_CheckRawId( bloomfilter_t filter )
#endif
#if XASH_WIN32
count += ID_CheckWMIC( filter, "wmic path win32_physicalmedia get SerialNumber" );
count += ID_CheckWMIC( filter, "wmic bios get serialnumber" );
count += ID_CheckWMIC( filter, L"wmic path win32_physicalmedia get SerialNumber" );
count += ID_CheckWMIC( filter, L"wmic bios get serialnumber" );
#endif
#if XASH_IOS
@@ -555,6 +585,15 @@ static uint ID_CheckRawId( bloomfilter_t filter )
value = 0;
}
#endif
#if XASH_PSVITA
{
char data[16];
PSVita_GetPSID( data, sizeof( data ));
value = BloomFilter_Process( data, sizeof( data ));
count += (filter & value) == value;
value = 0;
}
#endif
#if 0
Msg( "%s: %d\n", __func__, count );
#endif
@@ -590,25 +629,9 @@ static void ID_Check( void )
const char *ID_GetMD5( void )
{
if( id_customid[0] )
return id_customid;
return id_md5;
}
/*
===============
ID_SetCustomClientID
===============
*/
void GAME_EXPORT ID_SetCustomClientID( const char *id )
{
if( !id )
return;
Q_strncpy( id_customid, id, sizeof( id_customid ) );
}
void ID_Init( void )
{
MD5Context_t hash = { 0 };
@@ -632,7 +655,7 @@ void ID_Init( void )
#elif XASH_WIN32
{
CHAR szBuf[MAX_PATH];
ID_GetKeyData( HKEY_CURRENT_USER, "Software\\Xash3D\\", "xash_id", szBuf, MAX_PATH );
ID_GetKeyData( HKEY_CURRENT_USER, "Software\\"XASH_ENGINE_NAME"\\", "xash_id", szBuf, MAX_PATH );
sscanf(szBuf, "%016"PRIX64, &id);
id ^= SYSTEM_XOR_MASK;
@@ -686,7 +709,7 @@ void ID_Init( void )
{
CHAR Buf[MAX_PATH];
sprintf( Buf, "%016"PRIX64, id^SYSTEM_XOR_MASK );
ID_SetKeyData( HKEY_CURRENT_USER, "Software\\Xash3D\\", REG_SZ, "xash_id", Buf, Q_strlen(Buf) );
ID_SetKeyData( HKEY_CURRENT_USER, "Software\\"XASH_ENGINE_NAME"\\", REG_SZ, "xash_id", Buf, Q_strlen(Buf) );
}
#else
{

View File

@@ -43,7 +43,6 @@ static struct joy_axis_s
short val;
short prevval;
} joyaxis[MAX_AXES] = { 0 };
static byte currentbinding; // add posibility to remap keys, to place it in joykeys[]
static qboolean joy_initialized;
static CVAR_DEFINE_AUTO( joy_pitch, "100.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "joystick pitch sensitivity" );
@@ -60,9 +59,9 @@ static CVAR_DEFINE_AUTO( joy_pitch_deadzone, DEFAULT_JOY_DEADZONE, FCVAR_ARCHIVE
static CVAR_DEFINE_AUTO( joy_yaw_deadzone, DEFAULT_JOY_DEADZONE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "yaw axis deadzone. Value from 0 to 32767" );
static CVAR_DEFINE_AUTO( joy_axis_binding, "sfpyrl", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "axis hardware id to engine inner axis binding, "
"s - side, f - forward, y - yaw, p - pitch, r - left trigger, l - right trigger" );
static CVAR_DEFINE_AUTO( joy_found, "0", FCVAR_READ_ONLY, "is joystick is connected" );
static CVAR_DEFINE_AUTO( joy_index, "0", FCVAR_READ_ONLY, "current active joystick" );
CVAR_DEFINE_AUTO( joy_enable, "1", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enable joystick" );
static CVAR_DEFINE_AUTO( joy_have_gyro, "0", FCVAR_READ_ONLY, "tells whether current active gamepad has gyroscope or not" );
static CVAR_DEFINE_AUTO( joy_calibrated, "0", FCVAR_READ_ONLY, "tells whether current active gamepad gyroscope has been calibrated or not" );
/*
============
@@ -71,7 +70,30 @@ Joy_IsActive
*/
qboolean Joy_IsActive( void )
{
return joy_found.value && joy_enable.value;
return joy_enable.value;
}
/*
===========
Joy_SetCapabilities
===========
*/
void Joy_SetCapabilities( qboolean have_gyro )
{
Cvar_FullSet( joy_have_gyro.name, have_gyro ? "1" : "0", joy_have_gyro.flags );
}
/*
===========
Joy_SetCalibrationState
===========
*/
void Joy_SetCalibrationState( joy_calibration_state_t state )
{
if( (int)joy_calibrated.value == state )
return;
Cvar_FullSet( joy_calibrated.name, va( "%d", state ), joy_calibrated.flags );
}
/*
@@ -81,7 +103,7 @@ Joy_HatMotionEvent
DPad events
============
*/
void Joy_HatMotionEvent( byte hat, byte value )
static void Joy_HatMotionEvent( int value )
{
struct
{
@@ -96,9 +118,6 @@ void Joy_HatMotionEvent( byte hat, byte value )
};
int i;
if( !joy_found.value )
return;
for( i = 0; i < ARRAYSIZE( keys ); i++ )
{
if( value & keys[i].mask )
@@ -225,7 +244,7 @@ static void Joy_ProcessStick( const engineAxis_t engineAxis, short value )
val |= Joy_GetHatValueForAxis( JOY_AXIS_SIDE );
val |= Joy_GetHatValueForAxis( JOY_AXIS_FWD );
Joy_HatMotionEvent( 0, val );
Joy_HatMotionEvent( val );
}
}
@@ -236,23 +255,9 @@ Joy_AxisMotionEvent
Axis events
=============
*/
void Joy_AxisMotionEvent( byte axis, short value )
void Joy_AxisMotionEvent( engineAxis_t engineAxis, short value )
{
if( !joy_found.value )
return;
if( axis >= MAX_AXES )
{
Con_Reportf( "Only 6 axes is supported\n" );
return;
}
Joy_KnownAxisMotionEvent( joyaxesmap[axis], value );
}
void Joy_KnownAxisMotionEvent( engineAxis_t engineAxis, short value )
{
if( engineAxis == JOY_AXIS_NULL )
if( engineAxis >= JOY_AXIS_NULL )
return;
if( value == joyaxis[engineAxis].val )
@@ -266,66 +271,14 @@ void Joy_KnownAxisMotionEvent( engineAxis_t engineAxis, short value )
/*
=============
Joy_BallMotionEvent
Joy_GyroEvent
Trackball events. UNDONE
Gyroscope events
=============
*/
void Joy_BallMotionEvent( byte ball, short xrel, short yrel )
void Joy_GyroEvent( vec3_t data )
{
//if( !joy_found.value )
// return;
}
/*
=============
Joy_ButtonEvent
Button events
=============
*/
void Joy_ButtonEvent( byte button, byte down )
{
if( !joy_found.value )
return;
// generic game button code.
if( button > 32 )
{
int origbutton = button;
button = ( button & 31 ) + K_AUX1;
Con_Reportf( "Only 32 joybuttons is supported, converting %i button ID to %s\n", origbutton, Key_KeynumToString( button ) );
}
else button += K_AUX1;
Key_Event( button, down );
}
/*
=============
Joy_RemoveEvent
Called when joystick is removed. For future expansion
=============
*/
void Joy_RemoveEvent( void )
{
if( joy_found.value )
Cvar_FullSet( "joy_found", "0", FCVAR_READ_ONLY );
}
/*
=============
Joy_RemoveEvent
Called when joystick is removed. For future expansion
=============
*/
void Joy_AddEvent( void )
{
if( joy_enable.value && !joy_found.value )
Cvar_FullSet( "joy_found", "1", FCVAR_READ_ONLY );
}
/*
@@ -364,14 +317,19 @@ void Joy_FinalizeMove( float *fw, float *side, float *dpitch, float *dyaw )
*fw -= joy_forward.value * (float)joyaxis[JOY_AXIS_FWD ].val/(float)SHRT_MAX; // must be form -1.0 to 1.0
*side += joy_side.value * (float)joyaxis[JOY_AXIS_SIDE].val/(float)SHRT_MAX;
#if !defined(XASH_SDL)
*dpitch += joy_pitch.value * (float)joyaxis[JOY_AXIS_PITCH].val/(float)SHRT_MAX * host.realframetime; // abs axis rotate is frametime related
*dyaw -= joy_yaw.value * (float)joyaxis[JOY_AXIS_YAW ].val/(float)SHRT_MAX * host.realframetime;
#else
// HACKHACK: SDL have inverted look axis.
*dpitch -= joy_pitch.value * (float)joyaxis[JOY_AXIS_PITCH].val/(float)SHRT_MAX * host.realframetime;
*dyaw += joy_yaw.value * (float)joyaxis[JOY_AXIS_YAW ].val/(float)SHRT_MAX * host.realframetime;
#endif
}
static void Joy_CalibrateGyro_f( void )
{
if( !joy_have_gyro.value )
{
Con_Printf( "Current active gamepad doesn't have gyroscope\n" );
return;
}
Platform_CalibrateGamepadGyro();
}
/*
@@ -383,6 +341,8 @@ Main init procedure
*/
void Joy_Init( void )
{
Cmd_AddRestrictedCommand( "joy_calibrate_gyro", Joy_CalibrateGyro_f, "calibrate gamepad gyroscope. You must to put gamepad on stationary surface" );
Cvar_RegisterVariable( &joy_pitch );
Cvar_RegisterVariable( &joy_yaw );
Cvar_RegisterVariable( &joy_side );
@@ -402,11 +362,9 @@ void Joy_Init( void )
Cvar_RegisterVariable( &joy_yaw_deadzone );
Cvar_RegisterVariable( &joy_axis_binding );
Cvar_RegisterVariable( &joy_found );
// we doesn't loaded config.cfg yet, so this cvar is not archive.
// change by +set joy_index in cmdline
Cvar_RegisterVariable( &joy_index );
Cvar_RegisterVariable( &joy_have_gyro );
Cvar_RegisterVariable( &joy_calibrated );
Cvar_RegisterVariable( &joy_enable );
// renamed from -nojoy to -noenginejoy to not conflict with
@@ -417,7 +375,7 @@ void Joy_Init( void )
return;
}
Cvar_FullSet( "joy_found", va( "%d", Platform_JoyInit( joy_index.value )), FCVAR_READ_ONLY );
Platform_JoyInit();
joy_initialized = true;
}
@@ -431,8 +389,5 @@ Shutdown joystick code
*/
void Joy_Shutdown( void )
{
if( joy_initialized )
{
Cvar_FullSet( "joy_found", 0, FCVAR_READ_ONLY );
}
Platform_JoyShutdown();
}

File diff suppressed because it is too large Load Diff

View File

@@ -13,16 +13,17 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#if XASH_SDL == 2
#include <SDL.h>
#elif XASH_SDL == 3
#include <SDL3/SDL.h>
#endif
#include "common.h"
#include "input.h"
#include "client.h"
#include "vgui_draw.h"
#include "cursor_type.h"
#if XASH_SDL
#include <SDL.h>
#endif
#include "platform/platform.h"
void* in_mousecursor;
@@ -205,50 +206,58 @@ void IN_ToggleClientMouse( int newstate, int oldstate )
}
}
static void IN_SetRelativeMouseMode( qboolean set, qboolean verbose )
void IN_SetRelativeMouseMode( qboolean set )
{
static qboolean s_bRawInput;
qboolean verbose = m_grab_debug.value ? true : false;
if( set && !s_bRawInput )
{
#if XASH_SDL == 2
#if XASH_SDL >= 2
SDL_GetRelativeMouseState( NULL, NULL );
#if XASH_SDL == 2
SDL_SetRelativeMouseMode( SDL_TRUE );
#endif
#else // XASH_SDL != 2
SDL_SetWindowRelativeMouseMode( host.hWnd, true );
#endif // XASH_SDL != 2
#endif // XASH_SDL >= 2
s_bRawInput = true;
if( verbose )
Con_Printf( "%s: true\n", __func__ );
}
else if( !set && s_bRawInput )
{
#if XASH_SDL == 2
#if XASH_SDL >= 2
SDL_GetRelativeMouseState( NULL, NULL );
#if XASH_SDL == 2
SDL_SetRelativeMouseMode( SDL_FALSE );
#endif
#else // XASH_SDL != 2
SDL_SetWindowRelativeMouseMode( host.hWnd, false );
#endif // XASH_SDL != 2
#endif // XASH_SDL >= 2
s_bRawInput = false;
if( verbose )
Con_Printf( "%s: false\n", __func__ );
}
}
static void IN_SetMouseGrab( qboolean set, qboolean verbose )
void IN_SetMouseGrab( qboolean set )
{
static qboolean s_bMouseGrab;
qboolean verbose = m_grab_debug.value ? true : false;
if( set && !s_bMouseGrab )
{
#if XASH_SDL
SDL_SetWindowGrab( host.hWnd, SDL_TRUE );
#endif
Platform_SetMouseGrab( true );
s_bMouseGrab = true;
if( verbose )
Con_Printf( "%s: true\n", __func__ );
}
else if( !set && s_bMouseGrab )
{
#if XASH_SDL
SDL_SetWindowGrab( host.hWnd, SDL_FALSE );
#endif
Platform_SetMouseGrab( false );
s_bMouseGrab = false;
if( verbose )
@@ -258,7 +267,7 @@ static void IN_SetMouseGrab( qboolean set, qboolean verbose )
static void IN_CheckMouseState( qboolean active )
{
qboolean use_raw_input, verbose;
qboolean use_raw_input;
#if XASH_WIN32
use_raw_input = ( m_rawinput.value && clgame.client_dll_uses_sdl ) || clgame.dllFuncs.pfnLookEvent != NULL;
@@ -266,20 +275,18 @@ static void IN_CheckMouseState( qboolean active )
use_raw_input = true; // always use SDL code
#endif
verbose = m_grab_debug.value ? true : false;
if( m_ignore.value )
active = false;
if( active && use_raw_input && !host.mouse_visible && cls.state == ca_active )
IN_SetRelativeMouseMode( true, verbose );
IN_SetRelativeMouseMode( true );
else
IN_SetRelativeMouseMode( false, verbose );
IN_SetRelativeMouseMode( false );
if( active && !host.mouse_visible && cls.state == ca_active )
IN_SetMouseGrab( true, verbose );
IN_SetMouseGrab( true );
else
IN_SetMouseGrab( false, verbose );
IN_SetMouseGrab( false );
}
/*
@@ -332,7 +339,7 @@ static void IN_MouseMove( void )
if( !in_mouseinitialized )
return;
if( Touch_Emulated( ))
if( Touch_WantVisibleCursor( ))
{
// touch emulation overrides all input
Touch_KeyEvent( 0, 0 );
@@ -363,7 +370,7 @@ void IN_MouseEvent( int key, int down )
else ClearBits( in_mstate, BIT( key ));
// touch emulation overrides all input
if( Touch_Emulated( ))
if( Touch_WantVisibleCursor( ))
{
Touch_KeyEvent( K_MOUSE1 + key, down );
}

View File

@@ -46,6 +46,9 @@ uint IN_CollectInputDevices( void );
void IN_LockInputDevices( qboolean lock );
void IN_EngineAppendMove( float frametime, usercmd_t *cmd, qboolean active );
void IN_SetRelativeMouseMode( qboolean set );
void IN_SetMouseGrab( qboolean set );
extern convar_t m_yaw;
extern convar_t m_pitch;
//
@@ -74,7 +77,6 @@ void Touch_ResetDefaultButtons( void );
int IN_TouchEvent( touchEventType type, int fingerID, float x, float y, float dx, float dy );
void Touch_KeyEvent( int key, int down );
qboolean Touch_WantVisibleCursor( void );
qboolean Touch_Emulated( void );
void Touch_NotifyResize( void );
//
@@ -104,18 +106,21 @@ typedef enum engineAxis_e
JOY_AXIS_NULL
} engineAxis_t;
typedef enum joy_calibration_state_s
{
JOY_NOT_CALIBRATED = 0,
JOY_CALIBRATING,
JOY_FAILED_TO_CALIBRATE,
JOY_CALIBRATED
} joy_calibration_state_t;
qboolean Joy_IsActive( void );
void Joy_HatMotionEvent( byte hat, byte value );
void Joy_AxisMotionEvent( byte axis, short value );
void Joy_KnownAxisMotionEvent( engineAxis_t engineAxis, short value );
void Joy_BallMotionEvent( byte ball, short xrel, short yrel );
void Joy_ButtonEvent( byte button, byte down );
void Joy_AddEvent( void );
void Joy_RemoveEvent( void );
void Joy_SetCapabilities( qboolean have_gyro );
void Joy_SetCalibrationState( joy_calibration_state_t state );
void Joy_AxisMotionEvent( engineAxis_t engineAxis, short value );
void Joy_GyroEvent( vec3_t data );
void Joy_FinalizeMove( float *fw, float *side, float *dpitch, float *dyaw );
void Joy_Init( void );
void Joy_Shutdown( void );
void Joy_EnableTextInput(qboolean enable, qboolean force);
#endif//INPUT_H

View File

@@ -51,7 +51,7 @@ static const keyname_t keynames[] =
{"CTRL", K_CTRL, "+attack" },
{"SHIFT", K_SHIFT, "+speed" },
{"CAPSLOCK", K_CAPSLOCK, "" },
{"SCROLLOCK", K_SCROLLOCK, "" },
{"SCROLLOCK", K_SCROLLLOCK, "" },
{"F1", K_F1, "cmd help" },
{"F2", K_F2, "menu_savegame" },
{"F3", K_F3, "menu_loadgame" },
@@ -215,7 +215,7 @@ const char *Key_KeynumToString( int keynum )
return "<OUT OF RANGE>";
// check for printable ascii (don't use quote)
if( keynum > 32 && keynum < 127 && keynum != '"' && keynum != ';' && keynum != K_SCROLLOCK )
if( keynum > 32 && keynum < 127 && keynum != '"' && keynum != ';' && keynum != K_SCROLLLOCK )
{
tinystr[0] = keynum;
tinystr[1] = 0;
@@ -726,18 +726,8 @@ void GAME_EXPORT Key_Event( int key, int down )
return; // handled in client.dll
}
break;
case key_message:
Key_Message( key );
return;
case key_console:
if( cls.state == ca_active && !cl.background )
Key_SetKeyDest( key_game );
else UI_SetActiveMenu( true );
return;
case key_menu:
UI_KeyEvent( key, true );
return;
default: return;
default:
break;
}
}
@@ -861,7 +851,9 @@ void GAME_EXPORT Key_ClearStates( void )
for( i = 0; i < 256; i++ )
{
if( keys[i].down && i < K_MOUSE1 && i > K_MOUSE5 )
if( i >= K_MOUSE1 && i <= K_MOUSE5 )
IN_MouseEvent( i - K_MOUSE1, false );
else
Key_Event( i, false );
keys[i].down = 0;
@@ -869,9 +861,6 @@ void GAME_EXPORT Key_ClearStates( void )
keys[i].gamedown = 0;
}
for( i = K_MOUSE1; i < K_MOUSE5; i++ ) // from K_MOUSE1 to K_MOUSE5
IN_MouseEvent( i - K_MOUSE1, false );
if( clgame.hInstance )
clgame.dllFuncs.IN_ClearStates();
}
@@ -1108,7 +1097,7 @@ static qboolean OSK_KeyEvent( int key, int down )
/*
=============
Joy_EnableTextInput
OSK_EnableTextInput
Enables built-in IME
=============

View File

@@ -433,6 +433,8 @@ static const ref_api_t gEngfuncs =
&clgame.drawFuncs,
&g_fsapi,
R_GetWindowHandle,
};
static void R_UnloadProgs( void )
@@ -572,7 +574,7 @@ static void R_GetRendererName( char *dest, size_t size, const char *opt )
}
}
static qboolean R_LoadRenderer( const char *refopt )
static qboolean R_LoadRenderer( const char *refopt, qboolean quiet )
{
string refdll;
@@ -583,7 +585,8 @@ static qboolean R_LoadRenderer( const char *refopt )
if( !R_LoadProgs( refdll ))
{
R_Shutdown();
Sys_Warn( S_ERROR "Can't initialize %s renderer!\n", refdll );
if( !quiet )
Sys_Warn( S_ERROR "Can't initialize %s renderer!\n", refdll );
return false;
}
@@ -622,7 +625,7 @@ static void SetFullscreenModeFromCommandLine( void )
static void R_CollectRendererNames( void )
{
// ordering is important!
static const char *shortNames[] =
static const char *short_names[] =
{
#if XASH_REF_GL_ENABLED
"gl",
@@ -645,7 +648,7 @@ static void R_CollectRendererNames( void )
};
// ordering is important here too!
static const char *readableNames[ARRAYSIZE( shortNames )] =
static const char *long_names[ARRAYSIZE( short_names )] =
{
#if XASH_REF_GL_ENABLED
"OpenGL",
@@ -667,9 +670,9 @@ static void R_CollectRendererNames( void )
#endif
};
ref.numRenderers = ARRAYSIZE( shortNames );
ref.shortNames = shortNames;
ref.readableNames = readableNames;
ref.num_renderers = ARRAYSIZE( short_names );
ref.short_names = short_names;
ref.long_names = long_names;
}
qboolean R_Init( void )
@@ -730,28 +733,44 @@ qboolean R_Init( void )
requested_cvar[0] = 0;
if( Sys_GetParmFromCmdLine( "-ref", requested_cmdline ))
success = R_LoadRenderer( requested_cmdline );
success = R_LoadRenderer( requested_cmdline, false );
if( !success && COM_CheckString( r_refdll.string ) && Q_stricmp( requested_cmdline, r_refdll.string ))
{
Q_strncpy( requested_cvar, r_refdll.string, sizeof( requested_cvar ));
success = R_LoadRenderer( requested_cvar );
// do not show scary messages to user if renderer set in config cannot be loaded
// as game data could be copied from one platform to another, where this renderer
// might not be supported (ref_gl on Android for example)
success = R_LoadRenderer( requested_cvar, !host_developer.value );
}
if( !success )
{
int i;
for( i = 0; i < ref.numRenderers && !success; i++ )
for( i = 0; i < ref.num_renderers; i++ )
{
// skip renderer that was requested but failed to load
if( !Q_strcmp( requested_cmdline, ref.shortNames[i] ))
if( !Q_strcmp( requested_cmdline, ref.short_names[i] ))
continue;
if( !Q_strcmp( requested_cvar, ref.shortNames[i] ))
if( !Q_strcmp( requested_cvar, ref.short_names[i] ))
continue;
success = R_LoadRenderer( ref.shortNames[i] );
// do not show bruteforcing attempts, however, warn user about falling back
// to software mode
if( !Q_strcmp( "soft", ref.short_names[i] ) && !host_developer.value )
Sys_Warn( "Can't initialize any hardware accelerated renderer. Falling back to software rendering...\n" );
success = R_LoadRenderer( ref.short_names[i], !host_developer.value );
if( success )
{
// remember last valid renderer
Cvar_DirectSet( &r_refdll, ref.short_names[i] );
break;
}
}
}

View File

@@ -24,12 +24,12 @@ struct ref_state_s
{
HINSTANCE hInstance;
qboolean initialized;
int numRenderers;
int num_renderers;
ref_interface_t dllFuncs;
// depends on build configuration
const char **shortNames;
const char **readableNames;
const char **short_names;
const char **long_names;
};
extern struct ref_state_s ref;

View File

@@ -312,7 +312,7 @@ static int DLY_Init( int idelay, float delay )
cur = &rgsxdly[idelay];
cur->cdelaysamplesmax = ((int)(delay * idsp_dma_speed) << sxhires) + 1;
cur->lpdelayline = (int *)Z_Calloc( cur->cdelaysamplesmax * sizeof( int ));
cur->lpdelayline = (int *)Mem_Calloc( sndpool, cur->cdelaysamplesmax * sizeof( int ));
cur->xfade = 0;
// init modulation

View File

@@ -107,17 +107,18 @@ S_CreateDefaultSound
*/
static wavdata_t *S_CreateDefaultSound( void )
{
wavdata_t *sc;
wavdata_t *sc;
uint samples = SOUND_DMA_SPEED;
uint channels = 1;
uint width = 2;
size_t size = samples * width * channels;
sc = Mem_Calloc( sndpool, sizeof( wavdata_t ));
sc->width = 2;
sc->channels = 1;
sc->loopStart = 0;
sc = Mem_Calloc( sndpool, sizeof( wavdata_t ) + size );
sc->width = width;
sc->channels = channels;
sc->rate = SOUND_DMA_SPEED;
sc->samples = SOUND_DMA_SPEED;
sc->size = sc->samples * sc->width * sc->channels;
sc->buffer = Mem_Calloc( sndpool, sc->size );
sc->samples = samples;
sc->size = size;
return sc;
}

View File

@@ -1207,86 +1207,6 @@ void S_RawSamples( uint samples, uint rate, word width, word channels, const byt
S_RawEntSamples( entnum, samples, rate, width, channels, data, snd_vol );
}
/*
===================
S_PositionedRawSamples
===================
*/
void S_StreamAviSamples( void *Avi, int entnum, float fvol, float attn, float synctime )
{
int bufferSamples;
int fileSamples;
byte raw[MAX_RAW_SAMPLES];
float duration = 0.0f;
int r, fileBytes;
rawchan_t *ch = NULL;
if( !dma.initialized || s_listener.paused || !CL_IsInGame( ))
return;
if( entnum < 0 || entnum >= GI->max_edicts )
return;
if( !( ch = S_FindRawChannel( entnum, true )))
return;
if( ch->sound_info.rate == 0 )
{
if( !AVI_GetAudioInfo( Avi, &ch->sound_info ))
return; // no audiotrack
}
ch->master_vol = bound( 0, fvol * 255, 255 );
ch->dist_mult = (attn / SND_CLIP_DISTANCE);
// see how many samples should be copied into the raw buffer
if( ch->s_rawend < soundtime )
ch->s_rawend = soundtime;
// position is changed, synchronization is lost etc
if( fabs( ch->oldtime - synctime ) > s_mixahead.value )
ch->sound_info.loopStart = AVI_TimeToSoundPosition( Avi, synctime * 1000 );
ch->oldtime = synctime; // keep actual time
while( ch->s_rawend < soundtime + ch->max_samples )
{
wavdata_t *info = &ch->sound_info;
bufferSamples = ch->max_samples - (ch->s_rawend - soundtime);
// decide how much data needs to be read from the file
fileSamples = bufferSamples * ((float)info->rate / SOUND_DMA_SPEED );
if( fileSamples <= 1 ) return; // no more samples need
// our max buffer size
fileBytes = fileSamples * ( info->width * info->channels );
if( fileBytes > sizeof( raw ))
{
fileBytes = sizeof( raw );
fileSamples = fileBytes / ( info->width * info->channels );
}
// read audio stream
r = AVI_GetAudioChunk( Avi, raw, info->loopStart, fileBytes );
info->loopStart += r; // advance play position
if( r < fileBytes )
{
fileBytes = r;
fileSamples = r / ( info->width * info->channels );
}
if( r > 0 )
{
// add to raw buffer
ch->s_rawend = S_RawSamplesStereo( ch->rawsamples, ch->s_rawend, ch->max_samples,
fileSamples, info->rate, info->width, info->channels, raw );
}
else break; // no more samples for this frame
}
}
/*
===================
S_FreeIdleRawChannels
@@ -1954,14 +1874,15 @@ qboolean S_Init( void )
Cmd_AddCommand( "spk", S_SayReliable_f, "reliable play a specified sententce" );
Cmd_AddCommand( "speak", S_Say_f, "playing a specified sententce" );
sndpool = Mem_AllocPool( "Sound Zone" );
dma.backendName = "None";
if( !SNDDMA_Init( ) )
if( !SNDDMA_Init( ))
{
Con_Printf( "Audio: sound system can't be initialized\n" );
Mem_FreePool( &sndpool );
return false;
}
sndpool = Mem_AllocPool( "Sound Zone" );
soundtime = 0;
paintedtime = 0;

View File

@@ -16,6 +16,7 @@ GNU General Public License for more details.
#include "common.h"
#include "sound.h"
#include "client.h"
#include "soundlib.h"
static bg_track_t s_bgTrack;
static musicfade_t musicfade; // controlled by game dlls
@@ -212,7 +213,7 @@ void S_StreamBackgroundTrack( void )
while( ch->s_rawend < soundtime + ch->max_samples )
{
wavdata_t *info = FS_StreamInfo( s_bgTrack.stream );
const stream_t *info = s_bgTrack.stream;
bufferSamples = ch->max_samples - (ch->s_rawend - soundtime);

View File

@@ -557,7 +557,7 @@ static void VOX_ReadSentenceFile_( byte *buf, fs_offset_t size )
int index = cszrawsentences;
int size = strlen( name ) + strlen( value ) + 2;
rgpszrawsentence[index] = Mem_Malloc( host.mempool, size );
rgpszrawsentence[index] = Mem_Malloc( sndpool, size );
memcpy( rgpszrawsentence[index], name, size );
rgpszrawsentence[index][size - 1] = 0;
cszrawsentences++;

View File

@@ -114,7 +114,6 @@ typedef struct rawchan_s
vec3_t origin; // only use if fixed_origin is set
volatile uint s_rawend;
float oldtime; // catch time jumps
wavdata_t sound_info; // advance play position
size_t max_samples; // buffer length
portable_samplepair_t rawsamples[]; // variable sized
} rawchan_t;
@@ -171,6 +170,8 @@ typedef struct
int source; // may be game, menu, etc
} bg_track_t;
typedef int sound_t;
//====================================================================
#define MAX_DYNAMIC_CHANNELS (60 + NUM_AMBIENTS)

View File

@@ -29,17 +29,20 @@ static void Sound_Reset( void )
static MALLOC_LIKE( FS_FreeSound, 1 ) wavdata_t *SoundPack( void )
{
wavdata_t *pack = Mem_Calloc( host.soundpool, sizeof( wavdata_t ));
wavdata_t *pack = Mem_Malloc( host.soundpool, sizeof( *pack ) + sound.size );
pack->buffer = sound.wav;
pack->width = sound.width;
pack->rate = sound.rate;
pack->type = sound.type;
pack->size = sound.size;
pack->loopStart = sound.loopstart;
pack->samples = sound.samples;
pack->channels = sound.channels;
pack->type = sound.type;
pack->flags = sound.flags;
pack->rate = sound.rate;
pack->width = sound.width;
pack->channels = sound.channels;
memcpy( pack->buffer, sound.wav, sound.size );
Mem_Free( sound.wav );
sound.wav = NULL;
return pack;
}
@@ -53,12 +56,10 @@ loading and unpack to wav any known sound
*/
wavdata_t *FS_LoadSound( const char *filename, const byte *buffer, size_t size )
{
const char *ext = COM_FileExtension( filename );
string path, loadname;
qboolean anyformat = true;
fs_offset_t filesize = 0;
const loadwavfmt_t *format;
byte *f;
const char *ext = COM_FileExtension( filename );
string loadname;
qboolean anyformat = true;
const loadwavfmt_t *format;
Sound_Reset(); // clear old sounddata
Q_strncpy( loadname, filename, sizeof( loadname ));
@@ -67,7 +68,7 @@ wavdata_t *FS_LoadSound( const char *filename, const byte *buffer, size_t size )
{
// we needs to compare file extension with list of supported formats
// and be sure what is real extension, not a filename with dot
for( format = sound.loadformats; format && format->formatstring; format++ )
for( format = sound.loadformats; format && format->ext; format++ )
{
if( !Q_stricmp( format->ext, ext ))
{
@@ -83,28 +84,42 @@ wavdata_t *FS_LoadSound( const char *filename, const byte *buffer, size_t size )
goto load_internal;
// now try all the formats in the selected list
for( format = sound.loadformats; format && format->formatstring; format++)
for( format = sound.loadformats; format && format->ext; format++)
{
if( anyformat || !Q_stricmp( ext, format->ext ))
{
Q_snprintf( path, sizeof( path ),
format->formatstring, loadname, "", format->ext );
qboolean success = false;
fs_offset_t filesize = 0;
byte *f;
string path;
Q_snprintf( path, sizeof( path ), DEFAULT_SOUNDPATH "%s.%s", loadname, format->ext );
f = FS_LoadFile( path, &filesize, false );
if( f && filesize > 0 )
{
if( format->loadfunc( path, f, filesize ))
{
Mem_Free(f); // release buffer
return SoundPack(); // loaded
}
else Mem_Free(f); // release buffer
success = format->loadfunc( path, f, filesize );
Mem_Free( f ); // release buffer
}
if( success )
return SoundPack(); // loaded
Q_snprintf( path, sizeof( path ), "%s.%s", loadname, format->ext );
f = FS_LoadFile( path, &filesize, false );
if( f && filesize > 0 )
{
success = format->loadfunc( path, f, filesize );
Mem_Free( f ); // release buffer
}
if( success )
return SoundPack();
}
}
load_internal:
for( format = sound.loadformats; format && format->formatstring; format++ )
for( format = sound.loadformats; format && format->ext; format++ )
{
if( anyformat || !Q_stricmp( ext, format->ext ))
{
@@ -132,7 +147,6 @@ free WAV buffer
void FS_FreeSound( wavdata_t *pack )
{
if( !pack ) return;
if( pack->buffer ) Mem_Free( pack->buffer );
Mem_Free( pack );
}
@@ -146,7 +160,7 @@ open and reading basic info from sound stream
stream_t *FS_OpenStream( const char *filename )
{
const char *ext = COM_FileExtension( filename );
string path, loadname;
string loadname;
qboolean anyformat = true;
const streamfmt_t *format;
stream_t *stream = NULL;
@@ -158,7 +172,7 @@ stream_t *FS_OpenStream( const char *filename )
{
// we needs to compare file extension with list of supported formats
// and be sure what is real extension, not a filename with dot
for( format = sound.streamformat; format && format->formatstring; format++ )
for( format = sound.streamformat; format && format->ext; format++ )
{
if( !Q_stricmp( format->ext, ext ))
{
@@ -170,12 +184,13 @@ stream_t *FS_OpenStream( const char *filename )
}
// now try all the formats in the selected list
for( format = sound.streamformat; format && format->formatstring; format++)
for( format = sound.streamformat; format && format->ext; format++)
{
if( anyformat || !Q_stricmp( ext, format->ext ))
{
Q_snprintf( path, sizeof( path ),
format->formatstring, loadname, "", format->ext );
string path;
Q_snprintf( path, sizeof( path ), "%s.%s", loadname, format->ext );
if(( stream = format->openfunc( path )) != NULL )
{
@@ -199,33 +214,6 @@ stream_t *FS_OpenStream( const char *filename )
return stream;
}
/*
================
FS_StreamInfo
get basic stream info
================
*/
wavdata_t *FS_StreamInfo( stream_t *stream )
{
static wavdata_t info;
if( !stream ) return NULL;
// fill structure
info.loopStart = 0;
info.rate = stream->rate;
info.width = stream->width;
info.channels = stream->channels;
info.flags = SOUND_STREAM;
info.size = stream->size;
info.buffer = NULL;
info.samples = 0; // not actual for streams
info.type = stream->type;
return &info;
}
/*
================
FS_ReadStream

View File

@@ -17,7 +17,7 @@ GNU General Public License for more details.
#include "base_cmd.h"
#include "cdll_int.h"
#define HASH_SIZE 128 // 128 * 4 * 4 == 2048 bytes
#define HASH_SIZE 64 // 64 * 4 * 4 == 1024 bytes
typedef struct base_command_hashmap_s base_command_hashmap_t;
@@ -26,10 +26,11 @@ struct base_command_hashmap_s
base_command_t *basecmd; // base command: cvar, alias or command
base_command_hashmap_t *next;
base_command_type_e type; // type for faster searching
char name[1]; // key for searching
char name[]; // key for searching
};
static base_command_hashmap_t *hashed_cmds[HASH_SIZE];
static poolhandle_t basecmd_pool;
#define BaseCmd_HashKey( x ) COM_HashKey( name, HASH_SIZE )
@@ -42,11 +43,27 @@ Find base command in bucket
*/
static base_command_hashmap_t *BaseCmd_FindInBucket( base_command_hashmap_t *bucket, base_command_type_e type, const char *name )
{
base_command_hashmap_t *i = bucket;
for( ; i && ( i->type != type || Q_stricmp( name, i->name ) ); // filter out
i = i->next );
base_command_hashmap_t *i;
return i;
for( i = bucket; i != NULL; i = i->next )
{
int cmp;
if( i->type != type )
continue;
cmp = Q_stricmp( i->name, name );
if( cmp < 0 )
continue;
if( cmp > 0 )
break;
return i;
}
return NULL;
}
/*
@@ -90,27 +107,31 @@ void BaseCmd_FindAll( const char *name, base_command_t **cmd, base_command_t **a
base_command_hashmap_t *base = BaseCmd_GetBucket( name );
base_command_hashmap_t *i = base;
ASSERT( cmd && alias && cvar );
*cmd = *alias = *cvar = NULL;
for( ; i; i = i->next )
{
if( !Q_stricmp( i->name, name ) )
int cmp = Q_stricmp( i->name, name );
if( cmp < 0 )
continue;
if( cmp > 0 )
break;
switch( i->type )
{
switch( i->type )
{
case HM_CMD:
*cmd = i->basecmd;
break;
case HM_CMDALIAS:
*alias = i->basecmd;
break;
case HM_CVAR:
*cvar = i->basecmd;
break;
default: break;
}
case HM_CMD:
*cmd = i->basecmd;
break;
case HM_CMDALIAS:
*alias = i->basecmd;
break;
case HM_CVAR:
*cvar = i->basecmd;
break;
default:
break;
}
}
}
@@ -128,14 +149,14 @@ void BaseCmd_Insert( base_command_type_e type, base_command_t *basecmd, const ch
uint hash = BaseCmd_HashKey( name );
size_t len = Q_strlen( name );
elem = Z_Malloc( sizeof( base_command_hashmap_t ) + len );
elem = Mem_Malloc( basecmd_pool, sizeof( base_command_hashmap_t ) + len + 1 );
elem->basecmd = basecmd;
elem->type = type;
Q_strncpy( elem->name, name, len + 1 );
// link the variable in alphanumerical order
for( cur = NULL, find = hashed_cmds[hash];
find && Q_strcmp( find->name, elem->name ) < 0;
find && Q_stricmp( find->name, elem->name ) < 0;
cur = find, find = find->next );
if( cur ) cur->next = elem;
@@ -156,9 +177,23 @@ void BaseCmd_Remove( base_command_type_e type, const char *name )
uint hash = BaseCmd_HashKey( name );
base_command_hashmap_t *i, *prev;
for( prev = NULL, i = hashed_cmds[hash]; i &&
( Q_strcmp( i->name, name ) || i->type != type); // filter out
prev = i, i = i->next );
for( prev = NULL, i = hashed_cmds[hash]; i != NULL; prev = i, i = i->next )
{
int cmp;
if( i->type != type )
continue;
cmp = Q_stricmp( i->name, name );
if( cmp < 0 )
continue;
if( cmp > 0 )
i = NULL;
break;
}
if( !i )
{
@@ -183,9 +218,15 @@ initialize base command hashmap system
*/
void BaseCmd_Init( void )
{
basecmd_pool = Mem_AllocPool( "BaseCmd" );
memset( hashed_cmds, 0, sizeof( hashed_cmds ) );
}
void BaseCmd_Shutdown( void )
{
Mem_FreePool( &basecmd_pool );
}
/*
============
BaseCmd_Stats_f

View File

@@ -32,6 +32,7 @@ typedef enum base_command_type
typedef void base_command_t;
void BaseCmd_Init( void );
void BaseCmd_Shutdown( void );
base_command_t *BaseCmd_Find( base_command_type_e type, const char *name );
void BaseCmd_FindAll( const char *name,
base_command_t **cmd, base_command_t **alias, base_command_t **cvar );

View File

@@ -46,6 +46,7 @@ static cmdalias_t *cmd_alias;
static uint cmd_condition;
static int cmd_condlevel;
static qboolean cmd_currentCommandIsPrivileged;
static poolhandle_t cmd_pool;
static void Cmd_ExecuteStringWithPrivilegeCheck( const char *text, qboolean isPrivileged );
@@ -432,7 +433,7 @@ static void Cmd_Alias_f( void )
{
if( !Q_strcmp( s, a->name ))
{
Z_Free( a->value );
Mem_Free( a->value );
break;
}
}
@@ -441,7 +442,7 @@ static void Cmd_Alias_f( void )
{
cmdalias_t *cur, *prev;
a = Z_Malloc( sizeof( cmdalias_t ));
a = Mem_Malloc( cmd_pool, sizeof( cmdalias_t ));
Q_strncpy( a->name, s, sizeof( a->name ));
@@ -469,7 +470,7 @@ static void Cmd_Alias_f( void )
}
Q_strncat( cmd, "\n", sizeof( cmd ));
a->value = copystring( cmd );
a->value = copystringpool( cmd_pool, cmd );
}
/*
@@ -529,7 +530,7 @@ struct cmd_s
char *name;
xcommand_t function;
int flags;
char *desc;
char desc[];
};
static int cmd_argc;
@@ -636,7 +637,7 @@ void Cmd_TokenizeString( const char *text )
// clear the args from the last string
for( i = 0; i < cmd_argc; i++ )
Z_Free( cmd_argv[i] );
Mem_Free( cmd_argv[i] );
cmd_argc = 0; // clear previous args
cmd_args = NULL;
@@ -670,7 +671,7 @@ void Cmd_TokenizeString( const char *text )
if( cmd_argc < MAX_CMD_TOKENS )
{
cmd_argv[cmd_argc] = copystring( cmd_token );
cmd_argv[cmd_argc] = copystringpool( cmd_pool, cmd_token );
cmd_argc++;
}
}
@@ -683,7 +684,8 @@ Cmd_AddCommandEx
*/
int Cmd_AddCommandEx( const char *cmd_name, xcommand_t function, const char *cmd_desc, int iFlags, const char *funcname )
{
cmd_t *cmd, *cur, *prev;
cmd_t *cmd, *cur, *prev;
size_t desc_len;
if( !COM_CheckString( cmd_name ))
{
@@ -707,8 +709,8 @@ int Cmd_AddCommandEx( const char *cmd_name, xcommand_t function, const char *cmd
// unfortunately, we lose original command this way
if( FBitSet( cmd->flags, CMD_OVERRIDABLE ))
{
Mem_Free( cmd->desc );
cmd->desc = copystring( cmd_desc );
desc_len = Q_strlen( cmd->desc ) + 1;
Q_strncpy( cmd->desc, cmd_desc, desc_len );
cmd->function = function;
cmd->flags = iFlags;
@@ -723,9 +725,10 @@ int Cmd_AddCommandEx( const char *cmd_name, xcommand_t function, const char *cmd
}
// use a small malloc to avoid zone fragmentation
cmd = Z_Malloc( sizeof( cmd_t ) );
cmd->name = copystring( cmd_name );
cmd->desc = copystring( cmd_desc );
desc_len = Q_strlen( cmd_desc ) + 1;
cmd = Mem_Malloc( cmd_pool, sizeof( cmd_t ) + desc_len );
cmd->name = copystringpool( cmd_pool, cmd_name );
Q_strncpy( cmd->desc, cmd_desc, desc_len );
cmd->function = function;
cmd->flags = iFlags;
@@ -772,9 +775,6 @@ void GAME_EXPORT Cmd_RemoveCommand( const char *cmd_name )
if( cmd->name )
Mem_Free( cmd->name );
if( cmd->desc )
Mem_Free( cmd->desc );
Mem_Free( cmd );
return;
}
@@ -1202,7 +1202,6 @@ void Cmd_Unlink( int group )
*prev = cmd->next;
if( cmd->name ) Mem_Free( cmd->name );
if( cmd->desc ) Mem_Free( cmd->desc );
Mem_Free( cmd );
count++;
@@ -1340,6 +1339,7 @@ Cmd_Init
*/
void Cmd_Init( void )
{
cmd_pool = Mem_AllocPool( "Console Commands" );
cmd_functions = NULL;
cmd_condition = 0;
cmd_alias = NULL;
@@ -1366,6 +1366,11 @@ void Cmd_Init( void )
#endif
}
void Cmd_Shutdown( void )
{
Mem_FreePool( &cmd_pool );
}
#if XASH_ENGINE_TESTS
#include "tests.h"

View File

@@ -251,7 +251,7 @@ static void LZSS_BuildHash( lzss_state_t *state, const byte *source )
{
lzss_list_t *list;
lzss_node_t *node;
unsigned int targetindex = (uint)source & ( state->window_size - 1 );
unsigned int targetindex = (uintptr_t)source & ( state->window_size - 1 );
node = &state->hash_node[targetindex];
@@ -900,7 +900,7 @@ float GAME_EXPORT pfnTime( void )
qboolean COM_IsSafeFileToDownload( const char *filename )
{
char lwrfilename[4096];
const char *first, *last;
const char *last;
const char *ext;
size_t len;
int i;
@@ -934,25 +934,27 @@ qboolean COM_IsSafeFileToDownload( const char *filename )
return true;
}
for( i = 0; i < len; i++ )
{
if( !isprint( filename[i] ))
return false;
}
Q_strnlwr( filename, lwrfilename, sizeof( lwrfilename ));
ext = COM_FileExtension( lwrfilename );
if( Q_strpbrk( lwrfilename, "\\:~" ) || Q_strstr( lwrfilename, ".." ) )
if( Q_strpbrk( lwrfilename, "\\:~" ) || Q_strstr( lwrfilename, ".." ))
return false;
if( lwrfilename[0] == '/' )
return false;
first = Q_strchr( lwrfilename, '.' );
last = Q_strrchr( lwrfilename, '.' );
if( first == NULL || last == NULL )
if( last == NULL )
return false;
if( first != last )
return false;
if( Q_strlen( first ) != 4 )
if( Q_strlen( last ) != 4 )
return false;
for( i = 0; i < ARRAYSIZE( file_exts ); i++ )
@@ -1131,6 +1133,7 @@ void Test_RunCommon( void )
{
Msg( "Checking COM_IsSafeFileToDownload...\n" );
TASSERT_EQi( COM_IsSafeFileToDownload( "models/bsg_props/[hl-lab.ru]bush.mdl" ), true );
TASSERT_EQi( COM_IsSafeFileToDownload( "!MD5AAB5E8B307672DA86FBD10AC302BC732" ), true );
TASSERT_EQi( COM_IsSafeFileToDownload( "!MD56f1ffd8c96bd64c9c27955309f6ecfe6" ), false );
TASSERT_EQi( COM_IsSafeFileToDownload( "!MD5AAB5E8B307672DA86FBD10AC302B.exe" ), false );

View File

@@ -76,23 +76,14 @@ XASH SPECIFIC - sort of hack that works only in Xash3D not in GoldSrc
#define HACKS_RELATED_HLMODS // some HL-mods works differently under Xash and can't be fixed without some hacks at least at current time
enum
enum dev_level_e
{
DEV_NONE = 0,
DEV_NORMAL,
DEV_EXTENDED
};
enum
{
D_INFO = 1, // "-dev 1", shows various system messages
D_WARN, // "-dev 2", shows not critical system warnings
D_ERROR, // "-dev 3", shows critical warnings
D_REPORT, // "-dev 4", special case for game reports
D_NOTE // "-dev 5", show system notifications for engine developers
};
typedef enum
typedef enum instance_e
{
HOST_NORMAL, // listen server, singleplayer
HOST_DEDICATED,
@@ -108,14 +99,14 @@ typedef enum
#include "com_model.h"
#include "com_strings.h"
#include "crtlib.h"
#include "cvar.h"
#include "con_nprint.h"
#include "crclib.h"
#include "ref_api.h"
#define FSCALLBACK_OVERRIDE_OPEN
#define FSCALLBACK_OVERRIDE_LOADFILE
#define FSCALLBACK_OVERRIDE_MALLOC_LIKE
#include "fscallback.h"
#include "cvar.h"
#include "con_nprint.h"
#include "crclib.h"
#include "ref_api.h"
// PERFORMANCE INFO
#define MIN_FPS 20.0f // host minimum fps value for maxfps.
@@ -146,6 +137,11 @@ typedef enum
#define MAX_STATIC_ENTITIES 32 // static entities that moved on the client when level is spawn
#endif
#define MAX_SERVERINFO_STRING 512 // server handles too many settings. expand to 1024?
#define MAX_PRINT_MSG 8192 // how many symbols can handle single call of Con_Printf or Con_DPrintf
#define MAX_TOKEN 2048 // parse token length
#define MAX_USERMSG_LENGTH 2048 // don't modify it's relies on a client-side definitions
#define GameState (&host.game)
#define FORCE_DRAW_VERSION_TIME 5.0 // draw version for 5 seconds
@@ -171,6 +167,11 @@ extern convar_t cl_filterstuffcmd;
extern convar_t rcon_password;
extern convar_t hpk_custom_file;
extern convar_t con_gamemaps;
extern convar_t fs_mount_lv;
extern convar_t fs_mount_hd;
extern convar_t fs_mount_addon;
extern convar_t fs_mount_l10n;
extern convar_t ui_language; // historically used for UI, but now controls mounted localization directory
#define Mod_AllowMaterials() ( host_allow_materials.value != 0.0f && !FBitSet( host.features, ENGINE_DISABLE_HDTEXTURES ))
@@ -189,7 +190,7 @@ GAMEINFO stuff
internal shared gameinfo structure (readonly for engine parts)
========================================================================
*/
typedef enum
typedef enum host_status_e
{
HOST_INIT = 0, // initalize operations
HOST_FRAME, // host running
@@ -200,7 +201,7 @@ typedef enum
HOST_CRASHED // an exception handler called
} host_status_t;
typedef enum
typedef enum host_state_e
{
STATE_RUNFRAME = 0,
STATE_LOAD_LEVEL,
@@ -209,7 +210,7 @@ typedef enum
STATE_GAME_SHUTDOWN,
} host_state_t;
typedef struct
typedef struct game_status_e
{
host_state_t curstate;
host_state_t nextstate;
@@ -220,7 +221,7 @@ typedef struct
qboolean newGame; // unload the server.dll before start a new map
} game_status_t;
typedef enum
typedef enum keydest_e
{
key_console = 0,
key_game,
@@ -228,7 +229,7 @@ typedef enum
key_message
} keydest_t;
typedef enum
typedef enum rdtype_e
{
RD_NONE = 0,
RD_CLIENT,
@@ -238,7 +239,7 @@ typedef enum
#include "net_ws.h"
// console field
typedef struct
typedef struct field_e
{
string buffer;
int cursor;
@@ -256,7 +257,7 @@ typedef struct host_redirect_s
int lines;
} host_redirect_t;
typedef struct
typedef struct soundlist_e
{
char name[MAX_QPATH];
short entnum;
@@ -297,7 +298,7 @@ typedef struct host_parm_s
host_status_t status; // global host state
game_status_t game; // game manager
uint type; // running at
instance_t type; // running at
poolhandle_t mempool; // static mempool for misc allocations
poolhandle_t imagepool; // imagelib mempool
poolhandle_t soundpool; // soundlib mempool
@@ -341,7 +342,6 @@ typedef struct host_parm_s
qboolean apply_game_config; // when true apply only to game cvars and ignore all other commands
qboolean apply_opengl_config; // when true apply only to opengl cvars and ignore all other commands
qboolean config_executed; // a bit who indicated was config.cfg already executed e.g. from valve.rc
qboolean crashed; // set to true if crashed
#if XASH_DLL_LOADER
qboolean enabledll;
#endif
@@ -357,6 +357,7 @@ typedef struct host_parm_s
int window_center_y;
string gamedll;
string clientlib;
string menulib;
} host_parm_t;
extern host_parm_t host;
@@ -414,6 +415,8 @@ byte *FS_LoadFile( const char *path, fs_offset_t *filesizeptr, qboolean gamediro
MALLOC_LIKE( _Mem_Free, 1 ) WARN_UNUSED_RESULT;
byte *FS_LoadDirectFile( const char *path, fs_offset_t *filesizeptr )
MALLOC_LIKE( _Mem_Free, 1 ) WARN_UNUSED_RESULT;
void FS_Rescan_f( void );
void FS_CheckConfig( void );
//
// cmd.c
@@ -432,6 +435,7 @@ int Cmd_Argc( void );
const char *Cmd_Args( void ) RETURNS_NONNULL;
const char *Cmd_Argv( int arg ) RETURNS_NONNULL;
void Cmd_Init( void );
void Cmd_Shutdown( void );
void Cmd_Unlink( int group );
int Cmd_AddCommandEx( const char *cmd_name, xcommand_t function, const char *cmd_desc, int flags, const char *funcname );
@@ -490,7 +494,7 @@ internal sound format
typically expanded to wav buffer
========================================================================
*/
typedef enum
typedef enum sndformat_e
{
WF_UNKNOWN = 0,
WF_PCMDATA,
@@ -501,7 +505,7 @@ typedef enum
} sndformat_t;
// wavdata output flags
typedef enum
typedef enum sndFlags_e
{
// wavdata->flags
SOUND_LOOPED = BIT( 0 ), // this is looped sound (contain cue markers)
@@ -511,29 +515,29 @@ typedef enum
SOUND_RESAMPLE = BIT( 12 ), // resample sound to specified rate
} sndFlags_t;
typedef struct
typedef struct wavdata_s
{
word rate; // num samples per second (e.g. 11025 - 11 khz)
byte width; // resolution - bum bits divided by 8 (8 bit is 1, 16 bit is 2)
byte channels; // num channels (1 - mono, 2 - stereo)
size_t size; // for bounds checking
uint loopStart; // offset at this point sound will be looping while playing more than only once
uint samples; // total samplecount in wav
uint type; // compression type
uint flags; // misc sound flags
byte *buffer; // sound buffer
size_t size; // for bounds checking
word rate; // num samples per second (e.g. 11025 - 11 khz)
byte width; // resolution - bum bits divided by 8 (8 bit is 1, 16 bit is 2)
byte channels; // num channels (1 - mono, 2 - stereo)
byte buffer[]; // sound buffer
} wavdata_t;
//
// soundlib
//
typedef struct stream_s stream_t;
void Sound_Init( void );
void Sound_Shutdown( void );
void FS_FreeSound( wavdata_t *pack );
void FS_FreeStream( stream_t *stream );
wavdata_t *FS_LoadSound( const char *filename, const byte *buffer, size_t size ) MALLOC_LIKE( FS_FreeSound, 1 ) WARN_UNUSED_RESULT;
stream_t *FS_OpenStream( const char *filename ) MALLOC_LIKE( FS_FreeStream, 1 ) WARN_UNUSED_RESULT;
wavdata_t *FS_StreamInfo( stream_t *stream );
int FS_ReadStream( stream_t *stream, int bytes, void *buffer );
int FS_SetStreamPos( stream_t *stream, int newpos );
int FS_GetStreamPos( stream_t *stream );
@@ -628,6 +632,7 @@ int pfnNumberOfEntities( void );
int pfnIsInGame( void );
float pfnTime( void );
#define copystring( s ) _copystring( host.mempool, s, __FILE__, __LINE__ )
#define copystringpool( pool, s ) _copystring( pool, s, __FILE__, __LINE__ )
#define SV_CopyString( s ) _copystring( svgame.stringspool, s, __FILE__, __LINE__ )
#define freestring( s ) if( s != NULL ) { Mem_Free( s ); s = NULL; }
char *_copystring( poolhandle_t mempool, const char *s, const char *filename, int fileline );
@@ -678,6 +683,7 @@ int CSCR_WriteGameCVars( file_t *cfg, const char *scriptfilename );
//
// hpak.c
//
const char *COM_ResourceTypeFromIndex( int index );
void HPAK_Init( void );
qboolean HPAK_GetDataPointer( const char *filename, struct resource_s *pRes, byte **buffer, int *size );
qboolean HPAK_ResourceForHash( const char *filename, byte *hash, struct resource_s *pRes );
@@ -725,7 +731,7 @@ qboolean UI_CreditsActive( void );
int CL_GetMaxClients( void );
#else
static inline qboolean CL_Initialized( void ) { return false; }
static inline qboolean CL_IsInGame( void ) { return false; }
static inline qboolean CL_IsInGame( void ) { return true; } // always true for dedicated
static inline qboolean CL_IsInConsole( void ) { return false; }
static inline qboolean CL_IsIntermission( void ) { return false; }
static inline qboolean CL_DisableVisibility( void ) { return false; }
@@ -784,7 +790,7 @@ void Con_NPrintf( int idx, const char *fmt, ... ) FORMAT_CHECK( 2 );
void Con_NXPrintf( con_nprint_t *info, const char *fmt, ... ) FORMAT_CHECK( 2 );
void UI_NPrintf( int idx, const char *fmt, ... ) FORMAT_CHECK( 2 );
void UI_NXPrintf( con_nprint_t *info, const char *fmt, ... ) FORMAT_CHECK( 2 );
const char *Info_ValueForKey( const char *s, const char *key );
const char *Info_ValueForKey( const char *s, const char *key ) RETURNS_NONNULL NONNULL;
void Info_RemovePrefixedKeys( char *start, char prefix );
qboolean Info_RemoveKey( char *s, const char *key );
qboolean Info_SetValueForKey( char *s, const char *key, const char *value, int maxsize );
@@ -867,13 +873,6 @@ void V_CheckGamma( void );
void V_CheckGammaEnd( void );
intptr_t V_GetGammaPtr( int parm );
//
// identification.c
//
void ID_Init( void );
const char *ID_GetMD5( void );
void GAME_EXPORT ID_SetCustomClientID( const char *id );
//
// masterlist.c
//

View File

@@ -498,7 +498,6 @@ static qboolean Cmd_GetSoundList( const char *s, char *completedname, int length
return true;
}
#if !XASH_DEDICATED
/*
=====================================
Cmd_GetItemsList
@@ -508,6 +507,7 @@ Prints or complete item classname (weapons only)
*/
static qboolean Cmd_GetItemsList( const char *s, char *completedname, int length )
{
#if !XASH_DEDICATED
search_t *t;
string matchbuf;
int i, numitems;
@@ -521,7 +521,7 @@ static qboolean Cmd_GetItemsList( const char *s, char *completedname, int length
Q_strncpy( completedname, matchbuf, length );
if( t->numfilenames == 1 ) return true;
for(i = 0, numitems = 0; i < t->numfilenames; i++)
for( i = 0, numitems = 0; i < t->numfilenames; i++ )
{
if( Q_stricmp( COM_FileExtension( t->filenames[i] ), "txt" ))
continue;
@@ -544,6 +544,8 @@ static qboolean Cmd_GetItemsList( const char *s, char *completedname, int length
}
}
return true;
#endif // !XASH_DEDICATED
return false;
}
/*
@@ -555,6 +557,7 @@ Autocomplete for bind command
*/
static qboolean Cmd_GetKeysList( const char *s, char *completedname, int length )
{
#if !XASH_DEDICATED
size_t i, numkeys;
string keys[256];
string matchbuf;
@@ -595,8 +598,9 @@ static qboolean Cmd_GetKeysList( const char *s, char *completedname, int length
}
return true;
#endif // !XASH_DEDICATED
return false;
}
#endif // XASH_DEDICATED
/*
===============
@@ -604,13 +608,20 @@ Con_AddCommandToList
===============
*/
static void Con_AddCommandToList( const char *s, const char *unused1, const char *unused2, void *_autocompleteList )
static void Con_AddCommandToList( const char *s, const char *value, const void *ptoggle, void *_autocompleteList )
{
con_autocomplete_t *list = (con_autocomplete_t*)_autocompleteList;
qboolean toggle = ptoggle != NULL && *(qboolean *)ptoggle;
if( *s == '@' ) return; // never show system cvars or cmds
if( list->matchCount >= CON_MAXCMDS ) return; // list is full
if( toggle )
{
if( Q_strcmp( value, "0" ) && Q_strcmp( value, "1" ))
return; // exclude non-toggable cvars
}
if( Q_strnicmp( s, list->completionString, Q_strlen( list->completionString ) ) )
return; // no match
@@ -634,13 +645,11 @@ Cmd_GetCommandsList
Autocomplete for bind command
=====================================
*/
static qboolean Cmd_GetCommandsList( const char *s, char *completedname, int length )
static qboolean Cmd_GetCommandsAndCvarsList( const char *s, char *completedname, int length, qboolean cmds, qboolean cvars, qboolean toggle )
{
size_t i;
string matchbuf;
con_autocomplete_t list; // local autocomplete list
memset( &list, 0, sizeof( list ));
con_autocomplete_t list = { 0 }; // local autocomplete list
list.completionString = s;
@@ -652,8 +661,16 @@ static qboolean Cmd_GetCommandsList( const char *s, char *completedname, int len
return false;
// find matching commands and variables
Cmd_LookupCmds( NULL, &list, (setpair_t)Con_AddCommandToList );
Cvar_LookupVars( 0, NULL, &list, (setpair_t)Con_AddCommandToList );
if( cvars )
{
Cvar_LookupVars( 0, &toggle, &list, (setpair_t)Con_AddCommandToList );
}
if( cmds )
{
toggle = false;
Cmd_LookupCmds( &toggle, &list, (setpair_t)Con_AddCommandToList );
}
if( !list.matchCount ) return false;
Q_strncpy( matchbuf, list.cmds[0], sizeof( matchbuf ));
@@ -669,7 +686,7 @@ static qboolean Cmd_GetCommandsList( const char *s, char *completedname, int len
Con_Printf( "%16s\n", matchbuf );
}
Con_Printf( "\n^3 %i commands found.\n", list.matchCount );
Con_Printf( "\n^3 %i %s found.\n", list.matchCount, cmds ? "commands" : "variables" );
if( completedname && length )
{
@@ -691,6 +708,30 @@ static qboolean Cmd_GetCommandsList( const char *s, char *completedname, int len
return true;
}
/*
=====================================
Cmd_GetCommandsList
Autocomplete for bind command
=====================================
*/
static qboolean Cmd_GetCommandsList( const char *s, char *completedname, int length )
{
return Cmd_GetCommandsAndCvarsList( s, completedname, length, true, true, false );
}
/*
=====================================
Cmd_GetCvarList
Autocomplete for bind command
=====================================
*/
static qboolean Cmd_GetCvarsList( const char *s, char *completedname, int length )
{
qboolean toggle = !Q_stricmp( Cmd_Argv( 0 ), "toggle" );
return Cmd_GetCommandsAndCvarsList( s, completedname, length, false, true, toggle );
}
/*
=====================================
@@ -1010,36 +1051,38 @@ int GAME_EXPORT Cmd_CheckMapsList( int fRefresh )
return Cmd_CheckMapsList_R( fRefresh, true );
}
// keep this sorted
static const autocomplete_list_t cmd_list[] =
{
{ "map_background", 1, Cmd_GetMapList },
{ "bind", 1, Cmd_GetKeysList },
{ "bind", 2, Cmd_GetCommandsList },
{ "cd", 1, Cmd_GetCDList },
{ "changelevel2", 1, Cmd_GetMapList },
{ "changelevel", 1, Cmd_GetMapList },
{ "playdemo", 1, Cmd_GetDemoList, },
{ "timedemo", 1, Cmd_GetDemoList, },
{ "listdemo", 1, Cmd_GetDemoList, },
{ "playvol", 1, Cmd_GetSoundList },
{ "hpkval", 1, Cmd_GetCustomList },
{ "hpklist", 1, Cmd_GetCustomList },
{ "hpkextract", 1, Cmd_GetCustomList },
{ "entpatch", 1, Cmd_GetMapList },
{ "music", 1, Cmd_GetMusicList, },
{ "movie", 1, Cmd_GetMovieList },
{ "exec", 1, Cmd_GetConfigList },
#if !XASH_DEDICATED
{ "give", 1, Cmd_GetItemsList },
{ "drop", 1, Cmd_GetItemsList },
{ "bind", 1, Cmd_GetKeysList },
{ "unbind", 1, Cmd_GetKeysList },
{ "bind", 2, Cmd_GetCommandsList },
#endif
{ "entpatch", 1, Cmd_GetMapList },
{ "exec", 1, Cmd_GetConfigList },
{ "game", 1, Cmd_GetGamesList },
{ "save", 1, Cmd_GetSavesList },
{ "give", 1, Cmd_GetItemsList },
{ "hpkextract", 1, Cmd_GetCustomList },
{ "hpklist", 1, Cmd_GetCustomList },
{ "hpkval", 1, Cmd_GetCustomList },
{ "listdemo", 1, Cmd_GetDemoList, },
{ "load", 1, Cmd_GetSavesList },
{ "play", 1, Cmd_GetSoundList },
{ "map", 1, Cmd_GetMapList },
{ "cd", 1, Cmd_GetCDList },
{ "map_background", 1, Cmd_GetMapList },
{ "movie", 1, Cmd_GetMovieList },
{ "mp3", 1, Cmd_GetCDList },
{ "music", 1, Cmd_GetMusicList, },
{ "play", 1, Cmd_GetSoundList },
{ "playdemo", 1, Cmd_GetDemoList, },
{ "playvol", 1, Cmd_GetSoundList },
{ "reset", 1, Cmd_GetCvarsList },
{ "save", 1, Cmd_GetSavesList },
{ "set", 1, Cmd_GetCvarsList },
{ "timedemo", 1, Cmd_GetDemoList },
{ "toggle", 1, Cmd_GetCvarsList },
{ "unbind", 1, Cmd_GetKeysList },
};
/*
@@ -1160,6 +1203,7 @@ void Con_CompleteCommand( field_t *field )
{
field_t temp;
string filename;
qboolean toggle = false;
qboolean nextcmd;
int i;
@@ -1194,8 +1238,8 @@ void Con_CompleteCommand( field_t *field )
con.shortestMatch[0] = 0;
// find matching commands and variables
Cmd_LookupCmds( NULL, &con, (setpair_t)Con_AddCommandToList );
Cvar_LookupVars( 0, NULL, &con, (setpair_t)Con_AddCommandToList );
Cmd_LookupCmds( &toggle, &con, (setpair_t)Con_AddCommandToList );
Cvar_LookupVars( 0, &toggle, &con, (setpair_t)Con_AddCommandToList );
if( !con.matchCount ) return; // no matches

View File

@@ -19,6 +19,7 @@ GNU General Public License for more details.
#include "eiface.h" // ARRAYSIZE
static convar_t *cvar_vars = NULL; // head of list
static poolhandle_t cvar_pool;
CVAR_DEFINE_AUTO( cmd_scripting, "0", FCVAR_ARCHIVE|FCVAR_PRIVILEGED, "enable simple condition checking and variable operations" );
typedef struct cvar_filter_quirks_s
@@ -152,7 +153,7 @@ static qboolean Cvar_UpdateInfo( convar_t *var, const char *value, qboolean noti
{
if( FBitSet( var->flags, FCVAR_USERINFO ))
{
if ( Host_IsDedicated() )
if( Host_IsDedicated() )
{
// g-cont. this is a very strange behavior...
char *info = SV_Serverinfo();
@@ -431,8 +432,9 @@ convar_t *Cvar_Get( const char *name, const char *value, int flags, const char *
if( COM_CheckStringEmpty( var->desc ))
{
// directly set value
freestring( var->string );
var->string = copystring( value );
size_t len = Q_strlen( value ) + 1;
var->string = Mem_Realloc( cvar_pool, var->string, len );
Q_strncpy( var->string, value, len );
var->value = Q_atof( var->string );
SetBits( var->flags, flags );
@@ -448,22 +450,25 @@ convar_t *Cvar_Get( const char *name, const char *value, int flags, const char *
if( FBitSet( var->flags, FCVAR_ALLOCATED ) && Q_strcmp( var_desc, var->desc ))
{
size_t len = Q_strlen( var_desc ) + 1;
if( !FBitSet( flags, FCVAR_GLCONFIG ))
Con_Reportf( "%s change description from %s to %s\n", var->name, var->desc, var_desc );
// update description if needs
freestring( var->desc );
var->desc = copystring( var_desc );
var->desc = Mem_Realloc( cvar_pool, var->desc, len );
Q_strncpy( var->desc, var_desc, len );
}
return var;
}
// allocate a new cvar
var = Z_Malloc( sizeof( *var ));
var->name = copystring( name );
var->string = copystring( value );
var->def_string = copystring( value );
var->desc = copystring( var_desc );
var = Mem_Malloc( cvar_pool, sizeof( *var ));
var->name = copystringpool( cvar_pool, name );
var->string = copystringpool( cvar_pool, value );
var->def_string = copystringpool( cvar_pool, value );
var->desc = copystringpool( cvar_pool, var_desc );
var->value = Q_atof( var->string );
var->flags = flags|FCVAR_ALLOCATED;
@@ -549,7 +554,7 @@ void Cvar_RegisterVariable( convar_t *var )
if( FBitSet( var->flags, FCVAR_EXTENDED ))
var->def_string = var->string; // just swap pointers
var->string = copystring( var->string );
var->string = copystringpool( cvar_pool, var->string );
var->value = Q_atof( var->string );
// find the supposed position in chain (alphanumerical order)
@@ -601,9 +606,10 @@ Cvar_Set2
static convar_t *Cvar_Set2( const char *var_name, const char *value )
{
convar_t *var;
const char *pszValue;
qboolean dll_variable = false;
qboolean force = false;
const char *fixed_string;
size_t fixed_string_len;
if( !Cvar_ValidateVarName( var_name, false ))
{
@@ -667,19 +673,20 @@ static convar_t *Cvar_Set2( const char *var_name, const char *value )
return var;
}
pszValue = Cvar_ValidateString( var, value );
fixed_string = Cvar_ValidateString( var, value );
// nothing to change
if( !Q_strcmp( pszValue, var->string ))
if( !Q_strcmp( fixed_string, var->string ))
return var;
// fill it cls.userinfo, svs.serverinfo
if( !Cvar_UpdateInfo( var, pszValue, true ))
if( !Cvar_UpdateInfo( var, fixed_string, true ))
return var;
// and finally changed the cvar itself
freestring( var->string );
var->string = copystring( pszValue );
// and finally change the cvar itself
fixed_string_len = Q_strlen( fixed_string ) + 1;
var->string = Mem_Realloc( cvar_pool, var->string, fixed_string_len );
Q_strncpy( var->string, fixed_string, fixed_string_len );
var->value = Q_atof( var->string );
// tell engine about changes
@@ -696,7 +703,8 @@ way to change value for many cvars
*/
void GAME_EXPORT Cvar_DirectSet( convar_t *var, const char *value )
{
const char *pszValue;
const char *fixed_string;
size_t fixed_string_len;
if( unlikely( !var )) return; // ???
@@ -726,19 +734,20 @@ void GAME_EXPORT Cvar_DirectSet( convar_t *var, const char *value )
value = var->def_string; // reset to default value
}
pszValue = Cvar_ValidateString( var, value );
fixed_string = Cvar_ValidateString( var, value );
// nothing to change
if( !Q_strcmp( pszValue, var->string ))
if( !Q_strcmp( fixed_string, var->string ))
return;
// fill it cls.userinfo, svs.serverinfo
if( !Cvar_UpdateInfo( var, pszValue, true ))
if( !Cvar_UpdateInfo( var, fixed_string, true ))
return;
// and finally changed the cvar itself
freestring( var->string );
var->string = copystring( pszValue );
// and finally change the cvar itself
fixed_string_len = Q_strlen( fixed_string ) + 1;
var->string = Mem_Realloc( cvar_pool, var->string, fixed_string_len );
Q_strncpy( var->string, fixed_string, fixed_string_len );
var->value = Q_atof( var->string );
// tell engine about changes
@@ -772,7 +781,8 @@ can set any protected cvars
*/
void Cvar_FullSet( const char *var_name, const char *value, int flags )
{
convar_t *var = Cvar_FindVar( var_name );
convar_t *var = Cvar_FindVar( var_name );
size_t len = Q_strlen( value ) + 1;
if( !var )
{
@@ -780,8 +790,8 @@ void Cvar_FullSet( const char *var_name, const char *value, int flags )
return;
}
freestring( var->string );
var->string = copystring( value );
var->string = Mem_Realloc( cvar_pool, var->string, len );
Q_strncpy( var->string, value, len );
var->value = Q_atof( var->string );
SetBits( var->flags, flags );
@@ -1189,6 +1199,7 @@ static void Cvar_List_f( void )
for( var = cvar_vars; var; var = var->next )
{
char value[MAX_VA_STRING];
char *p;
if( var->name[0] == '@' )
continue; // never shows system cvars
@@ -1196,7 +1207,9 @@ static void Cvar_List_f( void )
if( match && !Q_strnicmpext( match, var->name, matchlen ))
continue;
if( Q_colorstr( var->string ))
p = Q_strchr( var->string, '^' );
if( IsColorString( p ))
Q_snprintf( value, sizeof( value ), "\"%s\"", var->string );
else Q_snprintf( value, sizeof( value ), "\"^2%s^7\"", var->string );
@@ -1257,7 +1270,7 @@ pending_cvar_t *Cvar_PrepareToUnlink( int group )
continue;
namelen = Q_strlen( cv->name ) + 1;
p = Mem_Malloc( host.mempool, sizeof( *list ) + namelen );
p = Mem_Malloc( cvar_pool, sizeof( *list ) + namelen );
p->next = NULL;
p->cv_cur = cv;
p->cv_next = cv->next;
@@ -1333,6 +1346,7 @@ Reads in all archived cvars
*/
void Cvar_Init( void )
{
cvar_pool = Mem_AllocPool( "Console Variables" );
cvar_vars = NULL;
cvar_active_filter_quirks = NULL;
Cvar_RegisterVariable( &cmd_scripting );
@@ -1345,6 +1359,11 @@ void Cvar_Init( void )
Cmd_AddCommand( "cvarlist", Cvar_List_f, "display all console variables beginning with the specified prefix" );
}
void Cvar_Shutdown( void )
{
Mem_FreePool( &cvar_pool );
}
/*
============
Cvar_PostFSInit

View File

@@ -30,6 +30,8 @@ typedef struct pending_cvar_s
char cv_name[];
} pending_cvar_t;
typedef void (*setpair_t)( const char *key, const void *value, const void *buffer, void *numpairs );
cvar_t *Cvar_GetList( void );
#define Cvar_FindVar( name ) Cvar_FindVarExt( name, 0 )
convar_t *Cvar_FindVarExt( const char *var_name, int ignore_group );
@@ -52,6 +54,7 @@ void Cvar_Reset( const char *var_name );
void Cvar_SetCheatState( void );
qboolean Cvar_CommandWithPrivilegeCheck( convar_t *v, qboolean isPrivileged );
void Cvar_Init( void );
void Cvar_Shutdown( void );
void Cvar_PostFSInit( void );
void Cvar_Unlink( int group );

View File

@@ -1,4 +1,4 @@
/*
/*
filesystem.c - game filesystem based on DP fs
Copyright (C) 2003-2006 Mathieu Olivier
Copyright (C) 2000-2007 DarkPlaces contributors
@@ -16,11 +16,23 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#if XASH_SDL == 2
#include <SDL.h> // SDL_GetBasePath
#elif XASH_SDL == 3
#include <SDL3/SDL.h>
#endif
#include <errno.h>
#include "common.h"
#include "library.h"
#include "platform/platform.h"
CVAR_DEFINE_AUTO( fs_mount_hd, "0", FCVAR_ARCHIVE|FCVAR_PRIVILEGED|FCVAR_LATCH, "mount high definition content folder" );
CVAR_DEFINE_AUTO( fs_mount_lv, "0", FCVAR_ARCHIVE|FCVAR_PRIVILEGED|FCVAR_LATCH, "mount low violence models content folder" );
CVAR_DEFINE_AUTO( fs_mount_addon, "0", FCVAR_ARCHIVE|FCVAR_PRIVILEGED|FCVAR_LATCH, "mount addon content folder" );
CVAR_DEFINE_AUTO( fs_mount_l10n, "0", FCVAR_ARCHIVE|FCVAR_PRIVILEGED|FCVAR_LATCH, "mount localization content folder" );
CVAR_DEFINE_AUTO( ui_language, "english", FCVAR_ARCHIVE|FCVAR_PRIVILEGED|FCVAR_LATCH, "selected game language" );
fs_api_t g_fsapi;
fs_globals_t *FI;
@@ -69,9 +81,23 @@ void *FS_GetNativeObject( const char *obj )
return NULL;
}
static void FS_Rescan_f( void )
void FS_Rescan_f( void )
{
FS_Rescan();
uint32_t flags = 0;
// FIXME: VFS shouldn't care about this, allow engine to mount gamedirs
if( fs_mount_lv.value ) SetBits( flags, FS_MOUNT_LV );
if( fs_mount_hd.value ) SetBits( flags, FS_MOUNT_HD );
if( fs_mount_addon.value ) SetBits( flags, FS_MOUNT_ADDON );
if( fs_mount_l10n.value ) SetBits( flags, FS_MOUNT_L10N );
g_fsapi.Rescan( flags, ui_language.string );
ClearBits( fs_mount_lv.flags, FCVAR_CHANGED );
ClearBits( fs_mount_hd.flags, FCVAR_CHANGED );
ClearBits( fs_mount_addon.flags, FCVAR_CHANGED );
ClearBits( fs_mount_l10n.flags, FCVAR_CHANGED );
ClearBits( ui_language.flags, FCVAR_CHANGED );
}
static void FS_ClearPaths_f( void )
@@ -183,14 +209,23 @@ static qboolean FS_DetermineRootDirectory( char *out, size_t size )
#elif XASH_PSVITA
if( PSVita_GetBasePath( out, size ))
return true;
Sys_Error( "couldn't find Xash3D data directory" );
Sys_Error( "couldn't find %s data directory", XASH_ENGINE_NAME );
return false;
#elif ( XASH_SDL == 2 ) && !XASH_NSWITCH // GetBasePath not impl'd in switch-sdl2
#elif ( XASH_SDL >= 2 ) && !XASH_NSWITCH // GetBasePath not impl'd in switch-sdl2
path = SDL_GetBasePath();
#if XASH_APPLE
if( path != NULL && Q_stristr( path, ".app" ))
{
SDL_free((void *)path );
path = SDL_GetPrefPath( NULL, XASH_ENGINE_NAME );
}
#endif
if( path != NULL )
{
Q_strncpy( out, path, size );
SDL_free(( void *)path );
SDL_free((void *)path );
return true;
}
@@ -227,6 +262,12 @@ static qboolean FS_DetermineReadOnlyRootDirectory( char *out, size_t size )
return false;
}
void FS_CheckConfig( void )
{
if( fs_mount_lv.value || fs_mount_hd.value || fs_mount_addon.value || fs_mount_l10n.value )
FS_Rescan_f();
}
/*
================
FS_Init
@@ -279,11 +320,19 @@ void FS_Init( const char *basedir )
Cmd_AddRestrictedCommand( "fs_clearpaths", FS_ClearPaths_f, "clear filesystem search pathes" );
Cmd_AddRestrictedCommand( "fs_make_gameinfo", FS_MakeGameInfo_f, "create gameinfo.txt for current running game" );
Cvar_RegisterVariable( &fs_mount_hd );
Cvar_RegisterVariable( &fs_mount_lv );
Cvar_RegisterVariable( &fs_mount_addon );
Cvar_RegisterVariable( &fs_mount_l10n );
if( !Sys_GetParmFromCmdLine( "-dll", host.gamedll ))
host.gamedll[0] = 0;
if( !Sys_GetParmFromCmdLine( "-clientlib", host.clientlib ))
host.clientlib[0] = 0;
if( !Sys_GetParmFromCmdLine( "-menulib", host.menulib ))
host.menulib[0] = 0;
}
/*

View File

@@ -14,9 +14,6 @@ GNU General Public License for more details.
*/
#include "build.h"
#ifdef XASH_SDL
#include <SDL.h>
#endif // XASH_SDL
#include <stdarg.h> // va_args
#if !XASH_WIN32
#include <unistd.h> // fork
@@ -140,7 +137,8 @@ static void Sys_PrintUsage( const char *exename )
"\nCommon options:\n"
O("-dev [level] ", "set log verbosity 0-2")
O("-log ", "write log to \"engine.log\"")
O("-log [file name] ", "write log to \"engine.log\" or [file name] if specified")
O("-logtime ", "enable writing timestamps to the log file")
O("-nowriteconfig ", "disable config save")
O("-noch ", "disable crashhandler")
#if XASH_WIN32 // !!!!
@@ -176,6 +174,7 @@ static void Sys_PrintUsage( const char *exename )
O("-dll <path> ", "override server DLL path")
#if !XASH_DEDICATED
O("-clientlib <path> ", "override client DLL path")
O("-menulib <path> ", "override menu DLL path")
O("-console ", "run engine with console enabled")
O("-toconsole ", "run engine witn console open")
O("-oldfont ", "enable unused Quake font in Half-Life")
@@ -201,7 +200,6 @@ static void Sys_PrintUsage( const char *exename )
O("-daemonize ", "run engine as a daemon")
#endif
#if XASH_SDL == 2
O("-sdl_joy_old_api ","use SDL legacy joystick API")
O("-sdl_renderer <n> ","use alternative SDL_Renderer for software")
#endif // XASH_SDL
#if XASH_ANDROID && !XASH_SDL
@@ -541,13 +539,6 @@ static void Host_MemStats_f( void )
}
}
static void Host_Minimize_f( void )
{
#ifdef XASH_SDL
if( host.hWnd ) SDL_MinimizeWindow( host.hWnd );
#endif
}
/*
=================
Host_RegisterDecal
@@ -698,17 +689,17 @@ static qboolean Host_Autosleep( double dt, double scale )
static double timewindow; // allocate a time window for sleeps
static int counter; // for debug
static double realsleeptime;
const double sleeptime = sleep * 0.001;
const double sleeptime = sleep * 0.000001;
if( dt < targetframetime * scale )
{
// if we have allocated time window, try to sleep
if( timewindow > realsleeptime )
{
// Platform_Sleep isn't guaranteed to sleep an exact amount of milliseconds
// Platform_Sleep isn't guaranteed to sleep an exact amount of microseconds
// so we measure the real sleep time and use it to decrease the window
double t1 = Sys_DoubleTime(), t2;
Platform_Sleep( sleep ); // in msec!
Platform_NanoSleep( sleep * 1000 ); // in usec!
t2 = Sys_DoubleTime();
realsleeptime = t2 - t1;
@@ -1044,7 +1035,7 @@ static void Host_InitCommon( int argc, char **argv, const char *progname, qboole
}
if( !Sys_CheckParm( "-noch" ))
Sys_SetupCrashHandler();
Sys_SetupCrashHandler( argv[0] );
#if XASH_DLL_LOADER
host.enabledll = !Sys_CheckParm( "-nodll" );
@@ -1131,7 +1122,7 @@ static void Host_InitCommon( int argc, char **argv, const char *progname, qboole
#if XASH_DEDICATED
Platform_SetupSigtermHandling();
#endif
Platform_Init( Host_IsDedicated( ) || developer >= DEV_EXTENDED );
Platform_Init( Host_IsDedicated( ) || developer >= DEV_EXTENDED, basedir );
FS_Init( basedir );
Sys_InitLog();
@@ -1236,6 +1227,14 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
Cvar_Getf( "host_ver", FCVAR_READ_ONLY, "detailed info about this build", "%i " XASH_VERSION " %s %s %s", Q_buildnum(), Q_buildos(), Q_buildarch(), g_buildcommit);
Cvar_Getf( "host_lowmemorymode", FCVAR_READ_ONLY, "indicates if engine compiled for low RAM consumption (0 - normal, 1 - low engine limits, 2 - low protocol limits)", "%i", XASH_LOW_MEMORY );
Cvar_Get( "host_hl25_extended_structs",
#if SUPPORT_HL25_EXTENDED_STRUCTS
"1",
#else
"0",
#endif
FCVAR_READ_ONLY, "indicates if engine was compiled with extended msurface_t struct" );
Mod_Init();
NET_Init();
NET_InitMasters();
@@ -1256,7 +1255,6 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
CL_Init();
HTTP_Init();
ID_Init();
SoundList_Init();
if( Host_IsDedicated( ))
@@ -1271,7 +1269,7 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
Cmd_AddRestrictedCommand( "quit", Sys_Quit_f, "quit the game" );
Cmd_AddRestrictedCommand( "exit", Sys_Quit_f, "quit the game" );
}
else Cmd_AddRestrictedCommand( "minimize", Host_Minimize_f, "minimize main window to tray" );
else Cmd_AddRestrictedCommand( "minimize", Platform_Minimize_f, "minimize main window to tray" );
host.errorframe = 0;
@@ -1312,6 +1310,7 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
Cmd_RemoveCommand( "setgl" );
Cbuf_ExecStuffCmds(); // execute stuffcmds (commandline)
SCR_CheckStartupVids(); // must be last
FS_CheckConfig();
if( Sys_GetParmFromCmdLine( "-timedemo", demoname ))
Cbuf_AddTextf( "timedemo %s\n", demoname );
@@ -1346,7 +1345,7 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
#endif // XASH_ANDROID
// main window message loop
while( !host.crashed )
while( host.status != HOST_CRASHED )
{
newtime = Sys_DoubleTime ();
COM_Frame( newtime - oldtime );
@@ -1400,6 +1399,10 @@ void Host_ShutdownWithReason( const char *reason )
Host_FreeCommon();
Platform_Shutdown();
BaseCmd_Shutdown();
Cmd_Shutdown();
Cvar_Shutdown();
// must be last, console uses this
Mem_FreePool( &host.mempool );

View File

@@ -38,7 +38,7 @@ static void HPAK_MaxSize_f( void )
Con_Printf( S_ERROR "hpk_maxsize is deprecated, use hpk_max_size\n" );
}
static const char *HPAK_TypeFromIndex( int type )
const char *COM_ResourceTypeFromIndex( int type )
{
switch( type )
{
@@ -220,7 +220,7 @@ void HPAK_AddLump( qboolean bUseQueue, const char *name, resource_t *pResource,
if( pResource->nDownloadSize < HPAK_ENTRY_MIN_SIZE || pResource->nDownloadSize > HPAK_ENTRY_MAX_SIZE )
{
Con_Printf( S_ERROR "%s: invalid size %s\n", name, Q_pretifymem( pResource->nDownloadSize, 2 ));
Con_Printf( S_ERROR "%s: invalid size %s\n", name, Q_memprint( pResource->nDownloadSize ));
return;
}
@@ -441,7 +441,7 @@ static qboolean HPAK_Validate( const char *filename, qboolean quiet, qboolean de
if( dataDir[i].disksize < HPAK_ENTRY_MIN_SIZE || dataDir[i].disksize > HPAK_ENTRY_MAX_SIZE )
{
// odd max size
Con_DPrintf( S_ERROR "%s: lump %i has invalid size %s\n", __func__, i, Q_pretifymem( dataDir[i].disksize, 2 ));
Con_DPrintf( S_ERROR "%s: lump %i has invalid size %s\n", __func__, i, Q_memprint( dataDir[i].disksize ));
Mem_Free( dataDir );
FS_Close( f );
if( delete ) FS_Delete( pakname );
@@ -461,8 +461,8 @@ static qboolean HPAK_Validate( const char *filename, qboolean quiet, qboolean de
if( !quiet )
{
Con_Printf( "%i: %s %s %s: ", i, HPAK_TypeFromIndex( pRes->type ),
Q_pretifymem( pRes->nDownloadSize, 2 ), pRes->szFileName );
Con_Printf( "%i: %s %s %s: ", i, COM_ResourceTypeFromIndex( pRes->type ),
Q_memprint( pRes->nDownloadSize ), pRes->szFileName );
}
if( memcmp( md5, pRes->rgucMD5_hash, 0x10 ))
@@ -942,7 +942,7 @@ static void HPAK_List_f( void )
{
entry = &directory.entries[nCurrent];
COM_FileBase( entry->resource.szFileName, lumpname, sizeof( lumpname ));
type = HPAK_TypeFromIndex( entry->resource.type );
type = COM_ResourceTypeFromIndex( entry->resource.type );
size = Q_memprint( entry->resource.nDownloadSize );
Con_Printf( "%i: %10s %s %s\n : %s\n", nCurrent + 1, type, size, lumpname, MD5_Print( entry->resource.rgucMD5_hash ));
@@ -1037,7 +1037,7 @@ static void HPAK_Extract_f( void )
continue;
COM_FileBase( entry->resource.szFileName, lumpname, sizeof( lumpname ) );
type = HPAK_TypeFromIndex( entry->resource.type );
type = COM_ResourceTypeFromIndex( entry->resource.type );
size = Q_memprint( entry->resource.nDownloadSize );
Con_Printf( "Extracting %i: %10s %s %s\n", nCurrent + 1, type, size, lumpname );

View File

@@ -45,7 +45,6 @@ typedef enum
typedef struct loadformat_s
{
const char *formatstring;
const char *ext;
qboolean (*loadfunc)( const char *name, const byte *buffer, fs_offset_t filesize );
image_hint_t hint;
@@ -53,7 +52,6 @@ typedef struct loadformat_s
typedef struct saveformat_s
{
const char *formatstring;
const char *ext;
qboolean (*savefunc)( const char *name, rgbdata_t *pix );
} savepixformat_t;

View File

@@ -211,7 +211,7 @@ static const loadpixformat_t *Image_GetLoadFormatForExtension( const char *ext )
if( !COM_CheckStringEmpty( ext ))
return NULL;
for( format = image.loadformats; format->formatstring; format++ )
for( format = image.loadformats; format->ext; format++ )
{
if( !Q_stricmp( ext, format->ext ))
return format;
@@ -237,7 +237,7 @@ static qboolean Image_ProbeLoadBuffer( const loadpixformat_t *fmt, const char *n
// bruteforce all loaders
if( !fmt )
{
for( fmt = image.loadformats; fmt->formatstring; fmt++ )
for( fmt = image.loadformats; fmt->ext; fmt++ )
{
if( Image_ProbeLoadBuffer_( fmt, name, buf, size, override_hint ))
return true;
@@ -256,7 +256,7 @@ static qboolean Image_ProbeLoad_( const loadpixformat_t *fmt, const char *name,
string path;
byte *f;
Q_snprintf( path, sizeof( path ), fmt->formatstring, name, suffix, fmt->ext );
Q_snprintf( path, sizeof( path ), "%s%s.%s", name, suffix, fmt->ext );
f = FS_LoadFile( path, &filesize, false );
if( f )
@@ -274,7 +274,7 @@ static qboolean Image_ProbeLoad( const loadpixformat_t *fmt, const char *name, c
if( !fmt )
{
// bruteforce all formats to allow implicit extension
for( fmt = image.loadformats; fmt->formatstring; fmt++ )
for( fmt = image.loadformats; fmt->ext; fmt++ )
{
if( Image_ProbeLoad_( fmt, name, suffix, override_hint ))
return true;
@@ -417,14 +417,13 @@ qboolean FS_SaveImage( const char *filename, rgbdata_t *pix )
picBuffer = pix->buffer;
// save all sides seperately
for( format = image.saveformats; format && format->formatstring; format++ )
for( format = image.saveformats; format && format->ext; format++ )
{
if( !Q_stricmp( ext, format->ext ))
{
for( i = 0; i < 6; i++ )
{
Q_snprintf( path, sizeof( path ),
format->formatstring, savename, box[i].suf, format->ext );
Q_snprintf( path, sizeof( path ), "%s%s.%s", savename, box[i].suf, format->ext );
if( !format->savefunc( path, pix )) break; // there were errors
pix->buffer += pix->size; // move pointer
}
@@ -442,12 +441,11 @@ qboolean FS_SaveImage( const char *filename, rgbdata_t *pix )
}
else
{
for( format = image.saveformats; format && format->formatstring; format++ )
for( format = image.saveformats; format && format->ext; format++ )
{
if( !Q_stricmp( ext, format->ext ))
{
Q_snprintf( path, sizeof( path ),
format->formatstring, savename, "", format->ext );
Q_snprintf( path, sizeof( path ), "%s.%s", savename, format->ext );
if( format->savefunc( path, pix ))
{
// clear any force flags

View File

@@ -46,7 +46,7 @@ qboolean Image_LoadPNG( const char *name, const byte *buffer, fs_offset_t filesi
short p, a, b, c, pa, pb, pc;
byte *buf_p, *pixbuf, *raw, *prior, *idat_buf = NULL, *uncompressed_buffer = NULL;
byte *pallete = NULL, *trns = NULL;
uint chunk_len, trns_len, plte_len, crc32, crc32_check, oldsize = 0, newsize = 0, rowsize;
uint chunk_len, trns_len = 0, plte_len = 0, crc32, crc32_check, oldsize = 0, newsize = 0, rowsize;
uint uncompressed_size, pixel_size, pixel_count, i, y, filter_type, chunk_sign, r_alpha, g_alpha, b_alpha;
qboolean has_iend_chunk = false;
z_stream stream = {0};

View File

@@ -90,23 +90,23 @@ static byte palette_hl[768] =
// stub
static const loadpixformat_t load_null[] =
{
{ NULL, NULL, NULL, IL_HINT_NO }
{ NULL, NULL, IL_HINT_NO }
};
static const loadpixformat_t load_game[] =
{
{ "%s%s.%s", "dds", Image_LoadDDS, IL_HINT_NO }, // dds for world and studio models
{ "%s%s.%s", "bmp", Image_LoadBMP, IL_HINT_NO }, // WON menu images
{ "%s%s.%s", "tga", Image_LoadTGA, IL_HINT_NO }, // hl vgui menus
{ "%s%s.%s", "png", Image_LoadPNG, IL_HINT_NO }, // NightFire 007 menus
{ "%s%s.%s", "mip", Image_LoadMIP, IL_HINT_NO }, // hl textures from wad or buffer
{ "%s%s.%s", "mdl", Image_LoadMDL, IL_HINT_HL }, // hl studio model skins
{ "%s%s.%s", "spr", Image_LoadSPR, IL_HINT_HL }, // hl sprite frames
{ "%s%s.%s", "lmp", Image_LoadLMP, IL_HINT_NO }, // hl menu images (cached.wad etc)
{ "%s%s.%s", "fnt", Image_LoadFNT, IL_HINT_HL }, // hl console font (fonts.wad etc)
{ "%s%s.%s", "pal", Image_LoadPAL, IL_HINT_NO }, // install studio\sprite palette
{ "%s%s.%s", "ktx2", Image_LoadKTX2, IL_HINT_NO }, // ktx2 for world and studio models
{ NULL, NULL, NULL, IL_HINT_NO }
{ "dds", Image_LoadDDS, IL_HINT_NO }, // dds for world and studio models
{ "bmp", Image_LoadBMP, IL_HINT_NO }, // WON menu images
{ "tga", Image_LoadTGA, IL_HINT_NO }, // hl vgui menus
{ "png", Image_LoadPNG, IL_HINT_NO }, // NightFire 007 menus
{ "mip", Image_LoadMIP, IL_HINT_NO }, // hl textures from wad or buffer
{ "mdl", Image_LoadMDL, IL_HINT_HL }, // hl studio model skins
{ "spr", Image_LoadSPR, IL_HINT_HL }, // hl sprite frames
{ "lmp", Image_LoadLMP, IL_HINT_NO }, // hl menu images (cached.wad etc)
{ "fnt", Image_LoadFNT, IL_HINT_HL }, // hl console font (fonts.wad etc)
{ "pal", Image_LoadPAL, IL_HINT_NO }, // install studio\sprite palette
{ "ktx2", Image_LoadKTX2, IL_HINT_NO }, // ktx2 for world and studio models
{ NULL, NULL, IL_HINT_NO }
};
/*
@@ -119,16 +119,16 @@ static const loadpixformat_t load_game[] =
// stub
static const savepixformat_t save_null[] =
{
{ NULL, NULL, NULL }
{ NULL, NULL }
};
// Xash3D normal instance
static const savepixformat_t save_game[] =
{
{ "%s%s.%s", "tga", Image_SaveTGA }, // tga screenshots
{ "%s%s.%s", "bmp", Image_SaveBMP }, // bmp levelshots or screenshots
{ "%s%s.%s", "png", Image_SavePNG }, // png screenshots
{ NULL, NULL, NULL }
{ "tga", Image_SaveTGA }, // tga screenshots
{ "bmp", Image_SaveBMP }, // bmp levelshots or screenshots
{ "png", Image_SavePNG }, // png screenshots
{ NULL, NULL }
};
void Image_Setup( void )

View File

@@ -28,12 +28,20 @@ Image_LoadPAL
qboolean Image_LoadPAL( const char *name, const byte *buffer, fs_offset_t filesize )
{
int rendermode = LUMP_NORMAL;
byte pal[768];
if( filesize != 768 )
if( filesize > sizeof( pal ))
{
Con_DPrintf( S_ERROR "%s: (%s) have invalid size (%li should be %d)\n", __func__, name, (long)filesize, 768 );
Con_DPrintf( S_ERROR "%s: (%s) have invalid size (%li should be less or equal than %zu)\n", __func__, name, (long)filesize, sizeof( pal ));
return false;
}
else if( filesize < sizeof( pal ) && buffer != NULL )
{
// palette might be truncated, fill it with zeros
memset( pal, 0, sizeof( pal ));
memcpy( pal, buffer, filesize );
buffer = pal;
}
if( name[0] == '#' )
{

View File

@@ -128,9 +128,9 @@ dll_user_t *FS_FindLibrary( const char *dllname, qboolean directpath )
static void COM_GenerateCommonLibraryName( const char *name, const char *ext, char *out, size_t size )
{
#if ( XASH_WIN32 || XASH_LINUX || XASH_APPLE ) && XASH_X86
#if ( XASH_WIN32 || ( XASH_LINUX && !XASH_ANDROID ) || XASH_APPLE ) && XASH_X86
Q_snprintf( out, size, "%s.%s", name, ext );
#elif ( XASH_WIN32 || XASH_LINUX || XASH_APPLE )
#elif XASH_WIN32 || ( XASH_LINUX && !XASH_ANDROID ) || XASH_APPLE
Q_snprintf( out, size, "%s_%s.%s", name, Q_buildarch(), ext );
#else
Q_snprintf( out, size, "%s_%s_%s.%s", name, Q_buildos(), Q_buildarch(), ext );
@@ -185,16 +185,12 @@ static void COM_GenerateServerLibraryPath( char *out, size_t size )
{
#ifdef XASH_INTERNAL_GAMELIBS // assuming library loader knows where to get libraries
Q_strncpy( out, "server", size );
#elif ( XASH_WIN32 || XASH_LINUX || XASH_APPLE ) && XASH_X86
#if XASH_WIN32
#elif XASH_X86 && XASH_WIN32
Q_strncpy( out, GI->game_dll, size );
#elif XASH_APPLE
#elif XASH_X86 && XASH_APPLE
Q_strncpy( out, GI->game_dll_osx, size );
#else // XASH_LINUX
#elif XASH_X86 && XASH_LINUX && !XASH_ANDROID
Q_strncpy( out, GI->game_dll_linux, size );
#endif
#else
string dllpath;
const char *ext;
@@ -203,7 +199,7 @@ static void COM_GenerateServerLibraryPath( char *out, size_t size )
Q_strncpy( dllpath, GI->game_dll, sizeof( dllpath ) );
#elif XASH_APPLE
Q_strncpy( dllpath, GI->game_dll_osx, sizeof( dllpath ) );
#else // XASH_APPLE
#else
Q_strncpy( dllpath, GI->game_dll_linux, sizeof( dllpath ) );
#endif
@@ -228,7 +224,14 @@ void COM_GetCommonLibraryPath( ECommonLibraryType eLibType, char *out, size_t si
switch( eLibType )
{
case LIBRARY_GAMEUI:
COM_GenerateClientLibraryPath( "menu", out, size );
if( COM_CheckStringEmpty( host.menulib ))
{
Q_strncpy( out, host.menulib, size );
}
else
{
COM_GenerateClientLibraryPath( "menu", out, size );
}
break;
case LIBRARY_CLIENT:
if( COM_CheckStringEmpty( host.clientlib ))

View File

@@ -419,14 +419,21 @@ void NET_InitMasters( void )
Cvar_RegisterVariable( &sv_verbose_heartbeats );
// keep main master always there
NET_AddMaster( MASTERSERVER_ADR, false, false );
NET_AddMaster( "mentality.rip:27011", false, false ); // testing server, might be offline
NET_AddMaster( "ms2.mentality.rip:27010", false, false ); // secondary master
{ // IPv4-only
NET_AddMaster( "mentality.rip:27010", false, false );
NET_AddMaster( "ms2.mentality.rip:27010", false, false );
NET_AddMaster( "ms3.mentality.rip:27010", false, false );
}
NET_AddMaster( "aaaa.mentality.rip:27010", false, true ); // IPv6-only
NET_AddMaster( "aaaa.mentality.rip:27011", false, true ); // IPv6-only, testing server, might be offline
NET_AddMaster( "aaaa.ms2.mentality.rip:27010", false, false ); // secondary IPv6-only master
{ // IPv6-only
NET_AddMaster( "aaaa.mentality.rip:27010", false, true );
NET_AddMaster( "aaaa.ms2.mentality.rip:27010", false, true );
}
{ // testing servers, might be offline
NET_AddMaster( "mentality.rip:27011", false, false );
NET_AddMaster( "aaaa.mentality.rip:27011", false, true );
}
NET_LoadMasters( );
}

View File

@@ -129,10 +129,11 @@ typedef struct
dclipnode32_t *clipnodes_out; // temporary 32-bit array to hold clipnodes
// misc stuff
int lightmap_samples; // samples per lightmap (1 or 3)
int version; // model version
qboolean isworld;
qboolean isbsp30ext;
int lightmap_samples; // samples per lightmap (1 or 3)
int version; // model version
qboolean isworld;
qboolean isbsp30ext;
qboolean need_clipnode_remap; // try to fit 32-bit clipnodes into 16-bit types
} dbspmodel_t;
typedef struct
@@ -482,7 +483,7 @@ static int Mod_LoadTextureFromWadList( wadlist_t *list, const char *name, rgbdat
return -1;
}
static fs_offset_t Mod_CalculateMipTexSize( mip_t *mt, qboolean palette )
static fs_offset_t Mod_CalculateMipTexSize( const mip_t *mt, qboolean palette )
{
if( !mt )
return 0;
@@ -1579,8 +1580,8 @@ static void CountClipNodes16_r( mclipnode16_t *src, hull_t *hull, int nodenum )
// leaf?
if( nodenum < 0 ) return;
if( hull->lastclipnode == MAX_MAP_CLIPNODES )
Host_Error( "MAX_MAP_CLIPNODES limit exceeded\n" );
if( hull->lastclipnode == MAX_MAP_CLIPNODES_HLBSP )
Host_Error( "%s: MAX_MAP_CLIPNODES_HLBSP limit exceeded\n", __func__ );
hull->lastclipnode++;
CountClipNodes16_r( src, hull, src[nodenum].children[0] );
@@ -1592,25 +1593,25 @@ static void CountClipNodes32_r( mclipnode32_t *src, hull_t *hull, int nodenum )
// leaf?
if( nodenum < 0 ) return;
if( hull->lastclipnode == MAX_MAP_CLIPNODES )
Host_Error( "MAX_MAP_CLIPNODES limit exceeded\n" );
if( hull->lastclipnode == MAX_MAP_CLIPNODES_BSP2 )
Host_Error( "%s: MAX_MAP_CLIPNODES_BSP2 limit exceeded\n", __func__ );
hull->lastclipnode++;
CountClipNodes32_r( src, hull, src[nodenum].children[0] );
CountClipNodes32_r( src, hull, src[nodenum].children[1] );
}
static void CountDClipNodes_r( dclipnode32_t *src, hull_t *hull, int nodenum )
static void CountDClipNodes_r( dclipnode32_t *src, hull_t *hull, int nodenum, const int max_clipnodes )
{
// leaf?
if( nodenum < 0 ) return;
if( hull->lastclipnode == MAX_MAP_CLIPNODES )
Host_Error( "MAX_MAP_CLIPNODES limit exceeded\n" );
if( hull->lastclipnode == max_clipnodes )
Host_Error( "%s: MAX_MAP_CLIPNODES (%d) limit exceeded\n", __func__, max_clipnodes );
hull->lastclipnode++;
CountDClipNodes_r( src, hull, src[nodenum].children[0] );
CountDClipNodes_r( src, hull, src[nodenum].children[1] );
CountDClipNodes_r( src, hull, src[nodenum].children[0], max_clipnodes );
CountDClipNodes_r( src, hull, src[nodenum].children[1], max_clipnodes );
}
/*
@@ -1628,8 +1629,17 @@ static int RemapClipNodes_r( dbspmodel_t *bmod, dclipnode32_t *srcnodes, hull_t
return nodenum;
// emit a clipnode
if( hull->lastclipnode == MAX_MAP_CLIPNODES )
Host_Error( "MAX_MAP_CLIPNODES limit exceeded\n" );
if( bmod->version == QBSP2_VERSION )
{
if( hull->lastclipnode == MAX_MAP_CLIPNODES_BSP2 )
Host_Error( "%s: MAX_MAP_CLIPNODES_BSP2 limit exceeded\n", __func__ );
}
else
{
if( hull->lastclipnode == MAX_MAP_CLIPNODES_HLBSP )
Host_Error( "%s: MAX_MAP_CLIPNODES_HLBSP limit exceeded\n", __func__ );
}
src = srcnodes + nodenum;
c = hull->lastclipnode;
@@ -1725,19 +1735,9 @@ static void Mod_MakeHull0( model_t *mod, const dbspmodel_t *bmod )
Mod_SetupHull
=================
*/
static void Mod_SetupHull( dbspmodel_t *bmod, model_t *mod, poolhandle_t mempool, int headnode, int hullnum )
static void Mod_SetupHull( dbspmodel_t *bmod, model_t *mod, int headnode, int hullnum, model_t *world )
{
hull_t *hull = &mod->hulls[hullnum];
// assume no hull
hull->firstclipnode = hull->lastclipnode = 0;
hull->planes = NULL; // hull is missed
if(( headnode == -1 ) || ( hullnum != 1 && headnode == 0 ))
return; // hull missed
if( headnode >= mod->numclipnodes )
return; // ZHLT weird empty hulls
hull_t *hull = &mod->hulls[hullnum];
switch( hullnum )
{
@@ -1761,13 +1761,75 @@ static void Mod_SetupHull( dbspmodel_t *bmod, model_t *mod, poolhandle_t mempool
if( VectorIsNull( hull->clip_mins ) && VectorIsNull( hull->clip_maxs ))
return; // no hull specified
CountDClipNodes_r( bmod->clipnodes_out, hull, headnode );
// assume no hull
hull->firstclipnode = hull->lastclipnode = 0;
hull->planes = NULL; // hull is missed
if( headnode >= mod->numclipnodes )
return; // ZHLT weird empty hulls
// take a simpler route if we don't need clipnodes remapping
if( !bmod->need_clipnode_remap )
{
hull->planes = mod->planes;
// some map "optimizers" (you know who you are!) put -1 here
hull->firstclipnode = Q_max( 0, headnode );
hull->lastclipnode = mod->numclipnodes - 1;
// only allocate clipnodes array for the base model, only for first hull
if( mod == world && hullnum == 1 )
{
int i;
if( bmod->version == QBSP2_VERSION )
{
hull->clipnodes32 = Mem_Malloc( world->mempool, sizeof( *hull->clipnodes32 ) * mod->numclipnodes );
for( i = 0; i < mod->numclipnodes; i++ )
{
hull->clipnodes32[i].planenum = bmod->clipnodes_out[i].planenum;
hull->clipnodes32[i].children[0] = bmod->clipnodes_out[i].children[0];
hull->clipnodes32[i].children[1] = bmod->clipnodes_out[i].children[1];
}
}
else
{
hull->clipnodes16 = Mem_Malloc( world->mempool, sizeof( *hull->clipnodes16 ) * mod->numclipnodes );
for( i = 0; i < mod->numclipnodes; i++ )
{
hull->clipnodes16[i].planenum = bmod->clipnodes_out[i].planenum;
hull->clipnodes16[i].children[0] = bmod->clipnodes_out[i].children[0];
hull->clipnodes16[i].children[1] = bmod->clipnodes_out[i].children[1];
}
}
}
else
{
if( bmod->version == QBSP2_VERSION )
hull->clipnodes32 = world->hulls[1].clipnodes32;
else
hull->clipnodes16 = world->hulls[1].clipnodes16;
}
return;
}
if(( headnode == -1 ) || ( hullnum != 1 && headnode == 0 ))
return; // hull missed
// fit array to real count
if( bmod->version == QBSP2_VERSION )
hull->clipnodes32 = Mem_Malloc( mempool, sizeof( *hull->clipnodes32 ) * hull->lastclipnode );
{
CountDClipNodes_r( bmod->clipnodes_out, hull, headnode, MAX_MAP_CLIPNODES_BSP2 );
hull->clipnodes32 = Mem_Malloc( world->mempool, sizeof( *hull->clipnodes32 ) * hull->lastclipnode );
}
else
hull->clipnodes16 = Mem_Malloc( mempool, sizeof( *hull->clipnodes16 ) * hull->lastclipnode );
{
CountDClipNodes_r( bmod->clipnodes_out, hull, headnode, MAX_MAP_CLIPNODES_HLBSP );
hull->clipnodes16 = Mem_Malloc( world->mempool, sizeof( *hull->clipnodes16 ) * hull->lastclipnode );
}
hull->planes = mod->planes; // share planes
hull->lastclipnode = 0; // restart counting
@@ -1851,28 +1913,19 @@ for embedded submodels
*/
static void Mod_SetupSubmodels( model_t *mod, dbspmodel_t *bmod )
{
qboolean colored = false;
qboolean qbsp2 = false;
poolhandle_t mempool;
char *ents;
dmodel_t *bm;
const qboolean colored = FBitSet( mod->flags, MODEL_COLORED_LIGHTING ) ? true : false;
const qboolean qbsp2 = FBitSet( mod->flags, MODEL_QBSP2 ) ? true : false;
const char *name = mod->name;
int i, j;
ents = mod->entities;
mempool = mod->mempool;
if( FBitSet( mod->flags, MODEL_COLORED_LIGHTING ))
colored = true;
if( FBitSet( mod->flags, MODEL_QBSP2 ))
qbsp2 = true;
model_t *world = mod; // submodels might want to share hulls
int i;
mod->numframes = 2; // regular and alternate animation
// set up the submodels
for( i = 0; i < mod->numsubmodels; i++ )
{
bm = &mod->submodels[i];
dmodel_t *bm = &mod->submodels[i];
int j;
// hull 0 is just shared across all bmodels
mod->hulls[0].firstclipnode = bm->headnode[0];
@@ -1886,7 +1939,7 @@ static void Mod_SetupSubmodels( model_t *mod, dbspmodel_t *bmod )
// but hulls1-3 is build individually for a each given submodel
for( j = 1; j < MAX_MAP_HULLS; j++ )
Mod_SetupHull( bmod, mod, mempool, bm->headnode[j], j );
Mod_SetupHull( bmod, mod, bm->headnode[j], j, world );
mod->firstmodelsurface = bm->firstface;
mod->nummodelsurfaces = bm->numfaces;
@@ -1907,7 +1960,7 @@ static void Mod_SetupSubmodels( model_t *mod, dbspmodel_t *bmod )
char temp[MAX_VA_STRING];
Q_snprintf( temp, sizeof( temp ), "*%i", i );
Mod_FindModelOrigin( ents, temp, bm->origin );
Mod_FindModelOrigin( world->entities, temp, bm->origin );
// mark models that have origin brushes
if( !VectorIsNull( bm->origin ))
@@ -2359,7 +2412,7 @@ static qboolean Mod_SearchForTextureReplacement( char *out, size_t size, const c
return false;
}
static void Mod_InitSkyClouds( model_t *mod, mip_t *mt, texture_t *tx, qboolean custom_palette )
static void Mod_InitSkyClouds( model_t *mod, const mip_t *mt, texture_t *tx, qboolean custom_palette )
{
#if !XASH_DEDICATED
rgbdata_t r_temp, *r_sky;
@@ -2516,9 +2569,6 @@ done:
static void Mod_LoadTextureData( model_t *mod, dbspmodel_t *bmod, int textureIndex )
{
texture_t *texture = NULL;
mip_t *mipTex = NULL;
qboolean usesCustomPalette = false;
uint32_t txFlags = 0;
char texpath[MAX_VA_STRING];
char safemtname[16]; // only for external textures
@@ -2526,12 +2576,10 @@ static void Mod_LoadTextureData( model_t *mod, dbspmodel_t *bmod, int textureInd
// don't load texture data on dedicated server, as there is no renderer.
// but count the wadusage for automatic precache
//
// FIXME: for ENGINE_IMPROVED_LINETRACE we need to load textures on server too
// but there is no facility for this yet
texture = mod->textures[textureIndex];
mipTex = Mod_GetMipTexForTexture( bmod, textureIndex );
usesCustomPalette = Mod_CalcMipTexUsesCustomPalette( mod, bmod, textureIndex );
texture_t *texture = mod->textures[textureIndex];
const mip_t *mipTex = Mod_GetMipTexForTexture( bmod, textureIndex );
const qboolean usesCustomPalette = Mod_CalcMipTexUsesCustomPalette( mod, bmod, textureIndex );
const qboolean iswater = Mod_LooksLikeWaterTexture( mipTex->name );
// check for multi-layered sky texture (quake1 specific)
if( bmod->isworld && Q_strncmp( mipTex->name, "sky", 3 ) == 0 && ( mipTex->width / mipTex->height ) == 2 )
@@ -2540,11 +2588,13 @@ static void Mod_LoadTextureData( model_t *mod, dbspmodel_t *bmod, int textureInd
return;
}
// FIXME: for ENGINE_IMPROVED_LINETRACE we need to load textures on server too
// but there is no facility for this yet
if( FBitSet( host.features, ENGINE_IMPROVED_LINETRACE ) && mipTex->name[0] == '{' )
SetBits( txFlags, TF_KEEP_SOURCE ); // Paranoia2 texture alpha-tracing
// check if this is water to keep the source texture and expand it to RGBA (so ripple effect works)
if( Mod_LooksLikeWaterTexture( mipTex->name ))
if( iswater )
SetBits( txFlags, TF_KEEP_SOURCE | TF_EXPAND_SOURCE );
// Texture loading order:
@@ -2609,8 +2659,13 @@ static void Mod_LoadTextureData( model_t *mod, dbspmodel_t *bmod, int textureInd
texture->gl_texturenum = R_GetBuiltinTexture( REF_DEFAULT_TEXTURE );
}
// Check for luma texture
texture->fb_texturenum = 0;
// Check for luma texture
// a1ba: ignore for water because fb_texturenum will be used to store ripple texture
if( iswater )
return;
if( load_external ) // external textures will not have TF_HAS_LUMA flag because it set only from WAD images loader
{
if( Mod_SearchForTextureReplacement( texpath, sizeof( texpath ), mod->name, safemtname, "_luma" ))
@@ -3432,7 +3487,12 @@ static void Mod_LoadClipnodes( model_t *mod, dbspmodel_t *bmod )
if(( bmod->version == QBSP2_VERSION ) || ( bmod->version == HLBSP_VERSION && bmod->isbsp30ext && bmod->numclipnodes >= MAX_MAP_CLIPNODES_HLBSP ))
{
dclipnode32_t *in = bmod->clipnodes32;
dclipnode32_t *in = bmod->clipnodes32;
// bsp30ext allows for extended total amount of clipnodes, but the limit is still 16-bit per submodel
// therefore we need to remap them
if( bmod->version == HLBSP_VERSION )
bmod->need_clipnode_remap = true;
for( i = 0; i < bmod->numclipnodes; i++, out++, in++ )
{
@@ -3452,7 +3512,7 @@ static void Mod_LoadClipnodes( model_t *mod, dbspmodel_t *bmod )
out->children[0] = (unsigned short)in->children[0];
out->children[1] = (unsigned short)in->children[1];
// Arguire QBSP 'broken' clipnodes
// aguirRe QBSP 'broken' clipnodes
if( out->children[0] >= bmod->numclipnodes )
out->children[0] -= 65536;
if( out->children[1] >= bmod->numclipnodes )

View File

@@ -169,7 +169,7 @@ void Mod_LoadAliasModel( model_t *mod, const void *buffer, qboolean *loaded );
//
void Mod_LoadBrushModel( model_t *mod, const void *buffer, qboolean *loaded );
qboolean Mod_TestBmodelLumps( file_t *f, const char *name, const byte *mod_base, qboolean silent, dlump_t *entities );
int Mod_FatPVS( const vec3_t org, float radius, byte *visbuffer, int visbytes, qboolean merge, qboolean fullvis, qboolean false );
int Mod_FatPVS( const vec3_t org, float radius, byte *visbuffer, int visbytes, qboolean merge, qboolean fullvis, qboolean phs );
qboolean Mod_BoxVisible( const vec3_t mins, const vec3_t maxs, const byte *visbits );
int Mod_CheckLump( const char *filename, const int lump, int *lumpsize );
int Mod_ReadLump( const char *filename, const int lump, void **lumpdata, int *lumpsize );

View File

@@ -382,8 +382,7 @@ static void Mod_StudioCalcRotations( int boneused[], int numbones, const byte *p
for( j = numbones - 1; j >= 0; j-- )
{
i = boneused[j];
R_StudioCalcBoneQuaternion( frame, s, &pbone[i], &panim[i], adj, q[i] );
R_StudioCalcBonePosition( frame, s, &pbone[i], &panim[i], adj, pos[i] );
R_StudioCalcBones( frame, s, &pbone[i], &panim[i], adj, pos[i], q[i] );
}
if( pseqdesc->motiontype & STUDIO_X ) pos[pseqdesc->motionbone][0] = 0.0f;
@@ -724,7 +723,7 @@ void Mod_StudioComputeBounds( void *buffer, vec3_t mins, vec3_t maxs, qboolean i
{
for( k = 0; k < pseqdesc->numframes; k++ )
{
R_StudioCalcBonePosition( k, 0, &pbones[j], panim, NULL, pos );
R_StudioCalcBones( k, 0, &pbones[j], panim, NULL, pos, NULL );
Mod_StudioBoundVertex( vert_mins, vert_maxs, &bone_count, pos );
}
}
@@ -868,7 +867,7 @@ void Mod_LoadStudioModel( model_t *mod, const void *buffer, qboolean *loaded )
mod->type = mod_studio;
phdr = R_StudioLoadHeader( mod, buffer );
if( !phdr )
if( !phdr || phdr->length < sizeof( studiohdr_t )) // garbage value in length
return; // bad model
#if !XASH_DEDICATED

View File

@@ -258,7 +258,7 @@ model_t *Mod_LoadModel( model_t *mod, qboolean crash )
{
char tempname[MAX_QPATH];
fs_offset_t length = 0;
qboolean loaded;
qboolean loaded, loaded2 = false;
byte *buf;
model_info_t *p;
@@ -279,7 +279,7 @@ model_t *Mod_LoadModel( model_t *mod, qboolean crash )
buf = FS_LoadFile( tempname, &length, false );
if( !buf )
if( !buf || length < sizeof( uint ))
{
memset( mod, 0, sizeof( model_t ));
@@ -329,11 +329,12 @@ model_t *Mod_LoadModel( model_t *mod, qboolean crash )
// let the server.dll load custom data
svgame.physFuncs.Mod_ProcessUserData( mod, true, buf );
}
loaded2 = true;
}
#if !XASH_DEDICATED
else
{
loaded = ref.dllFuncs.Mod_ProcessRenderData( mod, true, buf );
loaded2 = ref.dllFuncs.Mod_ProcessRenderData( mod, true, buf );
}
#endif
}
@@ -345,7 +346,7 @@ model_t *Mod_LoadModel( model_t *mod, qboolean crash )
hdr->pposeverts = NULL;
}
if( !loaded )
if( !loaded || !loaded2 )
{
Mod_FreeModel( mod );
Mem_Free( buf );
@@ -610,3 +611,41 @@ void Mod_NeedCRC( const char *name, qboolean needCRC )
if( needCRC ) SetBits( p->flags, FCRC_SHOULD_CHECKSUM );
else ClearBits( p->flags, FCRC_SHOULD_CHECKSUM );
}
#if XASH_ENGINE_TESTS
static const uint8_t *fuzz_data;
static size_t fuzz_size;
static byte *Fuzz_LoadFile( const char *path, fs_offset_t *filesizeptr, qboolean gamedironly )
{
byte *buf = Mem_Malloc( host.mempool, fuzz_size );
memcpy( buf, fuzz_data, fuzz_size );
*filesizeptr = fuzz_size;
return buf;
}
int EXPORT Fuzz_Mod_LoadModel( const uint8_t *Data, size_t Size );
int EXPORT Fuzz_Mod_LoadModel( const uint8_t *Data, size_t Size )
{
model_t mod = { .name = "test", .needload = NL_NEEDS_LOADED };
Memory_Init();
host.type = HOST_DEDICATED;
host.mempool = Mem_AllocPool( "fuzzing pool" );
fuzz_data = Data;
fuzz_size = Size;
refState.draw_surfaces = NULL;
g_fsapi.LoadFile = Fuzz_LoadFile;
if( Mod_LoadModel( &mod, false ) && mod.mempool )
Mem_FreePool( &mod.mempool );
Mem_FreePool( &host.mempool );
return 0;
}
#endif // XASH_ENGINE_TESTS

View File

@@ -18,11 +18,177 @@ GNU General Public License for more details.
#include "net_buffer.h"
#include "xash3d_mathlib.h"
// precalculated bit masks for WriteUBitLong.
// Using these tables instead of doing the calculations
// gives a 33% speedup in WriteUBitLong.
static uint32_t BitWriteMasks[32][33];
static uint32_t ExtraMasks[32];
static const uint32_t BitWriteMasks[32][32] =
{ {
0xfffffffe, 0xfffffffc, 0xfffffff8, 0xfffffff0, 0xffffffe0, 0xffffffc0, 0xffffff80, 0xffffff00,
0xfffffe00, 0xfffffc00, 0xfffff800, 0xfffff000, 0xffffe000, 0xffffc000, 0xffff8000, 0xffff0000,
0xfffe0000, 0xfffc0000, 0xfff80000, 0xfff00000, 0xffe00000, 0xffc00000, 0xff800000, 0xff000000,
0xfe000000, 0xfc000000, 0xf8000000, 0xf0000000, 0xe0000000, 0xc0000000, 0x80000000, 0x00000000,
}, {
0xfffffffd, 0xfffffff9, 0xfffffff1, 0xffffffe1, 0xffffffc1, 0xffffff81, 0xffffff01, 0xfffffe01,
0xfffffc01, 0xfffff801, 0xfffff001, 0xffffe001, 0xffffc001, 0xffff8001, 0xffff0001, 0xfffe0001,
0xfffc0001, 0xfff80001, 0xfff00001, 0xffe00001, 0xffc00001, 0xff800001, 0xff000001, 0xfe000001,
0xfc000001, 0xf8000001, 0xf0000001, 0xe0000001, 0xc0000001, 0x80000001, 0x00000001, 0x00000001,
}, {
0xfffffffb, 0xfffffff3, 0xffffffe3, 0xffffffc3, 0xffffff83, 0xffffff03, 0xfffffe03, 0xfffffc03,
0xfffff803, 0xfffff003, 0xffffe003, 0xffffc003, 0xffff8003, 0xffff0003, 0xfffe0003, 0xfffc0003,
0xfff80003, 0xfff00003, 0xffe00003, 0xffc00003, 0xff800003, 0xff000003, 0xfe000003, 0xfc000003,
0xf8000003, 0xf0000003, 0xe0000003, 0xc0000003, 0x80000003, 0x00000003, 0x00000003, 0x00000003,
}, {
0xfffffff7, 0xffffffe7, 0xffffffc7, 0xffffff87, 0xffffff07, 0xfffffe07, 0xfffffc07, 0xfffff807,
0xfffff007, 0xffffe007, 0xffffc007, 0xffff8007, 0xffff0007, 0xfffe0007, 0xfffc0007, 0xfff80007,
0xfff00007, 0xffe00007, 0xffc00007, 0xff800007, 0xff000007, 0xfe000007, 0xfc000007, 0xf8000007,
0xf0000007, 0xe0000007, 0xc0000007, 0x80000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007,
}, {
0xffffffef, 0xffffffcf, 0xffffff8f, 0xffffff0f, 0xfffffe0f, 0xfffffc0f, 0xfffff80f, 0xfffff00f,
0xffffe00f, 0xffffc00f, 0xffff800f, 0xffff000f, 0xfffe000f, 0xfffc000f, 0xfff8000f, 0xfff0000f,
0xffe0000f, 0xffc0000f, 0xff80000f, 0xff00000f, 0xfe00000f, 0xfc00000f, 0xf800000f, 0xf000000f,
0xe000000f, 0xc000000f, 0x8000000f, 0x0000000f, 0x0000000f, 0x0000000f, 0x0000000f, 0x0000000f,
}, {
0xffffffdf, 0xffffff9f, 0xffffff1f, 0xfffffe1f, 0xfffffc1f, 0xfffff81f, 0xfffff01f, 0xffffe01f,
0xffffc01f, 0xffff801f, 0xffff001f, 0xfffe001f, 0xfffc001f, 0xfff8001f, 0xfff0001f, 0xffe0001f,
0xffc0001f, 0xff80001f, 0xff00001f, 0xfe00001f, 0xfc00001f, 0xf800001f, 0xf000001f, 0xe000001f,
0xc000001f, 0x8000001f, 0x0000001f, 0x0000001f, 0x0000001f, 0x0000001f, 0x0000001f, 0x0000001f,
}, {
0xffffffbf, 0xffffff3f, 0xfffffe3f, 0xfffffc3f, 0xfffff83f, 0xfffff03f, 0xffffe03f, 0xffffc03f,
0xffff803f, 0xffff003f, 0xfffe003f, 0xfffc003f, 0xfff8003f, 0xfff0003f, 0xffe0003f, 0xffc0003f,
0xff80003f, 0xff00003f, 0xfe00003f, 0xfc00003f, 0xf800003f, 0xf000003f, 0xe000003f, 0xc000003f,
0x8000003f, 0x0000003f, 0x0000003f, 0x0000003f, 0x0000003f, 0x0000003f, 0x0000003f, 0x0000003f,
}, {
0xffffff7f, 0xfffffe7f, 0xfffffc7f, 0xfffff87f, 0xfffff07f, 0xffffe07f, 0xffffc07f, 0xffff807f,
0xffff007f, 0xfffe007f, 0xfffc007f, 0xfff8007f, 0xfff0007f, 0xffe0007f, 0xffc0007f, 0xff80007f,
0xff00007f, 0xfe00007f, 0xfc00007f, 0xf800007f, 0xf000007f, 0xe000007f, 0xc000007f, 0x8000007f,
0x0000007f, 0x0000007f, 0x0000007f, 0x0000007f, 0x0000007f, 0x0000007f, 0x0000007f, 0x0000007f,
}, {
0xfffffeff, 0xfffffcff, 0xfffff8ff, 0xfffff0ff, 0xffffe0ff, 0xffffc0ff, 0xffff80ff, 0xffff00ff,
0xfffe00ff, 0xfffc00ff, 0xfff800ff, 0xfff000ff, 0xffe000ff, 0xffc000ff, 0xff8000ff, 0xff0000ff,
0xfe0000ff, 0xfc0000ff, 0xf80000ff, 0xf00000ff, 0xe00000ff, 0xc00000ff, 0x800000ff, 0x000000ff,
0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
}, {
0xfffffdff, 0xfffff9ff, 0xfffff1ff, 0xffffe1ff, 0xffffc1ff, 0xffff81ff, 0xffff01ff, 0xfffe01ff,
0xfffc01ff, 0xfff801ff, 0xfff001ff, 0xffe001ff, 0xffc001ff, 0xff8001ff, 0xff0001ff, 0xfe0001ff,
0xfc0001ff, 0xf80001ff, 0xf00001ff, 0xe00001ff, 0xc00001ff, 0x800001ff, 0x000001ff, 0x000001ff,
0x000001ff, 0x000001ff, 0x000001ff, 0x000001ff, 0x000001ff, 0x000001ff, 0x000001ff, 0x000001ff,
}, {
0xfffffbff, 0xfffff3ff, 0xffffe3ff, 0xffffc3ff, 0xffff83ff, 0xffff03ff, 0xfffe03ff, 0xfffc03ff,
0xfff803ff, 0xfff003ff, 0xffe003ff, 0xffc003ff, 0xff8003ff, 0xff0003ff, 0xfe0003ff, 0xfc0003ff,
0xf80003ff, 0xf00003ff, 0xe00003ff, 0xc00003ff, 0x800003ff, 0x000003ff, 0x000003ff, 0x000003ff,
0x000003ff, 0x000003ff, 0x000003ff, 0x000003ff, 0x000003ff, 0x000003ff, 0x000003ff, 0x000003ff,
}, {
0xfffff7ff, 0xffffe7ff, 0xffffc7ff, 0xffff87ff, 0xffff07ff, 0xfffe07ff, 0xfffc07ff, 0xfff807ff,
0xfff007ff, 0xffe007ff, 0xffc007ff, 0xff8007ff, 0xff0007ff, 0xfe0007ff, 0xfc0007ff, 0xf80007ff,
0xf00007ff, 0xe00007ff, 0xc00007ff, 0x800007ff, 0x000007ff, 0x000007ff, 0x000007ff, 0x000007ff,
0x000007ff, 0x000007ff, 0x000007ff, 0x000007ff, 0x000007ff, 0x000007ff, 0x000007ff, 0x000007ff,
}, {
0xffffefff, 0xffffcfff, 0xffff8fff, 0xffff0fff, 0xfffe0fff, 0xfffc0fff, 0xfff80fff, 0xfff00fff,
0xffe00fff, 0xffc00fff, 0xff800fff, 0xff000fff, 0xfe000fff, 0xfc000fff, 0xf8000fff, 0xf0000fff,
0xe0000fff, 0xc0000fff, 0x80000fff, 0x00000fff, 0x00000fff, 0x00000fff, 0x00000fff, 0x00000fff,
0x00000fff, 0x00000fff, 0x00000fff, 0x00000fff, 0x00000fff, 0x00000fff, 0x00000fff, 0x00000fff,
}, {
0xffffdfff, 0xffff9fff, 0xffff1fff, 0xfffe1fff, 0xfffc1fff, 0xfff81fff, 0xfff01fff, 0xffe01fff,
0xffc01fff, 0xff801fff, 0xff001fff, 0xfe001fff, 0xfc001fff, 0xf8001fff, 0xf0001fff, 0xe0001fff,
0xc0001fff, 0x80001fff, 0x00001fff, 0x00001fff, 0x00001fff, 0x00001fff, 0x00001fff, 0x00001fff,
0x00001fff, 0x00001fff, 0x00001fff, 0x00001fff, 0x00001fff, 0x00001fff, 0x00001fff, 0x00001fff,
}, {
0xffffbfff, 0xffff3fff, 0xfffe3fff, 0xfffc3fff, 0xfff83fff, 0xfff03fff, 0xffe03fff, 0xffc03fff,
0xff803fff, 0xff003fff, 0xfe003fff, 0xfc003fff, 0xf8003fff, 0xf0003fff, 0xe0003fff, 0xc0003fff,
0x80003fff, 0x00003fff, 0x00003fff, 0x00003fff, 0x00003fff, 0x00003fff, 0x00003fff, 0x00003fff,
0x00003fff, 0x00003fff, 0x00003fff, 0x00003fff, 0x00003fff, 0x00003fff, 0x00003fff, 0x00003fff,
}, {
0xffff7fff, 0xfffe7fff, 0xfffc7fff, 0xfff87fff, 0xfff07fff, 0xffe07fff, 0xffc07fff, 0xff807fff,
0xff007fff, 0xfe007fff, 0xfc007fff, 0xf8007fff, 0xf0007fff, 0xe0007fff, 0xc0007fff, 0x80007fff,
0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff,
0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff,
}, {
0xfffeffff, 0xfffcffff, 0xfff8ffff, 0xfff0ffff, 0xffe0ffff, 0xffc0ffff, 0xff80ffff, 0xff00ffff,
0xfe00ffff, 0xfc00ffff, 0xf800ffff, 0xf000ffff, 0xe000ffff, 0xc000ffff, 0x8000ffff, 0x0000ffff,
0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff,
0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff,
}, {
0xfffdffff, 0xfff9ffff, 0xfff1ffff, 0xffe1ffff, 0xffc1ffff, 0xff81ffff, 0xff01ffff, 0xfe01ffff,
0xfc01ffff, 0xf801ffff, 0xf001ffff, 0xe001ffff, 0xc001ffff, 0x8001ffff, 0x0001ffff, 0x0001ffff,
0x0001ffff, 0x0001ffff, 0x0001ffff, 0x0001ffff, 0x0001ffff, 0x0001ffff, 0x0001ffff, 0x0001ffff,
0x0001ffff, 0x0001ffff, 0x0001ffff, 0x0001ffff, 0x0001ffff, 0x0001ffff, 0x0001ffff, 0x0001ffff,
}, {
0xfffbffff, 0xfff3ffff, 0xffe3ffff, 0xffc3ffff, 0xff83ffff, 0xff03ffff, 0xfe03ffff, 0xfc03ffff,
0xf803ffff, 0xf003ffff, 0xe003ffff, 0xc003ffff, 0x8003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff,
0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff,
0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff,
}, {
0xfff7ffff, 0xffe7ffff, 0xffc7ffff, 0xff87ffff, 0xff07ffff, 0xfe07ffff, 0xfc07ffff, 0xf807ffff,
0xf007ffff, 0xe007ffff, 0xc007ffff, 0x8007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff,
0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff,
0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff,
}, {
0xffefffff, 0xffcfffff, 0xff8fffff, 0xff0fffff, 0xfe0fffff, 0xfc0fffff, 0xf80fffff, 0xf00fffff,
0xe00fffff, 0xc00fffff, 0x800fffff, 0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff,
0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff,
0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff,
}, {
0xffdfffff, 0xff9fffff, 0xff1fffff, 0xfe1fffff, 0xfc1fffff, 0xf81fffff, 0xf01fffff, 0xe01fffff,
0xc01fffff, 0x801fffff, 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff,
0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff,
0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff,
}, {
0xffbfffff, 0xff3fffff, 0xfe3fffff, 0xfc3fffff, 0xf83fffff, 0xf03fffff, 0xe03fffff, 0xc03fffff,
0x803fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff,
0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff,
0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff,
}, {
0xff7fffff, 0xfe7fffff, 0xfc7fffff, 0xf87fffff, 0xf07fffff, 0xe07fffff, 0xc07fffff, 0x807fffff,
0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff,
0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff,
0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff,
}, {
0xfeffffff, 0xfcffffff, 0xf8ffffff, 0xf0ffffff, 0xe0ffffff, 0xc0ffffff, 0x80ffffff, 0x00ffffff,
0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff,
0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff,
0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff,
}, {
0xfdffffff, 0xf9ffffff, 0xf1ffffff, 0xe1ffffff, 0xc1ffffff, 0x81ffffff, 0x01ffffff, 0x01ffffff,
0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
}, {
0xfbffffff, 0xf3ffffff, 0xe3ffffff, 0xc3ffffff, 0x83ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff,
0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff,
0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff,
0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff,
}, {
0xf7ffffff, 0xe7ffffff, 0xc7ffffff, 0x87ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff,
0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff,
0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff,
0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff,
}, {
0xefffffff, 0xcfffffff, 0x8fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff,
0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff,
0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff,
0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff,
}, {
0xdfffffff, 0x9fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff,
0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff,
0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff,
0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff,
}, {
0xbfffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff,
0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff,
0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff,
0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff,
}, {
0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
} };
static const uint32_t ExtraMasks[32] =
{
0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
};
const char *const svc_strings[svc_lastmsg+1] =
{
"svc_bad",
@@ -132,65 +298,41 @@ const char *const svc_quake_strings[svc_lastmsg+1] =
[svc_fog] = "svc_quake_fog",
};
void MSG_InitMasks( void )
{
uint startbit, endbit;
uint maskBit, nBitsLeft;
for( startbit = 0; startbit < 32; startbit++ )
{
for( nBitsLeft = 0; nBitsLeft < 33; nBitsLeft++ )
{
endbit = startbit + nBitsLeft;
BitWriteMasks[startbit][nBitsLeft] = (uint)BIT( startbit ) - 1;
if( endbit < 32 ) BitWriteMasks[startbit][nBitsLeft] |= ~((uint)BIT( endbit ) - 1 );
}
}
for( maskBit = 0; maskBit < 32; maskBit++ )
ExtraMasks[maskBit] = (uint)BIT( maskBit ) - 1;
}
void MSG_WriteUBitLong( sizebuf_t *sb, uint curData, int numbits )
{
Assert( numbits >= 0 && numbits <= 32 );
int nBitsLeft = numbits;
int iCurBit = sb->iCurBit;
uint iDWord = iCurBit >> 5; // Mask in a dword.
uint32_t iCurBitMasked;
int nBitsWritten;
Assert( numbits >= 1 && numbits <= 32 );
// bounds checking..
if(( sb->iCurBit + numbits ) > sb->nDataBits )
if( MSG_Overflow( sb, numbits ))
{
sb->bOverflow = true;
sb->iCurBit = sb->nDataBits;
return;
}
else
{
int nBitsLeft = numbits;
int iCurBit = sb->iCurBit;
uint iDWord = iCurBit >> 5; // Mask in a dword.
uint32_t iCurBitMasked;
int nBitsWritten;
Assert(( iDWord * 4 + sizeof( int )) <= (uint)MSG_GetMaxBytes( sb ));
iCurBitMasked = iCurBit & 31;
((uint32_t *)sb->pData)[iDWord] &= BitWriteMasks[iCurBitMasked][nBitsLeft-1];
((uint32_t *)sb->pData)[iDWord] |= curData << iCurBitMasked;
// did it span a dword?
nBitsWritten = 32 - iCurBitMasked;
if( nBitsWritten < nBitsLeft )
{
nBitsLeft -= nBitsWritten;
iCurBit += nBitsWritten;
curData >>= nBitsWritten;
iCurBitMasked = iCurBit & 31;
((uint32_t *)sb->pData)[iDWord] &= BitWriteMasks[iCurBitMasked][nBitsLeft];
((uint32_t *)sb->pData)[iDWord] |= curData << iCurBitMasked;
// did it span a dword?
nBitsWritten = 32 - iCurBitMasked;
if( nBitsWritten < nBitsLeft )
{
nBitsLeft -= nBitsWritten;
iCurBit += nBitsWritten;
curData >>= nBitsWritten;
iCurBitMasked = iCurBit & 31;
((uint32_t *)sb->pData)[iDWord+1] &= BitWriteMasks[iCurBitMasked][nBitsLeft];
((uint32_t *)sb->pData)[iDWord+1] |= curData << iCurBitMasked;
}
sb->iCurBit += numbits;
((uint32_t *)sb->pData)[iDWord+1] &= BitWriteMasks[iCurBitMasked][nBitsLeft-1];
((uint32_t *)sb->pData)[iDWord+1] |= curData << iCurBitMasked;
}
sb->iCurBit += numbits;
}
/*
@@ -238,7 +380,7 @@ qboolean MSG_WriteBits( sizebuf_t *sb, const void *pData, int nBits )
int nBitsLeft = nBits;
// get output dword-aligned.
while((( uint32_t )pOut & 3 ) != 0 && nBitsLeft >= 8 )
while((( uintptr_t )pOut & 3 ) != 0 && nBitsLeft >= 8 )
{
MSG_WriteUBitLong( sb, *pOut, 8 );
@@ -275,16 +417,14 @@ qboolean MSG_WriteBits( sizebuf_t *sb, const void *pData, int nBits )
void MSG_WriteBitAngle( sizebuf_t *sb, float fAngle, int numbits )
{
uint mask, shift;
const uint shift = ( 1 << numbits );
const uint mask = shift - 1;
int d;
// clamp the angle before receiving
fAngle = fmod( fAngle, 360.0f );
if( fAngle < 0 ) fAngle += 360.0f;
shift = ( 1 << numbits );
mask = shift - 1;
d = (int)(( fAngle * shift ) / 360.0f );
d &= mask;
@@ -438,9 +578,8 @@ uint MSG_ReadUBitLong( sizebuf_t *sb, int numbits )
return 0; // end of message
}
if(( sb->iCurBit + numbits ) > sb->nDataBits )
if( MSG_Overflow( sb, numbits ))
{
sb->bOverflow = true;
sb->iCurBit = sb->nDataBits;
return 0;
}
@@ -479,7 +618,7 @@ qboolean MSG_ReadBits( sizebuf_t *sb, void *pOutData, int nBits )
int nBitsLeft = nBits;
// get output dword-aligned.
while((( uint32_t )pOut & 3) != 0 && nBitsLeft >= 8 )
while((( uintptr_t )pOut & 3) != 0 && nBitsLeft >= 8 )
{
*pOut = (byte)MSG_ReadUBitLong( sb, 8 );
++pOut;
@@ -513,13 +652,9 @@ qboolean MSG_ReadBits( sizebuf_t *sb, void *pOutData, int nBits )
float MSG_ReadBitAngle( sizebuf_t *sb, int numbits )
{
float fReturn, shift;
int i;
shift = (float)( 1 << numbits );
i = MSG_ReadUBitLong( sb, numbits );
fReturn = (float)i * ( 360.0f / shift );
float shift = (float)( 1 << numbits );
int i = MSG_ReadUBitLong( sb, numbits );
float fReturn = (float)i * ( 360.0f / shift );
// clamp the finale angle
if( fReturn < -180.0f ) fReturn += 360.0f;
@@ -531,11 +666,11 @@ float MSG_ReadBitAngle( sizebuf_t *sb, int numbits )
// Append numbits least significant bits from data to the current bit stream
int MSG_ReadSBitLong( sizebuf_t *sb, int numbits )
{
int r, sign;
int r;
if( sb->iAlternateSign )
{
sign = MSG_ReadOneBit( sb );
int sign = MSG_ReadOneBit( sb );
r = MSG_ReadUBitLong( sb, numbits - 1 );
if( sign )
@@ -544,9 +679,7 @@ int MSG_ReadSBitLong( sizebuf_t *sb, int numbits )
else
{
r = MSG_ReadUBitLong( sb, numbits - 1 );
sign = MSG_ReadOneBit( sb );
if( sign )
if( MSG_ReadOneBit( sb ))
r = -( BIT( numbits - 1 ) - r );
}
@@ -667,12 +800,12 @@ qboolean MSG_ReadBytes( sizebuf_t *sb, void *pOut, int nBytes )
static char *MSG_ReadStringExt( sizebuf_t *sb, qboolean bLine )
{
static char string[4096];
int l = 0, c;
int l = 0;
do
{
// use MSG_ReadByte so -1 is out of bounds
c = MSG_ReadByte( sb );
int c = MSG_ReadByte( sb );
if( c == 0 ) break;
else if( bLine && c == '\n' )
@@ -740,7 +873,7 @@ static void Test_Buffer_Write( void )
MSG_Init( &sb, __func__, testdata, sizeof( testdata ));
TASSERT_EQi( sb.iCurBit, 0 );
TASSERT_EQi( sb.nDataBits, sizeof( testdata ) << 3 );
TASSERT_EQi( sb.pData, testdata );
TASSERT_EQp( sb.pData, (void *)testdata );
TASSERT_EQi( sb.bOverflow, false );
MSG_WriteBytes( &sb, "asdf", 4 );
@@ -796,7 +929,7 @@ static void Test_Buffer_Read( void )
MSG_StartReading( &sb, (void *)g_testbuf, -1, 0, g_testbuf_bits );
TASSERT_EQi( sb.iCurBit, 0 );
TASSERT_EQi( sb.nDataBits, g_testbuf_bits );
TASSERT_EQi( sb.pData, g_testbuf );
TASSERT_EQp( sb.pData, (void *)g_testbuf );
TASSERT_EQi( sb.bOverflow, false );
MSG_ReadBytes( &sb, buf, 4 );
@@ -865,8 +998,6 @@ static void Test_Buffer_ExciseBits( void )
void Test_RunBuffer( void )
{
MSG_InitMasks();
TRUN( Test_Buffer_BitByte( ));
TRUN( Test_Buffer_Write( ));
TRUN( Test_Buffer_Read( ));

View File

@@ -193,7 +193,6 @@ static inline void MSG_StartBitWriting( sizebuf_t *sb )
sb->iAlternateSign++;
}
void MSG_InitMasks( void ); // called once at startup engine
void MSG_ExciseBits( sizebuf_t *sb, int startbit, int bitstoremove );
// Bit-write functions

View File

@@ -272,8 +272,6 @@ void Netchan_Init( void )
Cvar_FullSet( net_qport.name, buf, net_qport.flags );
net_mempool = Mem_AllocPool( "Network Pool" );
MSG_InitMasks(); // initialize bit-masks
}
void Netchan_Shutdown( void )
@@ -343,6 +341,7 @@ void Netchan_Setup( netsrc_t sock, netchan_t *chan, netadr_t adr, int qport, voi
chan->split = FBitSet( flags, NETCHAN_USE_LEGACY_SPLIT ) ? true : false;
chan->use_munge = FBitSet( flags, NETCHAN_USE_MUNGE ) ? true : false;
chan->use_bz2 = FBitSet( flags, NETCHAN_USE_BZIP2 ) ? true : false;
chan->use_lzss = FBitSet( flags, NETCHAN_USE_LZSS ) ? true : false;
chan->gs_netchan = FBitSet( flags, NETCHAN_GOLDSRC ) ? true : false;
MSG_Init( &chan->message, "NetData", chan->message_buf, sizeof( chan->message_buf ));
@@ -768,7 +767,7 @@ static void Netchan_CreateFragments_( netchan_t *chan, sizebuf_t *msg )
Host_Error( "%s: BZ2 compression is not supported for server", __func__ );
#endif
}
else if( !chan->use_bz2 && !LZSS_IsCompressed( MSG_GetData( msg ), MSG_GetMaxBytes( msg )))
else if( chan->use_lzss && !LZSS_IsCompressed( MSG_GetData( msg ), MSG_GetMaxBytes( msg )))
{
uint uCompressedSize = 0;
uint uSourceSize = MSG_GetNumBytesWritten( msg );
@@ -1175,7 +1174,7 @@ qboolean Netchan_CopyNormalFragments( netchan_t *chan, sizebuf_t *msg, size_t *l
p = n;
}
if( chan->use_bz2 && !memcmp( MSG_GetData( msg ), "BZ2", 4 ) )
if( chan->use_bz2 && !memcmp( MSG_GetData( msg ), "BZ2", 4 ))
{
#if !XASH_DEDICATED
byte buf[0x10000];
@@ -1196,7 +1195,7 @@ qboolean Netchan_CopyNormalFragments( netchan_t *chan, sizebuf_t *msg, size_t *l
Host_Error( "%s: BZ2 compression is not supported for server\n", __func__ );
#endif
}
else if( !chan->use_bz2 && LZSS_IsCompressed( MSG_GetData( msg ), size ))
else if( chan->use_lzss && LZSS_IsCompressed( MSG_GetData( msg ), size ))
{
uint uDecompressedLen = LZSS_GetActualSize( MSG_GetData( msg ), size );
byte buf[NET_MAX_MESSAGE];
@@ -1347,7 +1346,7 @@ qboolean Netchan_CopyFileFragments( netchan_t *chan, sizebuf_t *msg )
Host_Error( "%s: BZ2 compression is not supported for server", __func__ );
#endif
}
else if( LZSS_IsCompressed( buffer, nsize + 1 ))
else if( chan->use_lzss && LZSS_IsCompressed( buffer, nsize + 1 ))
{
byte *uncompressedBuffer;

View File

@@ -2282,10 +2282,6 @@ void Test_RunDelta( void )
char buffer[4096] = { 0 };
const double timebase = 123.123;
// a1ba: netbuffer bitmasks are initialized in netchan for some reason
// initialize it ourselves just in case
MSG_InitMasks(); // initialize bit-masks
Delta_AddField( dt, "dt_string", DT_STRING, 1, 1.0f, 1.0f );
Delta_AddField( dt, "dt_timewindow_big", DT_TIMEWINDOW_BIG, 24, 1000.f, 1.0f );
Delta_AddField( dt, "dt_timewindow_8", DT_TIMEWINDOW_8, 8, 1.0f, 1.0f );

View File

@@ -505,11 +505,14 @@ static int HTTP_FileDecompress( httpfile_t *file )
if( zlib_result == Z_OK || zlib_result == Z_STREAM_END )
{
Mem_Free( data_in );
g_fsapi.WriteFile( name, data_out, decompressed_len );
HTTP_FreeFile( file, false );
}
else HTTP_FreeFile( file, true );
Mem_Free( data_in );
Mem_Free( data_out );
g_fsapi.WriteFile( name, data_out, decompressed_len );
HTTP_FreeFile( file, false );
return 1;
}
@@ -841,7 +844,16 @@ static int HTTP_FileProcessStream( httpfile_t *curfile )
if( curfile->downloaded >= curfile->size )
{
HTTP_FreeFile( curfile, false ); // success
// chunked files are finalized in FileSaveReceivedData
if( curfile->compressed && !curfile->chunked )
{
curfile->pfn_process = HTTP_FileDecompress;
curfile->success = true;
}
else
{
HTTP_FreeFile( curfile, false ); // success
}
return 0;
}
}

View File

@@ -121,7 +121,7 @@ static CVAR_DEFINE_AUTO( net_resolve_debug, "0", FCVAR_PRIVILEGED, "print resolv
CVAR_DEFINE( net_clockwindow, "clockwindow", "0.5", FCVAR_PRIVILEGED, "timewindow to execute client moves" );
netadr_t net_local;
netadr_t net6_local;
static netadr_t net6_local;
// cvars equivalents for IPv6
static CVAR_DEFINE( net_ip6name, "ip6", "localhost", FCVAR_PRIVILEGED, "network ip6 address" );
@@ -151,17 +151,24 @@ static inline qboolean NET_IsSocketValid( int socket )
void NET_NetadrToIP6Bytes( uint8_t *ip6, const netadr_t *adr )
{
memcpy( ip6, adr->ip6, sizeof( adr->ip6 ));
memcpy( &ip6[0], adr->ip6_0, 2 );
memcpy( &ip6[2], adr->ip6_1, 14 );
}
void NET_IP6BytesToNetadr( netadr_t *adr, const uint8_t *ip6 )
{
memcpy( adr->ip6, ip6, sizeof( adr->ip6 ));
memcpy( adr->ip6_0, &ip6[0], 2 );
memcpy( adr->ip6_1, &ip6[2], 14 );
}
static int NET_NetadrIP6Compare( const netadr_t *a, const netadr_t *b )
{
return memcmp( a->ip6, b->ip6, sizeof( a->ip6 ));
uint8_t ip6_a[16], ip6_b[16];
NET_NetadrToIP6Bytes( ip6_a, a );
NET_NetadrToIP6Bytes( ip6_b, b );
return memcmp( ip6_a, ip6_b, sizeof( ip6_a ));
}
/*
@@ -171,27 +178,29 @@ NET_NetadrToSockadr
*/
static void NET_NetadrToSockadr( netadr_t *a, struct sockaddr_storage *s )
{
netadrtype_t type = NET_NetadrType( a );
memset( s, 0, sizeof( *s ));
if( a->type == NA_BROADCAST )
if( type == NA_BROADCAST )
{
s->ss_family = AF_INET;
((struct sockaddr_in *)s)->sin_port = a->port;
((struct sockaddr_in *)s)->sin_addr.s_addr = INADDR_BROADCAST;
}
else if( a->type == NA_IP )
else if( type == NA_IP )
{
s->ss_family = AF_INET;
((struct sockaddr_in *)s)->sin_port = a->port;
((struct sockaddr_in *)s)->sin_addr.s_addr = a->ip4;
}
else if( a->type6 == NA_IP6 )
else if( type == NA_IP6 )
{
s->ss_family = AF_INET6;
((struct sockaddr_in6 *)s)->sin6_port = a->port;
NET_NetadrToIP6Bytes(((struct sockaddr_in6 *)s)->sin6_addr.s6_addr, a );
}
else if( a->type6 == NA_MULTICAST_IP6 )
else if( type == NA_MULTICAST_IP6 )
{
s->ss_family = AF_INET6;
((struct sockaddr_in6 *)s)->sin6_port = a->port;
@@ -208,13 +217,13 @@ static void NET_SockadrToNetadr( const struct sockaddr_storage *s, netadr_t *a )
{
if( s->ss_family == AF_INET )
{
a->type = NA_IP;
NET_NetadrSetType( a, NA_IP );
a->ip4 = ((struct sockaddr_in *)s)->sin_addr.s_addr;
a->port = ((struct sockaddr_in *)s)->sin_port;
}
else if( s->ss_family == AF_INET6 )
{
a->type6 = NA_IP6;
NET_NetadrSetType( a, NA_IP6 );
NET_IP6BytesToNetadr( a, ((struct sockaddr_in6 *)s)->sin6_addr.s6_addr );
a->port = ((struct sockaddr_in6 *)s)->sin6_port;
}
@@ -549,8 +558,8 @@ qboolean NET_StringToFilterAdr( const char *s, netadr_t *adr, uint *prefixlen )
// try to parse as IPv6 first
if( ParseIPv6Addr( copy, ip6, NULL, NULL ))
{
NET_NetadrSetType( adr, NA_IP6 );
NET_IP6BytesToNetadr( adr, ip6 );
adr->type6 = NA_IP6;
if( !hasCIDR )
*prefixlen = 128;
@@ -620,7 +629,7 @@ qboolean NET_StringToFilterAdr( const char *s, netadr_t *adr, uint *prefixlen )
adr->ip4 = ntohl( mask );
}
adr->type = NA_IP;
NET_NetadrSetType( adr, NA_IP );
}
return true;
@@ -634,10 +643,11 @@ NET_AdrToString
const char *NET_AdrToString( const netadr_t a )
{
static char s[64];
netadrtype_t type = NET_NetadrType( &a );
if( a.type == NA_LOOPBACK )
if( type == NA_LOOPBACK )
return "loopback";
if( a.type6 == NA_IP6 || a.type6 == NA_MULTICAST_IP6 )
if( type == NA_IP6 || type == NA_MULTICAST_IP6 )
{
uint8_t ip6[16];
@@ -661,10 +671,11 @@ NET_BaseAdrToString
const char *NET_BaseAdrToString( const netadr_t a )
{
static char s[64];
netadrtype_t type = NET_NetadrType( &a );
if( a.type == NA_LOOPBACK )
if( type == NA_LOOPBACK )
return "loopback";
if( a.type6 == NA_IP6 || a.type6 == NA_MULTICAST_IP6 )
if( type == NA_IP6 || type == NA_MULTICAST_IP6 )
{
uint8_t ip6[16];
@@ -689,16 +700,19 @@ Compares without the port
*/
qboolean NET_CompareBaseAdr( const netadr_t a, const netadr_t b )
{
if( a.type6 != b.type6 )
netadrtype_t type_a = NET_NetadrType( &a );
netadrtype_t type_b = NET_NetadrType( &b );
if( type_a != type_b )
return false;
if( a.type == NA_LOOPBACK )
if( type_a == NA_LOOPBACK )
return true;
if( a.type == NA_IP )
if( type_a == NA_IP )
return a.ip4 == b.ip4;
if( a.type6 == NA_IP6 )
if( type_a == NA_IP6 )
{
if( !NET_NetadrIP6Compare( &a, &b ))
return true;
@@ -707,36 +721,6 @@ qboolean NET_CompareBaseAdr( const netadr_t a, const netadr_t b )
return false;
}
/*
====================
NET_CompareClassBAdr
Compare local masks
====================
*/
qboolean NET_CompareClassBAdr( const netadr_t a, const netadr_t b )
{
if( a.type6 != b.type6 )
return false;
if( a.type == NA_LOOPBACK )
return true;
if( a.type == NA_IP )
{
if( a.ip[0] == b.ip[0] && a.ip[1] == b.ip[1] )
return true;
}
// NOTE: we don't check for IPv6 here
// this check is very dumb and only used for LAN restriction
// Actual check is in IsReservedAdr
// for real mask compare use NET_CompareAdrByMask
return false;
}
/*
====================
NET_CompareAdrByMask
@@ -746,10 +730,13 @@ Checks if adr is a part of subnet
*/
qboolean NET_CompareAdrByMask( const netadr_t a, const netadr_t b, uint prefixlen )
{
if( a.type6 != b.type6 || a.type == NA_LOOPBACK )
netadrtype_t type_a = NET_NetadrType( &a );
netadrtype_t type_b = NET_NetadrType( &b );
if( type_a != type_b || type_a == NA_LOOPBACK )
return false;
if( a.type == NA_IP )
if( type_a == NA_IP )
{
uint32_t ipa = htonl( a.ip4 );
uint32_t ipb = htonl( b.ip4 );
@@ -757,7 +744,7 @@ qboolean NET_CompareAdrByMask( const netadr_t a, const netadr_t b, uint prefixle
if(( ipa & (( 0xFFFFFFFFU ) << ( 32 - prefixlen ))) == ipb )
return true;
}
else if( a.type6 == NA_IP6 )
else if( type_a == NA_IP6 )
{
uint16_t a_[8], b_[8];
size_t check = prefixlen / 16;
@@ -798,11 +785,13 @@ Check for reserved ip's
*/
qboolean NET_IsReservedAdr( netadr_t a )
{
if( a.type == NA_LOOPBACK )
netadrtype_t type_a = NET_NetadrType( &a );
if( type_a == NA_LOOPBACK )
return true;
// Following checks was imported from GameNetworkingSockets library
if( a.type == NA_IP )
if( type_a == NA_IP )
{
if(( a.ip[0] == 10 ) || // 10.x.x.x is reserved
( a.ip[0] == 127 ) || // 127.x.x.x
@@ -814,7 +803,7 @@ qboolean NET_IsReservedAdr( netadr_t a )
}
}
if( a.type6 == NA_IP6 )
if( type_a == NA_IP6 )
{
uint8_t ip6[16];
@@ -847,20 +836,23 @@ Compare full address
*/
qboolean NET_CompareAdr( const netadr_t a, const netadr_t b )
{
if( a.type6 != b.type6 )
netadrtype_t type_a = NET_NetadrType( &a );
netadrtype_t type_b = NET_NetadrType( &b );
if( type_a != type_b )
return false;
if( a.type == NA_LOOPBACK )
if( type_a == NA_LOOPBACK )
return true;
if( a.type == NA_IP )
if( type_a == NA_IP )
{
if( a.ip4 == b.ip4 && a.port == b.port )
return true;
return false;
}
if( a.type6 == NA_IP6 )
if( type_a == NA_IP6 )
{
if( a.port == b.port && !NET_NetadrIP6Compare( &a, &b ))
return true;
@@ -883,9 +875,13 @@ int NET_CompareAdrSort( const void *_a, const void *_b )
{
const netadr_t *a = _a, *b = _b;
int porta, portb, portdiff, addrdiff;
netadrtype_t type_a, type_b;
if( a->type6 != b->type6 )
return bound( -1, (int)a->type6 - (int)b->type6, 1 );
type_a = NET_NetadrType( a );
type_b = NET_NetadrType( b );
if( type_a != type_b )
return bound( -1, (int)type_a - (int)type_b, 1 );
porta = ntohs( a->port );
portb = ntohs( b->port );
@@ -896,7 +892,7 @@ int NET_CompareAdrSort( const void *_a, const void *_b )
else
portdiff = 0;
switch( a->type6 )
switch( type_a )
{
case NA_IP6:
if(( addrdiff = NET_NetadrIP6Compare( a, b )))
@@ -904,14 +900,7 @@ int NET_CompareAdrSort( const void *_a, const void *_b )
// fallthrough
case NA_MULTICAST_IP6:
return portdiff;
}
// don't check for full type earlier, as it's value depends on v6 address
if( a->type != b->type )
return bound( -1, (int)a->type - (int)b->type, 1 );
switch( a->type )
{
case NA_IP:
if(( addrdiff = memcmp( a->ip, b->ip, sizeof( a->ipx ))))
return addrdiff;
@@ -946,7 +935,7 @@ static qboolean NET_StringToAdrEx( const char *string, netadr_t *adr, int family
if( !Q_stricmp( string, "localhost" ) || !Q_stricmp( string, "loopback" ))
{
adr->type = NA_LOOPBACK;
NET_NetadrSetType( adr, NA_LOOPBACK );
return true;
}
@@ -971,7 +960,7 @@ net_gai_state_t NET_StringToAdrNB( const char *string, netadr_t *adr, qboolean v
if( !Q_stricmp( string, "localhost" ) || !Q_stricmp( string, "loopback" ))
{
adr->type = NA_LOOPBACK;
NET_NetadrSetType( adr, NA_LOOPBACK );
return NET_EAI_OK;
}
@@ -1017,7 +1006,7 @@ static qboolean NET_GetLoopPacket( netsrc_t sock, netadr_t *from, byte *data, si
*length = loop->msgs[i].datalen;
memset( from, 0, sizeof( *from ));
from->type = NA_LOOPBACK;
NET_NetadrSetType( from, NA_LOOPBACK );
return true;
}
@@ -1523,7 +1512,7 @@ static int NET_SendLong( netsrc_t sock, int net_socket, const char *buf, size_t
total_sent += size;
len -= size;
packet_number++;
Platform_Sleep( 1 );
Platform_NanoSleep( 100 * 1000 );
}
return total_sent;
@@ -1546,19 +1535,20 @@ void NET_SendPacketEx( netsrc_t sock, size_t length, const void *data, netadr_t
int ret;
struct sockaddr_storage addr = { 0 };
SOCKET net_socket = 0;
netadrtype_t type = NET_NetadrType( &to );
if( !net.initialized || to.type == NA_LOOPBACK )
if( !net.initialized || type == NA_LOOPBACK )
{
NET_SendLoopPacket( sock, length, data, to );
return;
}
else if( to.type == NA_BROADCAST || to.type == NA_IP )
else if( type == NA_BROADCAST || type == NA_IP )
{
net_socket = net.ip_sockets[sock];
if( !NET_IsSocketValid( net_socket ))
return;
}
else if( to.type6 == NA_MULTICAST_IP6 || to.type6 == NA_IP6 )
else if( type == NA_MULTICAST_IP6 || type == NA_IP6 )
{
net_socket = net.ip6_sockets[sock];
if( !NET_IsSocketValid( net_socket ))
@@ -1566,7 +1556,7 @@ void NET_SendPacketEx( netsrc_t sock, size_t length, const void *data, netadr_t
}
else
{
Host_Error( "%s: bad address type %i (%i)\n", __func__, to.type, to.type6 );
Host_Error( "%s: bad address type %i (%i, %i)\n", __func__, to.type, to.ip6_0[0], to.ip6_0[1] );
}
NET_NetadrToSockadr( &to, &addr );
@@ -1582,7 +1572,7 @@ void NET_SendPacketEx( netsrc_t sock, size_t length, const void *data, netadr_t
return;
// some PPP links don't allow broadcasts
if( err == WSAEADDRNOTAVAIL && ( to.type == NA_BROADCAST || to.type6 == NA_MULTICAST_IP6 ))
if( err == WSAEADDRNOTAVAIL && ( type == NA_BROADCAST || type == NA_MULTICAST_IP6 ))
return;
if( Host_IsDedicated( ))
@@ -1801,12 +1791,12 @@ static void NET_OpenIP( qboolean change_port, int *sockets, const char *net_ifac
/*
================
NET_GetLocalAddress
NET_DetermineLocalAddress
Returns the servers' ip address as a string.
================
*/
static void NET_GetLocalAddress( void )
static void NET_DetermineLocalAddress( void )
{
char hostname[512];
char buff[512];
@@ -1920,7 +1910,7 @@ void NET_Config( qboolean multiplayer, qboolean changeport )
// get our local address, if possible
if( bFirst )
{
NET_GetLocalAddress();
NET_DetermineLocalAddress();
bFirst = false;
}
}
@@ -2016,6 +2006,32 @@ static void NET_ClearLagData( qboolean bClient, qboolean bServer )
if( bServer ) NET_ClearLaggedList( &net.lagdata[NS_SERVER] );
}
/*
====================
NET_GetLocalAddress
get local server addresses
====================
*/
void NET_GetLocalAddress( netadr_t *ip4, netadr_t *ip6 )
{
if( ip4 )
{
if( net.allow_ip )
*ip4 = net_local;
else
memset( ip4, 0, sizeof( *ip4 ));
}
if( ip6 )
{
if( net.allow_ip6 )
*ip6 = net6_local;
else
memset( ip6, 0, sizeof( *ip6 ));
}
}
/*
====================
NET_Init
@@ -2037,6 +2053,7 @@ void NET_Init( void )
Cvar_RegisterVariable( &net_fakelag );
Cvar_RegisterVariable( &net_fakeloss );
Cvar_RegisterVariable( &net_resolve_debug );
Cvar_RegisterVariable( &net_clockwindow );
Q_snprintf( cmd, sizeof( cmd ), "%i", PORT_SERVER );
Cvar_FullSet( "hostport", cmd, FCVAR_READ_ONLY );

View File

@@ -64,7 +64,6 @@ void NET_Config( qboolean net_enable, qboolean changeport );
const char *NET_AdrToString( const netadr_t a ) RETURNS_NONNULL;
const char *NET_BaseAdrToString( const netadr_t a ) RETURNS_NONNULL;
qboolean NET_IsReservedAdr( netadr_t a );
qboolean NET_CompareClassBAdr( const netadr_t a, const netadr_t b );
qboolean NET_StringToAdr( const char *string, netadr_t *adr );
qboolean NET_StringToFilterAdr( const char *s, netadr_t *adr, uint *prefixlen );
net_gai_state_t NET_StringToAdrNB( const char *string, netadr_t *adr, qboolean v6only );
@@ -80,9 +79,11 @@ void NET_NetadrToIP6Bytes( uint8_t *ip6, const netadr_t *adr );
static inline qboolean NET_IsLocalAddress( netadr_t adr )
{
return adr.type == NA_LOOPBACK ? true : false;
return NET_NetadrType( &adr ) == NA_LOOPBACK;
}
void NET_GetLocalAddress( netadr_t *ip4, netadr_t *ip6 );
#if !XASH_DEDICATED
int CL_GetSplitSize( void );
#endif

View File

@@ -69,7 +69,6 @@ GNU General Public License for more details.
// bytes will be stripped by the networking channel layer
#define NET_MAX_MESSAGE PAD_NUMBER(( NET_MAX_PAYLOAD + HEADER_BYTES ), 16 )
#define MASTERSERVER_ADR "mentality.rip:27010"
#define MS_SCAN_REQUEST "1\xFF" "0.0.0.0:0\0"
#define PORT_MASTER 27010
@@ -214,6 +213,7 @@ typedef enum netchan_flags_e
NETCHAN_USE_MUNGE = BIT( 1 ),
NETCHAN_USE_BZIP2 = BIT( 2 ),
NETCHAN_GOLDSRC = BIT( 3 ),
NETCHAN_USE_LZSS = BIT( 4 ), // mutually exclusive with bzip2
} netchan_flags_t;
// Network Connection Channel
@@ -285,12 +285,11 @@ typedef struct netchan_s
qboolean split;
qboolean use_munge;
qboolean use_bz2;
qboolean use_lzss;
qboolean gs_netchan;
} netchan_t;
extern netadr_t net_from;
extern netadr_t net_local;
extern netadr_t net6_local;
extern sizebuf_t net_message;
extern byte net_message_buffer[NET_MAX_MESSAGE];
extern convar_t sv_lan;

View File

@@ -14,9 +14,6 @@ GNU General Public License for more details.
*/
#include "soundlib.h"
#if XASH_SDL
#include <SDL_audio.h>
#endif // XASH_SDL
// global sound variables
sndlib_t sound;
@@ -31,19 +28,15 @@ sndlib_t sound;
static const loadwavfmt_t load_game[] =
{
#ifndef XASH_DEDICATED
{ DEFAULT_SOUNDPATH "%s%s.%s", "wav", Sound_LoadWAV },
{ "%s%s.%s", "wav", Sound_LoadWAV },
{ DEFAULT_SOUNDPATH "%s%s.%s", "mp3", Sound_LoadMPG },
{ "%s%s.%s", "mp3", Sound_LoadMPG },
{ DEFAULT_SOUNDPATH "%s%s.%s", "ogg", Sound_LoadOggVorbis },
{ "%s%s.%s", "ogg", Sound_LoadOggVorbis },
{ DEFAULT_SOUNDPATH "%s%s.%s", "opus", Sound_LoadOggOpus },
{ "%s%s.%s", "opus", Sound_LoadOggOpus },
{ "wav", Sound_LoadWAV },
{ "mp3", Sound_LoadMPG },
{ "ogg", Sound_LoadOggVorbis },
{ "opus", Sound_LoadOggOpus },
#else // we only need extensions
{ NULL, "wav" },
{ NULL, "mp3" },
{ NULL, "ogg" },
{ NULL, "opus" },
{ "wav" },
{ "mp3" },
{ "ogg" },
{ "opus" },
#endif
{ NULL },
};
@@ -58,15 +51,15 @@ static const loadwavfmt_t load_game[] =
static const streamfmt_t stream_game[] =
{
#ifndef XASH_DEDICATED
{ "%s%s.%s", "mp3", Stream_OpenMPG, Stream_ReadMPG, Stream_SetPosMPG, Stream_GetPosMPG, Stream_FreeMPG },
{ "%s%s.%s", "wav", Stream_OpenWAV, Stream_ReadWAV, Stream_SetPosWAV, Stream_GetPosWAV, Stream_FreeWAV },
{ "%s%s.%s", "ogg", Stream_OpenOggVorbis, Stream_ReadOggVorbis, Stream_SetPosOggVorbis, Stream_GetPosOggVorbis, Stream_FreeOggVorbis },
{ "%s%s.%s", "opus", Stream_OpenOggOpus, Stream_ReadOggOpus, Stream_SetPosOggOpus, Stream_GetPosOggOpus, Stream_FreeOggOpus },
{ "mp3", Stream_OpenMPG, Stream_ReadMPG, Stream_SetPosMPG, Stream_GetPosMPG, Stream_FreeMPG },
{ "wav", Stream_OpenWAV, Stream_ReadWAV, Stream_SetPosWAV, Stream_GetPosWAV, Stream_FreeWAV },
{ "ogg", Stream_OpenOggVorbis, Stream_ReadOggVorbis, Stream_SetPosOggVorbis, Stream_GetPosOggVorbis, Stream_FreeOggVorbis },
{ "opus", Stream_OpenOggOpus, Stream_ReadOggOpus, Stream_SetPosOggOpus, Stream_GetPosOggOpus, Stream_FreeOggOpus },
#else // we only need extensions
{ NULL, "mp3" },
{ NULL, "wav" },
{ NULL, "ogg" },
{ NULL, "opus" },
{ "mp3" },
{ "wav" },
{ "ogg" },
{ "opus" },
#endif
{ NULL },
};
@@ -89,16 +82,6 @@ void Sound_Shutdown( void )
Mem_FreePool( &host.soundpool );
}
static byte *Sound_Copy( size_t size )
{
byte *out;
out = Mem_Realloc( host.soundpool, sound.tempbuffer, size );
sound.tempbuffer = NULL;
return out;
}
uint GAME_EXPORT Sound_GetApproxWavePlayLen( const char *filepath )
{
string name;
@@ -378,6 +361,7 @@ static qboolean Sound_ResampleInternal( wavdata_t *sc, int outrate, int outwidth
const int inwidth = sc->width;
const int inchannels = sc->channels;
const int incount = sc->samples;
const int insize = sc->size;
qboolean handled = false;
double stepscale;
double t1, t2;
@@ -397,31 +381,6 @@ static qboolean Sound_ResampleInternal( wavdata_t *sc, int outrate, int outwidth
if( FBitSet( sc->flags, SOUND_LOOPED ))
sc->loopStart = sc->loopStart / stepscale;
#if 0 && XASH_SDL // slow but somewhat accurate (wasn't updated to channel manipulation!!!)
{
const SDL_AudioFormat infmt = inwidth == 1 ? AUDIO_S8 : AUDIO_S16;
const SDL_AudioFormat outfmt = outwidth == 1 ? AUDIO_S8 : AUDIO_S16;
SDL_AudioCVT cvt;
// SDL_AudioCVT does conversion in place, original buffer is used for it
if( SDL_BuildAudioCVT( &cvt, infmt, inchannels, inrate, outfmt, outchannels, outrate ) > 0 && cvt.needed )
{
sc->buffer = (byte *)Mem_Realloc( host.soundpool, sc->buffer, oldsize * cvt.len_mult );
cvt.len = oldsize;
cvt.buf = sc->buffer;
if( !SDL_ConvertAudio( &cvt ))
{
t2 = Sys_DoubleTime();
Con_Reportf( "Sound_Resample: from [%d bit %d Hz] to [%d bit %d Hz] (took %.3fs through SDL)\n", inwidth * 8, inrate, outwidth * 8, outrate, t2 - t1 );
sc->rate = outrate;
sc->width = outwidth;
return false; // HACKHACK: return false so Sound_Process won't reallocate buffer
}
}
}
#endif
sound.tempbuffer = (byte *)Mem_Realloc( host.soundpool, sound.tempbuffer, sc->size );
if( inrate == outrate ) // no resampling, just copy data
@@ -431,22 +390,30 @@ static qboolean Sound_ResampleInternal( wavdata_t *sc, int outrate, int outwidth
else // upsample case, w/ interpolation
handled = Sound_ConvertUpsample( sc, inwidth, inchannels, incount, outwidth, outchannels, outcount, stepscale );
t2 = Sys_DoubleTime();
if( handled )
if( !handled )
{
if( t2 - t1 > 0.01f ) // critical, report to mod developer
Con_Printf( S_WARN "%s: from [%d bit %d Hz %dch] to [%d bit %d Hz %dch] (took %.3fs)\n", __func__, inwidth * 8, inrate, inchannels, outwidth * 8, outrate, outchannels, t2 - t1 );
else
Con_Reportf( "%s: from [%d bit %d Hz %dch] to [%d bit %d Hz %dch] (took %.3fs)\n", __func__, inwidth * 8, inrate, inchannels, outwidth * 8, outrate, outchannels, t2 - t1 );
}
else
// restore previously changed data
sc->rate = inrate;
sc->width = inwidth;
sc->channels = inchannels;
sc->samples = incount;
sc->size = insize;
Con_Printf( S_ERROR "%s: unsupported from [%d bit %d Hz %dch] to [%d bit %d Hz %dch]\n", __func__, inwidth * 8, inrate, inchannels, outwidth * 8, outrate, outchannels );
return false;
}
t2 = Sys_DoubleTime();
sc->rate = outrate;
sc->width = outwidth;
return handled;
if( t2 - t1 > 0.01f ) // critical, report to mod developer
Con_Printf( S_WARN "%s: from [%d bit %d Hz %dch] to [%d bit %d Hz %dch] (took %.3fs)\n", __func__, inwidth * 8, inrate, inchannels, outwidth * 8, outrate, outchannels, t2 - t1 );
else
Con_Reportf( "%s: from [%d bit %d Hz %dch] to [%d bit %d Hz %dch] (took %.3fs)\n", __func__, inwidth * 8, inrate, inchannels, outwidth * 8, outrate, outchannels, t2 - t1 );
return true;
}
qboolean Sound_Process( wavdata_t **wav, int rate, int width, int channels, uint flags )
@@ -464,8 +431,11 @@ qboolean Sound_Process( wavdata_t **wav, int rate, int width, int channels, uint
if( result )
{
Mem_Free( snd->buffer ); // free original image buffer
snd->buffer = Sound_Copy( snd->size ); // unzone buffer
snd = Mem_Realloc( host.soundpool, snd, sizeof( *snd ) + snd->size );
memcpy( snd->buffer, sound.tempbuffer, snd->size );
Mem_Free( sound.tempbuffer );
sound.tempbuffer = NULL;
}
}
@@ -479,7 +449,7 @@ qboolean Sound_SupportedFileFormat( const char *fileext )
const loadwavfmt_t *format;
if( COM_CheckStringEmpty( fileext ))
{
for( format = sound.loadformats; format && format->formatstring; format++ )
for( format = sound.loadformats; format && format->ext; format++ )
{
if( !Q_stricmp( format->ext, fileext ))
return true;

Some files were not shown because too many files have changed in this diff Show More