Compare commits

...

1038 Commits

Author SHA1 Message Date
Alibek Omarov
29c9393da3 wscript: enable faster builds with gccdeps/msvcdeps 2023-10-31 04:30:27 +03:00
Alibek Omarov
bf6829189e wscript: move XASH_BUILD_COMMIT definition to libpublic, as this is the only place where it's used, for faster builds 2023-10-31 04:30:27 +03:00
Alibek Omarov
a62a9429c9 engine: launcher: remove Windows code from single binary launcher, as Windows completely supports running from external launcher and don't need dedicated builds 2023-10-31 04:30:22 +03:00
mittorn
f2c080e736 gl2shim: fix broken matrix update when fog attribute enabled (32 bit shift overflow) 2023-10-30 22:34:34 +03:00
Alibek Omarov
ea55e78855 ref: _inline -> static 2023-10-29 23:38:43 +03:00
Alibek Omarov
f7c536b81c engine: server: allow loading maps from subdirectories as this is used by some Half-Life mods 2023-10-29 02:44:46 +03:00
Alibek Omarov
6c40104c66 public: better fix for ExtractFilePath 2023-10-28 19:31:17 +03:00
Alibek Omarov
4d7d592918 engine: mod_bmodel: completely get rid of global loadmodel pointer 2023-10-28 16:06:00 +03:00
Alibek Omarov
c5e91f299b engine: mod_studio: reduce dependency on global loadmodel pointer, make it private for brush model loader 2023-10-28 15:38:40 +03:00
Alibek Omarov
cff276db71 engine: client: mod_dbghulls: reduce dependency on global loadmodel pointer 2023-10-28 15:35:20 +03:00
Alibek Omarov
30d1492b93 engine: remove Set/GetCurrentLoadingModel from RefAPI 2023-10-28 15:22:21 +03:00
Alibek Omarov
f07eea5073 engine: server: allow server unloading for Win32 targets until we figure out the issues with MetaMod 2023-10-28 11:14:12 +03:00
Alibek Omarov
fe407fbe00 public: workaround when empty string is passed to COM_ExtractFilePath (should make safe COM_ExtractFilePath) 2023-10-28 11:06:18 +03:00
Alibek Omarov
78bc177e05 engine: server: remove unused host struct field 2023-10-28 11:06:18 +03:00
Alibek Omarov
8fb908e3d4 engine: server: disable SV_UnloadProgs, only call it when shutting down engine 2023-10-28 11:06:18 +03:00
Alibek Omarov
d8b261370a engine: common: do not probe server to collect cvars for game.cfg (CHECK THIS) 2023-10-28 11:06:18 +03:00
Alibek Omarov
a2c9ac5b1f engine: client: disable server DLL probe for GameUI, check it's existence instead 2023-10-28 11:06:18 +03:00
Alibek Omarov
7f9025e178 engine: server: sv_pmove: use model name for physent name to avoid crash when classname isn't initialized yet 2023-10-28 11:04:43 +03:00
Alibek Omarov
8647110a10 Revert "engine: wscript: move libasound uselib under linux condition, as the ALSA interface is only relevant for Linux"
This reverts commit 48e44f0057.
2023-10-28 10:10:03 +03:00
Alibek Omarov
48e44f0057 engine: wscript: move libasound uselib under linux condition, as the ALSA interface is only relevant for Linux 2023-10-27 17:03:04 +03:00
Alibek Omarov
e3934af7d1 wscript: always load cmakelists generation tool 2023-10-27 16:57:22 +03:00
Alibek Omarov
a5ee631191 engine: server: sv_game: disable searching closer to server library memory region for Android 2023-10-27 14:31:16 +03:00
Alibek Omarov
ce39255ef0 engine: host: set rootdir on Android SDL port 2023-10-27 14:25:16 +03:00
Alibek Omarov
5aac5d2a52 filesystem: VFileSystem009: add pathid support to RemoveFile method 2023-10-27 08:02:45 +03:00
Alibek Omarov
061b50404d engine: server: register dummy cvar sv_allow_dlfile for GoldSrc compatibility 2023-10-27 08:02:10 +03:00
Alibek Omarov
279cec5ae9 engine: rename cl/sv_allowdownload for GoldSrc compatibility 2023-10-27 07:25:09 +03:00
Alibek Omarov
83a5648335 filesystem: only allow setting true or false for boolean type keys in gameinfo/liblist.gam 2023-10-27 07:24:42 +03:00
Alibek Omarov
a8fc9a4c5a waf: update to latest waifu 2023-10-27 07:24:18 +03:00
Alibek Omarov
6f6ddbce28 engine: add argument -timedemo that makes engine run timedemo and exit 2023-10-27 03:49:00 +03:00
Alibek Omarov
4cb425d2bb engine: console: do not draw console and do not draw notify in timedemo 2023-10-27 03:47:52 +03:00
mittorn
bf5fd40d64 gl2shim: workaround empty rgb5/rgb8 textures 2023-10-26 23:08:02 +03:00
mittorn
6bc613bdb4 ref_gl: force gles2 on non-nanogl until we support gles1 directly 2023-10-26 23:07:39 +03:00
mittorn
a982562658 ref_gl: Fix missing DebugOutput functions on GLES 2023-10-26 23:07:22 +03:00
Alibek Omarov
96a9172e36 engine: platform: sdl: check that we're handling SDL errors according to it's documentation 2023-10-26 23:06:50 +03:00
Alibek Omarov
34d7664342 ref: gl: disable TGA flip for detail textures, GoldSrc ignores it, so we will too 2023-10-26 05:12:38 +03:00
Alibek Omarov
b0a79df86f ref: change r_traceglow to 0, as GoldSrc does 2023-10-26 04:59:01 +03:00
Alibek Omarov
9e107e900c engine: network: fix async NS resolve
If we're currently running NS resolving thread, any request would block.

Co-Authored-by: mittorn <mittorn@sibmail.com>
2023-10-24 18:11:31 +03:00
Alibek Omarov
8f819a2fde engine: platform: sdl: fix forgotten icon setup call 2023-10-23 00:31:30 +03:00
Alibek Omarov
3251b68df5 ref: gl: more simple search of GL func with alternative name (EXT, OES suffixes or no suffix) 2023-10-22 20:02:14 +03:00
Alibek Omarov
3ac8ad9484 engine: fixup endianness found by -Werror=strict-aliasing in old armv7hf compiler (d259421111) 2023-10-22 20:02:14 +03:00
Alibek Omarov
b9ca0d4563 engine: common: network: more simple IP address copying from sockaddr to netadr_t and back 2023-10-22 20:02:14 +03:00
mittorn
dcb3da53b0 engine/client: fallback to defaults in touch_reloadconfig if config not exist 2023-10-22 20:02:14 +03:00
mittorn
e68b19ed1a engine/client: handle touch config aspect ratio, try correctly handle touch aspect on resizeable windows 2023-10-22 20:02:14 +03:00
mittorn
14c7a84482 engine/client: always save touch config if it was resetted manually (helps after writing broken/empty config) 2023-10-22 20:02:14 +03:00
mittorn
c1d1aa6787 ref_gl: rewrite ARB workaround to check EXT/OES names, notify user that function found with different name 2023-10-22 20:02:14 +03:00
mittorn
bee81e9723 engine: Make SDL_GetBasePath error not fatal 2023-10-22 20:02:14 +03:00
mittorn
1bfb6c560a platform/sdl: add check for missing hint defines 2023-10-22 20:02:14 +03:00
mittorn
24d6f1788a platform/sdl: workaround ubuntu SDL2 bug preventing resolving any extensions on EGL 2023-10-22 20:02:14 +03:00
mittorn
fb95cc9a97 engine/client: respect m_ignore in mouse client code as grabbing window breaks touch input 2023-10-22 20:02:14 +03:00
mittorn
b949da291e engine: fix strict aliasing issues found by an old armv7hf compiler 2023-10-22 20:02:14 +03:00
Alibek Omarov
2ecbe5b67e engine: add testing master server at mentality.rip:27011 2023-10-22 19:39:58 +03:00
Andrey Akhmichin
6634e0487c Documentation: opensource-mods.md: update. 2023-10-22 19:21:13 +03:00
Alibek Omarov
7d61b5317c engine: client: add random key to the query, so we can validate master server response 2023-10-22 18:16:42 +03:00
Alibek Omarov
201258dc9e engine: client: allow passing additional filter through internetservers command arguments 2023-10-22 17:58:28 +03:00
Alibek Omarov
0330569537 engine: client: remove master server queries from NetAPI, they are never used by mods 2023-10-22 17:49:52 +03:00
Alibek Omarov
a1ab84a2ca mainui: update 2023-10-22 17:38:44 +03:00
Alibek Omarov
2d79f3ef7a engine: common: sys_con: enable writing build commit, os and arch to the engine.log 2023-10-22 17:37:09 +03:00
Alibek Omarov
99a7e9ad87 wscript: enable -Werror=nonnull 2023-10-22 17:37:09 +03:00
Alibek Omarov
02b8037f33 common: xash3d_types: add NONNULL attribute 2023-10-22 17:37:09 +03:00
Andrey Akhmichin
fc55a685e3 utils: mdldec: small optimizations. 2023-10-22 16:00:01 +03:00
Alibek Omarov
b76a75d6b4 ref: gl: respect gl_texture_nearest value for skyboxes 2023-10-20 18:55:22 +03:00
Ivan Avdeev
a251600c8a engine: common: imagelib: add KTX2 support (#1455)
* engine: common: imagelib: add KTX2 support

Adds basic KTX2 support for a few compressed formats. KTX2 essentially
is a Vulkan-centric texture format that supports literally hundreds of
pixel formats.
For now only support for these is added:
- `VK_FORMAT_BC4_UNORM_BLOCK`
- `VK_FORMAT_BC4_SNORM_BLOCK`
- `VK_FORMAT_BC5_UNORM_BLOCK`
- `VK_FORMAT_BC5_SNORM_BLOCK`
- `VK_FORMAT_BC6H_UFLOAT_BLOCK`
- `VK_FORMAT_BC6H_SFLOAT_BLOCK`
- `VK_FORMAT_BC7_UNORM_BLOCK`
- `VK_FORMAT_BC7_SRGB_BLOCK`

Adding more formats is relatively straightforward:
- Copy format definition from `VkFormat` enum in `vulkan_core.h`
- Add a new definition into `pixformat_t` enum.
- Add format size calculation into `Image_ComputeSize()`

While we're at it, also adds a few new formats to DDS:
- BC4_UNORM -- PF_BC4_UNSIGNED
- BC4_SNORM -- PF_BC4_SIGNED
- BC5_UNORM -- PF_BC5_UNSIGNED
- BC5_SNORM -- PF_BC5_SIGNED
- BC7 is expanded into BC7_UNORM and BC7_SRGB

ref_gl and ref_soft code is updated where it made sense. But not tested
really. Support for these formats has been tested with ref_vk.

* address spaces-vs-parentheses formatting where noticed

* parenthesize sizeofs

* move ktx2.h to imagelib as img_ktx2.h; massage it a bit

* use SetBits() instead of |=

* remove stale TODO comments
2023-10-18 10:31:40 +03:00
Andrey Akhmichin
c551aefd77 utils: mdldec: add boneweights support. 2023-10-18 10:12:48 +03:00
Andrey Akhmichin
f343f0da41 utils: mdldec: return different errorcodes on error. 2023-10-16 09:36:26 +03:00
Andrey Akhmichin
6d318a4102 utils: mdldec: smd.c: replace loop with VectorMA. 2023-10-16 09:35:51 +03:00
mittorn
a2b992d865 ref_gl: fix codestyle 2023-10-16 06:47:55 +03:00
mittorn
ddf3f2ffdb gl2shim: Allow drawing huge QUADS sequences by splitting drawcalls on overflow 2023-10-16 06:47:55 +03:00
Alibek Omarov
2454e87509 ref_gl: gl2shim: refactoring, add missing spaces in parentheses and ternary ops, remove singleline multiple assignments, use bitset macros 2023-10-16 06:47:55 +03:00
mittorn
0dc44249a2 ref_gl: fix XASH_GL_STATIC build 2023-10-16 06:47:55 +03:00
mittorn
150cbfa4de ref_gl: do not trust REFAPI context version, get it from OpenGL anyway 2023-10-16 06:47:55 +03:00
mittorn
c0b068d81b ref_gl: add workarounds for detecting extensions correctly on gles1/gles2 without wrapper (swiftshader works now) 2023-10-16 06:47:55 +03:00
mittorn
fbc312b6cf gl2shim: remove float suffix in shaders, that makes glsl100 work in swiftshader 2023-10-16 06:47:55 +03:00
mittorn
342e0d3e2e gl2shim: add glsl100 support 2023-10-16 06:47:55 +03:00
mittorn
202b228691 gl2shim: correct allocation/cleanup 2023-10-16 06:47:55 +03:00
mittorn
c9c1286803 ref_gl: fix typo 2023-10-16 06:47:55 +03:00
mittorn
eab98b0eda gl2shim: dynamic extension checking and autoconfiguration 2023-10-16 06:47:55 +03:00
mittorn
35be80fc21 ref_gl: request gl1.1 if compatibility profile unavailiable, this fixes launching with GL <= 2.0, improve old version extension detection 2023-10-16 06:47:55 +03:00
mittorn
6041bb0a43 platform/sdl: fix safegl 2023-10-16 06:47:55 +03:00
mittorn
c7dd9d6437 ref_gl: init r_temppool before InitExtensions, fix extension string allocation 2023-10-16 06:47:55 +03:00
mittorn
d378878c91 gl2shim: try fix getting program link log 2023-10-16 06:47:55 +03:00
mittorn
4a2f8cafcd gl2shim: try fix errors in ViZual ZtudiO 2023-10-16 06:47:55 +03:00
mittorn
d254bac16b ref_gl: integrate gl2shim extensions 2023-10-16 06:47:55 +03:00
mittorn
e23b632ce5 ref_gl: add missing non-arb shader functions 2023-10-16 06:47:55 +03:00
mittorn
2f321b1471 ref_gl: implement minimum inclusion version for GL extensions, implement quering extensions on core profile 2023-10-16 06:47:55 +03:00
mittorn
0265e88d8f gl2shim: fix wrong color vertex 2023-10-16 06:47:55 +03:00
mittorn
4114d2f24d gl2shim: more refactoring 2023-10-16 06:47:55 +03:00
mittorn
8124035763 ref_gl: try fix psvita 2023-10-16 06:47:55 +03:00
mittorn
96127c6eb0 gl2shim: make shaders code more portable 2023-10-16 06:47:55 +03:00
mittorn
cf65a39b83 gl2shim: refactoring 2023-10-16 06:47:55 +03:00
mittorn
0341f96b70 gl2shim: use IBO for quads 2023-10-16 06:47:55 +03:00
mittorn
c95d91cfe3 gl2shim: limit begin-end chain length, cycle incremental buffers 2023-10-16 06:47:55 +03:00
mittorn
cbd10c6279 gl2shim: improve shader version handling, fix particle issues 2023-10-16 06:47:55 +03:00
mittorn
5df9e57743 gl2shim: support incremental non-persistent buffers for arrays 2023-10-16 06:47:55 +03:00
mittorn
c178022fb5 gl2shim: persistent incremental streaming buffers, buffer cycling support 2023-10-16 06:47:55 +03:00
mittorn
724c29d711 gl2shim: implement fallback vbo, glDrawRangeElements with non-vbo buffer works now on core contexts 2023-10-16 06:47:55 +03:00
mittorn
74a2dbeb91 gl2shim: batcher experiments (UGLY, DO NOT USE), fix bad shader bindings, Draw QUADS with TRIFAN when possible 2023-10-16 06:47:55 +03:00
mittorn
5d20d24ebc gl2shim: simple matrix invalidation, do not calculate MVP every drawcall 2023-10-16 06:47:55 +03:00
mittorn
0e2fc277c8 gl2shim: bind dummy VAO on DrawElements implementation on glcore, this generates GL Errors, but renders fine on mesa 2023-10-16 06:47:55 +03:00
mittorn
1505740b73 ref_gl: fix enabling multitexturing on GLES 2023-10-16 06:47:55 +03:00
mittorn
6bad07b39d gl2shim: support low (<130) shaders 2023-10-16 06:47:55 +03:00
mittorn
f85437dfc5 gl2shim: implement client arrays (not in glcore/vao mode), make studio/world array render work 2023-10-16 06:47:55 +03:00
mittorn
c765261db6 ref_gl: fix late studio cvars registration, enable DrawRangeElements in GLES contexts 2023-10-16 06:47:55 +03:00
mittorn
73087ead2d ref_gl: fix build with XASH_GL_STATIC, avoid using ARB shader extension on core context 2023-10-16 06:47:55 +03:00
mittorn
8c88e82709 gl2shim: support more GLSL versions 2023-10-16 06:47:55 +03:00
mittorn
40dd6e0234 gl2shim: Cleanup warnings, use APIENTRY declarations, stub unsupported functions 2023-10-16 06:47:55 +03:00
mittorn
eb23b226cc Workaround core context issues 2023-10-16 06:47:55 +03:00
mittorn
676526a518 ref_gl: fix creating core context, support core in gl2shim by creating dumb array object 2023-10-16 06:47:55 +03:00
mittorn
7e0bd86b65 ref_gl: allow enabling XASH_GLES without wrapper, add ref_gles3compat, wrap gles functions in gl2wrap when XASH_GLES enabled 2023-10-16 06:47:55 +03:00
mittorn
97489635af gl2shim: limited matrix support 2023-10-16 06:47:55 +03:00
mittorn
a9ea3976a7 ref_gl: introduce gl2_shim based on vgl_shim for future limited core/gles context support (SLOW, still needs ffp for matrix operations) 2023-10-16 06:47:55 +03:00
Alibek Omarov
5501ca927a engine: client: respect cl_allow_download and cl_download_ingame for legacy servers 2023-10-16 06:47:55 +03:00
Andrey Akhmichin
a19fb82d66 utils: mdldec: smd.c: add leading zero to number in sequence filenames. 2023-10-16 06:18:06 +03:00
Andrey Akhmichin
9d032e953f utils: mdldec: qc.c: avoid to use brackets with conclusions. 2023-10-16 06:18:06 +03:00
Andrey Akhmichin
38587151a9 utils: mdldec: qc.c: add missing refence meshes count. 2023-10-16 06:18:06 +03:00
Andrey Akhmichin
02d5bab04b utils: mdldec: qc.c: put every sequence property to separate line. 2023-10-16 06:18:06 +03:00
Andrey Akhmichin
d8f3e53b1f utils: mdldec: qc.c: add missing quotes. 2023-10-16 06:18:06 +03:00
Andrey Akhmichin
877ed8a92a utils: mdldec: qc.c: put every texture name to separate line. 2023-10-16 06:18:06 +03:00
Andrey Akhmichin
487a652aa8 utils: mdldec: qc.c: calculate sequence group size. 2023-10-16 06:18:06 +03:00
Andrey Akhmichin
64c5d141af utils: mdldec: qc.c: put controller name instead of index for mouth controller. 2023-10-16 06:18:06 +03:00
Andrey Akhmichin
16db8a8008 utils: mdldec: qc.c: put tabs where possible. 2023-10-16 06:18:06 +03:00
Andrey Akhmichin
b6b14da102 utils: mdldec: qc.c: reorder output. 2023-10-16 06:18:06 +03:00
Andrey Akhmichin
a575605c75 utils: mdldec: qc.c: always put $flags keyword with value. 2023-10-16 06:18:06 +03:00
Andrey Akhmichin
a205a3e878 utils: mdldec: qc.c: remove useless backward slashes from output. 2023-10-16 06:18:06 +03:00
Andrey Akhmichin
26ef3e274c utils: mdldec: smd.c: linear movement loss fix. 2023-10-14 17:38:48 +03:00
Alibek Omarov
33be1b7591 engine: client: let time flow in Xash demos 2023-10-14 15:11:26 +03:00
Alibek Omarov
de19d78571 ref: fix late registration of studio cvars (thanks, @mittorn) 2023-10-14 08:11:25 +03:00
mittorn
287381d5ca ref_gl: remove complete useless macro, enable VBO under option 2023-10-14 08:04:17 +03:00
Alibek Omarov
4acd0e5304 engine: platform: sdl: grab input only in true fullscreen mode 2023-10-11 16:49:49 +03:00
Alibek Omarov
cb1063c305 engine: platform: sdl: fix qboolean to window_mode_t conversions 2023-10-10 14:41:39 +03:00
Alibek Omarov
59bfc8c32f engine: platform: sdl: fix qboolean to window_mode_t conversions 2023-10-10 14:41:05 +03:00
Alibek Omarov
23494f4e20 mainui: update 2023-10-10 14:36:59 +03:00
Alibek Omarov
b58fbc0c94 engine: platform: linux: fix according to platform.h changes 2023-10-10 14:12:53 +03:00
Alibek Omarov
46f38c84b5 engine: platform: dos: fix according to platform.h changes 2023-10-10 14:12:42 +03:00
Alibek Omarov
99f290b622 engine: platform: sdl: support borderless mode, slight refactoring 2023-10-10 14:11:28 +03:00
Alibek Omarov
680ecfefab engine: platform: pass desired window mode through R_ChangeDisplaySettings 2023-10-10 14:11:06 +03:00
Alibek Omarov
7222c74000 engine: host: expose new -borderless flag in command line help 2023-10-10 14:09:05 +03:00
Alibek Omarov
1e43cb734b engine: client: add definitions for borderless fullscreen mode 2023-10-10 14:08:06 +03:00
Alibek Omarov
cb19fa2f6d engine: client: restore window maximized state after engine restart 2023-10-09 05:26:17 +03:00
Alibek Omarov
73fcb84b62 engine: client: console: remove unneeded return from Con_DrawConsoleLen 2023-10-09 05:24:58 +03:00
Alibek Omarov
3584d3d1a6 engine: client: yet another BloodStream fix, normalize input velocity vector 2023-10-09 05:24:29 +03:00
Alibek Omarov
e95139af94 engine: client: avoid unneeded comparisons in CL_UpdateFlashlight 2023-10-09 03:20:43 +03:00
Alibek Omarov
962f88d31b engine: client: use physents for flashlight tracing, as GoldSrc does 2023-10-08 01:52:42 +03:00
Alibek Omarov
a738b2a50b ref: restore missing PARM_TEX_MEMORY RenderAPI parameter 2023-10-06 19:24:02 +03:00
Alibek Omarov
34fa1b5ec8 engine: remove PORT_CLIENT, we should randomize client port by default, thus allowing easier connections from same IP address 2023-10-05 11:06:04 +03:00
Alibek Omarov
2fdd080eef mainui: update 2023-10-02 19:31:35 +03:00
Alibek Omarov
95f87e24ee ref: soft: do not register cl_righthand cvar 2023-09-29 13:45:24 +03:00
Alibek Omarov
bfe17fa241 Documentation: update ports list, remove old engine ports that has new engine alternatives, re-sort it by status and platform 2023-09-17 08:50:37 +03:00
sofakng
a94a5f1f29 Update port maintainer list (#1427)
* Update ports.md

* Update ports.md
2023-09-17 08:40:40 +03:00
Alibek Omarov
dc71456174 scripts: flatpak: upgrade to Freedesktop SDK 23.08 2023-09-15 22:32:52 +03:00
Alibek Omarov
c6b6938e14 wscript: fix RPATH usage on OSX (by @sofakng) 2023-09-15 20:35:51 +03:00
Alibek Omarov
2823a6d269 filesystem: VFileSystem009: just in case, always rewrite fs_api_t requested through CreateInterface export 2023-09-14 00:20:28 +03:00
Alibek Omarov
bee35a1873 engine: client: do not check screenshots in base directory to guess the name 2023-09-13 18:49:10 +03:00
Alibek Omarov
e4ae386964 engine: network: fix incorrect usage of qboolean, when it should be net_gai_state_t 2023-09-12 20:40:14 +03:00
Alibek Omarov
36831555b9 waf: upgrade to latest waifu 2023-09-12 19:23:30 +03:00
Alibek Omarov
8eef212726 ref: gl: fix compile 2023-09-11 21:22:53 +03:00
Velaron
1589defda1 ref: gl: don't create cl_righthand cvar 2023-09-08 15:52:07 +03:00
Velaron
df921d8664 some cleaner code 2023-09-08 15:52:07 +03:00
Velaron
f3949474b9 ref: gl: fix cl_righthand behaviour 2023-09-08 15:52:07 +03:00
Alibek Omarov
706ef65208 engine: client: make unprefixed important userinfo cvars filterable, so servers won't be able to change them, for security 2023-09-04 02:39:34 +03:00
Alibek Omarov
435b95fc5a engine: client: don't write download notify outside of window 2023-08-31 08:40:24 +03:00
Alibek Omarov
aeece35291 engine: soundlib: mp3: fix check for Unicode in ID3v2.4 TXXX tag 2023-08-30 22:57:39 +03:00
Emil Tomczyk
abd7f3dca3 engine: crashhandler: changed register names for NetBSD x86 (#1414)
Probably also needs change for x86_64
2023-08-30 18:53:41 +03:00
Alibek Omarov
1c9f333420 engine: server: fix attempting to free pool instead of an allocated memory 2023-08-30 18:52:44 +03:00
Alibek Omarov
75e5da071c engine: platform: win32: fix calculating RVAs for LLP64 2023-08-29 19:18:22 +03:00
Alibek Omarov
52bd923d9d engine: server: use generic host pool for temporary string allocation in case of PhysicAPI 2023-08-29 19:10:33 +03:00
Alibek Omarov
ab5a9eec53 engine: soundlib: snd_mp3: fix extra-format-args 2023-08-21 10:02:43 +03:00
Alibek Omarov
88916fdac4 engine: ref_api: remove dead XASH_TEXTURE4 definition 2023-08-21 10:02:18 +03:00
Alibek Omarov
22f60d50ac ref: gl: only enable/disable texture units in fixed-function pipeline rendering, in our case, low TMUs 2023-08-21 10:01:59 +03:00
Alibek Omarov
4ed562697b engine: soundlib: fix sizeof parameter in previous commit, I'm an idiot 2023-08-18 11:50:58 +03:00
Alibek Omarov
64166c7d82 engine: soundlib: fix slashes in Sound_GetApproxWavePlayLen, as it can be called from game DLL 2023-08-18 11:47:01 +03:00
Alibek Omarov
0df89bddeb engine: common: ipv6text: accept changes from upstream GameNetworkingSockets 2023-08-08 19:38:57 +03:00
Alibek Omarov
3168e5ccf0 wscript: add an option to request and accept any servers 2023-08-08 09:24:10 +03:00
Alibek Omarov
72fe214f49 engine: server: pre-process string before passing it to PhysicAPI AllocString, for compatibility with existing Xash3D games 2023-08-07 21:11:20 +03:00
Alibek Omarov
e1cbf96100 wscript: make stringop-overflow non-fatal 2023-08-07 19:45:03 +03:00
Alibek Omarov
1d6f695749 wscript: disable stringop-overflow for NSW to workaround buggy toolchain 2023-08-07 19:26:04 +03:00
Alibek Omarov
08a2d431da engine: client: cl_qparse: refactor quake baseline parser, so we don't call memset for nothing 2023-08-07 19:11:47 +03:00
Alibek Omarov
8bdb49516d filesystem: fix stringop-overflow 2023-08-06 00:44:32 +03:00
Alibek Omarov
e7f5cb6910 wscript: add stringop-overflow to our Werror list 2023-08-06 00:41:12 +03:00
Alibek Omarov
9968b192c3 engine: server: fix buffer overflow in invalid Q_strncpy call 2023-08-06 00:39:41 +03:00
Alibek Omarov
79f2c69963 engine: soundlib: missing newline in warning message about truncated WAV file 2023-08-05 04:05:23 +03:00
Alibek Omarov
2067667c9c engine: fix inverted check in DLL unloading in settings.scr parsing
Fixes: aee99f6094
2023-08-03 02:40:02 +03:00
Alibek Omarov
e017b9145f engine: common: cvar: fix buffer overflow in Cvar_ValidateString 2023-08-03 01:12:16 +03:00
Alibek Omarov
c1c27c5f18 engine: net_ws: fix printing multicast IPv6 address 2023-08-03 01:11:54 +03:00
Alibek Omarov
87a56a5fa1 engine: client: initialize netadr_t structure in LAN games scan 2023-08-03 01:11:31 +03:00
Alibek Omarov
aee99f6094 engine: don't release DLL that wasn't loaded during settings.scr parsing. This should be deleted as soon as possible! 2023-08-03 01:11:06 +03:00
Alibek Omarov
bf03f739bb engine: soundlib: snd_wav: take FindNextChunk fixes from FTEQW 2023-08-03 01:05:46 +03:00
Alibek Omarov
e23580c1de engine: remove czeror sequence parser
This file initially came from HLND, a Chinese GoldSrc recreation.
It turned out to be suspiciously close to the original version, down
to the comments and code style. We don't work with leaked sources here,
so remove it.

A proper parser should be reimplemented from ground-up, when we will
start working on CZDS support.
2023-07-26 19:40:03 +03:00
Alibek Omarov
e49848d090 github: bump SDL2 version to 2.28.1 2023-07-23 03:16:03 +03:00
Alibek Omarov
1bfc6e6705 filesystem: try to fix case of library filename in FindLibrary 2023-07-22 07:04:26 +03:00
Alibek Omarov
e7c41759fb Revert "filesystem: allow to reference game libraries in different case"
This reverts commit 43fde38d88.
2023-07-22 06:39:23 +03:00
Alibek Omarov
a07f81820c engine: client: ref_common: fix missing newline in Host_Error 2023-07-22 05:51:18 +03:00
Alibek Omarov
b39378a6da engine: common: fix warning about read-only cvar. In fact, we should force set them. 2023-07-22 05:50:38 +03:00
Alibek Omarov
5c6b9d3235 scripts: flatpak: set correct bindir for flatpak installation 2023-07-22 04:49:48 +03:00
Alibek Omarov
3d49ca25b3 scripts: flatpak: disable LTO for Flatpak for now, it causes linker errors 2023-07-22 00:23:03 +03:00
Alibek Omarov
43fde38d88 filesystem: allow to reference game libraries in different case 2023-07-22 00:19:37 +03:00
Alibek Omarov
6461fa5042 engine: client: make ref params static so client.dll can save address of it and don't trigger ASan 2023-07-17 05:52:45 +03:00
Alibek Omarov
788bc820c8 filesystem: automatically fixup directory name case for base directories 2023-07-17 05:52:06 +03:00
Alibek Omarov
36ff819daf engine: client: fix heap-buffer-overflow in remap when we switch model that have more remap textures than previous 2023-07-17 04:48:02 +03:00
Alibek Omarov
8905883225 utils: xar: add new utility called Xar that helps interacting with Xash3D FWGS archives using filesystem_stdio C API
The utility is not yet finalized, disable from wscript for now
2023-07-05 07:00:39 +03:00
Alibek Omarov
4031f5cb01 public: allow matching anything in matchpattern 2023-07-05 07:00:39 +03:00
Alibek Omarov
cd46ad19a3 filesystem: expose a special flag for archive mounter to skip included WADs 2023-07-05 07:00:39 +03:00
Alibek Omarov
6f7b1695d7 filesystem: expose archive mount generic function for Xar 2023-07-05 07:00:39 +03:00
Alibek Omarov
28a4b51939 Documentation: gameinfo: wording 2023-07-04 03:39:17 +03:00
Alibek Omarov
5e878aae89 mainui: upgrade 2023-07-03 02:25:31 +03:00
Alibek Omarov
7e05562c14 engine: platform: sdl: check SDL version in Platform_Vibrate 2023-07-03 02:18:49 +03:00
Alibek Omarov
777dd3a03c public: add definitions for PowerPC
This doesn't mean we have a port but at least it allows building for ppc64el
2023-07-03 01:40:47 +03:00
Alibek Omarov
9977cb20c0 Documentation: gameinfo: clarify internal_vgui_support is intended to be used only for developers and that it's required for PrimeXT 2023-07-02 08:14:26 +03:00
Alibek Omarov
5661766c79 Documentation: gameinfo: wording 2023-07-02 06:45:29 +03:00
Alibek Omarov
60d65d368a Documentation: add basic document on gameinfo.txt keys and liblist.gam conversion 2023-07-02 06:36:57 +03:00
Alibek Omarov
031594cc99 filesystem: update max_particles limits based on Unkle Mike's latest engine version 2023-07-02 06:36:35 +03:00
Alibek Omarov
d4bf57c7c2 filesystem: delete unused edicts key handler in liblist.gam parsing 2023-07-02 06:36:09 +03:00
Alibek Omarov
8e16c0e410 filesystem: simplify common parsing of type key for liblist.gam and gameinfo.txt 2023-07-02 06:35:34 +03:00
Alibek Omarov
d5f4b409e8 engine: server: sv_save: use new quicksave_aged_count and autosave_aged_count gameinfo.txt keys 2023-07-02 04:53:39 +03:00
Alibek Omarov
88c560aac4 filesystem: add two new gameinfo.txt keys quicksave_aged_count and autosave_aged_count that control the amount of quick/autosaves rotated 2023-07-02 04:53:16 +03:00
Alibek Omarov
c3a6cad0c1 filesystem: do not print error in FS_Delete if file doesn't exist 2023-07-02 04:49:33 +03:00
Alibek Omarov
a862446072 engine: client: restore cl_trace_events from old engine branch 2023-07-02 04:48:43 +03:00
Alibek Omarov
8d04ae8802 engine: client: fix appending extra .dem in record command 2023-07-02 02:44:25 +03:00
Alibek Omarov
0de0615eeb engine: client: implement map CRC32 checking on client side 2023-07-02 01:20:24 +03:00
Alibek Omarov
ea24b5f3ca engine: server: make CRC32_MapFile public 2023-07-02 01:19:38 +03:00
Alibek Omarov
eb7f19d3cf engine: server: properly remove remaining server operator commands 2023-07-02 01:19:21 +03:00
Alibek Omarov
ca134a85ee engine: client: make it more obvious that CL_InitEdicts depends on maxclients value 2023-06-30 02:51:47 +03:00
Alibek Omarov
00765f1ff2 engine: client: cl_parse_48: add a temporary hack to avoid the lag issues after changelevel on legacy servers 2023-06-30 02:35:36 +03:00
Alibek Omarov
013bfe5c34 engine: common: sys_con: always read from stdin when engine is in dedicated mode 2023-06-30 01:44:03 +03:00
Alibek Omarov
5f625bb6e1 wscript: remove option --enable-stdin-input, it's enabled by default in dedicated mode sys_con now 2023-06-30 01:43:26 +03:00
Alibek Omarov
547a862024 engine: client: split protocol 48 support to separate file 2023-06-29 04:09:36 +03:00
Alibek Omarov
6ea8d141d9 engine: common: net_encode: fix usage of new Delta_ClampIntegerField, minor fixes 2023-06-28 14:30:06 +03:00
Alibek Omarov
bdc2390d41 Revert "engine: common: net_encode: rewrite Delta_CompareField to be more efficient"
This reverts commit 82addf11bb.
2023-06-28 14:26:42 +03:00
Alibek Omarov
acc113309c Revert "engine: common: net_encode: fix Delta_CompareField to include integer clamping, in case if no updates happen in significant bits"
This reverts commit 6a7b330463.
2023-06-28 14:26:40 +03:00
Alibek Omarov
5afda72290 engine: common: net_encode: simplify Delta_ClampIntegerField 2023-06-28 05:07:53 +03:00
Alibek Omarov
6a7b330463 engine: common: net_encode: fix Delta_CompareField to include integer clamping, in case if no updates happen in significant bits 2023-06-28 04:47:12 +03:00
Alibek Omarov
f5b9826fd9 engine: common: net_encode: directly access delta description struct than searching for it every time 2023-06-27 19:56:32 +03:00
Alibek Omarov
82addf11bb engine: common: net_encode: rewrite Delta_CompareField to be more efficient 2023-06-27 18:06:24 +03:00
Alibek Omarov
aee5e46516 public: rewrite Q_strncpy with standard C functions, make it inlined to allow compiler remove unneeded checks
So far, passes all tests.
2023-06-27 17:30:09 +03:00
Alibek Omarov
40e248aa63 engine: common: remove unused tentlist_t definition 2023-06-27 17:30:09 +03:00
fgsfds
24ee3ae318 scripts: psvita: bump vitaGL version 2023-06-25 18:15:18 +03:00
fgsfds
f79aaf93f8 ref: gl: psvita: disable NPOT textures, they're broken again 2023-06-25 18:15:18 +03:00
Alibek Omarov
0d89849cab public: move some simple functions to mathlib header. Remove assembler version specific for MSVC6 2023-06-25 13:32:06 +03:00
Alibek Omarov
d962255ebe public: mathlib: remove unused RemapVal, ApproachVal 2023-06-25 13:25:51 +03:00
Alibek Omarov
21b47dff32 ref: gl: static-ize globals and functions in gl_warp 2023-06-25 13:17:46 +03:00
Alibek Omarov
1905782c41 3rdparty: vgui_support: update submodule 2023-06-23 06:10:27 +03:00
Alibek Omarov
b29b3d5859 wscript: clarify that higher versions of opus also accepted in a comment 2023-06-21 13:21:19 +03:00
Alibek Omarov
3533b0d284 wscript: check for opus 1.4, which fixes an assertion in custom modes decoder initialize 2023-06-21 13:19:03 +03:00
Alibek Omarov
7e06d049f5 engine: common: static-ize common.c functions, set GAME_EXPORT to API functions 2023-06-20 14:19:44 +03:00
Alibek Omarov
5a4c443c79 filesystem: fix regression in FS_LoadFile not skipping leading slashes
Earlier it used FS_Open which handles this, but because we don't call
that anymore, just skip it ourselves for compatibility.
2023-06-20 14:11:55 +03:00
Alibek Omarov
4bbd1e59a4 engine: server: static-ize world functions 2023-06-19 07:47:38 +03:00
Alibek Omarov
0809453b2c engine: server: static-ize sv_query functions 2023-06-19 07:39:00 +03:00
Alibek Omarov
8350d81c18 engine: server: static-ize sv_pmove functions 2023-06-19 07:38:18 +03:00
Alibek Omarov
57499dea33 engine: server: static-ize sv_phys functions, set GAME_EXPORT attribute for PhysicAPI functions 2023-06-19 07:32:22 +03:00
Alibek Omarov
6b223f1325 engine: server: static-ize functions in sv_game. Set GAME_EXPORT attribute to server GameAPI functions 2023-06-19 07:11:49 +03:00
Alibek Omarov
03a85e0caa engine: platform: psvita: add unused data to workaround bug in vita-elf-create (thanks @fgsfdsfgs) 2023-06-18 22:49:44 +03:00
Alibek Omarov
01ad3dda2a engine: server: escape rcon arguments before passing it to command buffer, also use more efficient concatenation 2023-06-18 04:44:28 +03:00
Alibek Omarov
2a05624615 engine: server: keep silence in case of unset or invalid rcon password 2023-06-18 04:30:21 +03:00
Alibek Omarov
f3ed9b21c0 scripts: add sample systemd service 2023-06-16 08:47:25 +03:00
Alibek Omarov
16c87ae2c9 engine: platform: reorganize UpdateStatusLine, make it shared but implemented only if platform has SetStatus. Implement SetStatus for systemd/Linux 2023-06-16 08:43:16 +03:00
Alibek Omarov
c16a10e6f3 engine: platform: refactor Platform_Init/Shutdown/GetNativeObject functions. They are now defined in the header, and call platform-specific functios that defined in platform code 2023-06-16 07:32:19 +03:00
Alibek Omarov
c7d748e8df engine: server: add sv_log_outofband cvar that controls whether connectionless packets should be printed or not 2023-06-16 07:19:17 +03:00
Alibek Omarov
0e16110c3a github: use ubuntu-latest for PSVita and NSwitch CI 2023-06-15 19:26:19 +03:00
Alibek Omarov
c966589a50 engine: server: static-ize few game API functions, set GAME_EXPORT attribute 2023-06-15 19:22:13 +03:00
Alibek Omarov
4c02c25506 engine: server: do not assert if SetFatPVS/PAS were called without active player
Fixes issues with POD-Bot based bots.
2023-06-15 19:17:34 +03:00
Alibek Omarov
a4997d0647 engine: server: port old engine's fullupdate ratelimit, but simplify it 2023-06-15 18:09:59 +03:00
Alibek Omarov
243c3cc80f engine: server: port old engine's userinfo penalty 2023-06-15 04:46:22 +03:00
Alibek Omarov
a8dbec56c3 mainui: update 2023-06-14 01:38:41 +03:00
Alibek Omarov
9c62fa901f engine: server: pregenerate CRC table and testpacket data 2023-06-14 00:35:07 +03:00
Alibek Omarov
996897e30e public: use standard uint32_t in place of dword 2023-06-13 06:57:24 +03:00
Alibek Omarov
93ee5b9446 public: crclib: simplify CRC32_ProcessByte 2023-06-13 06:57:24 +03:00
Alibek Omarov
c0c8119040 public: crclib: rework CRC32 code (thanks to @Mr0maks for implementation) 2023-06-13 06:57:24 +03:00
jeefo
61c75b9809 engine: server: log: use S_USAGE in logaddress for consistency with existing code 2023-06-11 16:28:36 +03:00
jeefo
868d10a842 engine: server: log: allow to disable logaddress without turning off logs completely 2023-06-11 16:28:36 +03:00
jeefo
699f3579fe engine: server: log: fix log off command not disabling logging to console (fixes #1340) 2023-06-11 16:28:36 +03:00
jeefo
873ce0ce48 engine: server: query: A2S_PLAYER response should contain bots and normal players 2023-06-11 14:14:59 +03:00
Alibek Omarov
450f77443d engine: client: ignore some out of band packets if we're not connecting to server 2023-06-11 07:06:01 +03:00
Alibek Omarov
278ff22ba9 engine: server: query: use common SV_GetPlayerCount, fix random styling issues 2023-06-10 02:47:52 +03:00
jeefo
d9ef1d4608 server: implement correct answers to TSourceEngineQuery server queries
* count bots as clients as in goldsrc
* handle source-style packets after xash's built-in packets to not interfere with them
2023-06-10 02:06:45 +03:00
Alibek Omarov
58df771c9e filesystem: implement .pk3dir convention 2023-06-08 22:58:24 +03:00
Alibek Omarov
a6ecc778fc filesystem: dir: fix FS_FixFileCase when empty string is passed. Always append slash to searchpath. 2023-06-08 22:58:24 +03:00
Alibek Omarov
37e890f326 filesystem: make fs_searchpaths completely private to the filesystem core 2023-06-08 22:30:45 +03:00
Alibek Omarov
0d6137ee40 filesystem: make generic archive loading functions (with the exception of WADs). Do not alter global searchpath from archives. 2023-06-08 22:14:30 +03:00
Alibek Omarov
653eb00cc6 filesystem: unify prototypes of archive opening functions 2023-06-08 20:02:48 +03:00
Alibek Omarov
b84aba68fa engine: platform: implement generic GetNativeObject for POSIX systems without SDL2 2023-06-07 04:07:53 +03:00
Alibek Omarov
1855fab80b filesystem: fix Platform_GetNativeObject macro definition 2023-06-06 17:46:38 +03:00
Alibek Omarov
23f1c43282 engine: common: net_buffer: use uint32_t in place of dword 2023-06-06 00:28:23 +03:00
Alibek Omarov
a7c76ac0bf engine: common: net_buffer: use stdint.h types in sizebuf_t reading/writing funcs 2023-06-06 00:26:54 +03:00
Alibek Omarov
26959cd280 engine: common: net_encode: use stdint.h types in Delta_CompareField 2023-06-06 00:20:56 +03:00
Alibek Omarov
1fdf6180e6 engine: platform: sdl: merge required SDL2 platform changes for new Android port from @Velaron's tree 2023-06-05 21:51:59 +03:00
Alibek Omarov
d2237fa144 engine: platform: android: merge new SDL2 based Android port from @Velaron's tree 2023-06-05 21:35:58 +03:00
Alibek Omarov
febdfacbd3 wscript: merge CMakeLists generating tool from Velaron's tree 2023-06-05 21:30:07 +03:00
Alibek Omarov
ef663a8790 engine: partially remove legacy Android port, in preparation of new port merge 2023-06-05 20:30:18 +03:00
Alibek Omarov
ba039b8e71 engine: drop XASH_DYNAMIC_DLADDR 2023-06-05 20:30:18 +03:00
Alibek Omarov
02ce80981c filesystem: update optional funcs interface, add platform-specific GetNativeObject call 2023-06-05 20:30:18 +03:00
Alibek Omarov
a40a325d3c 3rdparty: mainui: update 2023-06-03 03:54:49 +03:00
Alibek Omarov
85cc942a3c wscript: fix Sailfish misdetection 2023-06-02 06:35:51 +03:00
Alibek Omarov
a23e17c6d7 engine: platform: sdl: set QtWayland hints 2023-06-02 06:18:47 +03:00
Alibek Omarov
59412f3d92 public: define XASH_MOBILE_PLATFORM by XASH_SAILFISH (defined externally) 2023-06-02 06:18:17 +03:00
Alibek Omarov
0a15cc389d mainui: update 2023-06-02 06:17:14 +03:00
Alibek Omarov
13f8a02cdf wscript: better Sailfish/AuroraOS macros 2023-06-02 06:16:40 +03:00
Alibek Omarov
8caa2d142f scripts: sailfish: initial SailfishOS support 2023-06-02 05:37:13 +03:00
Alibek Omarov
3b8009917a 3rdparty: upgrade GL wrappers submodules 2023-06-02 04:10:24 +03:00
Alibek Omarov
e2e14945e4 contrib: delete outdated files 2023-06-02 00:28:31 +03:00
Alibek Omarov
16595bf2c0 ref: gl: fix r_showhull check 2023-05-29 14:42:16 +03:00
Alibek Omarov
f49a2bc8f3 engine: server: move pfnWriteString character replacement hack to the ALLOC_STRING, the same way as GoldSrc does 2023-05-29 14:40:54 +03:00
Alibek Omarov
d994c6df9a ref: a bit more verbosity if UserTracer color exceed limit 2023-05-27 22:06:33 +03:00
Alibek Omarov
3a57f26351 ref: gl: move ref_gl cvars to static allocation 2023-05-27 21:52:58 +03:00
Alibek Omarov
7fd1534753 engine: common: cvar: remove unused CVAR_TO_BOOL macro 2023-05-27 21:52:58 +03:00
Alibek Omarov
bd52a9ec2d engine: platform: linux: move evdev_keydebug cvar to static allocation 2023-05-27 21:52:58 +03:00
Alibek Omarov
9e0d389d9e engine: server: moved server cvars to static allocation 2023-05-27 21:52:58 +03:00
Alibek Omarov
8680757844 ref: soft: move ref_soft cvars to static allocation, remove dead cvars 2023-05-27 21:52:58 +03:00
Alibek Omarov
95a8d2f51f ref: soft: attempt to fix freeze in decals on software renderer 2023-05-27 21:52:58 +03:00
Alibek Omarov
70b26a13c2 engine: allow ref dlls to use convar_t 2023-05-27 21:52:58 +03:00
Alibek Omarov
6a1f96a2c6 engine: always unlink variables and commands BEFORE all pointers to them would be lost 2023-05-27 21:52:58 +03:00
Alibek Omarov
4ce2475602 engine: common: move network cvars to static allocation 2023-05-27 21:52:58 +03:00
Alibek Omarov
e7ece41ba0 engine: common: move model cvars to static allocation 2023-05-27 21:52:58 +03:00
Alibek Omarov
05579927a5 engine: client: sound: move dsp cvars to static allocation 2023-05-27 21:52:58 +03:00
Alibek Omarov
2f5b359c99 engine: client: move tracer cvars to static allocation 2023-05-27 21:52:58 +03:00
Alibek Omarov
214fc7e827 engine: common: move host cvars to static allocation 2023-05-27 21:52:58 +03:00
Alibek Omarov
df173a83ed engine: client: move touch cvars to static allocation 2023-05-27 21:52:58 +03:00
Alibek Omarov
3918bcd71c engine: client: move console cvars to static allocation 2023-05-27 21:52:58 +03:00
Alibek Omarov
f19ed1c1c2 engine: client: move joystick cvars to static allocation 2023-05-27 21:52:58 +03:00
Alibek Omarov
03ec2f603b engine: client: move netgraph cvars to static allocation 2023-05-27 21:52:58 +03:00
Alibek Omarov
1ee01163b7 engine: client: move scrn cvars to static allocation 2023-05-27 21:52:58 +03:00
Alibek Omarov
b1d60c248d engine: client: move main client cvars to static allocation 2023-05-27 21:52:58 +03:00
Alibek Omarov
d9cbf1fa89 engine: client: move input cvars to static allocation 2023-05-27 21:52:58 +03:00
Alibek Omarov
cd022bdac7 engine: client: move keys cvars to static allocation 2023-05-27 21:52:58 +03:00
Alibek Omarov
5d7d5319fd engine: move ref cvars to static allocation 2023-05-27 21:52:58 +03:00
Alibek Omarov
d4470402ee engine: move vid cvars to static allocation 2023-05-27 21:52:58 +03:00
Alibek Omarov
05560c7607 engine: always read and set vid_fullscreen value directly with it's object 2023-05-27 21:52:58 +03:00
Alibek Omarov
81c752da2b filesystem: wad: static-ize WAD functions 2023-05-27 20:51:00 +03:00
Alibek Omarov
fd2ad447a8 filesystem: zip: static-ize ZIP functions 2023-05-27 20:49:06 +03:00
Alibek Omarov
18d55c1de2 filesystem: zip: adapt to new interface 2023-05-27 20:48:48 +03:00
Alibek Omarov
d0d09c878f filesystem: wad: adapt to new interface 2023-05-27 20:47:49 +03:00
Alibek Omarov
e791d44dd8 filesystem: properly support compressed archives in FS_LoadFile 2023-05-27 20:46:48 +03:00
Alibek Omarov
152f6d154c filesystem: remove unused argument from FS_CheckNastyPath 2023-05-27 20:22:12 +03:00
Alibek Omarov
5627dbbf34 engine: server: greatly simplify pfnWriteString implementation, it shouldn't modify input string 2023-05-27 20:02:09 +03:00
Alibek Omarov
9cd9744407 filesystem: fix Windows build 2023-05-27 19:40:44 +03:00
Alibek Omarov
f13c285287 filesystem: verbose error printing in FS_SetCurrentDirectory, move error reporting from engine 2023-05-26 22:29:34 +03:00
Alibek Omarov
cca7744f1c filesystem: make some calls from API safe to use without initialize 2023-05-26 18:31:00 +03:00
Alibek Omarov
31ae22961b filesystem: add base test case to call ShutdownStdio without calling Init prior 2023-05-26 18:30:13 +03:00
Alibek Omarov
a3603f497d scripts: waifulib: compiler_optimizations: fix -march applying on x86_64 toolchains forced to compile in 32-bit mode 2023-05-24 04:30:28 +03:00
Alibek Omarov
d36cb62a2e mainui: update 2023-05-24 04:25:25 +03:00
Alibek Omarov
2ca6029e03 Revert "github: don't wait for flatpak build finish, it's broken for us anyway"
This reverts commit eb61bcf76a.
2023-05-24 04:24:55 +03:00
Alibek Omarov
dee5cae5f3 scripts: waifulib: compiler_optimizations: set pentium-m minimum cpu requirement for Intel 32-bits, like HLSDK 2023-05-24 04:19:08 +03:00
Alibek Omarov
ef4bc2acf2 scripts: flatpak: try to fix flatpak build on GitHub Actions 2023-05-24 04:18:33 +03:00
Alibek Omarov
eb61bcf76a github: don't wait for flatpak build finish, it's broken for us anyway 2023-05-24 03:52:38 +03:00
Alibek Omarov
cb43df43ef engine: common: cvar: do not check if cvar was registered in DirectSet when it has valid next pointer 2023-05-24 03:51:16 +03:00
Alibek Omarov
356f78ee81 engine: platform: sdl: fix possible buffer overrun in SDL port audio code 2023-05-24 03:49:13 +03:00
Alibek Omarov
275cd73ade engine: server: do not trigger speedhack detection for fakeclients 2023-05-24 00:36:54 +03:00
Velaron
bb1b9dad23 ref: gl: Goldsrc compatible fog implementation 2023-05-20 23:36:04 +03:00
Velaron
e27ac6b092 platform: win32: properly change icon 2023-05-20 23:32:19 +03:00
Alibek Omarov
7333ddc1d9 engine: client: move some RenderAPI GetParm queries to engine 2023-05-19 05:03:25 +03:00
Alibek Omarov
fbd7d8f58a engine: server: use sv_speedhack_kick cvar value as a number of speedhack warns before automatic kick
Thanks to @tyabus for suggestion
2023-05-19 04:49:29 +03:00
Alibek Omarov
3415185dde engine: server: implement simple anti-speedhack 2023-05-19 04:44:42 +03:00
Alibek Omarov
551ea71906 engine: server: make generic function to kick players with a reason 2023-05-19 04:44:42 +03:00
Alibek Omarov
1d965d7543 ref: gl: ignore GenTextures objects that fall into reserved space for skyboxes 2023-05-19 04:37:53 +03:00
Alibek Omarov
1d62df0e2d ref: gl: turn magic skybox numbers into defined macros 2023-05-19 04:36:05 +03:00
Alibek Omarov
b0f52236bc engine: platform: psvita: use _impure_ptr declaration from sys/reent.h 2023-05-17 17:45:17 +03:00
Alibek Omarov
7dcddc559c engine: platform: sdl: set PulseAudio role only on POSIX systems 2023-05-17 17:38:18 +03:00
Alibek Omarov
277bead9b7 ref: remove SetCullState function from StudioAPI. It does nothing on GoldSrc. 2023-05-17 17:23:35 +03:00
Alibek Omarov
d8093ec587 engine: platform: psvita: attempt to fix PSVita builds by exporting _impure_ptr 2023-05-17 17:17:25 +03:00
Alibek Omarov
323626c308 engine: platform: sdl: try to avoid random crash in SDL pulse audio driver 2023-05-17 05:02:12 +03:00
Alibek Omarov
68ff265e8d ref: gl: switch texture object allocation to GenTextures usage
This should fix most overlay programs but I only tested it on MangoHud
2023-05-16 23:47:05 +03:00
Alibek Omarov
a3ab04e0cb ref: gl: track current bound texture index in gl_textures array in separate glState field 2023-05-16 23:44:52 +03:00
Alibek Omarov
7d2bf93c72 engine: client: voice: do not reinitialize voice with same parameters 2023-05-15 17:48:15 +03:00
Alibek Omarov
04107d384e engine: client: fix incorrectly parsed timings for TE_TEXTMESSAGE 2023-05-15 02:11:44 +03:00
Alibek Omarov
3a0f1763fb engine: whereami: update from our downstream fork (only cosmetic changes) 2023-05-15 01:51:14 +03:00
Alibek Omarov
377dd9a255 engine: client: bring back NetAPI infostring options, as they conform to the API definitions 2023-05-14 12:24:40 +03:00
Alibek Omarov
8961e37d7c github: update flatpak-builder action to latest version 2023-05-14 12:10:39 +03:00
Alibek Omarov
de1e53311a engine: client: cl_game: static-ize engine functions in client API 2023-05-14 12:10:14 +03:00
Alibek Omarov
19582cdf11 engine: simplify force version drawing logic 2023-05-14 09:50:17 +03:00
Alibek Omarov
fa0e7e4369 scripts: enable LTO for Linux builds too 2023-05-14 09:49:39 +03:00
Alibek Omarov
2378331e47 wscript: enable -Werror=unsequenced, Clang's analogue of -Werror=sequence-point 2023-05-14 09:39:15 +03:00
Alibek Omarov
5549e7301c scripts: gha: win32: enable LTO by default 2023-05-14 09:36:46 +03:00
Alibek Omarov
5ab7d09a00 scripts: waifulib: compiler_optimizations: allow -fno-semantic-interposition for GCC (less overhead on PIC binaries) 2023-05-14 09:35:00 +03:00
Alibek Omarov
c54e1625d1 scripts: waifulib: compiler_optimizations: fixes for LTO 2023-05-14 09:34:29 +03:00
Alibek Omarov
d0127e5e14 filesystem: fix FS_GetDiskPath, it was broken since implementing caseinsensitive emulation, oops
Anyway, FS_GetFullDiskPath is a proper safe version that lacks this bug
2023-05-14 08:21:17 +03:00
Andrey Akhmichin
0f643f1f87 Documentation: opensource-mods.md: update link to "bubblemod". 2023-05-13 23:19:30 +03:00
Andrey Akhmichin
16eb12b1e0 Documentation: opensource-mods.md: add "HL: Rally". 2023-05-13 23:19:30 +03:00
Alibek Omarov
4856a3c084 Revert "engine: soundlib: wav: attempt to make FindNextChunk more safe"
This reverts commit 78e239d883.
2023-05-05 21:19:58 +03:00
Alibek Omarov
78e239d883 engine: soundlib: wav: attempt to make FindNextChunk more safe 2023-05-02 08:54:37 +03:00
Alibek Omarov
5a7b68fcc1 filesystem: add new export FS_GetFullDiskPath, similar to FS_GetDiskPath, but generates full path to the file, including searchpath 2023-05-02 08:52:54 +03:00
Alibek Omarov
c33a384975 engine: client: s_vox: do not crash in VOX if sentence wasn't sound in sequences 2023-05-02 08:51:53 +03:00
Alibek Omarov
5b582b744a engine: client: check if filesystem was initialized during client shutdown 2023-04-30 10:14:02 +03:00
Alibek Omarov
c96f8ba722 engine: client: in_joy: do not create cvar on shutdown 2023-04-30 10:14:02 +03:00
Alibek Omarov
9f92e2a1f7 engine: client: console: do not save history if nothing was executed in console 2023-04-30 10:14:02 +03:00
Alibek Omarov
710b234493 engine: add new pretty --help output 2023-04-30 10:14:02 +03:00
Alibek Omarov
75759530e3 engine: remove doublecolons from MSGBOX macros 2023-04-30 10:14:02 +03:00
Alibek Omarov
5162ab62fd engine: filesystem: do not crash if engine was shutdown before filesystem was loaded 2023-04-30 10:14:02 +03:00
Alibek Omarov
3e2a215c15 engine: client: in_joy: rename -nojoy to -noenginejoy to avoid conflict with client.dll's joystick support 2023-04-30 10:14:02 +03:00
Alibek Omarov
e2540bd446 filesystem: turn unused caseinsensitive argument in InitStdio into a reserved argument (set to true by default) 2023-04-30 10:14:02 +03:00
Alibek Omarov
07fd4f37ef engine: remove unused -caseinsensitive command line argument 2023-04-30 10:14:02 +03:00
Alibek Omarov
92b72a7d33 game_launch: add icons that were used for Android port 2023-04-30 00:56:28 +03:00
Alibek Omarov
cb3b16e2ec engine: client: implement v_dark in engine, instead of making it ref-specific 2023-04-28 16:52:22 +03:00
Alibek Omarov
bd3dc71f39 engine: server: refactor banid, explicitly does not allow ban using userid for now 2023-04-28 16:24:41 +03:00
Alibek Omarov
48176233bd public: move FOV calculating functions out of libpublic, as they are very specific to engine view 2023-04-26 05:22:34 +03:00
Alibek Omarov
a292d2fd53 platform: win32: replace Q_sprintf calls by Q_snprintf 2023-04-26 05:20:45 +03:00
Alibek Omarov
27aad9f4a0 ref: gl: add size argument to COM_Default/ReplaceExtension calls 2023-04-26 05:20:45 +03:00
Alibek Omarov
71a3cedba8 filesystem: add size argument to COM_Default/ReplaceExtension calls 2023-04-26 05:20:45 +03:00
Alibek Omarov
ec2951cf45 engine: add size argument to COM_Default/ReplaceExtension calls 2023-04-26 05:20:45 +03:00
Alibek Omarov
ff436ae100 public: crtlib: add safe COM_DefaultExtension and COM_ReplaceExtension 2023-04-26 05:20:45 +03:00
Alibek Omarov
cfdfdd5c93 utils: mdldec: add size argument to COM_FileBase calls 2023-04-26 05:20:45 +03:00
Alibek Omarov
8b96e7ca87 ref: add size argument to COM_FileBase calls 2023-04-26 05:20:45 +03:00
Alibek Omarov
1603b8028c filesystem: add size argument to COM_FileBase calls 2023-04-26 05:20:45 +03:00
Alibek Omarov
8c7db8499f engine: add size argument to COM_FileBase calls 2023-04-26 05:20:45 +03:00
Alibek Omarov
fbdd79644b public: test new COM_FileBase and compare it's results with old implementation (embedded into test itself) 2023-04-26 05:20:45 +03:00
Alibek Omarov
ac39090f6e public: crtlib: add safe COM_FileBase implementation 2023-04-26 05:20:45 +03:00
Alibek Omarov
8f207362a5 public: remove Q_sprintf, and patch all code that used it to use Q_snprintf instead 2023-04-26 05:20:45 +03:00
Alibek Omarov
b16fa8eddc public: remove Q_strcat and Q_strcpy, and patch the code that uses it 2023-04-26 05:20:45 +03:00
Alibek Omarov
2261b0dcab scripts: gha: set --disable-werror for building HLSDK 2023-04-25 13:10:12 +03:00
Alibek Omarov
9eb49fc673 scripts: gha: win32: finally use destdir instead of prefix on Windows 2023-04-25 13:05:34 +03:00
Alibek Omarov
c61c84ad4f Revert "wscript: check malloc.h first to make checks on Windows slightly faster"
This reverts commit 1464e1e2be.
2023-04-25 12:39:47 +03:00
Alibek Omarov
71c9fd2772 wscript: do not check for --prefix without --enable-packaging, as it's still valid to use 2023-04-25 03:01:35 +03:00
Alibek Omarov
1464e1e2be wscript: check malloc.h first to make checks on Windows slightly faster 2023-04-25 02:39:07 +03:00
Alibek Omarov
cf557d191a wscript: make prefix vs destdir installing more safe and predictable 2023-04-25 02:38:36 +03:00
Alibek Omarov
b72033eb74 engine: client: fix master server query through NetAPI 2023-04-23 22:05:11 +03:00
Alibek Omarov
cec903fd10 mainui: update 2023-04-23 18:44:17 +03:00
Alibek Omarov
b333edeefe public: crtlib: remove unused Q_strlwr macro 2023-04-23 18:31:08 +03:00
Alibek Omarov
76c7273600 utils: mdldec: remove usage of string functions with unspecified size 2023-04-23 18:30:44 +03:00
Alibek Omarov
096ee34f67 public: remove Q_vsprintf, replace by proper Q_vsnprintf proper calls
Fixes weird off by one error caused by glibc updates? I didn't tracked
what causes it exactly but replacing it seems to work. Anyway, we should
remove all 99999 hacks in libpublic.
2023-04-23 18:19:28 +03:00
Alibek Omarov
5b52a9a19f engine: protocol: increase MAX_LIGHTSTYLES from 64 to 256, protocol limit as it encoded as unsigned byte 2023-04-20 10:35:21 +03:00
Alibek Omarov
cacfff008f engine: common: enable autocomplete for mp3 command 2023-04-19 17:54:45 +03:00
Alibek Omarov
398cec626e engine: client: remove media/ prefix for CD tracks, add it while parsing cdaudio.txt for compatibility 2023-04-19 17:54:28 +03:00
Alibek Omarov
cadad6ce34 github: attempt to avoid release draft issue by sleeping for 20s 2023-04-19 16:32:21 +03:00
Alibek Omarov
588d080a63 github: migrate to softprops/action-gh-release to avoid drafts being randomly created (thanks @SNMetamorph) 2023-04-19 15:05:41 +03:00
Alibek Omarov
1affc36f06 engine: client: more accurate ScreenShake implementation, thanks @vasiavasiavasia95 for sharing it 2023-04-18 17:28:27 +03:00
Alibek Omarov
8d6ac3fad4 engine: common: net_encode: cosmetic changes, static-ize functions, move private macros 2023-04-18 05:16:57 +03:00
Alibek Omarov
0d5d30398b filesystem: VFileSystem009: refactoring 2023-04-18 04:50:47 +03:00
Alibek Omarov
eb0686fca1 filesystem: fix wrong data type for character in Gets and Ungetc 2023-04-18 04:47:55 +03:00
Alibek Omarov
41025c0049 engine: client: reset connection retries counter on changelevel
Fixes an issue when connection retry counter near the failure state
and the server changes level
2023-04-18 04:45:27 +03:00
Tim Schumacher
6518a5cf8b engine: whereami: Add SerenityOS 2023-04-17 19:30:11 +03:00
Alibek Omarov
49936120ca public: tests: add new test to check return values of Q_Architecture/PlatformStringByID and Q_buildnum 2023-04-17 19:11:16 +03:00
Alibek Omarov
e4a5b95e81 public: build: split Q_buildnum to separate function that calculates build number from arbitrary date string 2023-04-17 19:10:40 +03:00
Alibek Omarov
84fc8d4281 public: build: fix naming for 32-bit RISCV with double precision float ABI 2023-04-17 19:09:59 +03:00
Alibek Omarov
e9da3e2976 public: build: reorder enums by probability, rename ARCHITECTURE_ ABI macros to just ARCH_ for easier matching 2023-04-17 06:37:08 +03:00
Alibek Omarov
c1252b5642 scripts: waifulib: vgui: fix Logs aren't being imported 2023-04-17 06:36:58 +03:00
Alibek Omarov
7d54952422 3rdparty: vgui_support: update submodule 2023-04-17 05:22:02 +03:00
Alibek Omarov
b28d10f69f scripts: waifulib: split vgui_support VGUI detection to separate module 2023-04-17 05:20:22 +03:00
Alibek Omarov
6cb3b2f01a wscript: print modules help before engine common options 2023-04-17 05:19:56 +03:00
Alibek Omarov
248be5458f engine: common: hpak: do not print hashpak contents in quiet mode 2023-04-17 04:39:21 +03:00
Alibek Omarov
2e7306e96a engine: network: fix missing newline in IP port allocation error message 2023-04-17 04:37:16 +03:00
Alibek Omarov
558ded6d6a filesystem: tests: interface: use correct type for module on Win32 2023-04-15 04:58:29 +03:00
Alibek Omarov
c52dc69360 scripts: gha, cirrus: fix failing workflows because of --enable-fs-tests flag removal 2023-04-15 04:24:45 +03:00
Alibek Omarov
ba1648c689 mainui: update 2023-04-15 04:19:14 +03:00
Alibek Omarov
101a7a1240 engine: client: try to fix random crash in CL_ClearWorld when using legacy protocol 2023-04-15 04:08:40 +03:00
Alibek Omarov
25d6b2b069 engine: client: fix FlushEntityPacket message overflow on legacy servers 2023-04-15 04:08:40 +03:00
Alibek Omarov
f67b97e63c engine: common: mod_bmodel: remove useless copy before Q_strnlwr, as Q_strnlwr already copies string 2023-04-15 04:08:40 +03:00
Alibek Omarov
9a24cb8c96 engine: client: console: remove useless function Con_StringLength 2023-04-15 04:08:40 +03:00
Alibek Omarov
c157b7def3 filesystem: tests: interface: various fixes
* correctly check success variable value in CreateInterface
* get rid of C language quirks because this file is C++
* check that globals were filled
2023-04-15 04:08:12 +03:00
Alibek Omarov
de88aec958 filesystem: restore DarkPlaces contributors copyrights lost in filesystem_stdio
* Add Xash3D FWGS contributors copyrights
2023-04-15 02:39:38 +03:00
Alibek Omarov
7f31871b5a engine: common: zone: restore Id Software and Darkplaces copyrights, add Xash3D FWGS copyrights 2023-04-15 02:39:16 +03:00
Alibek Omarov
f55ef63e26 ref: optimize R_LightLambert function
* Quick exit if no local lights
* Try to minimize Q_min() checks by apply it on temp variables
* Cap final light values only once, after all local lights are calculated
2023-04-14 20:33:07 +03:00
Alibek Omarov
824a34ee1e engine: common: imgelib: fix declaration after statement in test code 2023-04-14 18:58:43 +03:00
Alibek Omarov
46e2ccd2bf filesystem: wscript: check interface test before everything else
It makes sense since we're using sequential execution here anyway
2023-04-13 20:07:58 +03:00
Alibek Omarov
339c08d89f public: add basic test for our strcpy, strcmp and strcat functions 2023-04-13 19:56:31 +03:00
Alibek Omarov
2db2375b4d waifu: upgrade to latest revision 2023-04-13 18:43:08 +03:00
Alibek Omarov
d86ab19351 wscript: refactoring, replace --enable-fs-tests with --enable-tests
* Run filesystem tests in sequential order, to avoid tests being run
before filesystem_stdio DLL is linked
* Include new interface test in filesystem
2023-04-13 18:40:27 +03:00
Alibek Omarov
db40d58208 filesystem: add test for probing all interfaces 2023-04-13 18:39:21 +03:00
Alibek Omarov
33ff7bbd61 scripts: waifulib: compiler_optimizations: set default build type to release
I think this will make configuration less confusing, also we're stable enough to be built
with optimizations and without debug information
2023-04-13 16:14:09 +03:00
Alibek Omarov
4d4162336a engine: common: mod_bmodel: apply code style fixes to match existing code, for consistency 2023-04-11 03:11:23 +03:00
Jonathan Poncelet
372514151d engine: common: mod_bmodel: Fixed default texture name check
REF_DEFAULT_TEXTURE defines the canonical name, so is used
instead of a string literal.
2023-04-11 01:41:20 +03:00
Jonathan Poncelet
6c9ce478a9 engine: common: mod_bmodel: Fixed Con_Printf warnings
Some formatting characters did not match up with their
values.
2023-04-11 01:41:20 +03:00
Jonathan Poncelet
78555ab125 engine: common: mod_bmodel: Tidied texture loading procedure 2023-04-11 01:41:20 +03:00
Andrey Akhmichin
f2c671d809 utils: mdldec: Fix typo. 2023-04-10 01:03:52 +03:00
Alibek Omarov
4bce193645 mainui: update 2023-04-03 06:45:05 +03:00
Alibek Omarov
129de871e3 engine: common: hpak: use statically allocated hpk_maxsize cvar because gamedll can re-register it for some reason 2023-04-03 06:22:55 +03:00
Alibek Omarov
c24a1fafc5 engine: add missing HPAK_CheckSize/Integrity calls 2023-04-03 06:04:48 +03:00
Alibek Omarov
cee3757e6f engine: common: hpak: add hpak deletion in validate function 2023-04-03 06:04:18 +03:00
Alibek Omarov
12ed092446 engine: client: register VGui surface cvars 2023-04-03 06:03:29 +03:00
Alibek Omarov
2fb19a0cfd public: matrixlib: cleanup unused functions 2023-04-03 05:14:59 +03:00
Alibek Omarov
79624fa400 ref: gl: cleanup unused functions 2023-04-03 05:09:33 +03:00
Alibek Omarov
550ced9c36 ref: gl: cleanup unused functions in frustum 2023-04-03 05:05:32 +03:00
Alibek Omarov
fd795d5612 ref: soft: cleanup unused functions 2023-04-03 04:57:41 +03:00
Alibek Omarov
dc0982932b engine: common: sequence: static-ize private functions 2023-04-03 04:33:19 +03:00
Alibek Omarov
5d387101b9 engine: client: remove unused Key_IsBind 2023-04-03 04:33:19 +03:00
Alibek Omarov
eef1e1868a engine: common: remove unused BaseCmd_Replace 2023-04-03 04:33:19 +03:00
Alibek Omarov
4005ef831a engine: common: remove unused IsBackgroundMap/Demo calls, remove unused gamma function 2023-04-03 04:33:19 +03:00
Alibek Omarov
b0c71c598f engine: common: remove unused Mod_AmbientLevels 2023-04-03 04:33:19 +03:00
Alibek Omarov
d7848b7b8d engine: client: efx: remove unused CL_FreeParticle 2023-04-03 04:33:19 +03:00
Alibek Omarov
9cdce1ce69 engine: network: remove unused MSG_Read/WriteBitFloat 2023-04-03 04:17:54 +03:00
Alibek Omarov
84edd9d0c4 engine: client: use ReadVec3Angles in svc_setangle, as server uses WriteVec3Angles 2023-04-03 04:17:02 +03:00
Alibek Omarov
d8355a651f engine: add missing Sequence_Init and Sequence_OnLevelLoad calls 2023-04-03 04:12:47 +03:00
Alibek Omarov
004ac8105e engine: common: identification: static-ize all functions 2023-04-03 04:04:25 +03:00
Alibek Omarov
2e8ab13242 engine: client: fix parsing svc_spawnentity on old protocol 2023-04-03 03:56:31 +03:00
Alibek Omarov
27d9fc0afe engine: client: sound: remove unused functions 2023-04-03 03:55:57 +03:00
Alibek Omarov
192d510924 engine: client: remove unused function CL_FreeEntity and everything that used it 2023-04-03 03:55:57 +03:00
Alibek Omarov
3614cfa878 engine: client: avi: remove unused function 2023-04-03 03:55:57 +03:00
Alibek Omarov
12efcf1c44 engine: network: remove some totally ununsed functions 2023-04-03 03:13:50 +03:00
Alibek Omarov
a8de11643c engine: platform: sdl: make GL_CreateContext and GL_DeleteContext functions static 2023-04-03 03:13:33 +03:00
Alibek Omarov
597027277c engine: server: remove some totally unused functions 2023-04-03 03:12:52 +03:00
Alibek Omarov
48988e66bd engine: client: fix missing HTTP_ResetProcessState call 2023-04-03 03:11:39 +03:00
Alibek Omarov
37e3cf7e86 public: crtlib: remove unused functions 2023-04-03 02:46:23 +03:00
Alibek Omarov
01e0542223 engine: server: move master announce logic to masterlist, keep unique heartbeat challenge and heartbeat timer for each master 2023-04-03 00:57:47 +03:00
Alibek Omarov
93a7ccd14f engine: network: add net_gai_state_t enum for NET_StringToAdrNB result value 2023-04-03 00:15:35 +03:00
Alibek Omarov
892e5c59eb engine: server: convert public_server cvar to static allocation 2023-04-02 22:48:47 +03:00
Alibek Omarov
c2992afb4a engine: network: make all HTTP commands and cvars restricted, except http_addcustomserver. Also zero http_useragent by default (it's autogenerated now) 2023-03-31 01:22:41 +03:00
Alibek Omarov
b99e7a6304 engine: network: include build info to default HTTP useragent 2023-03-31 01:16:17 +03:00
Alibek Omarov
8888b456df engine: client: cl_tent: rewrite R_Sprite_Explode to be closer to original function but support Xash extensions 2023-03-30 04:42:48 +03:00
Alibek Omarov
53987f47e2 engine: client: use alternative ease-in ease-out function in sound fade 2023-03-30 04:40:54 +03:00
Alibek Omarov
7cac1d290d scripts: gha: it's pretty safe to not do clean on Waf, since it's much better at tracking modified files 2023-03-29 00:22:47 +03:00
Alibek Omarov
55b048aab9 github: enable nswitch and psvita CI builds back, test if continuous tag gets correctly deleted 2023-03-29 00:05:40 +03:00
Alibek Omarov
881a7edb9f github: try to fix uploading release again 2023-03-28 23:54:49 +03:00
Alibek Omarov
6c62136f11 engine: client: avi: convert filename to wide characters before passing it into VFW API 2023-03-28 22:42:16 +03:00
Alibek Omarov
f34b35be5a engine: client: avi: re-attribute AVI support code by restoring original author copyright 2023-03-28 22:42:16 +03:00
Alibek Omarov
4b5ee87de1 engine: client: adapt to RefAPI 4 changes. Fix interpolation issue after reloading a save 2023-03-28 21:34:51 +03:00
Alibek Omarov
67903b55cc ref: soft: adapt to RefAPI 4 changes 2023-03-28 21:34:43 +03:00
Alibek Omarov
55bf0e8a53 ref: gl: adapt to RefAPI 4 changes 2023-03-28 20:45:26 +03:00
Alibek Omarov
f1487cf576 engine: ref_api: bump RefAPI version to 4, R_StudioEstimateFrame now has time argument 2023-03-28 20:42:18 +03:00
Alibek Omarov
29e32310cf github: update linux builds to ubuntu-20.04 2023-03-28 20:08:42 +03:00
Alibek Omarov
2ea549f250 github: update upload-release-action to 2.5.0, print outputs in repackage binaries step 2023-03-28 19:49:35 +03:00
SNMetamorph
b2ea8c9d18 engine: platform: win32: enabled attaching to existing console instead of creating new 2023-03-27 20:31:52 +03:00
Alibek Omarov
6e27926a10 engine: simplify XASH_USE_EVDEV macro usage by giving it's defined positive value 2023-03-27 17:28:19 +03:00
Alibek Omarov
96c30371b7 engine: client: better specify rawinput enabling condition on Win32 2023-03-27 17:22:48 +03:00
Alibek Omarov
9a42f4149f engine: client: disable enabling mouse cursor in key_message (typing in chat) 2023-03-27 17:22:48 +03:00
Alibek Omarov
dca4226e4b github: re-use PrimeXT's actions to upload artifacts to GitHub Releases 2023-03-27 06:01:19 +03:00
Alibek Omarov
b3c1c173a9 scripts: gha: exit if we can't move to a specified directory 2023-03-27 04:30:21 +03:00
Alibek Omarov
3e67445ef3 scripts: gha: psvita: fix building HLSDK, exit if we can't move to a directory 2023-03-27 04:27:55 +03:00
Alibek Omarov
127bd89b44 filesystem: remove unused watch.c file, added by mistake from inotify branch 2023-03-27 03:56:57 +03:00
SNMetamorph
3361e74f54 engine: client: console: fixed console scrolling on psvita platform 2023-03-27 03:52:51 +03:00
SNMetamorph
48e199bfa1 engine: common: enabled printing logs to stderr for psvita platform only in developer mode 2023-03-27 03:52:51 +03:00
SNMetamorph
575179dbf5 engine: client: added default dead zone values for psvita platform 2023-03-27 03:52:51 +03:00
SNMetamorph
e024a67436 engine: platform: psvita: fixed vrtld error reporting 2023-03-27 03:52:51 +03:00
SNMetamorph
e3103249f4 engine: platform: psvita: added developer mode button to launcher 2023-03-27 03:52:51 +03:00
SNMetamorph
0746cb5365 engine: platform: psvita: disabled back touch sensor 2023-03-27 03:52:51 +03:00
Alibek Omarov
fcda7517fe engine: common: soundlib: add support for MP3 looping through custom ID3v2.4.0 tagging 2023-03-27 03:51:42 +03:00
Alibek Omarov
2c77f4c566 engine: client: notify client.dll about local player in firstplayer mode for use in custom renderers 2023-03-27 03:47:42 +03:00
Alibek Omarov
1caa276531 engine: common: imagelib: fix loading cubemaps
Loop break was a bug that was added after refactoring imagelib loader.

In fact, it was mindlessly copypasted from old code, where same break was
used to quickly exit from inner format bruteforcing loop, than outer cubemap
loading loop.
2023-03-25 07:02:29 +03:00
Alibek Omarov
e673fe9a02 filesystem: only create readwrite directories if they look like a gamedirectory in rodir 2023-03-25 03:27:32 +03:00
Alibek Omarov
3ccbc7a28c engine: client: ref_common: r_refdll is not a VIDRESTART cvar 2023-03-24 18:03:06 +03:00
Alibek Omarov
8bb5ec5e26 ref: remove renderer description export, it's unused now 2023-03-24 02:54:14 +03:00
Alibek Omarov
35ff062407 wscript: restore NSwitch and PSVita specific link and compiler flags 2023-03-24 02:28:25 +03:00
Alibek Omarov
ec355a83d1 engine: client: ref_common: eliminate COM_FreeLibrary in renderer names query, hardcoding them instead 2023-03-24 01:52:14 +03:00
Alibek Omarov
182d8edb42 engine: wscript: define enabled renderers as macros 2023-03-24 01:50:53 +03:00
Alibek Omarov
762e4da7a0 wscript: generic refactoring
* Add RefDll class to aid in enabling renderers, creating help options, etc
* Fix optimization flags and werrors are being added twice
* Rewrite if not win32: if elif elif into a set of elifs
* Remove mandatory=True in checks, as it's a default option
2023-03-24 01:50:21 +03:00
Alibek Omarov
098c4c009b engine: platform: sdl: fix incorrect HICON cast in SetClassLongPtr call 2023-03-21 05:16:07 +03:00
Alibek Omarov
f8cf2c8953 scripts: continious_upload: retry if upload failed 2023-03-21 05:15:30 +03:00
Alibek Omarov
cc6838ec97 scripts: gha: psvita: try to fix vitaGL dependency fetching 2023-03-21 04:32:37 +03:00
Alibek Omarov
dca637d4bb engine: client: eliminate pfnServerCmd limit and, like GoldSrc, send our server command immediately to netchan 2023-03-21 04:25:32 +03:00
Alibek Omarov
3949422430 scripts: gha: psvita: fix HLSDK branches names, as all needed PSVita changes have been merged to hlsdk-portable 2023-03-20 18:14:51 +03:00
Alibek Omarov
2c8488f07a scripts: gha: psvita: disable SINGLE_THREADED_GC for vitaGL as it was fixed in upstream (thanks, @fgsfds) 2023-03-20 18:05:24 +03:00
Alibek Omarov
1df1fc32df scripts: gha: psvita: lock vitaGL revision, use --depth=1 in git clone 2023-03-20 18:05:24 +03:00
SNMetamorph
eac8c116a8 engine: server: sv_init: compiling error fix & minor cleanup 2023-03-20 16:29:43 +03:00
SNMetamorph
a03019f5e4 engine: server: sv_init: enabled handling sound resources specifically
This is for timely precaching on client side. Otherwise, files are being downloaded to client, but not precached immediatly after it, and therefore causing a late precaching of sound (obvious, this is bad)
2023-03-20 16:29:43 +03:00
SNMetamorph
714b4f45e4 engine: common: added COM_GetResourceTypeName function 2023-03-20 16:29:43 +03:00
SNMetamorph
68be8157ea engine: common: soundlib: added Sound_SupportedFileFormat function 2023-03-20 16:29:43 +03:00
Alibek Omarov
ea2a8b6785 3rdparty: update submodules (extras, mainui, opus) 2023-03-20 16:03:36 +03:00
Alibek Omarov
8c80d3b85d engine: common: cvar: add exception for cl_dodmusic cvar to fix Day of Defeat Beta 1.3 music issue 2023-03-18 20:34:30 +03:00
Alibek Omarov
33c0764e65 engine: common: system: fix inverted COM_CheckStringEmpty in Sys_GetCurrentUser for Vita
Thanks @fgsfdsfgs for pointing out
2023-03-17 17:29:40 +03:00
Alibek Omarov
d085c5a843 ref: gl: gl_cull: remove thirdperson check, as it handled in client instead 2023-03-15 06:29:29 +03:00
Alibek Omarov
4ada40e8a8 engine: client: check if we should discard local player entity before HUD_AddEntity call, allowing CL_IsThirdPerson hack used in MMod 2023-03-15 06:28:20 +03:00
Alibek Omarov
1630d87c0d engine: client: do not alter the state if invalid HANDLE was passed to pfnSPR_Set. Fixes Half-Life: MMod 2023-03-15 04:58:33 +03:00
Alibek Omarov
3a956a1ad3 engine: client: initialize variables in SPR_Width/Height/Frames functions, in case R_GetSpriteParms fails 2023-03-15 04:58:00 +03:00
Alibek Omarov
774ced312f wscript: enforce -Werror=strict-aliasing 2023-03-14 21:29:35 +03:00
Alibek Omarov
fec3d33dcf engine: client: cl_securedstub: fix strict aliasing in secured module initializing 2023-03-14 21:29:35 +03:00
Alibek Omarov
d4610e30fd engine: common: net_encode: fix strict aliasing by converting it to use float_bits_t union 2023-03-14 21:29:35 +03:00
Alibek Omarov
885cda971d engine: common: net_buffer: fix strict aliasing by converting it to use float_bits_t union 2023-03-14 21:29:35 +03:00
Alibek Omarov
ef0b227967 ref: gl: alias: fix strict aliasing by converting it to use float_bits_t union 2023-03-14 21:29:35 +03:00
Alibek Omarov
19a785a98a public: mathlib: convert rsqrt to use float_bits_t union 2023-03-14 21:29:35 +03:00
Alibek Omarov
b96bfcfe7a public: mathlib: convert FloatToHalf and HalfToFloat to use float_bits_t union 2023-03-14 21:29:35 +03:00
Alibek Omarov
412c635499 public: add float_bits_t union to access float as 32-bit signed or unsigned integer 2023-03-14 21:29:35 +03:00
Alibek Omarov
da5ec56567 engine: common: con_utils: fix const qualifier discard in Con_CheckName 2023-03-14 00:35:07 +03:00
Alibek Omarov
e664e80b27 engine: common: mod_bmodel: replace few more obvious va calls by temp buffer and Q_snprintf 2023-03-13 06:25:57 +03:00
Alibek Omarov
d177b6f528 engine: cvar: consolidate auto description for GLCONFIG cvars
Fix bug when GLCONFIG cvars didn't had it's respective CLIENTDLL or GAMEUIDLL flags
2023-03-13 06:22:54 +03:00
Alibek Omarov
2ef3d78d9f engine: client: netgraph: replace CL_DrawString with va calls by CL_DrawStringf 2023-03-13 06:16:17 +03:00
Alibek Omarov
5ea5e1167b engine: client: font: add CL_DrawStringf wrapper 2023-03-13 06:15:45 +03:00
Alibek Omarov
116a605248 engine: common: replace some obvious va uses by temp buffer and Q_snprintf or equivalent code 2023-03-13 06:08:36 +03:00
Alibek Omarov
9690fe9334 engine: client: replace some obvious va uses by temp buffer and Q_snprintf 2023-03-13 06:03:44 +03:00
Alibek Omarov
a81fa84321 engine: server: replace some obvious va uses to temp buffer and Q_snprintf 2023-03-13 06:00:38 +03:00
Alibek Omarov
5ef97ae99e engine: convert Info_SetValueForKey with va to Info_SetValueForKeyf 2023-03-13 05:37:45 +03:00
Alibek Omarov
d667845777 engine: convert Cbuf_AddText with va to Cbuf_AddTextf 2023-03-13 05:31:27 +03:00
Alibek Omarov
b12b2aaf79 engine: common: cmd: add Cbuf_AddTextf wrapper 2023-03-13 05:28:53 +03:00
Alibek Omarov
6b62f9c1b9 engine: convert Cvar_Get with va to Cvar_Getf 2023-03-13 05:19:32 +03:00
Alibek Omarov
ba1cf25314 engine: convert MSG_WriteString with va to MSG_WriteStringf 2023-03-13 05:13:52 +03:00
Alibek Omarov
fb2ba6a6e2 engine: common: net_buffer: add MSG_WriteStringf wrapper 2023-03-13 05:12:46 +03:00
Alibek Omarov
fb6e310eab public: move va() function back to engine, it's not recommended to use in shared modules 2023-03-13 02:44:59 +03:00
Alibek Omarov
bcbd1a59c6 engine: common: base_cmd: add a simple benchmark within basecmd_test command 2023-03-13 02:40:48 +03:00
Alibek Omarov
8e45a43ad2 engine: common: base_cmd: alphabetically order inserts for faster lookups 2023-03-13 02:39:54 +03:00
Alibek Omarov
115ed82c19 engine: common: base_cmd: static-ize internal fuctions 2023-03-13 02:39:02 +03:00
Alibek Omarov
5c1e06ae74 public: crclib: optimize COM_HashKey, implement typical djb hashing as this function is used for hashtables with string lookup 2023-03-13 02:37:19 +03:00
SNMetamorph
f9205825b6 engine: platform: sdl: fixed psvita & nswitch platform initializing 2023-03-12 16:09:20 +03:00
Andrey Akhmichin
9040c34f48 ref: gl: replace va function calls. 2023-03-11 17:56:05 +03:00
Andrey Akhmichin
9e9703e6de engine: common: imagelib: replace va function calls. 2023-03-11 17:37:16 +03:00
Andrey Akhmichin
6486533355 engine: platform: android: replace va function calls. 2023-03-11 16:29:55 +03:00
Andrey Akhmichin
34160151a4 filesystem: replace va function calls. 2023-03-11 16:28:54 +03:00
Andrey Akhmichin
daaaa324bd engine: platform: emscripten: replace va function calls. 2023-03-11 15:32:14 +03:00
Andrey Akhmichin
af5c74981b ref: soft: replace va function calls. 2023-03-11 15:31:17 +03:00
Andrey Akhmichin
249ce6bca1 engine: platform: win32: replace va function calls. 2023-03-11 15:30:56 +03:00
Andrey Akhmichin
b648c74815 engine: platform: posix: replace va function calls. 2023-03-11 15:30:29 +03:00
Andrey Akhmichin
a2d459ae84 engine: common: add printf-like version of Cvar_Get function. 2023-03-11 15:29:54 +03:00
Andrey Akhmichin
573781b45d engine: platform: sdl: replace va function calls. 2023-03-11 15:29:34 +03:00
Andrey Akhmichin
3299999f3d engine: common: add printf-like version of Info_SetValueForKey function. 2023-03-11 15:28:54 +03:00
Alibek Omarov
91be4f6521 engine: common: cmd: fix inverted check in apropos 2023-03-11 07:50:33 +03:00
fgsfds
f2f21b24a1 scripts: psvita: no need for fsigned-char either 2023-03-11 07:09:19 +03:00
fgsfds
9ef43a4794 scripts: psvita: no need to force GNU_SOURCE everywhere 2023-03-11 07:09:19 +03:00
fgsfds
fc02a69686 docs: add nswitch and psvita to ports.md 2023-03-11 07:09:19 +03:00
fgsfds
b10a0dc5c5 ci: psvita: build bshift libraries 2023-03-11 07:09:19 +03:00
fgsfds
e5f0d1557c docs: psvita: add install/build instructions 2023-03-11 07:09:19 +03:00
fgsfds
d8a3f4850a ci: psvita: libk is not required 2023-03-11 07:09:19 +03:00
fgsfds
882d957b5c ci: psvita: vdpm is in the current directory 2023-03-11 07:09:19 +03:00
fgsfds
afd1727898 ci: psvita: only download necessary packages 2023-03-11 07:09:19 +03:00
fgsfds
70a73e47a7 psvita: use crtlib where possible 2023-03-11 07:09:19 +03:00
fgsfds
fe3f15ad33 engine: input: psvita: reimplement OSK manually 2023-03-11 07:09:19 +03:00
fgsfds
66f625f840 engine: psvita: use a macro for ioctlsocket like on all other platforms 2023-03-11 07:09:19 +03:00
fgsfds
3e1833722f engine: psvita: check req in ioctlsocket() 2023-03-11 07:09:19 +03:00
fgsfds
4b8e11f561 engine: remove stray #if XASH_PSVITA 2023-03-11 07:09:19 +03:00
fgsfds
0d04c20578 ref: gl: psvita: skip deleting the shaders since glDeleteProgram can block for a long time 2023-03-11 07:09:19 +03:00
fgsfds
41c819f3d3 engine: psvita: keep old arguments in Sys_NewInstance 2023-03-11 07:09:19 +03:00
fgsfds
957154f097 scripts: psvita: move TITLEID and APPNAME to engine elf build arguments 2023-03-11 07:09:19 +03:00
fgsfds
fad506ef03 ref: gl: vgl_shim: remove normal support, it's not necessary 2023-03-11 07:09:19 +03:00
fgsfds
9150bbdfd8 ref: gl: psvita: remove the GL_CheckExtension hack 2023-03-11 07:09:19 +03:00
fgsfds
aa4e2f0ae4 ref: gl: psvita: use Cvar_FullSet to disable r_studio_drawelements 2023-03-11 07:09:19 +03:00
fgsfds
2bacc91922 ref: gl: move vgl_shim to ref/gl 2023-03-11 07:09:19 +03:00
fgsfds
458aa6d8b8 ci: psvita: copy the vpk as well 2023-03-11 07:09:19 +03:00
fgsfds
6963741020 ci: psvita: fix copypaste error 2023-03-11 07:09:19 +03:00
fgsfds
b55aa982b0 ci: psvita: vrtld uses cmake 2023-03-11 07:09:19 +03:00
fgsfds
492481eea8 ci: basic psvita scripts 2023-03-11 07:09:19 +03:00
fgsfds
76bff9cd4b ref: gl: psvita: fix long hang on shutdown 2023-03-11 07:09:19 +03:00
fgsfds
47a6be86b1 engine: psvita: export stpcpy 2023-03-11 07:09:18 +03:00
fgsfds
287688d985 engine: psvita: implement Sys_NewInstance 2023-03-11 07:09:18 +03:00
fgsfds
610d528042 engine: psvita: implement Sys_GetCurrentUser 2023-03-11 07:09:18 +03:00
fgsfds
89ec39821e ref: gl: psvita: add fog support; bump max verts to 32768 2023-03-11 07:09:18 +03:00
fgsfds
82cfd3ecc3 ref: gl: psvita: revert arrayverts change, it doesn't matter that much 2023-03-11 07:09:18 +03:00
fgsfds
5a3e3b3977 ref: gl: add immediate mode shim for psvita 2023-03-11 07:09:18 +03:00
fgsfds
9cf6e421cb ref: gl: psvita: force-enable NPOT textures 2023-03-11 07:09:18 +03:00
fgsfds
5c56b51044 engine: client: don't pop up OSK during loading screens on the PSVita either 2023-03-11 07:09:18 +03:00
fgsfds
577add56f1 filesystem: fs is non case sensitive on nswitch and psvita 2023-03-11 07:09:18 +03:00
fgsfds
adc5aa4659 psvita: don't default to -dev 255 2023-03-11 07:09:18 +03:00
fgsfds
5beed5ab29 engine: psvita: rebalance memory pools a bit 2023-03-11 07:09:18 +03:00
fgsfds
34dd52ca90 ref: gl: trust the GL_EXTENSIONS string on psvita 2023-03-11 07:09:18 +03:00
fgsfds
6304b51f32 psvita: fno-short-enums, make ref_gl function somewhat 2023-03-11 07:09:18 +03:00
fgsfds
97a7de3377 engine: server: remove duplicate registration for sv_autosave 2023-03-11 07:09:18 +03:00
fgsfds
7424b29e56 engine: initial psvita build support 2023-03-11 07:09:14 +03:00
Alibek Omarov
3c64d2ad80 public: build: don't confuse other libcs with built with glibc game libraries by specifying them into separate platform, like Android 2023-03-11 05:45:11 +03:00
Alibek Omarov
1274fa13c8 engine: common: cmd: slightly simplify apropos taking all arguments and checking for filtering symbols 2023-03-11 05:38:28 +03:00
Alibek Omarov
3765686077 public: make va() buffer size public 2023-03-11 05:28:17 +03:00
SNMetamorph
9fffd7a270 Documentation: added page about debugging mods using minidump files 2023-03-11 04:28:25 +03:00
SNMetamorph
e37c07f44f engine: crashhandler: added support for minidumps generation 2023-03-11 04:28:25 +03:00
SNMetamorph
214a3cce73 engine: host: added -minidumps startup parameter for win32 platform 2023-03-11 04:28:25 +03:00
Andrey Akhmichin
d738b07660 Documentation: mod-porting-guide.md: Update. 2023-03-11 04:22:30 +03:00
Alibek Omarov
48ca8f9a70 engine: server: fix call to non existent function, in this tree it's called IsMasterAdr 2023-03-02 17:36:56 +03:00
Alibek Omarov
c565b0a505 mainui: update 2023-03-02 17:35:50 +03:00
Alibek Omarov
474833a3bf engine: server: send heartbeats to master server if sv_nat is active, despite public cvar value 2023-03-01 15:57:30 +03:00
Alibek Omarov
602f23fbdf engine: server: check if we got info request from master server, that acts as a bridge for NAT servers 2023-03-01 15:57:30 +03:00
Alibek Omarov
7e9d46689c engine: client: fix multiline CenterPrint 2023-02-24 19:46:02 +03:00
Alibek Omarov
b6347d17c9 engine: client: sound: don't print sound/ twice in soundlist command 2023-02-19 12:25:03 +03:00
Alibek Omarov
8293bc91d4 engine: client: sound: fix PickDynamicChannel to correctly find channel with minimum time left 2023-02-18 03:37:20 +03:00
Alibek Omarov
fb0f184d6b engine: common: lib_common: fix offset by one UB 2023-02-17 22:51:56 +03:00
Alibek Omarov
58e95c7d6f engine: client: console: elinimate unneeded Sys_DoubleTime call in Con_DrawDebug 2023-02-17 22:50:42 +03:00
Alibek Omarov
7a5381e658 engine: common: mod_studio: fix uninitialized adj array 2023-02-17 22:50:12 +03:00
Alibek Omarov
375c06400c engine: server: avoid unaligned access in pfnMessageEnd 2023-02-17 22:48:56 +03:00
Alibek Omarov
e481c86ba2 engine: client: console: fix NXPrintf newlines, small refactoring 2023-02-15 05:53:39 +03:00
Alibek Omarov
21b9f07323 engine: platform: sdl: remove legacy XASH_NANOGL macro from vid code, it's only relevant for ref_gl 2023-02-14 18:52:51 +03:00
Alibek Omarov
0bff62e696 engine: sprite: migrate header to stdint.h, remove usage of enums in data structs for portability, add static sizeof checks 2023-02-14 18:29:27 +03:00
Alibek Omarov
858597832d engine: alias: migrate header to stdint.h, remove usage of enums in data structs for portability, add static sizeof checks 2023-02-14 18:29:18 +03:00
Alibek Omarov
9b0ac7cb32 common: add shared synctype_t definition header, borrowed from Quake's modelgen.h 2023-02-14 18:18:16 +03:00
Alibek Omarov
3c27384b6b filesystem: speedup fs_ext_path case in FS_FindFile 2023-02-13 06:49:52 +03:00
Alibek Omarov
1e8c26a527 filesystem: wad: fix loading WADs by absolute paths 2023-02-13 06:49:29 +03:00
Alibek Omarov
f4069de7f2 engine: move SlerpBones, CalcBonePosition/Quaternion from engine to libpublic 2023-02-13 05:23:13 +03:00
Alibek Omarov
e95161aa14 filesystem: fix ClearSearchPath 2023-02-12 17:09:53 +03:00
Alibek Omarov
0984368a31 engine: server: GoldSrc compliant pfnServerExecute(), don't execute config.cfg for server! 2023-02-11 07:22:04 +03:00
Alibek Omarov
f4961d9da7 engine: client: return empty string in pfnGetLevelName if no map is loaded yet 2023-02-11 06:50:46 +03:00
Alibek Omarov
f42a174482 engine: client: empty current map name in CL_ClearState 2023-02-11 06:45:20 +03:00
Alibek Omarov
13bf607031 engine: client: call VidInit early in svc_serverdata parsing, GoldSrc compatibility 2023-02-11 06:43:38 +03:00
Alibek Omarov
3cfdb1213b engine: client: consolidate modern and legacy protocol parsing functions, if possible 2023-02-11 06:06:21 +03:00
Alibek Omarov
d58105d64d scripts: flatpak: fix Half-Life directory detection 2023-02-11 03:56:40 +03:00
Alibek Omarov
1bdd844860 scripts: flatpak: minimize filesystem permissions, add Steam Flatpak data directory 2023-02-11 03:36:40 +03:00
Alibek Omarov
11f3d97cd7 scripts: flatpak: respect XDG data home in launcher script, add Steam Flatpak data directory 2023-02-11 03:36:40 +03:00
Alibek Omarov
fccf044976 engine: initialize network buffers used on player connect and after 2023-02-09 17:57:45 +03:00
Alibek Omarov
c23396f533 engine: client: keys: hardcode K_START_BUTTON as escape button, cancelselect doesn't exist anymore and many games seems to use this button for menu access, and back for pause 2023-02-09 06:32:14 +03:00
Alibek Omarov
33c9f7118b engine: platform: sdl: sanitize buttons/axes from SDL, add ABXY->BAYX swap for NSwitch 2023-02-09 06:31:19 +03:00
Alibek Omarov
c741ec223f engine: client: keys: reserve some more buttons as gamepad buttons according to latest SDL2 GameController header 2023-02-09 06:30:08 +03:00
Alibek Omarov
d6d98bd297 engine: platform: sdl: minor style changes 2023-02-09 05:59:34 +03:00
Alibek Omarov
5e1b5d89f7 engine: client: console: allow opening OSK and existing console with gamepads for all platforms 2023-02-09 05:58:54 +03:00
Alibek Omarov
a0edfd28b2 engine: common: host: use DEFAULT_ALLOWCONSOLE macro to set default console state 2023-02-09 05:56:11 +03:00
Alibek Omarov
555fd02407 defaults: reorganize platform default overrides, disable touch for nswitch 2023-02-09 05:55:35 +03:00
Alibek Omarov
f7f9cfecfc ci: nswitch: use waf install to copy build artifacts 2023-02-09 05:35:30 +03:00
Alibek Omarov
2aeee59a31 Merge remote-tracking branch 'fgsfds/switch_newer' 2023-02-09 05:18:06 +03:00
Alibek Omarov
12b8965a8c mainui: update 2023-02-08 20:01:06 +03:00
Alibek Omarov
b5b6b8b785 engine: network: fix some unitialized sockaddr_storage's 2023-02-08 20:00:51 +03:00
fgsfds
35e073ceff ci: nswitch: don't forget filesystem_stdio 2023-02-08 01:53:26 +01:00
fgsfds
b2cc96cf0d scripts: wscript: nswitch: do the libstdc++ hack right before build to not pollute the environment 2023-02-08 01:37:35 +01:00
fgsfds
f7489a3747 scripts: nswitch: it's arm64, not aarch64 2023-02-08 01:04:31 +01:00
fgsfds
0e7ebf6d44 Merge branch 'master' of https://github.com/FWGS/xash3d-fwgs into switch_newer 2023-02-08 00:56:20 +01:00
fgsfds
69607d7890 nswitch: do not link libstdc++ into dynamic libraries
instead only link it to the main executable with --whole-archive, letting the dynamic libs import anything they want from it
2023-02-08 00:52:48 +01:00
fgsfds
4e87eb068a engine: common: nswitch: use #if instead of #ifdef 2023-02-07 23:03:59 +01:00
Alibek Omarov
03a7c67731 public: build: revert arm64 renaming to aarch64, we shouldn't enforce naming changes without a reason 2023-02-08 00:03:15 +03:00
Alibek Omarov
5ba2449d10 engine: common: static-ify functions in mod_studio.c 2023-02-08 00:03:15 +03:00
fgsfds
0ee2fd8a8a ci: nswitch: do not dumb, 00 penalty 2023-02-07 20:52:23 +01:00
fgsfds
080b9b30a1 ci: nswitch: do not put the pkgtemp folder into the .7z 2023-02-07 20:45:42 +01:00
fgsfds
749ac5ed54 ci: nswitch: do not rely on dkp-pacman at all 2023-02-07 20:38:40 +01:00
fgsfds
6c8b9af6bb ci: nswitch: fix artifact packaging 2023-02-07 20:35:24 +01:00
fgsfds
07922c0239 ci: nswitch: actually set env vars properly 2023-02-07 20:26:24 +01:00
fgsfds
1a54ec92e0 github: ref name not required 2023-02-07 20:26:13 +01:00
fgsfds
663b574b8b github: checkout the switch_newer branch for now 2023-02-07 20:22:30 +01:00
fgsfds
430c51b71a ci: nswitch: there is no python-is-python3 where we're going 2023-02-07 20:14:11 +01:00
fgsfds
20bcd03f19 ci: nswitch: ...and set it to be the default python install 2023-02-07 20:07:48 +01:00
fgsfds
dab959fc32 ci: nswitch: the docker container is missing python, install it 2023-02-07 20:04:36 +01:00
fgsfds
eff75e5d50 ci: nswitch: the docker container is missing dkp-toolchain-vars, install it 2023-02-07 20:00:49 +01:00
fgsfds
d103f022b4 ci: nswitch: forgot run 2023-02-07 19:55:33 +01:00
fgsfds
72b8246969 ci: nswitch: attempt to use dkp's docker image
because they banned the ci server from accessing their pacman repo
2023-02-07 19:54:00 +01:00
fgsfds
030d05f018 ci: nswitch: make install with sudo 2023-02-07 18:38:18 +01:00
fgsfds
59cd5493e7 github: add nswitch build target 2023-02-07 18:35:08 +01:00
fgsfds
98a7f6fa3f ci: add nswitch build scripts 2023-02-07 18:34:58 +01:00
fgsfds
65095df124 Merge branch 'master' of https://github.com/FWGS/xash3d-fwgs into switch_newer 2023-02-07 17:15:01 +01:00
fgsfds
ee370ea007 Merge branch 'master' of https://github.com/FWGS/xash3d-fwgs into switch_newer 2023-02-07 17:14:47 +01:00
Alibek Omarov
05016f8639 engine: vgui: add EnableTextInput to the API 2023-02-06 16:42:09 +03:00
Alibek Omarov
12154de6f5 ref: soft: fix -Wsequence-point 2023-02-06 16:42:09 +03:00
Alibek Omarov
3fca567b81 wscript: few more warnings-as-errors 2023-02-06 16:42:09 +03:00
Alibek Omarov
634574f249 engine: platform: sdl: don't enable text mode with cursor??? 2023-02-06 00:29:14 +03:00
fgsfds
f782d444a8 engine: platform: posix: don't redefine _GNU_SOURCE 2023-02-06 00:05:41 +03:00
fgsfds
b68def2b9c engine: touch: only pop up touch keyboard on FINGERDOWN events 2023-02-06 00:05:32 +03:00
fgsfds
d944301a60 engine: client: add barebones gamepad controls to input fields 2023-02-06 00:05:28 +03:00
fgsfds
15ba932046 engine: server: add sv_autosave cvar
* a1ba: added FCVAR_PRIVILEGED just in case
2023-02-06 00:05:20 +03:00
fgsfds
b73c16c216 engine: net_ws: pass correct sockaddr lengths where needed 2023-02-05 23:51:48 +03:00
fgsfds
0ba4ef678c engine: net_ws: pass correct sockaddr lengths where needed 2023-02-05 03:39:32 +01:00
fgsfds
919d510f63 Merge branch 'master' of https://github.com/FWGS/xash3d-fwgs into switch_newer 2023-02-05 02:37:40 +01:00
fgsfds
6557ac7fb4 server: add sv_autosave cvar 2023-02-05 02:29:22 +01:00
Alibek Omarov
87c307f47e scripts: flatpak: install vgui 2023-02-05 04:27:58 +03:00
fgsfds
f3e50b5500 add barebones gamepad controls for input fields and console 2023-02-05 02:27:12 +01:00
fgsfds
705f252ed8 nswitch: don't automatically pop up OSK when opening console 2023-02-05 02:26:48 +01:00
fgsfds
cb28101732 touch: only pop up OSK on FINGERDOWN events 2023-02-05 02:26:17 +01:00
fgsfds
f87863b8bc nswitch: always enable console 2023-02-05 02:18:11 +01:00
fgsfds
25fb89f717 nswitch: don't redefine O_BINARY 2023-02-05 02:16:56 +01:00
fgsfds
36e7856b9c don't redefine _GNU_SOURCE 2023-02-05 02:16:38 +01:00
Alibek Omarov
34b0cdc125 scripts: flatpak: use relative paths as RoDir doesn't allow absolute paths for now 2023-02-05 04:13:45 +03:00
fgsfds
25a1cb8ce7 Nintendo Switch support (again) 2023-02-05 02:09:32 +01:00
Alibek Omarov
a610b1545b scripts: flatpak: check .local directory for steam library 2023-02-05 03:44:58 +03:00
Alibek Omarov
30b698067a scripts: flatpak: allow easy debugger attach 2023-02-05 03:25:07 +03:00
Alibek Omarov
f63f1a0dc6 scripts: flatpak: add another default Steam library path 2023-02-05 02:43:36 +03:00
Alibek Omarov
9cb867a7d4 filesystem: wad: print errno if wad can't be opened 2023-02-05 02:42:35 +03:00
Alibek Omarov
00ddd95c27 scripts: flatpak: try to add ourselves to desktop menu entries 2023-02-05 02:25:21 +03:00
Alibek Omarov
0ffd1b9ff1 github: try to enable building flatpak bundle 2023-02-05 00:40:08 +03:00
Alibek Omarov
2109d49aa3 ci: disable xash-extras fetching, it's a submodule now 2023-02-05 00:06:19 +03:00
Alibek Omarov
f910f4896c engine: client: font: finally add support for tab character in engine 2023-02-04 22:53:10 +03:00
Alibek Omarov
6eae3471cf engine: client: font: fix consecutive newlines skipped, add flag to reset color after a newline 2023-02-04 21:59:46 +03:00
Alibek Omarov
c0fa91bec9 engine: client: consolidate client and menu scissor functions 2023-02-04 21:24:19 +03:00
Alibek Omarov
ba6dd3c751 engine: client: font: fix another inverted check 2023-02-04 21:23:51 +03:00
Alibek Omarov
fd63018fb5 engine: client: make client string drawing functions ignore linefeeds 2023-02-04 20:58:33 +03:00
Alibek Omarov
2225915702 engine: client: font: fix CL_DrawStringLen 2023-02-04 20:54:17 +03:00
Alibek Omarov
d14e486721 engine: client: font: add special flag to ignore linefeeds when drawing strings 2023-02-04 20:53:52 +03:00
Alibek Omarov
82b6da493a wscript: enforce GCC suspicious sizeof operations warnings as errors 2023-02-03 18:51:50 +03:00
Alibek Omarov
bec0b36bb9 engine: client: font: fix colorcodes, don't reset Colo4ub, it will be reset by consequent draw calls anyway 2023-02-03 18:20:02 +03:00
Alibek Omarov
e2c2821191 engine: client: font: do not apply filtering hack when fonts aren't upscaled 2023-02-03 18:06:07 +03:00
Alibek Omarov
a19d34035d engine: client: font: do not use OpenFile on WADs >_< 2023-02-03 17:49:06 +03:00
Alibek Omarov
77ea03a62c engine: client: introduce bare-bones font manager and text drawing manager
* wire hud_fontscale so HUD font scaling can be used independently from
  hud_scale
* allow small optimizatinons, like optional UTF-8 decoding, or not calling
  SetRenderMode for each character
* even less copypasted code in text drawing between client code and console
* get rid of direct DrawCharacter calls when it can be just DrawString
* fix net_speeds, r_speeds with scaled console fonts
* try to fix MobilityAPI's pfnDrawCharacterScaled
* center keyboard keys in OSK code
2023-02-03 08:51:18 +03:00
Alibek Omarov
402a0f129d engine: platform: sdl: use SDL joystick rumble for Platform_Vibrate 2023-02-03 08:50:41 +03:00
Alibek Omarov
d7116afc92 engine: client: add hud_fontscale cvar to control HUD font scaling (not wired to any logic yet) 2023-02-02 04:57:53 +03:00
Alibek Omarov
d5fe491c14 engine: client: add a little auto-disconnect message in case of server timeout 2023-02-02 02:49:25 +03:00
Alibek Omarov
92138428c5 engine: touch: don't emulate touch and mouse through SDL2 (taken from @Velaron branch) 2023-02-01 06:42:31 +03:00
Alibek Omarov
f3ff942ea9 scripts: flatpak: add basic i386 flatpak script 2023-02-01 04:58:12 +03:00
Alibek Omarov
ced6e8869a ref: fix chrome texture being misaligned 2023-02-01 04:55:47 +03:00
Alibek Omarov
d7af50ea6c engine: ref: remove direction vectors from Ref API, renderers calculate them from viewangles to local data anyway 2023-01-31 07:18:23 +03:00
Alibek Omarov
f7d4e5a2ea engine: server: don't show GAMESAVED message in autosaves, small refactoring 2023-01-31 07:16:08 +03:00
Alibek Omarov
2e3788f23d engine: dedicated: add CL_HudMessage to dedicated stubs 2023-01-31 07:14:26 +03:00
Alibek Omarov
eaf9a9283a Revert "engine: network: do not read from uninitialized sockaddr storage"
This reverts commit 4f78ec01cf.
2023-01-31 04:33:27 +03:00
Alibek Omarov
ae66291272 scripts: compiler_optimizations: added MSan target 2023-01-31 04:28:08 +03:00
Alibek Omarov
4f78ec01cf engine: network: do not read from uninitialized sockaddr storage 2023-01-31 04:14:18 +03:00
Alibek Omarov
be084d5603 engine: crashhandler: fully initialize struct sigaction 2023-01-31 00:50:48 +03:00
Alibek Omarov
aac0be1ab3 engine: imagelib: img_bmp: fully initialize local palette array 2023-01-31 00:50:04 +03:00
Alibek Omarov
6282acc825 engine: client: simplify drawing loading or paused bar, fix position with hud_scale active 2023-01-30 23:17:53 +03:00
Alibek Omarov
39fd30a472 engine: client: fix HUD font loading 2023-01-27 19:07:26 +03:00
Alibek Omarov
279e391949 engine: sound: allow mouth move for CHAN_STREAM 2023-01-27 06:19:31 +03:00
Alibek Omarov
6df25392b8 engine: server: redirect special sounds, detected by leading asterisk, into CHAN_STREAM
In GoldSrc this magic symbol means that we should not override channel this
sound is playing on. Originally handled on client but for both static and dynamic sounds
so let's redirect channel on server side instead.
2023-01-27 06:19:31 +03:00
Alibek Omarov
327372e253 engine: client: call SND_ForceOpen/CloseMouth within SND_Open/CloseMouth to avoid copypasted code 2023-01-27 06:19:31 +03:00
Andrey Akhmichin
801dbaa387 engine: common: soundlib: libmpg: backport fix for CVE-2017-11126.
Original patch: https://www.mpg123.de/cgi-bin/scm/mpg123/trunk/src/libmpg123/layer3.c?view=patch&r1=4275&r2=4274
Same as: f246a0cdfd
2023-01-25 15:57:52 +03:00
Andrey Akhmichin
ffd5c2d3d0 engine: common: soundlib: libmpg: backport fix for CVE-2017-12839.
Original patch: https://www.mpg123.de/cgi-bin/scm/mpg123/trunk/src/libmpg123/getbits.h?view=patch&r1=2024&r2=4323
Same as: 8a5e21a2a2
2023-01-25 15:57:52 +03:00
Alibek Omarov
84c14b32ec engine: client: fix filtering errors by adjusting texcoords by half of a pixel
Remove useless wrapper functions and conversions
Don't scale texcoords and position if hud_scale is not active
2023-01-25 04:17:48 +03:00
Alibek Omarov
c481e52558 engine: client: consolidate variable and quake fixed width font loading functions 2023-01-25 02:38:18 +03:00
Alibek Omarov
b946ed4625 engine: platform: sdl: don't flood about closest display mode in case of no changes 2023-01-18 20:05:00 +03:00
Alibek Omarov
ef1572b15b engine: crashhandler: fix build on FreeBSD (and probably on NetBSD and OpenBSD) 2023-01-18 19:45:21 +03:00
Alibek Omarov
aaeb18f433 engine: inline version of MSG_BigShort 2023-01-18 19:29:27 +03:00
Alibek Omarov
dd1d86c289 engine: platform: sdl: check usable display rect before creating window 2023-01-18 19:28:16 +03:00
Alibek Omarov
16b162f7bb engine: vid: position window in center by default 2023-01-18 19:27:40 +03:00
Alibek Omarov
500ca54550 Revert "engine: get rid of MSG_BigShort, use htons instead, since network headers are always included"
This reverts commit a6475f530b.
2023-01-18 19:21:51 +03:00
Alibek Omarov
5313dc9475 engine: client: fix uninitialized fadeTotalEnd in screenfade parsing code 2023-01-16 09:21:30 +03:00
Alibek Omarov
9c0c1a802c filesystem: fix strict order of loading archives 2023-01-15 13:12:39 +03:00
Alibek Omarov
fbedbdca7d engine: client: fix fullscreen reapplied on window resize 2023-01-14 18:52:38 +03:00
Alibek Omarov
6232e288e1 engine: client: fool proof R_SaveVideoMode 2023-01-14 11:45:42 +03:00
Alibek Omarov
a6475f530b engine: get rid of MSG_BigShort, use htons instead, since network headers are always included 2023-01-14 10:58:04 +03:00
Alibek Omarov
de84df99f3 engine: fix functions returning void returning void value 2023-01-14 10:58:03 +03:00
Alibek Omarov
a5d5c1f60b wscript: cast-align is less effective than ubsan 2023-01-14 10:58:03 +03:00
Alibek Omarov
6ac3156a82 engine: fix discarded const pointer qualifier in PM_HullPointContents 2023-01-14 10:57:22 +03:00
Alibek Omarov
2705e77a4e ci: don't spew config.log when it's not needed, less verbosity 2023-01-14 10:06:32 +03:00
Alibek Omarov
a09aa31b7a github: comment out CI builds for MAGX and Android 2023-01-14 09:52:44 +03:00
Xav101
9466461ce0 engine: preliminary support for SGI IRIX (#1211)
* Added definitions for IRIX

* Patchset to get dedicated server to compile on IRIX.

* Cleaned up debug statements in wscript

* Potential bug in IRIX implementation of isnan? For now just use the portable macro.

* Include the platform port files in the build

* Temporary execution script for setting appropriate library search paths to the right locations in the build directory. This should probably get replaced with a more permanent script at some point which lives in the same directory as the normal xash binary, or be replaced by a solution that sets the rpath during config or modifies rpath during install.

* Clean up formatting and remove unneeded debugging statements

* Added GPL copyright notice and description

* Moved to irix platform folder and edited script

* Re-introduced _inline macro

* Replace spaces with tabs

Co-authored-by: Xav101 <xaviernye@msn.com>
2023-01-14 09:35:30 +03:00
Alibek Omarov
74ce7e9b10 ref: don't apply rendercolor to studio models where it's not needed 2023-01-13 15:25:58 +03:00
Alibek Omarov
10481a4ecc github: upgrade SDL2 2023-01-13 11:50:01 +03:00
Alibek Omarov
acd86ce490 engine: sound: select which to buffer raw channels will be painted to, choose stream buffer for voice 2023-01-13 08:50:33 +03:00
Alibek Omarov
1119a9ac22 engine: network: reenable DNS resolving in separate thread for Windows 2023-01-13 08:09:16 +03:00
Alibek Omarov
171c0c8d3b engine: common: zone: use stdint types 2023-01-12 04:04:53 +03:00
Alibek Omarov
9b5e0fef01 engine: common: zone: make Mem_Alloc return aligned addresses on ILP32, thanks Xav101 on Discord for heads up 2023-01-12 04:02:04 +03:00
Alibek Omarov
2f5e3b0aea mainui: update 2023-01-11 13:41:54 +03:00
Alibek Omarov
ca3b0e6246 Documentation: document the _i?86 quirk in library naming scheme 2023-01-10 04:59:28 +03:00
Alibek Omarov
eb0459a045 engine: strip Intel suffixes from server library name, but only on special platforms
Remove same code from filesystem, it's not what filesystem should do
2023-01-10 04:51:34 +03:00
Alibek Omarov
5d98e13fb8 public: add Q_ArcitectureStringByID function to get library naming compliant CPU and ABI string 2023-01-09 22:53:05 +03:00
Alibek Omarov
113904ea91 public: fix build 2023-01-09 22:47:54 +03:00
Alibek Omarov
1dc3cc2d57 public: add Q_PlatformStringByID function that returns library naming compliant string by platform identifier from buildenums 2023-01-09 08:06:58 +03:00
Alibek Omarov
15a5975abf public: build.h refactoring, removed XASH_MSVC, XASH_MINGW, as this header never intended to detect the compiler 2023-01-09 08:05:59 +03:00
Alibek Omarov
65debeb738 public: add header buildenums.h declaring all platforms, architectures and ABIs as integer constants. 2023-01-09 08:04:58 +03:00
Alibek Omarov
209a03a12a engine, public: prepare to removal of XASH_MSVC macro 2023-01-09 08:01:52 +03:00
Alibek Omarov
c28aeb2362 engine: make crashhandler implementation choice private to crashhandler code 2023-01-09 07:55:54 +03:00
Alibek Omarov
9152bbf106 engine: client: more accurate decompilation of CL_LerpPoint and ComputeInterpolationAmount 2023-01-07 11:08:32 +03:00
Alibek Omarov
40ba0238f8 engine: client: cosmetic changes in pmove code 2023-01-07 11:07:32 +03:00
Alibek Omarov
4a3efa511c engine: client: correctly decompiled version of CL_AdjustClock (with removed useless float-to-int operation) 2023-01-07 07:23:14 +03:00
Alibek Omarov
2479d28cd5 engine: remove useless pfnHullPointContents wrapper 2023-01-06 00:38:05 +03:00
Alibek Omarov
787d3bc5dd engine: share playermove ClearPhysEnts function 2023-01-06 00:28:24 +03:00
Alibek Omarov
0bec78a958 engine: client: make few function between pmove and client interface shared, remove unused CL_PointContents wrapper 2023-01-06 00:09:36 +03:00
Alibek Omarov
e305b81df0 engine: merge PM_TraceTexture into PM_TraceTexturePmove 2023-01-05 23:59:31 +03:00
Alibek Omarov
4cb109abe0 engine: make playermove funcs truly shared between client and server 2023-01-05 23:50:42 +03:00
Alibek Omarov
49a65edfc3 engine: imagelib: img_quant: fix a bug in quantizer (thanks, @SNMetamorph for fix) 2023-01-05 07:24:24 +03:00
Alibek Omarov
c6bfc82019 ref: soft: implement screenshots 2023-01-05 07:09:23 +03:00
Alibek Omarov
a4865fd2fc engine: client: fix ScreenFade FFADE_MODULATE rendering, more accurate alpha blending 2023-01-05 06:09:10 +03:00
Alibek Omarov
4bbd0cc404 ref: add new special rendermode that specifically used for modulate mode in engine's ScreenFade 2023-01-05 06:07:56 +03:00
Alibek Omarov
4684f174ee public: completely get rid of PATH_SEPARATOR macros 2023-01-05 06:06:07 +03:00
Alibek Omarov
34eb258cae filesystem: dir: remove PATH_SEPARATOR, fix return value when directory is caseinsensitive 2023-01-04 22:34:45 +03:00
Alibek Omarov
b4c0ccbede filesystem: fix _wstat usage under Windows, remove PATH_SEPARATOR usage, fix listdirectory 2023-01-04 22:33:59 +03:00
Alibek Omarov
51b5d7a41d engine: host: ensure we always have right slashes under Windows 2023-01-04 19:39:52 +03:00
Alibek Omarov
15846a8ea8 filesystem: use POSIX funcs for Windows too, where possible, apply wide char conversion for Sys functions 2023-01-04 18:10:33 +03:00
Alibek Omarov
e694081626 filesystem: dir: guarantee file existense in FS_FixFileCase for caseinsensitive directories 2023-01-04 18:09:00 +03:00
Alibek Omarov
cb9605430d filesystem: bump FS_API_VERSION (removed unused argument from SysFileExists) 2023-01-04 18:07:18 +03:00
Alibek Omarov
80507b2eca engine: mod_bmodel: fix const qualifier discard warning 2023-01-04 17:55:59 +03:00
Alibek Omarov
ed47346ef1 engine: crashhandler: fix _GNU_SOURCE redefined warning 2023-01-04 17:54:45 +03:00
Alibek Omarov
75ccd2283b public: fix Q_memmem counting haystack size incorrectly 2023-01-04 17:17:18 +03:00
Alibek Omarov
409edf5a70 filesystem: zip: use stdint types, use enum for errors 2023-01-04 17:15:40 +03:00
Alibek Omarov
d047dfc319 engine: add few lines in mod_bmodel back, got removed in previous commits accidentally 2023-01-03 18:26:18 +03:00
Alibek Omarov
13ed2742b2 engine: check for bsp30ext before trying to use extended clipnodes, fix 32-bit clipnodes check 2023-01-03 07:50:50 +03:00
Alibek Omarov
03a3fb83b6 filesystem: write extended fields to gameinfo.txt, as this function is used to write game info when using rodir 2023-01-03 07:34:05 +03:00
Alibek Omarov
df1c9a5029 engine: simplify blue shift swapped lump check, change TestBmodelLumps to avoid reading past mod buffer 2023-01-03 07:01:39 +03:00
Alibek Omarov
07e622f224 public: add generic implementation for Q_memmem 2023-01-03 06:58:58 +03:00
Alibek Omarov
aa3a0fa392 engine: server: increase infostring size in SV_Info allowing longer hostnames but try to cut off if it's even longer than that 2023-01-03 04:01:53 +03:00
Alibek Omarov
c1287b3950 engine: client: speed up reconnect for legacy servers 2023-01-03 03:19:46 +03:00
Alibek Omarov
e5763e2e9a filesystem: dir: check dir casesensitivity after dir entries list was properly initialized 2023-01-03 01:15:28 +03:00
Alibek Omarov
42a3c7b059 filesystem: dir: fix dir entry cache init in case of directory was empty previously 2023-01-03 00:24:57 +03:00
Alibek Omarov
e621c98602 engine: network: do not crash if one of v4 or v6 socket opening failed but crash if both. Fix hostport/clientport cvars usage 2022-12-30 02:06:15 +03:00
Alibek Omarov
eb7eb4acbc engine: client: cl_scrn: minor refactoring 2022-12-30 01:58:26 +03:00
Alibek Omarov
e5b32fe8ac engine: client: force nearest filter for HUD textures and sprites to avoid artifacts with hud_scale 2022-12-30 01:57:10 +03:00
Alibek Omarov
52061621ac engine: client: do not let client.dll overwrite usercmd that's was read from demo 2022-12-27 23:10:11 +03:00
Alibek Omarov
339711c3c7 filesystem: dir: check casefold directory flag 2022-12-27 02:31:46 +03:00
Alibek Omarov
256fe7ede9 scripts: make sure to test filesystem on CI 2022-12-27 02:31:46 +03:00
Alibek Omarov
2febe632c5 filesystem: add caseinsensitive emulation test 2022-12-27 02:31:46 +03:00
Alibek Omarov
c454e37064 filesystem: allow to init with NULL overrides 2022-12-27 02:31:46 +03:00
Alibek Omarov
fe1aba3561 filesystem: apply caseinsensitivity to file creation
Replace fs_writedir with fs_writepath, exposing current writeable searchpath.
Fix caseinsensitive FS_Search
Remove unused argument from listdirectory()
Minor optimizations and refactoring
2022-12-27 02:31:46 +03:00
Alibek Omarov
41aa867a21 engine: common: don't try to delete now non-existing config file after backing up 2022-12-27 02:31:46 +03:00
Alibek Omarov
b36ebc294f filesystem: dir: exit from loop immediately if directory is caseinsensitive 2022-12-27 02:31:46 +03:00
Alibek Omarov
3d71e5d111 filesystem: dir: fix merging existing cache with new directory entries 2022-12-27 02:31:46 +03:00
Alibek Omarov
ac59f25375 DO NOT MERGE filesystem: add naive FixFileCase 2022-12-27 02:31:46 +03:00
Alibek Omarov
3393e2d95c filesystem: implement directory entries caching, to avoid excessive directory listing syscalls to emulate case-insensitive filesystems
* simplify game directory initialization code
2022-12-27 02:31:46 +03:00
Alibek Omarov
e1ea3387ee common: rename PATH_SPLITTER to PATH_SEPARATOR, change it's type to character 2022-12-27 02:31:46 +03:00
Alibek Omarov
071638794a public: redefine Q_strpbrk to C standard version, add Q_strchrnul 2022-12-27 02:31:46 +03:00
Alibek Omarov
953dd3d1a7 wscript: tidy up checks, add check for GNU strchrnul 2022-12-27 02:31:46 +03:00
Andrey Akhmichin
12bb0ca44b engine: server: Fix broken description for saves. 2022-12-25 04:26:00 +03:00
MoeMod Server #2
499cd48e83 filesystem: fix lseek for mpg123 2022-12-24 22:02:58 +03:00
Andrey Akhmichin
444e08f59a engine: common: simplify strings operations. 2022-12-21 03:26:41 +03:00
Andrey Akhmichin
9450c08eec engine: server: simplify strings operations. 2022-12-21 03:26:11 +03:00
Alibek Omarov
18e68f1ab3 filesystem: fix missing cast 2022-12-20 16:34:23 +03:00
Andrey Akhmichin
7555fefc18 ref: gl: simplify strings operations. 2022-12-20 16:11:21 +03:00
Andrey Akhmichin
f4fb8b4ac2 engine: client: simplify strings operation. 2022-12-20 16:07:34 +03:00
Andrey Akhmichin
0d5cd89144 engine: client: Fix access to uninitialized variable. 2022-12-20 16:06:41 +03:00
Andrey Akhmichin
e273e09fc9 engine: platform: win32: simplify strings operations. 2022-12-20 16:06:25 +03:00
Alibek Omarov
327017421c engine: common: zone: redefine poolhandle_t back to pointer for 32-bit systems 2022-12-19 18:38:49 +03:00
Alibek Omarov
6e179346c9 common: redefine poolhandle_t back to pointer for 32-bit systems 2022-12-19 18:36:31 +03:00
Alibek Omarov
ee218f36e0 filesystem: pak: no need to free files ptr anymore 2022-12-17 00:25:20 +03:00
Alibek Omarov
f3400c983e engine: network: fix address comparator 2022-12-15 12:25:03 +03:00
Alibek Omarov
9397301a73 filesystem: remove excessive filename field from archive structs, use common in searchpath_t. Small optimizations for PAK 2022-12-15 04:06:38 +03:00
Alibek Omarov
f1ec612819 filesystem: hungry 2022-12-15 01:06:20 +03:00
Alibek Omarov
08f834cd82 filesystem: make all archive searchpath functions private 2022-12-15 00:59:52 +03:00
Alibek Omarov
48c17d08d9 filesystem: dir: move searchpath initialization to dir.c, make all DIR functions static 2022-12-15 00:52:09 +03:00
Alibek Omarov
f20fddee1c common: bspfile: add separate definitions for clipnodes limit for HLBSP and QBSP2 2022-12-15 00:42:40 +03:00
Alibek Omarov
754d55beef engine: common: fix for HLBSP extended clipnodes hack when BSP2 support is enabled 2022-12-13 11:34:42 +03:00
Alibek Omarov
cd813bbfbe engine: server: do not apply sound precache check for sentences, as they may start with 0 index 2022-12-13 11:12:08 +03:00
Alibek Omarov
07afbd64d4 engine: common: host: force set HOST_FRAME status for dedicated as it finished initializing 2022-12-13 10:54:06 +03:00
Alibek Omarov
af7d6f6fa8 engine: common: no point to allow if and else commands in unprivileged mode since scripting is available only for privileged 2022-12-12 08:18:00 +03:00
Alibek Omarov
cb0f513bf0 engine: common: allow cvar substituion in privileged mode only to prevent leaking sensitive data 2022-12-12 08:14:01 +03:00
Alibek Omarov
a3ef6c955c engine: don't double register rcon_password cvar 2022-12-12 08:13:24 +03:00
Alibek Omarov
60e7a7aa23 engine: server: set correct flags for rcon_ cvars on server 2022-12-12 08:05:55 +03:00
Alibek Omarov
e1431e1040 engine: server: add rcon_enable cvar to control whether server should accept remote commands 2022-12-12 08:02:56 +03:00
Alibek Omarov
b794f2fda0 mainui: update 2022-12-12 07:56:03 +03:00
Alibek Omarov
934d9ba69a filesystem: fix FS_GetDiskPath 2022-12-12 06:54:42 +03:00
Alibek Omarov
9e54ddfd55 engine: client: treat dem_unknown as no-op, until we find real cause of empty holes in demoheader 2022-12-12 06:31:54 +03:00
Alibek Omarov
a86a24d33d mainui: update 2022-12-12 06:30:47 +03:00
Alibek Omarov
fe9ed0ac9b engine: client: gameui: add new NET_CompareAdrSort function to menu API 2022-12-12 06:30:47 +03:00
Alibek Omarov
18c94b6ec4 engine: common: add network address comparator function 2022-12-12 06:30:47 +03:00
SNMetamorph
8fa0290e25 Documentation: extensions: added page about expanded common structures 2022-12-11 22:59:17 +03:00
SNMetamorph
080cd146dd common: com_model: changed common structs reserved fields type to intptr_t 2022-12-11 22:59:17 +03:00
SNMetamorph
b1d910a3a5 engine: client: fixed connection hang when all resources downloaded (fix #829) 2022-12-09 19:20:53 +03:00
SNMetamorph
840283d6e5 engine: netchan: fixed fragbufs very high memory usage 2022-12-09 19:20:53 +03:00
SNMetamorph
d72481e5ac engine: netchan: fixed downloading files output directory 2022-12-09 19:20:53 +03:00
SNMetamorph
dbe9309475 engine: netchan: fixed wrong compressed file size calculation 2022-12-09 19:20:53 +03:00
Alibek Omarov
9fa4de6ee8 mainui: update 2022-12-08 06:55:32 +03:00
Alibek Omarov
fd3c5e8384 ref: gl: VBO is disabled unless somebody picks it up and fixes memory corruption and other bugs 2022-12-08 06:50:12 +03:00
Alibek Omarov
d50ed1c087 engine: common: host: don't prepend # to command arguments when changing game to dedicated, it wasn't used and implement anymore 2022-12-08 05:44:17 +03:00
Alibek Omarov
e48133bf4b engine: server: fix sv_log output for enttools usage 2022-12-08 05:40:36 +03:00
Alibek Omarov
ea3bfd969c engine: imagelib: img_wad: dirty hack to fix black holes in console background images 2022-12-08 05:40:11 +03:00
Alibek Omarov
7469d6a248 engine: server: implement server-to-master challenge extension, to secure server from IP spoofing 2022-12-07 23:39:57 +03:00
Alibek Omarov
859f36afce engine: server: remove Master_Add call in ActivateServer, server will announce itself through heartbeat 2022-12-07 23:14:34 +03:00
Alibek Omarov
436a788ac8 engine: client: disable FPS counter by default 2022-12-07 21:54:23 +03:00
Velaron
5098e24806 engine: client: touch: fix empty list when opening touch buttons menu for the first time 2022-12-07 15:35:51 +03:00
Alibek Omarov
1d8acc16f1 engine: server: give master server a small time window to reply (by default 4000 ms, should be enough even when master server is overloaded) 2022-12-06 20:28:44 +03:00
Alibek Omarov
802c7a86a9 engine: platform: sdl: add pause and scrolllock handlers 2022-12-06 11:50:38 +03:00
Alibek Omarov
406eb828da ref: gl: disable underwater distortion by default, enable for Quake compatible mode only 2022-12-05 11:59:29 +03:00
Alibek Omarov
0e9106685b engine: imagelib: img_png: fix Mem_Free on null ptr 2022-12-05 06:13:04 +03:00
Alibek Omarov
9b001987e9 engine: imagelib: fix crash when chunk length is more than file size 2022-12-05 05:39:41 +03:00
Alibek Omarov
5c2c02c317 engine: common: custom: use IL_LOAD_PLAYER_DECAL flag when loading custom player decals 2022-12-05 04:56:07 +03:00
Alibek Omarov
21c898d796 engine: imagelib: validate player decal image size (max 512x512) 2022-12-05 04:55:24 +03:00
Alibek Omarov
e48b708fa6 engine: imagelib: img_png: validate image size through common engine function 2022-12-05 04:54:20 +03:00
Alibek Omarov
ccf7619ae5 engine: imagelib: refactor image loading function 2022-12-05 03:22:07 +03:00
Alibek Omarov
eabbd0061f mainui: update 2022-12-05 03:22:07 +03:00
Alibek Omarov
7d0d6b8e0d engine: common: host: implement adaptive sleeptime, log time to first time for debug purposes 2022-12-05 03:22:07 +03:00
Alibek Omarov
eb36fe0155 filesystem: fill searchpath DIR functions only if file was found in direct path 2022-12-05 03:22:07 +03:00
Alibek Omarov
9381a40506 filesystem: check only DLLs for encryption 2022-12-05 03:22:07 +03:00
SNMetamorph
a19270a0dc engine: client: max fragment size test retries increased to 3 2022-12-04 23:29:26 +03:00
SNMetamorph
c34ce2d9e1 engine: client: fixed max fragment size wrong calculation 2022-12-04 23:29:26 +03:00
SNMetamorph
58465c3727 engine: common: fixed dedicated server bug
The problem is server wasn't executing server.cfg if map specified in startup parameters
2022-12-04 23:29:26 +03:00
Andrey Akhmichin
177ed2c603 engine: common: simplify strings operations. 2022-12-04 22:37:45 +03:00
Andrey Akhmichin
7bb994f7bc engine: common: imagelib: img_png.c: fix wrong palette decoding. 2022-12-04 22:09:24 +03:00
Andrey Akhmichin
0c4f35e2d0 filesystem: simplify strings operations. 2022-12-04 22:08:06 +03:00
Andrey Akhmichin
3287501f97 engine: client: simplify strings operations. 2022-12-04 22:04:07 +03:00
Andrey Akhmichin
2454594a18 engine: server: simplify strings operations. 2022-12-04 22:03:48 +03:00
Alibek Omarov
4daab23e2d mainui: update 2022-12-04 05:31:02 +03:00
Alibek Omarov
51161004eb engine: common: simplify string operations 2022-12-04 05:26:22 +03:00
Alibek Omarov
6477f1656e filesystem: simplify string operation 2022-12-04 05:26:22 +03:00
Alibek Omarov
270e2a76a8 engine: soundlib: simplify string operation 2022-12-04 05:26:22 +03:00
Alibek Omarov
c61442e960 engine: imagelib: simplify string operation 2022-12-04 05:26:22 +03:00
Alibek Omarov
d0928af355 mainui: update to png-decals branch 2022-12-04 05:26:22 +03:00
Alibek Omarov
674093517e 3rdparty: update various submodules 2022-12-02 21:29:51 +03:00
Alibek Omarov
ebf3877cda engine: common: throw an error message into log in normal mode too! 2022-12-02 21:22:22 +03:00
Alibek Omarov
e97310c441 engine: common: net_ws: fix uninitialized family in IPSocket 2022-12-02 21:21:53 +03:00
Alibek Omarov
cbe3e608b6 engine: client: add cl_logoext cvar that's used by mainui to tell the engine which logo must be packed 2022-12-01 18:25:21 +03:00
Alibek Omarov
f30f23ba51 engine: common: validate and load PNG images in customization 2022-12-01 18:25:11 +03:00
Alibek Omarov
1ba117a8e9 engine: client: netgraph: fix few global-buffer-overflow errors 2022-12-01 18:23:52 +03:00
Alibek Omarov
d9a245dcb5 engine: reset cheat cvars on remote games 2022-12-01 02:44:01 +03:00
Alibek Omarov
9cbf5ab6a6 engine: client: streamline constructing master server scan request through common function 2022-12-01 01:51:07 +03:00
Alibek Omarov
c9e4e62474 engine: client: allow IPv6 in NetAPI 2022-12-01 00:35:05 +03:00
Alibek Omarov
aa6a1db0a9 engine: remove duplicate svc_strings definition 2022-12-01 00:34:33 +03:00
Alibek Omarov
e9d66be10a mainui: update 2022-11-29 13:30:06 +03:00
Alibek Omarov
8b6f12418e engine: common: make few network cvars privileged 2022-11-29 13:29:47 +03:00
Alibek Omarov
7013d447ca engine: client: get rid of s_registration_sequence, it was incorrect way to look for unused sounds. We're trying to rely on cl.servercount here 2022-11-28 07:54:24 +03:00
Alibek Omarov
93b2f535e2 engine: client: tune max commands/max backup commands values for legacy protocol 2022-11-27 18:26:53 +03:00
Alibek Omarov
591d572870 mainui: update 2022-11-27 06:02:42 +03:00
SNMetamorph
3ab749cc2e engine: client: cl_tent: fixed incorrect players spray textures update 2022-11-27 04:50:30 +03:00
SNMetamorph
084fac3606 engine: common: hpak: fixed rest of bugs in HPAK_AddLump 2022-11-27 04:50:30 +03:00
Alibek Omarov
f377461fdf engine: common: made a filter for a filter (lol), so it's possible to play selected games with cl_filterstuffcmd enabled 2022-11-27 04:45:03 +03:00
SNMetamorph
a2971ce939 filesystem: fixed uninitialized pointers in FS_FindFile when fs_ext_path enabled 2022-11-26 02:45:18 +03:00
SNMetamorph
65671d8788 engine: common: minor code fixes in hpak.c 2022-11-25 23:05:48 +03:00
Andrey Akhmichin
809d5f1aa8 engine: client: in_touch.c: add spray button. 2022-11-25 22:32:33 +03:00
SNMetamorph
49fc6143ab engine: common: imagelib: fixed loading 32 bits per pixel BMP files 2022-11-25 22:30:49 +03:00
SNMetamorph
8717843333 engine: common: imagelib: fixed BMP files estimate size calculation with NPOT textures 2022-11-25 22:30:49 +03:00
SNMetamorph
f6d8996968 engine: common: imagelib: added missed BMP compression type macros 2022-11-25 22:30:49 +03:00
Alibek Omarov
9389305072 engine: common: set cl_filterstuffcmd to 1 by default 2022-11-25 22:23:51 +03:00
Alibek Omarov
b6bd4bc6f8 engine: server: precisely set client connected time after they were spawned 2022-11-25 05:45:20 +03:00
Alibek Omarov
4c6fbafd20 mainui: update 2022-11-25 02:37:07 +03:00
Velaron
43c6175918 filesystem: dir.c: safer string operations 2022-11-24 03:19:21 +03:00
Velaron
fcd741e2b8 filesystem: fix FS_FixFileCase behavior 2022-11-24 03:19:15 +03:00
Velaron
89807250e5 filesystem: dir.c: optimize string operations 2022-11-24 03:19:10 +03:00
Velaron
24f7db19d8 filesystem: switch file operations to an interface 2022-11-24 03:19:05 +03:00
SNMetamorph
49d93c0e76 engine: common: custom: increased custom decal size limit to 128Kb, added wrong size warning 2022-11-22 17:59:41 +03:00
SNMetamorph
707c93c32c engine: common: hpak: all file operations made to use gamedir only 2022-11-22 17:59:41 +03:00
SNMetamorph
e204f05726 engine: client: fixed players spray textures not being updated 2022-11-22 17:59:41 +03:00
SNMetamorph
3bd8ad50d2 ref: gl: fixed crash when opening "Customize" menu 2022-11-21 22:52:27 +03:00
Andrey Akhmichin
3488d4e65f public: simplified strings operations. 2022-11-18 19:32:17 +03:00
Alibek Omarov
3da736a1eb engine: server: try to solve issue when server dll has no voice mgr 2022-11-17 21:06:15 +03:00
Alibek Omarov
e30c61c0e2 common: netadr: use static_assert macro 2022-11-17 19:44:47 +03:00
Alibek Omarov
64e97124c3 Merge master to ipv6 2022-11-17 19:34:46 +03:00
Alibek Omarov
46979419ae wscript: check Android's log library globally 2022-11-17 01:23:33 +03:00
Alibek Omarov
30d9b6d844 engine: platform: win32: fix compile 2022-11-17 01:20:01 +03:00
Alibek Omarov
88045ce3be ref: gl: link liblog for Android 2022-11-17 01:08:11 +03:00
Alibek Omarov
dd881d3da9 engine: server: remove duplicate function 2022-11-16 23:37:26 +03:00
Alibek Omarov
76d0608ee1 ref: fix beams end point 2022-11-16 22:54:07 +03:00
Alibek Omarov
a894ca60c6 engine: client: vgui: fix vgui viewport height being limited at 480 pixels 2022-11-16 22:05:31 +03:00
Alibek Omarov
023f6712f9 engine: client: always toggle mouse on when in console, menu or typing chat message 2022-11-16 21:14:48 +03:00
Alibek Omarov
42740149ac engine: client: fix mouse cursor being hidden in background map 2022-11-16 21:02:41 +03:00
Alibek Omarov
7b74015c4d engine: server: check if player can hear other before sending voicedata 2022-11-16 20:59:18 +03:00
Alibek Omarov
57c71efe53 Documentation: fix wrong envvar in windows xcompile instructions, better wording 2022-11-16 04:25:34 +03:00
Alibek Omarov
45de874598 wscript: always load msvc options 2022-11-16 04:20:02 +03:00
Alibek Omarov
aa702f0678 scripts: waifulib: xcompile: add msvc-wine support in cross-compile helper script 2022-11-16 04:19:46 +03:00
Alibek Omarov
927dccc71d Documentation: add simple instructions on how to cross-compile for Windows from normal operating systems 2022-11-16 04:19:07 +03:00
Alibek Omarov
c2a24fbbce engine: client: put internal vgui shutdown AFTER HUD_Shutdown, to simulate default, external behavior 2022-11-14 20:12:10 +03:00
SNMetamorph
ae94a6aeba engine: client: fixed client VGUI API shutdown 2022-11-14 20:09:20 +03:00
Alibek Omarov
e9da43666c engine: client: fix loading internal vgui (thx @SNMetamorph) 2022-11-14 20:08:01 +03:00
Alibek Omarov
d27dd68072 engine: client: vgui: rework loading VGUI and probing client for internal vgui support API 2022-11-12 16:35:18 +03:00
Alibek Omarov
b1ee27a3f3 filesystem: add new token internal_vgui_support to mark client dlls that have internal VGUI implementation(to support other UI systems) 2022-11-12 16:35:18 +03:00
SNMetamorph
32372654c2 engine: server: sv_client: fixed working ent_create command on XashXT/PrimeXT 2022-11-11 16:12:56 +03:00
Alibek Omarov
17d0b19f9e engine: use generic S_USAGE macro everywhere 2022-11-10 13:18:20 +03:00
Alibek Omarov
d13f7f06e4 engine: fix framerate being capped to 60FPS with vsync, remove vid_displayfrequency cvar. Never sleep with vsync or timedemo, for accuracy 2022-11-10 13:05:03 +03:00
Alibek Omarov
f469b56b93 engine: host: only sleep once between frames 2022-11-10 12:42:48 +03:00
Alibek Omarov
ef74f86ce2 Documentation: restore enttools docs from old engine wiki 2022-11-10 12:37:51 +03:00
Alibek Omarov
616cbdb1eb engine: client: change cl_cmdrate and cl_smoothtime default values to match GoldSrc 2022-11-10 12:11:16 +03:00
Alibek Omarov
0a49e69818 engine: introduce Sys_DebugBreak function to raise an exception for debugger 2022-11-10 12:10:48 +03:00
Alibek Omarov
adb8ec1da8 filesystem: try to normalize linux gamedll path for liblist.gam 2022-11-10 11:58:44 +03:00
SNMetamorph
5d73c6cb84 engine: server: backported enttools from old engine 2022-11-10 11:56:10 +03:00
SNMetamorph
afa1d429fe engine: client: backported enttool from old engine 2022-11-10 11:56:10 +03:00
SNMetamorph
d1309c3aeb engine: common: backported "set" command from old engine 2022-11-10 11:56:10 +03:00
SNMetamorph
b35cf6e30c engine: platform: update VGUI cursor state in Platform_SetCursorType 2022-11-08 06:39:09 +06:00
SNMetamorph
8cbe0e5b30 engine: client: vgui: added VGui_UpdateInternalCursorState function 2022-11-08 06:39:09 +06:00
Andrey Akhmichin
c1fe547925 public: update miniz to version 3.0.0 from upstream. 2022-11-06 12:35:04 +06:00
Andrey Akhmichin
1064b41ab2 readme: update. 2022-11-05 10:45:47 +06:00
Andrey Akhmichin
2a6c2e5db4 .github: workflows: update github actions. 2022-11-05 10:43:15 +06:00
Bien Pham
816337a7bb filesystem: set root directory as static
Counter-Strike uses COM_ExpandFileName to get
full path to filesystem_stdio. When reading liblist.gam,
the engine will clear the search path and the root search path
will be cleared. Set it as static so it will be excluded from clearing.
2022-11-02 18:07:25 +06:00
Andrey Akhmichin
d237114962 engine: common: imagelib: img_png.c: unroll loops. 2022-11-02 14:14:05 +06:00
Andrey Akhmichin
c1ca2c1a95 Documentation: opensource-mods.md: add "Oz Deathmatch". 2022-10-27 01:53:27 +06:00
SNMetamorph
44a43c2c09 engine: client: cl_parse: minor code fix in CL_ParseLegacyServerData 2022-10-27 00:52:16 +06:00
SNMetamorph
ee8098839e engine: common: pm_trace: fixed non portable code in PM_ConvertTrace 2022-10-27 00:52:16 +06:00
Alibek Omarov
305b2579eb engine: client: voice: fix crackling voice file input on low FPS 2022-10-19 01:08:39 +03:00
Alibek Omarov
1a09d297ee engine: minimize SetCursorType calls count 2022-10-13 14:49:48 +03:00
Alibek Omarov
d45e6e0ad1 engine: platform: sdl: SetCursorType shouldn't know about current game state 2022-10-13 14:07:48 +03:00
Alibek Omarov
2d2523df4a engine: client: touch: generalise touch emulation code
* fix doubleclicks and wheels in VGUI
2022-10-12 05:18:19 +03:00
Alibek Omarov
5a0fcfffb0 mainui: update 2022-10-10 13:09:01 +03:00
Alibek Omarov
f252161d90 readme: fix typo and wording 2022-10-04 15:14:54 +03:00
Alibek Omarov
e0216e2658 wscript: don't clean QtCreator files and reconfigure saved options
Cleanup imports
2022-10-04 03:02:49 +03:00
Alibek Omarov
0f2bb5720b wscript: respect --libdir argument with packaging enabled. Fix a typo in --disable-soft description 2022-10-02 22:28:53 +03:00
Alibek Omarov
0621e365ff mainui: update 2022-09-27 17:19:32 +03:00
Alibek Omarov
8ea455def7 mainui: update 2022-09-27 14:00:18 +03:00
Alibek Omarov
8cf822c426 mainui: update 2022-09-27 14:00:18 +03:00
Alibek Omarov
4a009c1c2c engine: client: touch: move copypasted code from export & writeconfig into separate function 2022-09-27 14:00:18 +03:00
Alibek Omarov
360dc4f7ed engine: try to make hashpaks more compatible between 32-bit and 64-bit platforms 2022-09-20 21:57:13 +03:00
Alibek Omarov
ffe43e1f22 scripts: waifulib: fix error reporting in zip.py 2022-09-20 21:56:25 +03:00
Alibek Omarov
a52d901f25 common: add STATIC_ASSERT macro
We're trying to guess if we have C11 static_assert defined in assert.h
otherwise use good ol' trick with negative array
2022-09-20 21:55:32 +03:00
Alibek Omarov
5bae2f06ad engine: platform: sdl: do not lock audio device, for some reason it sometimes causes problems although it shouldn't 2022-09-20 21:29:19 +03:00
Alibek Omarov
69b0954007 engine: change RenderAPI's RenderGetParm return type to intptr_t to insure compatibility with 64-bit 2022-09-20 18:06:19 +03:00
Alibek Omarov
0645402946 engine: fix crash when reading GoldSrc hashpaks 2022-09-19 06:03:01 +03:00
Владислав Сухов
c59b244d04 scripts: gha: fix path to vgui_support submodule 2022-09-17 15:55:40 +03:00
Alibek Omarov
5678d9a253 engine: server: support MAP_ANON synonym for MAP_ANONYMOUS, disable allocating string pool near server library for OSX 2022-09-12 08:42:50 +03:00
dettlaff
a520d245a6 wscript: fix typo in --enable-bundled-deps configure option 2022-09-12 07:18:24 +03:00
Alibek Omarov
b56f6fa330 scripts: waifulib: fix zipfile init for older Python 2022-09-11 02:50:52 +03:00
Alibek Omarov
f141869ce3 wscript: disable building extras.pk3 for Android 2022-09-11 02:22:26 +03:00
Alibek Omarov
807f3852bd scripts: gha: remove building extras.pak, as it's already being built 2022-09-11 02:20:36 +03:00
Alibek Omarov
084089b919 3rdparty: extras: build ZIP archive and install to engine default gamefolder 2022-09-11 02:13:23 +03:00
Alibek Omarov
f571a41cf3 wscript: allow to setup engine default gamedir during configure 2022-09-11 02:12:44 +03:00
Alibek Omarov
686a966ff7 wscript: now waf builds extras archive by itself, using Python standard library's zipfile 2022-09-11 01:39:29 +03:00
Alibek Omarov
c29eb458ea 3rdparty: add xash-extras submodule 2022-09-11 01:38:17 +03:00
Alibek Omarov
234c843f60 filesystem: integrate inotify for file changes 2022-09-10 22:55:07 +03:00
Alibek Omarov
2b8b3e1993 engine: server: new IP filter, rewritten with IPv6 in mind 2022-06-09 03:10:02 +03:00
Alibek Omarov
b0a889d1a1 engine: bring back simple netadr_t, as we don't care about IPv4-to-IPv6 mapped addresses anymore 2022-06-09 03:10:02 +03:00
Alibek Omarov
bd1bfea695 engine: second iteration of IPv6 support
Made code smaller
Fixed problem where v6 and v4 socket can't use same port
Added support for v4-to-v6 mapped addresses, although it's kept unused
Probably final version
2022-06-09 03:10:02 +03:00
Alibek Omarov
a1299e1dfe common: third iteration of ipv6 netadr_t, now binary compatible with v4-to-v6 mapped addresses 2022-06-09 03:10:02 +03:00
Alibek Omarov
1a5a76a201 engine: common: minor fixes to ipv6text library 2022-06-09 03:10:02 +03:00
Alibek Omarov
b072b627a2 engine: enable getaddrinfo on Windows, fix build 2022-06-09 03:10:02 +03:00
Alibek Omarov
5d18c6d678 engine: fix declaration-after-statement 2022-06-09 03:10:02 +03:00
Alibek Omarov
59fba30a52 engine: IPv6 support
* v6 equivalent cvars
* hostname resolving for v6
* fix for nonblocking hostname resolve (inverted check)
* enabled by default, probably should be disabled for dedicated servers
2022-06-09 03:10:02 +03:00
Alibek Omarov
193cde83b6 engine: add IPv6 address parsing/printing library from GameNetworkingSockets 2022-06-09 03:10:02 +03:00
Alibek Omarov
12bfb8f795 common: another approach on netadr_t with better compatibility 2022-06-09 03:10:02 +03:00
Alibek Omarov
9ae72dbc47 common: update netadr_t structure to include IPv6 addresses 2022-06-09 03:10:02 +03:00
347 changed files with 24491 additions and 18121 deletions

View File

@@ -13,27 +13,35 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-18.04
# Linux build specifically want oldest Ubuntu as possible
# to be crossdistribution compatible, otherwise use ubuntu-latest
- os: ubuntu-20.04
targetos: linux
targetarch: amd64
- os: ubuntu-18.04
- os: ubuntu-20.04
targetos: linux
targetarch: i386
# - os: ubuntu-aarch64-20.04
# targetos: linux
# targetarch: aarch64
- os: ubuntu-18.04
targetos: android
targetarch: 32
- os: ubuntu-18.04
targetos: android
targetarch: 64
# - os: ubuntu-20.04
# targetos: android
# targetarch: 32
# - os: ubuntu-20.04
# targetos: android
# targetarch: 64
- os: ubuntu-18.04
targetos: motomagx
targetarch: armv6
# - os: ubuntu-20.04
# targetos: motomagx
# targetarch: armv6
- os: ubuntu-latest
targetos: nswitch
targetarch: arm64
- os: ubuntu-latest
targetos: psvita
targetarch: armv7hf
- os: windows-latest
targetos: win32
targetarch: amd64
@@ -41,32 +49,80 @@ jobs:
targetos: win32
targetarch: i386
env:
SDL_VERSION: 2.0.14
SDL_VERSION: 2.28.1
GH_CPU_ARCH: ${{ matrix.targetarch }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ANDROID_SDK_TOOLS_VER: 4333796
UPLOADTOOL_ISPRERELEASE: true
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
submodules: recursive
- name: Checkout xash-extras
uses: actions/checkout@v2
with:
repository: FWGS/xash-extras
path: xash-extras
- name: Install dependencies
run: bash scripts/gha/deps_${{ matrix.targetos }}.sh
- name: Build engine
run: bash scripts/gha/build_${{ matrix.targetos }}.sh
- name: Upload engine (prereleases)
run: bash scripts/continious_upload.sh artifacts/*
- name: Upload engine (artifacts)
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: artifact-${{ matrix.targetos }}-${{ matrix.targetarch }}
path: artifacts/*
flatpak:
name: "Flatpak"
runs-on: ubuntu-latest
strategy:
matrix:
include:
- app: su.xash.Engine.Compat.i386
container:
image: bilelmoussaoui/flatpak-github-actions:freedesktop-22.08
options: --privileged
steps:
- name: Checkout
uses: actions/checkout@v3
with:
submodules: recursive
- name: Build flatpak (Compat.i386)
uses: FWGS/flatpak-github-actions/flatpak-builder@v6.1
with:
bundle: ${{ matrix.app }}.flatpak
manifest-path: scripts/flatpak/${{ matrix.app }}.yml
- name: Upload engine (artifacts)
uses: actions/upload-artifact@v3
with:
name: artifact-${{ matrix.targetos }}-${{ matrix.targetarch }}
path: artifacts/*
release:
name: "Upload releases"
runs-on: ubuntu-latest
needs: [build, flatpak]
if: ${{ github.event_name == 'push' }}
steps:
- name: Remove old release
uses: FWGS/delete-tag-and-release@v0.2.1-dev
with:
tag_name: ${{ github.ref_name == 'master' && 'continuous' || format('continuous-{0}', github.ref_name) }}
delete_release: true
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Fetch artifacts
uses: actions/download-artifact@v3.0.1
with:
path: artifacts/
- name: Repackage binaries and allow GitHub to process removed release for few seconds
run: |
cd artifacts/
for i in artifact-* su.xash.Engine.*; do
mv "$i"/* .
rm -rf "$i"
done
ls -R .
cd ../
sleep 20s
- name: Upload new release
uses: FWGS/action-gh-release@v0.1.15
with:
name: Xash3D FWGS Continuous ${{ github.ref_name }} Build
tag_name: ${{ github.ref_name == 'master' && 'continuous' || format('continuous-{0}', github.ref_name) }}
prerelease: true
token: ${{ secrets.GITHUB_TOKEN }}
files: artifacts/*
draft: false

4
.gitignore vendored
View File

@@ -60,6 +60,7 @@ Makefile.dep
ALL_BUILD.*
INSTALL.*
ZERO_CHECK.*
CMakeLists.txt
# Visual Studio
*.obj
@@ -333,3 +334,6 @@ __pycache__
.history/*
.cache/*
enc_temp_folder/
# KDevelop4
*.kdev4

3
.gitmodules vendored
View File

@@ -16,3 +16,6 @@
[submodule "opus"]
path = 3rdparty/opus/opus
url = https://github.com/xiph/opus
[submodule "3rdparty/xash-extras"]
path = 3rdparty/extras/xash-extras
url = https://github.com/FWGS/xash-extras

29
3rdparty/extras/wscript vendored Normal file
View File

@@ -0,0 +1,29 @@
#! /usr/bin/env python
# encoding: utf-8
import os
def options(opt):
pass
def configure(conf):
if not conf.path.find_dir('xash-extras'):
conf.fatal('Can\'t find xash-extras submodule.')
return
conf.load('zip')
def build(bld):
srcdir = bld.path.find_dir('xash-extras')
if bld.env.DEST_OS in ['android']:
install_path = bld.env.PREFIX
else:
install_path = os.path.join(bld.env.SHAREDIR, bld.env.GAMEDIR)
bld(features='zip',
name = 'extras.pk3',
files = srcdir.ant_glob('**/*'),
relative_to = srcdir,
compresslevel = 0,
install_path = install_path)

1
3rdparty/extras/xash-extras vendored Submodule

View File

@@ -0,0 +1,9 @@
# Cross-compiling for Windows with Wine
This can be useful to test engine in Wine without using virtual machines or dual-booting to Windows.
0. Clone and install https://github.com/mstorsjo/msvc-wine (you can skip CMake part)
1. Set environment variable MSVC_WINE_PATH to the path to installed MSVC toolchain
2. Pre-load wine: `wineserver -k; wineserver -p; wine64 wineboot`
3. Run `./waf configure -T <build-type> --enable-wine-msvc --sdl2=../SDL2_VC`. Configuration step will take more time than usual.
4. .. other typical steps to build from console ...

View File

@@ -0,0 +1,10 @@
# Debugging your mod using minidump files (Windows only)
Minidump files is awesome instrument for debugging your mod after it's being released, or for catch specific crashes which are presented only in one specific configuration, but doesn't happens in other configurations or even on developer machine. It contains a lot of information useful for debugging, and therefore it size is not so small: around hundreds or even thousands of megabytes. But this is not a problem, since minidump files compresses very effectively using common algorithms.
There are short algorithm, explaining how to use this debugging instrument:
1. User starts your mod with `-minidumps` startup parameter
2. Finally, crash happened on user's machine, and minidump file being written. This file has `.mdmp` extension and located in same folder, where mod folder located
3. User packs this minidump file to .zip/.7z archive, and somehow sends it to developer
4. Developer just opens minidump file in Visual Studio, then a virtual debugging session is opened and now reasons of crash is pretty easy to detect: you can see call stack, local function variables and global variables, information about exception and a lot of other information
You can find more information about minidumps in this [awesome article](https://learn.microsoft.com/en-us/windows/win32/dxtecharts/crash-dump-analysis?source=recommendations#writing-a-minidump).

View File

@@ -0,0 +1,150 @@
# There are few new commands availiable in xash3d fork:
## Commands:
### ent_create
Create entity with specified classname and key/values
`ent_create <classname> <key> <value> <key> <value> ...`
for example:
`ent_create monster_zombie targetname zomb1`
after creating entity, ent_last_xxx cvars are set to new entity and ent_last_cb called, look at ent_getvars description
### ent_fire
Make some actions on entity
`ent_fire <pattern> <command> <args>`
Availiavle commands:
* Set fields (Only set entity field, does not call any functions):
* health
* gravity
* movetype
* solid
* rendermode
* rendercolor (vector)
* renderfx
* renderamt
* hullmin (vector)
* hullmax (vector)
* Actions
* rename: set entity targetname
* settarget: set entity target (only targetnames)
* setmodel: set entity model (does not update)
* set: set key/value by server library
* See game FGD to get list.
* command takes two arguments
* touch: touch entity by current player.
* use: use entity by current player.
* movehere: place entity in player fov.
* drop2floor: place entity to nearest floor surface
* moveup: move entity to 25 units up
* moveup (value): move by y axis relatively to specified value
* Flags (Set/clear specified flag bit, arg is bit number):
* setflag
* clearflag
* setspawnflag
* clearspawnflag
### ent_info
Print information about entity by identificator
`ent_info <identificator>`
### ent_getvars
Set client cvars containing entity information (useful for [[Scripting]]) and call ent_last_cb
`ent_getvars <identificator>`
These cvars are set:
```
ent_last_name
ent_last_num
ent_last_inst
ent_last_origin
ent_last_class
```
### ent_list
Print short information about antities, filtered by pattern
`ent_list <pattern>`
## Syntax description
### \<identificator\>
* !cross: entity under aim
* Instance code: !\<number\>_\<seria\l>
* set by ent_getvars command
* Entity index
* targetname pattern
### \<pattern\>
Pattern is like identificator, but may filter many entities by classname
### (vector)
used by ent_fire command. vector means three float values, entered without quotes
### key/value
All entities parameters may be set by specifiing key and value strings.
Originally, this mechanizm is used in map/bsp format, but it can be used in enttools too.
Keys and values are passed to server library and processed by entity keyvalue function, setting edict and entity owns parameters.
If value contains spaces, it must be put in quotes:
`ent_fire !cross set origin "0 0 0"`
## Using with scripting
ent_create and ent_getvars commands are setting cvars on client
It can be used with ent_last_cb alias that is executed after setting cvars.
Simple example:
```
ent_create weapon_c4
alias ent_last_cb "ent_fire \$ent_last_inst use"
```
Use weapon_c4 after creating it.
Note that you cannot use many dfferent callbacks at the same time.
You can set entity name by by pattern and create special script, contatning all callbacks.
Example:
example.cfg
```
alias ent_last_cb exec entity_cb.cfg
ent create \<class\> targetname my_ent1_$name
ent_create \<class\> targetname my_ent2_$name
```
entity_cb.cfg
```
if $ent_last_name == my_ent1_$name
:(ent1 actions)
if $ent_last_name == my_ent2_$name
:(ent2 actions)
```
Note that scripting cannot be blocking. You cannot wait for server answer and continue. But you can use small scripts, connected with ent_last_cb command. The best usage is user interaction. You can add touch buttons to screen or call user command menu actions by callbacks.
## Server side
To enable entity tools on server, set sv_enttools_enable to 1
To change maximum number of entities, touched by ent_fire, change sv_enttools_maxfire to required number.
To enable actions on players, set sv_enttools_players to 1.
To enable entity tools for player by nickname, set sv_enttools_godplayer to nickname. Useful to temporary enable from rcon.
To prevent crash on some actions, set host_mapdesign_fatal to 0

View File

@@ -0,0 +1,8 @@
# Expanded structures that used by engine and mods
To make porting and developing mods on 64-bit platforms less painful, we decided to expand size of several structures.
This information important in case you are using codebase like XashXT, Paranoia 2: Savior and want to compile your mod for platform with 64-bit pointer size: you should replace old definitions with new ones, otherwise your mod will not work with Xash3D FWGS (typically, it's just crashing when starting map).
| Structure name | Locates in file | Original size on 64-bit | Current size on 64-bit |
|----------------|-----------------|-------------------------|------------------------|
|`mfaceinfo_t` | `common/com_model.h` | 176 bytes | 304 bytes |
|`decal_s` | `common/com_model.h` | 72 bytes | 88 bytes |
|`mextrasurf_t` | `common/com_model.h` | 376 bytes | 504 bytes |

View File

@@ -31,11 +31,14 @@ Issue #0. Inconsistency between ABI and Q_buildarch.\
Resolution: Change Q_buildarch return value to use Debian-styled architectures list: https://www.debian.org/ports/, which includes a special naming for big/little-endian and hard/soft-float ARM.
Issue #1: Build-system integration.\
Resolution: implemented as [LibraryNaming.cmake](https://github.com/FWGS/hlsdk-xash3d/blob/master/cmake/LibraryNaming.cmake) and [library_naming.py](https://github.com/FWGS/hlsdk-xash3d/blob/master/scripts/waifulib/library_naming.py) extensions, see
Resolution: implemented as [LibraryNaming.cmake](https://github.com/FWGS/hlsdk-portable/blob/master/cmake/LibraryNaming.cmake) and [library_naming.py](https://github.com/FWGS/hlsdk-portable/blob/master/scripts/waifulib/library_naming.py) extensions, see
Issue #2(related to #0): Which ARM flavours we actually need to handle?\
Resolution: Little-endian only, as there is no known big-endian ARM platforms in the wild.
Architecture is coded this way:
* ```armvxy```, where `x` is ARM instruction set level and `y` is hard-float ABI presence: `hf` where hard float ABI used, otherwise `l`.
Issue #3: Some mods (like The Specialists, Tyrian, ...) already apply suffixes _i386, _i686 to the gamedll path:\
Resolution: On x86 on **Win/Lin/Mac**, don't change anything. Otherwise, strip the _i?86 part and follow the usual scheme.
See discussion: https://github.com/FWGS/xash3d-fwgs/issues/39

View File

@@ -0,0 +1,22 @@
## Looping MP3 extension
It is now possible to loop MP3 file in Xash3D FWGS by adding a custom text tag with `LOOP_START` or `LOOPSTART` in description and time point (in raw samples) in value.
### Example with foobar2000
1. Open Foobar2000
2. Add your .mp3 file to playlist
3. Right click to newly added file and select Properties
4. In Metadata tab, at the bottom of the table, select "+add new"
5. In newly added line replace `<60>input field name<6D>` with `LOOP_START` (without any symbols).
6. Press Tab and enter loop time point in raw samples. For example, `0` will replay sound file from beginning to end indefinitely.
### Possible alternatives
1. Classic WAV files looping. HQ WAV files can take too much disk space, and recommended software supporting cue points is paid, outdated and can't run on modern systems. (Although there is alternative that's proven to work with idTech-based engines called LoopAuditioneer.)
2. Vorbis looping through comment. Engine doesn't support Vorbis but this extension was highly inspired by this hack.
### Known bugs and limitations
1. At this time using MP3 as SFX requires complete decoding. This can cause noticeable stutters, so keep MP3 file length in mind.
2. We deliberately only support modern ID3v2.3 and ID3v2.4 tags. Using ID3v1 is not possible.

112
Documentation/gameinfo.md Normal file
View File

@@ -0,0 +1,112 @@
# Game definition and information file
gameinfo.txt is an essential part of any Xash3D based game. It allows basic customization for games creators, like setting game title, DLL paths, etc.
This document defines gameinfo.txt syntax, supported keys and liblist.gam conversion rules for the latest version of the engine. Note for engine developers, keep this document in sync with an implementation.
## gameinfo.txt syntax
* gameinfo.txt is a simple list of keys and values, separated by newline.
* You can add single line comments using double slashes (//).
* Keys can accept integer, float, string or boolean values.
* Boolean keys use 0 as false and 1 as true value.
* To have spaces in string values, you must enclose them in double quotes. Then, to have double quotes, you must escape it with backslash, and to have a backslash you need to use double backslashes.
The example:
```
// this is a comment :)
// this is another comment
some_integer_key 123
this_is_float_key 13.37 // optional comment
enable_feature 1 // boolean, 1 to enable, 0 to disable
example_string_key string_value
example_spaces "string with spaces"
example_title "Fate\\Stay Night" // engine will parse it as Fate\Stay Night
```
## gameinfo.txt keys
This is a list of all gameinfo.txt keys supported by the engine. Be aware that the engine will silently skip all unrecognized keys.
| Key | Type | Default value | Description |
| ---------------- | ---------- | --------------- | ----------- |
| `ambient0` | string | Empty string | Automatic ambient sound |
| `ambient1` | string | Empty string | Automatic ambient sound |
| `ambient2` | string | Empty string | Automatic ambient sound |
| `ambient3` | string | Empty string | Automatic ambient sound |
| `basedir` | string | `valve` | Game base directory, used to share assets between games |
| `date` | string | Empty string | Game release date. Unused. |
| `dllpath` | string | `cl_dlls` | Game DLL path. Engine will search custom DLLs (client or menu, for example) in this directory, except `gamedll`, see below. |
| `fallback_dir` | string | Empty string | Additional game base directory |
| `gamedir` | string | Current gamedir | Game directory, ignored in FWGS, as game directory is defined by the game directory name |
| `gamedll` | string | `dlls/hl.dll` | Game server DLL for 32-bit x86 Windows (see LibraryNaming.md for details) |
| `gamemode` | string | Empty string | Game type. When set to `singleplayer_only` or `multiplayer_only` marks the game as SP or MP only respectively, hiding the option in game UI. Omitting this key or using custom values mark the game as both MP and SP compatible. |
| `icon` | string | `game.ico` | Game icon. Engine will automatically append .ico and may automatically switch to .tga icon as well |
| `max_beams` | integer | 128 | Beams limit, 64 min, 512 max |
| `max_edicts` | integer | 900 | Entities limit, 600 min, 8192 max (protocol limit). In FWGS, minimum is 64. |
| `max_particles` | integer | 4096 | Particles limit, 1024 min, 131072 max |
| `max_tempents` | integer | 500 | Temporary entities limit. 300 min, 2048 max |
| `mp_entity` | string | `info_player_deathmatch` | Entity used to mark maps as multiplayer |
| `mp_filter` | string | Empty string | When set, used to filter multiplayer maps instead of `mp_entity`.<br>If the map name starts with the same characters as this filter, it's considered a multiplayer map |
| `nomodels` | boolean | 0 | When set to 1, disallows changing player model in UI |
| `noskills` | boolean | 0 | When set to 1, disallows selection of game difficulty |
| `secure` | boolean | 0 | When set to 1, original Unkle Mike's engine will completely disable developer mode. FWGS ignores but preserves this value for compatibility. |
| `size` | integer | 0 | Game directory size in bytes, used in Change Game dialog only |
| `startmap` | string | `c0a0` | The name of the map used in new game |
| `sp_entity` | string | `info_player_start` | Entity used to mark map as single player. Used in map validation |
| `title` | string | `New Game` | Game title, used in window title, default server name, etc. |
| `trainmap` | string | `t0a0` | The name of the training map (Hazard Course) |
| `type` | string | Empty string | Game type, used in Change Game UI. |
| `url_info` | string | Empty string | Game homepage URL, used in Change Game UI |
| `url_update` | string | Empty string | Game updates URL, used in Settings UI |
| `version` | float | 1.0 | Game version, used in Change Game dialog and in server info |
## FWGS-specific gameinfo.txt keys
These strings are specific to Xash3D FWGS.
| Key | Type | Default value | Description |
| ----------------------- | ---------- | ------------------------ | ----------- |
| `autosave_aged_count` | integer | 2 | Auto saves limit used in saves rotation |
| `gamedll_linux` | string | Generated from `gamedll` | Game server DLL for 32-bit x86 Linux (see LibraryNaming.md for details) |
| `gamedll_osx` | string | Generated from `gamedll` | Game server DLL for 32-bit x86 macOS (see LibraryNaming.md for details) |
| `internal_vgui_support` | boolean | 0 | Only for programmers! Required to be set as 1 for PrimeXT!<br>When set to 1, the engine will not load vgui_support DLL, as VGUI support is done (or intentionally ignored) on the game side. |
| `render_picbutton_text` | boolean | 0 | When set to 1, the UI will not use prerendered `btns_main.bmp` and dynamically render them instead |
| `quicksave_aged_count` | integer | 2 | Quick saves limit used in saves rotation |
## Note on GoldSrc liblist.gam support
As Xash3D accidentally supports GoldSrc games, it also supports parsing liblist.gam.\
Xash3D will use this file if gameinfo.txt is absent, or if its modification timestamp is older than liblist.gam.
For game creators who plan supporting only Xash3D, using this file is not recommended.
The table below defines conversion rules from liblist.gam to gameinfo.txt. Some keys' interpretation does differ from `gameinfo.txt`, in this case a note will be left. If `liblist.gam` key isn't present in this table, it's ignored.
| `liblist.gam` key | `gameinfo.txt` key | Note |
| ----------------- | ------------------ | ---- |
| `edicts` | `max_edicts` | |
| `fallback_dir` | `fallback_dir` | |
| `game` | `title` | |
| `gamedir` | `gamedir` | |
| `gamedll` | `gamedll` | |
| `gamedll_linux` | `gamedll_linux` | |
| `gamedll_osx` | `gamedll_osx` | |
| `icon` | `icon` | |
| `mpentity` | `mp_entity` | |
| `mpfilter` | `mp_filter` | |
| `nomodels` | `nomodels` | |
| `secure` | `secure` | In GoldSrc it's used to mark the multiplayer game as anti-cheat enabled.<br>Original Xash3D misinterprets its value for disallowing console and developer mode.<br>FWGS ignores this key but preserves for compatibility. |
| `startmap` | `startmap` | |
| `size` | `size` | |
| `trainingmap` | `trainmap` | |
| `trainmap` | `trainmap` | |
| `type` | `type` & `gamemode`| In `liblist.gam` this key works as both `type` and `gamemode`.<br>If value is `singleplayer_only` or `multiplayer_only` the game is marked as SP or MP only, and `gameinfo.txt` type set to `Single` or `Multiplayer`.<br>Any custom value will mark the game as both SP and MP compatible, and type is set to whatever custom value. |
| `url_dl` | `url_update` | |
| `url_info` | `url_info` | |
| `version` | `version` | |

View File

@@ -1,7 +1,40 @@
# Server porting
# Self-made port
## Compatibility with RISC architectures
### Unaligned access
Unaligned access on **i386** causes only performance penalty, but on **RISC** it can cause unstable work.
For HLSDK at least you need such patches in util.cpp:
- https://github.com/FWGS/halflife/commit/7bfefe86e35d67867ae7af830ac1fc38f2908360
- https://github.com/FWGS/hlsdk-portable/commit/617d75545f2ecb9b2d46cc30728dc37c9eb6d35e
### Signed chars
`char` type defined as **signed** for **x86** and as **unsigned** for **arm**.
And sometimes such difference can break logic.
As a solution you can use `signed char` type in code directly or use `-fsigned-char` option for gcc/clang compilers.
For HLSDK at least you need such [fix](https://github.com/FWGS/hlsdk-portable/commit/1ca34fcb4381682bd517612b530db22a1354a795) in nodes.cpp/.h.
## Compatibility with 64bit architectures
You need list of patches for Studio Model Render, MAKE_STRING macro and nodes:
- https://github.com/FWGS/hlsdk-portable/commit/d287ed446332e615ab5fb25ca81b99fa14d18a73
- https://github.com/FWGS/hlsdk-portable/commit/3bce17e3a04f8af10a927a07ceb8ab0f09152ec4
- https://github.com/FWGS/hlsdk-portable/commit/9ebfc981773ec4c7a89ffe52d9c249e1fbef9634
- https://github.com/FWGS/hlsdk-portable/commit/00833188dab87ef5746286479ba5aeb9d83b4a0c
- https://github.com/FWGS/hlsdk-portable/commit/4661b5c1a5245b27a5532745c11e44b5540e4172
- https://github.com/FWGS/hlsdk-portable/commit/2b61380146b1d58a8c465f0e312c061b12bda115
- https://github.com/FWGS/hlsdk-portable/commit/8ef6cb2427ee16a763103bd3f315f38e2f01cfe2
## Mobility API
Xash3D FWGS has special extended interface in `mobility_int.h` which adds some new features like vibration on mobile platforms.
## Porting server-side code
Original valve's server code was compatible with linux and gcc 2.x.
Newer gcc versions have restriction which breaks build.
Now, to make it building with gcc 4.x, you need do following:
Now, to make it building with gcc 4.x+ or clang, you need to do following:
* Go to cbase.h and redefine macros as following
```
#define SetThink( a ) m_pfnThink = static_cast <void (CBaseEntity::*)(void)> (&a)
@@ -18,58 +51,60 @@ Now, to make it building with gcc 4.x, you need do following:
* Replace all SetThink(NULL), SetTouch(NULL), setUse(NULL) and SetBlocked(NULL) by ResetThink(), ResetTouch(), ResetUse() and ResetBlocked()
* Sometimes you may need to add #include <ctype.h> if functions tolower or isspace are missing
# Client porting
## Porting client-side code
## VGUI library
Valve's client uses vgui library which is available only on x86 systems and has big amount of mistakes in headers. The best and simplest way of porting is removing VGUI dependency at all.
Most singleplayer mods don't really use VGUI at all. It is used in multiplayer only to show score table and MOTD window
## Porting
### First strategy: full port
#### Basic port (Stage 1)
* First, remove all files and headers which use vgui (contains "vgui" in file name).
* After that, try to build it and remove vgui includes.
* Remove all gViewPort usings.
* Remove all CVoiceManager usings (xash3d does not support voice)
* Redefine all DLLEXPORT defines as empty field (Place it under _WIN32 macro if you want to keep windows compatibility).
* Remove hud_servers.cpp and Servers_Init/Servers_Shutdown from hud.cpp
* Remove hud_servers.cpp and Servers_Init/Servers_Shutdown from hud.cpp.
* Fix CAPS filenames in includes (like STDIO.H, replace by stdio.h).
* Replace broken macros as DECLARE_MESSAGE, DECLARE_COMMAND by fixed examples from our hlsdk-xash3d port (cl_util.h)
* Add ctype.h where it is need (tolower, isspace functions)
* Add string.h where it is need (memcpy, strcpy, etc)
* Use in_defs.h from hlsdk_client
* Add scoreboard_stub.cpp and input_stub.cpp from hlsdk-xash3d to fix linking.
Now your client should be able to build and work correctly. Add input_xash3d.cpp from hlsdk-xash3d project to fix input.
* Replace broken macros as DECLARE_MESSAGE, DECLARE_COMMAND by fixed examples from our hlsdk-portable port (cl_util.h).
* Add ctype.h where is needed (tolower, isspace functions).
* Add string.h where is needed (memcpy, strcpy, etc).
* Use in_defs.h from hlsdk-portable.
* Add input_xash3d.cpp from hlsdk-portable project to fix input.
#### Multiplayer fix (Stage 2)
Look at hlsdk-xash3d project.
Now your client should be able to build and work correctly.
Main changes are:
* Add MOTD.cpp, scoreboard.cpp and input_xash3d.cpp
* Add missing functions to hud_redraw.cpp, hud.cpp and tri.cpp, fix class defination in hud.h
* Remove duplicate functions from hud.cpp and HOOK_MESSAGE's for it
* Remove +showscores/-showscores hooks from input.h
* Fix cl_util.h
# Porting mod to hlsdk-portable
Look at changes which was made.
### Second way: move mod to hlsdk-xash3d
Look at changes you made in client.
If there are not too much changes (for example, only some weapons was added), add these changes in hlsdk-portable.
If there are not much changes (for example, only some weapons was add), add these changes in hlsdk-xash3d.
You may use diff with original HLSDK you used and apply it as patch to hlsdk-xash3d.
You can use diff with original HLSDK and apply it as patch to hlsdk-portable.
```
NOTE: Many an old mods was made on HLSDK 2.0-2.1 and some rare mods on HLSDK 1.0.
So you need to have different versions of HLSDK to make diffs.
Plus different Spirit of Half-Life versions if mod was made on it.
Also, weapons in old HLSDK versions does not use client weapon prediction system and you may be need to port standart half-life weapons to server side.
```
Files must have same line endings (use dos2unix on all files).
I recommend to enable ignoring space changes in diff.
### Writing Makefiles
We recommend to enable ignoring space changes in diff.
Use Makefile from hlsdk-xash3d as Makefile example.
Move all new files to separate directories.
Get .c and .cpp file lists from Visual Studio project and fill SRCS and SRCS_C variables to Makefile.
# Possible replacements for non-portable external dependencies
1. If mod uses **fmod.dll** or **base.dll** to play mp3/ogg on client-side or to precache sounds on server-side, you can replace it with:
- [pfnPrimeMusicStream](https://github.com/FWGS/hlsdk-portable/blob/master/engine/cdll_int.h#L293=) engine callback;
- [miniaudio](https://github.com/mackron/miniaudio);
- [phonon](https://community.kde.org/Phonon).
Remove all files containing vgui in name from list, add missing include dirs.
2. If mod uses **OpenGL**, porting code to Xash3D render interface is recommended.
3. If mod uses **cg.dll**, you can try to port code to [NVFX](https://github.com/tlorach/nvFX).
4. If mod uses detours, comment code or try to find replacement somehow by yourself.
# Additional recommendations
1. If mod uses STL, you can replace it with [MiniUTL](https://github.com/FWGS/MiniUTL).
2. Avoid to use dynamic casts to make small size binaries.
3. Avoid to use exceptions to make small size binaries.
# Writing build scripts
Use wscript/CMakeLists.txt files from hlsdk-portable as build scripts example.
Get .c and .cpp file lists from Visual Studio project.
Add missing include dirs.
Do same for Android.mk if you are building for android.

View File

@@ -17,7 +17,7 @@ Mirrored on github - https://github.com/JoelTroch/am_src_rebirth
Mirrored on github - https://github.com/nekonomicon/BattleGrounds
## Bubblemod
Download page on official site - http://www.bubblemod.org/dl_default.php (dead link!)
Download page on official site(WM snapshot) - [http://www.bubblemod.org/dl_default.php](https://web.archive.org/web/20130717133158/http://www.bubblemod.org/dl_default.php)
Mirrored on github - https://github.com/HLSources/BubbleMod
@@ -85,6 +85,9 @@ Official gitlab repository - https://gitlab.com/Sockman/hltopdown
## Half-Life: Update
Official github repository - https://github.com/Fograin/hl-subsmod-ex
## Half-Life: Rally
Official gitlab repository - https://gitlab.com/hlrally/src
## Half-Life: Weapon Edition
Available on ModDB - https://www.moddb.com/mods/half-life-weapon-edition/downloads/half-life-weapon-edition-1508-alpha-open-src
@@ -127,22 +130,11 @@ Official github repository - https://github.com/unknownworlds/NS
## Overturn
Available in mod archive on ModDB - https://www.moddb.com/mods/overturn
## Spirit of Half-Life
[Logic&Trick's](https://github.com/LogicAndTrick) mirror - https://files.logic-and-trick.com/#/Half-Life/Mods/Spirit%20of%20Half-Life
## Threewave CTF
*Unfinished mod by Valve Software*
Available in Valve's Half-Life repository with Deathmatch Classic sources - https://github.com/ValveSoftware/halflife/tree/master/dmc
## Trinity Render
Available on ModDB: https://www.moddb.com/mods/half-life-episode-two/downloads/trinity-rendering-engine-v308f
## Tyrian: Ground Assault
Available on ModDB: https://www.moddb.com/mods/tyriangroundassault/downloads/tyrianga-v1-0-src
## Oz Deathmatch
Mirrored on github - https://github.com/nekonomicon/OZDM
## Paranoia
Available on ModDB: https://www.moddb.com/mods/paranoia/downloads/paranoia-toolkit
Available on ModDB - https://www.moddb.com/mods/paranoia/downloads/paranoia-toolkit
## Paranoia 2: The Savior
Prealpha, mirrored on github - https://github.com/a1batross/Paranoia2_ancient
@@ -157,12 +149,37 @@ Was found on HLFX - http://hlfx.ru/forum/showthread.php?s=2c892dfc52f72be52a89c3
## Ricochet
Available in Valve's Half-Life repository - https://github.com/ValveSoftware/halflife/tree/master/ricochet
## Spirit of Half-Life
[Logic&Trick's](https://github.com/LogicAndTrick) mirror - https://files.logic-and-trick.com/#/Half-Life/Mods/Spirit%20of%20Half-Life
## The Wastes
Version 1.5: mirrored on code.idtech.space - https://code.idtech.space/vera/halflife-thewastes-sdk
## Threewave CTF
*Unfinished mod by Valve Software*
Available in Valve's Half-Life repository with Deathmatch Classic sources - https://github.com/ValveSoftware/halflife/tree/master/dmc
## Trinity Render
Available on ModDB - https://www.moddb.com/mods/half-life-episode-two/downloads/trinity-rendering-engine-v308f
## Tyrian: Ground Assault
Available on ModDB - https://www.moddb.com/mods/tyriangroundassault/downloads/tyrianga-v1-0-src
## Wasteland
Mirrored on code.idtech.space - https://code.idtech.space/vera/halflife-wasteland-sdk
## Wizard Wars
Download page on official site - http://www.thothie.com/ww/
## XashXT
Mirrored on github - https://github.com/a1batross/XashXT_original
## Xen-Warrior
*Source code is a part of Spirit of Half-Life 1.0-1.2 under XENWARRIOR macro*
[Logic&Trick's](https://github.com/LogicAndTrick) mirror - https://files.logic-and-trick.com/#/Half-Life/Mods/Spirit%20of%20Half-Life
## Zombie-X
Available in mod archive on ModDB - https://www.moddb.com/mods/zombie-x-10-final/downloads/zombie-x-10-dle-beta6-last-version
@@ -184,12 +201,12 @@ malortie's recreation - https://github.com/malortie/hl-aom
Branch **aom** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/aom
## Afraid of Monsters: Director's cut
Reverse-engineered code, branch **aomdc** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/aomdc
Reverse-engineered code: branch **aomdc** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/aomdc
## Azure Sheep
malortie's recreation - https://github.com/malortie/hl-asheep
Reverse-engineered code, branch **asheep** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/asheep
Reverse-engineered code: branch **asheep** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/asheep
## Big Lolly
malortie's recreation - https://github.com/malortie/hl-biglolly
@@ -226,12 +243,17 @@ Recreation by lostgamer aka nillerusr - https://github.com/LostGamerHL/crack_lif
## Escape from the Darkness
malortie's recreation - https://github.com/malortie/hl-eftd
Reverse-engineered code, branch **eftd** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/eftd
Reverse-engineered code: branch **eftd** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/eftd
## Half-Life: Black Guard
*This mod uses dlls from Cleaner's Adventures*
Branch **CAd** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/CAd
## Half-Life: Blue Shift
Unkle Mike's recreation - https://hlfx.ru/forum/showthread.php?s=&threadid=5253
Reverse-engineered code, branch **bshift** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/bshift
Reverse-engineered code: branch **bshift** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/bshift
## Half-Life: Induction
Branch **induction** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/induction
@@ -239,12 +261,12 @@ Branch **induction** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/
## Half-Life: Opposing Force
Recreation by lostgamer aka nillerusr - https://github.com/LostGamerHL/hlsdk-xash3d
Reverse-engineered code, clean branch **opfor** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/opfor
Reverse-engineered code: clean branch **opfor** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/opfor
Spirit of Half Life: Opposing-Force Edition - https://github.com/Hammermaps-DEV/SOHL-V1.9-Opposing-Force-Edition
## Half-Life: Rebellion
Reverse-engineered code, branch **rebellion** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/rebellion
Reverse-engineered code: branch **rebellion** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/rebellion
## Half-Life: Urbicide
Branch **hl_urbicide** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/hl_urbicide
@@ -252,7 +274,7 @@ Branch **hl_urbicide** in hlsdk-portable - https://github.com/FWGS/hlsdk-portabl
## Half-Life: Visitors
malortie's recreation - https://github.com/malortie/hl-visitors
Reverse-engineered code, branch **visitors** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/visitors
Reverse-engineered code: branch **visitors** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/visitors
## Half-Secret
Branch **half-secret** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/half-secret
@@ -265,18 +287,18 @@ Branch **noffice** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tr
## Poke 646
malortie's recreation - https://github.com/malortie/hl-poke646
Reverse-engineered code, branch **poke646** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/poke646
Reverse-engineered code: branch **poke646** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/poke646
## Poke 646: Vendetta
malortie's recreation - https://github.com/malortie/hl-poke646-vendetta
Reverse-engineered code, branch **poke646_vendetta** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/poke646_vendetta
Reverse-engineered code: branch **poke646_vendetta** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/poke646_vendetta
## Residual Life
Reverse-engineered code, branch **residual_point** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/residual_point
Reverse-engineered code: branch **residual_point** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/residual_point
## Residual Point
Reverse-engineered code, branch **residual_point** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/residual_point
Reverse-engineered code: branch **residual_point** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/residual_point
## Sewer Beta
Branch **sewer_beta** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/sewer_beta
@@ -287,12 +309,12 @@ Reverse-engineered code by Velaron - https://github.com/Velaron/tf15-client
## The Gate
malortie's recreation - https://github.com/malortie/hl-thegate
Reverse-engineered code, branch **thegate** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/thegate
Reverse-engineered code: branch **thegate** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/thegate
## They Hunger
malortie's recreation - https://github.com/malortie/hl-theyhunger
Reverse-engineered code, branch **theyhunger** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/theyhunger
Reverse-engineered code: branch **theyhunger** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/theyhunger
They Hunger: Tactical - https://www.moddb.com/mods/they-hunger-tactical/downloads/tht-source-code-documentation
@@ -335,16 +357,22 @@ Branch **half-screwed** in hlsdk-portable - https://github.com/FWGS/hlsdk-portab
Port to Linux - https://github.com/fmoraw/NS
## Spirit of Half-Life
Version 1.2, branch **sohl1.2** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/sohl1.2
Version 1.2: branch **sohl1.2** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/sohl1.2
## Swiss Cheese Halloween 2002
Just more playable version by malortie - https://github.com/malortie/hl-shall
Branch **halloween** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/halloween
## The Wastes
Version 1.5: Port to Linux - https://git.mentality.rip/a1batross/halflife-thewastes-sdk
## Threewave CTF
Branch **dmc** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/dmc
## Xen-Warrior
Branch **sohl1.2** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/sohl1.2
## Zombie-X
Branch **zombie-x** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/zombie-x

View File

@@ -2,37 +2,32 @@ Xash3D FWGS is intended to be easily ported to specific platform, however main i
This page is about merged ports to main source tree and responsible for it developers.
For porting guidelines, look here(TODO!)
For porting guidelines, look engine-porting-guide.md.
Status:
* **Supported**: active, confirmed to be fully functional.
* **Supported**: active, was confirmed to be fully functional.
* **In progress**: active, under development.
* **Incomplete**: not active, but some work was accepted to main repository before
* **Old Engine**: port was for old engine fork
* **Not maintained**: lack of human resources
* **Not merged**: was done in third-party fork, real status unknown
* **Deprecated**: not supported anymore
Table is sorted by status.
Table is sorted by status and platform.
| Platform | Status | Maintainer | Note
| -------- | ------ | ---------- | ----
| Windows | Supported | @a1batross, @SNMetamorph |
| Android | Supported | @Velaron |
| *BSD | Supported | @nekonomicon |
| GNU/Linux(x86, amd64, arm) | Supported | @a1batross, @mittorn |
| Android | Supported | @a1batross, @mittorn |
| MotoMAGX | Supported | @a1batross |
| GNU/Linux(elbrus) | Supported | @a1batross, @mittorn | Rare and eventual access to e2k machine
| Haiku | Supported | not maintained | Was added by #478 and #483
| DOS4GW | Supported | @mittorn |
| GNU/Linux(mipsel) | Supported | @mittorn |
| Switch | In progress | @fgsfdsfgs | [GitHub Repository](https://github.com/fgsfdsfgs/xash3d-fwgs/tree/switch_new)
| Wii | In progress | Collaborative effort | [GitHub Repository](https://github.com/saucesaft/xash3d-wii)
| GNU/Linux | Supported | @a1batross, @mittorn |
| Haiku | Supported | not maintained | Was added by #478 and #483
| macOS | Supported | @sofakng |
| MotoMAGX | Supported | @a1batross |
| PSVita | Supported | @fgsfdsfgs |
| Switch | Supported | @fgsfdsfgs |
| Windows | Supported | @a1batross, @SNMetamorph |
| PSP | In progress | @Crow_bar, @Velaron | [GitHub Repository](https://github.com/Crow-bar/xash3d-fwgs)
| Wii | In progress | Collaborative effort | [GitHub Repository](https://github.com/saucesaft/xash3d-wii)
| Emscripten | Old Engine | not maintained |
| Oculus Quest | Old Engine fork | @DrBeef | [GitHub Repository](https://github.com/DrBeef/Lambda1VR)
| PSVita | Old Engine fork | not maintained | [GitHub Repository](https://github.com/fgsfdsfgs/vitaXash3D)
| Switch | Old Engine fork | not maintained | [GitHub Repository](https://github.com/switchports/xash3d-switch)
| 3DS | Old Engine fork | not maintained | [GitHub Repository](https://github.com/masterfeizz/Xash3DS)
| macOS | Deprecated | not maintained | See GitHub issue #61
| Oculus Quest | Old Engine fork | @DrBeef | [GitHub Repository](https://github.com/DrBeef/Lambda1VR)
| iOS | Deprecated | not maintained | See GitHub issue #61

49
Documentation/psvita.md Normal file
View File

@@ -0,0 +1,49 @@
## PlayStation Vita port
### 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:
```
*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
1. If you have an old vitaXash3D install, remove it.
2. Get `xash3d-fwgs-psvita.7z` from the latest [automatic build](https://github.com/FWGS/xash3d-fwgs/releases/tag/continuous).
3. Install `xash.vpk` from the 7z archive onto your PSVita.
4. Copy the `data` directory from the 7z archive to the root of your PSVita's SD card.
5. Copy the valve folder and any other mod folders from your Half-Life install to `ux0:/data/xash3d/` (you can use other mountpoints instead of `ux0`). **Do not overwrite anything.**
### Build instructions
1. Install [VitaSDK](https://vitasdk.org/).
2. Build and install [vitaGL](https://github.com/Rinnegatamante/vitaGL):
```
git clone https://github.com/Rinnegatamante/vitaGL.git
make -C vitaGL NO_TEX_COMBINER=1 HAVE_UNFLIPPED_FBOS=1 HAVE_PTHREAD=1 SINGLE_THREADED_GC=1 MATH_SPEEDHACK=1 DRAW_SPEEDHACK=1 HAVE_CUSTOM_HEAP=1 -j2 install
```
3. Build and install [vita-rtld](https://github.com/fgsfdsfgs/vita-rtld):
```
git clone https://github.com/fgsfdsfgs/vita-rtld.git && cd vita-rtld
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make -j2 install
```
4. Build and install [this SDL2 fork](https://github.com/Northfear/SDL) with vitaGL integration:
```
git clone https://github.com/Northfear/SDL.git && cd SDL
mkdir build && cd build
cmake -DCMAKE_TOOLCHAIN_FILE=${VITASDK}/share/vita.toolchain.cmake -DCMAKE_BUILD_TYPE=Release -DVIDEO_VITA_VGL=ON ..
make -j2 install
```
5. Use `waf`:
```
./waf configure -T release --psvita
./waf build
```
6. Copy all the resulting `.so` files into a single folder:
```
./waf install --destdir=xash3d
```
7. `xash.vpk` is located in `build/engine/`.

View File

@@ -18,19 +18,22 @@ Read more about Xash3D on ModDB: https://www.moddb.com/engines/xash3d-engine
* Mobility API: allows better game integration on mobile devices(vibration, touch controls)
* Different input methods: touch, gamepad and classic mouse & keyboard.
* TrueType font rendering, as a part of mainui_cpp.
* Multiple renderers support: OpenGL, GLESv1, GLESv2, Software
* Multiple renderers support: OpenGL, GLESv1, GLESv2, Software.
* Voice support.
* External filesystem module like in GoldSrc engine.
* External vgui support module.
* PNG image format support.
* A set of small improvements, without broken compatibility.
## Planned fork features
* Virtual Reality support and game API
* Voice support
* Vulkan renderer
* Virtual Reality support and game API.
* Vulkan renderer.
## Installation & Running
0) Get Xash3D FWGS binaries: you can use [testing](https://github.com/FWGS/xash3d-fwgs/releases/tag/continuous) build or you can compile engine from source code.
1) Copy engine binaries to some directory.
2) Copy `valve` directory from [Half-Life](https://store.steampowered.com/app/70/HalfLife/) to directory with engine binaries.
If your CPU is NOT x86 compatible or you're running 64-bit version of the engine, you may want to compile [Half-Life SDK](https://github.com/FWGS/hlsdk-xash3d).
If your CPU is NOT x86 compatible or you're running 64-bit version of the engine, you may want to compile [Half-Life SDK](https://github.com/FWGS/hlsdk-portable).
This repository contains our fork of HLSDK and restored source code for some of the mods. Not all of them, of course.
You still needed to copy `valve` directory as all game resources located there.
3) Run the main executable (`xash3d.exe` or AppImage).
@@ -49,10 +52,10 @@ NOTE: NEVER USE GitHub's ZIP ARCHIVES. GitHub doesn't include external dependenc
### Prerequisites
If your CPU is x86 compatible, we are building 32-bit code by default. This was dont for keeping compatibility with Steam releases of Half-Life and based on it's engine games.
If your CPU is x86 compatible, 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.
Even if Xash3D FWGS does support targetting 64-bit, you can't load games without recompiling them from source code!
If your CPU is NOT x86 compatible or you decided build 64-bit version of engine, you may want to compile [Half-Life SDK](https://github.com/FWGS/hlsdk-xash3d).
If your CPU is NOT x86 compatible or you decided build 64-bit version of engine, you may want to compile [Half-Life SDK](https://github.com/FWGS/hlsdk-portable).
This repository contains our fork of HLSDK and restored source code for some of the mods. Not all of them, of course.
#### Windows (Visual Studio)

View File

@@ -18,27 +18,17 @@ GNU General Public License for more details.
// video backends (XASH_VIDEO)
#define VIDEO_NULL 0
#define VIDEO_SDL 1
#define VIDEO_ANDROID 2
#define VIDEO_FBDEV 3
#define VIDEO_DOS 4
// audio backends (XASH_SOUND)
#define SOUND_NULL 0
#define SOUND_SDL 1
#define SOUND_OPENSLES 2
#define SOUND_ALSA 3
// crash handler (XASH_CRASHHANDLER)
#define CRASHHANDLER_NULL 0
#define CRASHHANDLER_UCONTEXT 1
#define CRASHHANDLER_DBGHELP 2
#define CRASHHANDLER_WIN32 3
// input (XASH_INPUT)
#define INPUT_NULL 0
#define INPUT_SDL 1
#define INPUT_ANDROID 2
#define INPUT_EVDEV 3
// timer (XASH_TIMER)
@@ -51,9 +41,8 @@ GNU General Public License for more details.
// messageboxes (XASH_MESSAGEBOX)
#define MSGBOX_STDERR 0
#define MSGBOX_SDL 1
#define MSGBOX_ANDROID 2
#define MSGBOX_WIN32 3
#define MSGBOX_NSWITCH 4
// library loading (XASH_LIB)
#define LIB_NULL 0
@@ -61,5 +50,4 @@ GNU General Public License for more details.
#define LIB_WIN32 2
#define LIB_STATIC 3
#endif /* BACKENDS_H */

View File

@@ -61,13 +61,16 @@ BRUSH MODELS
#define LS_UNUSED 0xFE
#define LS_NONE 0xFF
#define MAX_MAP_CLIPNODES_HLBSP 32767
#define MAX_MAP_CLIPNODES_BSP2 524288
// these limis not using by modelloader but only for displaying 'mapstats' correctly
#ifdef SUPPORT_BSP2_FORMAT
#define MAX_MAP_MODELS 2048 // embedded models
#define MAX_MAP_ENTSTRING 0x200000 // 2 Mb should be enough
#define MAX_MAP_PLANES 131072 // can be increased without problems
#define MAX_MAP_NODES 262144 // can be increased without problems
#define MAX_MAP_CLIPNODES 524288 // can be increased without problems
#define MAX_MAP_CLIPNODES MAX_MAP_CLIPNODES_BSP2 // can be increased without problems
#define MAX_MAP_LEAFS 131072 // CRITICAL STUFF to run ad_sepulcher!!!
#define MAX_MAP_VERTS 524288 // can be increased without problems
#define MAX_MAP_FACES 262144 // can be increased without problems
@@ -78,7 +81,7 @@ BRUSH MODELS
#define MAX_MAP_ENTSTRING 0x100000 // 1 Mb should be enough
#define MAX_MAP_PLANES 65536 // can be increased without problems
#define MAX_MAP_NODES 32767 // because negative shorts are leafs
#define MAX_MAP_CLIPNODES 32767 // because negative shorts are contents
#define MAX_MAP_CLIPNODES MAX_MAP_CLIPNODES_HLBSP // because negative shorts are contents
#define MAX_MAP_LEAFS 32767 // signed short limit
#define MAX_MAP_VERTS 65535 // unsigned short limit
#define MAX_MAP_FACES 65535 // unsigned short limit

View File

@@ -9,7 +9,20 @@ NOTE: number at end of pixelformat name it's a total bitscount e.g. PF_RGB_24 ==
========================================================================
*/
#define ImageRAW( type ) (type == PF_RGBA_32 || type == PF_BGRA_32 || type == PF_RGB_24 || type == PF_BGR_24 || type == PF_LUMINANCE)
#define ImageDXT( type ) (type == PF_DXT1 || type == PF_DXT3 || type == PF_DXT5 || type == PF_ATI2 || type == PF_BC6H_SIGNED || type == PF_BC6H_UNSIGNED || type == PF_BC7)
#define ImageCompressed( type ) \
( type == PF_DXT1 \
|| type == PF_DXT3 \
|| type == PF_DXT5 \
|| type == PF_ATI2 \
|| type == PF_BC4_SIGNED \
|| type == PF_BC4_UNSIGNED \
|| type == PF_BC5_SIGNED \
|| type == PF_BC5_UNSIGNED \
|| type == PF_BC6H_SIGNED \
|| type == PF_BC6H_UNSIGNED \
|| type == PF_BC7_UNORM \
|| type == PF_BC7_SRGB \
|| type == PF_KTX2_RAW )
typedef enum
{
@@ -25,9 +38,15 @@ typedef enum
PF_DXT3, // s3tc DXT3/BC2 format
PF_DXT5, // s3tc DXT5/BC3 format
PF_ATI2, // latc ATI2N/BC5 format
PF_BC4_SIGNED,
PF_BC4_UNSIGNED,
PF_BC5_SIGNED,
PF_BC5_UNSIGNED,
PF_BC6H_SIGNED, // bptc BC6H signed FP16 format
PF_BC6H_UNSIGNED, // bptc BC6H unsigned FP16 format
PF_BC7, // bptc BC7 format
PF_BC7_UNORM, // bptc BC7 format
PF_BC7_SRGB,
PF_KTX2_RAW, // Raw KTX2 data, used for yet unsupported KTX2 subformats
PF_TOTALCOUNT, // must be last
} pixformat_t;
@@ -49,6 +68,8 @@ typedef enum
IL_DDS_HARDWARE = BIT(4), // DXT compression is support
IL_LOAD_DECAL = BIT(5), // special mode for load gradient decals
IL_OVERVIEW = BIT(6), // overview required some unque operations
IL_LOAD_PLAYER_DECAL = BIT(7), // special mode for player decals
IL_KTX2_RAW = BIT(8), // renderer can consume raw KTX2 files (e.g. ref_vk)
} ilFlags_t;
// goes into rgbdata_t->encode

View File

@@ -105,7 +105,7 @@ typedef struct
vec3_t mins, maxs; // terrain bounds (fill by user)
int reserved[32]; // just for future expansions or mod-makers
intptr_t reserved[32]; // just for future expansions or mod-makers
} mfaceinfo_t;
typedef struct
@@ -173,8 +173,8 @@ struct decal_s
short entityIndex; // Entity this is attached to
// Xash3D specific
vec3_t position; // location of the decal center in world space.
glpoly_t *polys; // precomputed decal vertices
int reserved[4]; // just for future expansions or mod-makers
glpoly_t *polys; // precomputed decal vertices
intptr_t reserved[4]; // just for future expansions or mod-makers
};
typedef struct mleaf_s
@@ -228,7 +228,7 @@ typedef struct mextrasurf_s
unsigned short numverts; // world->vertexes[]
int firstvertex; // fisrt look up in tr.tbn_vectors[], then acess to world->vertexes[]
int reserved[32]; // just for future expansions or mod-makers
intptr_t reserved[32]; // just for future expansions or mod-makers
} mextrasurf_t;
struct msurface_s

View File

@@ -47,29 +47,11 @@ SETUP BACKENDS DEFINITIONS
#endif // XASH_TIMER
#ifndef XASH_MESSAGEBOX
#define XASH_MESSAGEBOX MSGBOX_SDL
#if !XASH_NSWITCH // SDL2 messageboxes not available
#define XASH_MESSAGEBOX MSGBOX_SDL
#endif
#endif // XASH_MESSAGEBOX
#endif
#elif XASH_ANDROID
// we are building for Android platform, use Android APIs
#ifndef XASH_VIDEO
#define XASH_VIDEO VIDEO_ANDROID
#endif // XASH_VIDEO
#ifndef XASH_INPUT
#define XASH_INPUT INPUT_ANDROID
#endif // XASH_INPUT
#ifndef XASH_SOUND
#define XASH_SOUND SOUND_OPENSLES
#endif // XASH_SOUND
#ifndef XASH_MESSAGEBOX
#define XASH_MESSAGEBOX MSGBOX_ANDROID
#endif // XASH_MESSAGEBOX
#define XASH_USE_EVDEV
#define XASH_DYNAMIC_DLADDR
#elif XASH_LINUX
// we are building for Linux without SDL2, can draw only to framebuffer yet
#ifndef XASH_VIDEO
@@ -84,7 +66,7 @@ SETUP BACKENDS DEFINITIONS
#define XASH_SOUND SOUND_ALSA
#endif // XASH_SOUND
#define XASH_USE_EVDEV
#define XASH_USE_EVDEV 1
#elif XASH_DOS4GW
#ifndef XASH_VIDEO
#define XASH_VIDEO VIDEO_DOS
@@ -105,22 +87,13 @@ SETUP BACKENDS DEFINITIONS
#ifndef XASH_MESSAGEBOX
#if XASH_WIN32
#define XASH_MESSAGEBOX MSGBOX_WIN32
#elif XASH_NSWITCH
#define XASH_MESSAGEBOX MSGBOX_NSWITCH
#else // !XASH_WIN32
#define XASH_MESSAGEBOX MSGBOX_STDERR
#endif // !XASH_WIN32
#endif // XASH_MESSAGEBOX
//
// select crashhandler based on defines
//
#ifndef XASH_CRASHHANDLER
#if XASH_WIN32 && defined(DBGHELP)
#define XASH_CRASHHANDLER CRASHHANDLER_DBGHELP
#elif XASH_LINUX || XASH_BSD
#define XASH_CRASHHANDLER CRASHHANDLER_UCONTEXT
#endif // !(XASH_LINUX || XASH_BSD || XASH_WIN32)
#endif
//
// no timer - no xash
//
@@ -157,10 +130,6 @@ SETUP BACKENDS DEFINITIONS
#define XASH_INPUT INPUT_NULL
#endif // XASH_INPUT
#ifndef XASH_CRASHHANDLER
#define XASH_CRASHHANDLER CRASHHANDLER_NULL
#endif // XASH_CRASHHANDLER
/*
=========================================================================
@@ -169,27 +138,55 @@ Default build-depended cvar and constant values
=========================================================================
*/
#if XASH_MOBILE_PLATFORM
#define DEFAULT_TOUCH_ENABLE "1"
#define DEFAULT_M_IGNORE "1"
#else // !XASH_MOBILE_PLATFORM
// Platform overrides
#if XASH_NSWITCH
#define DEFAULT_TOUCH_ENABLE "0"
#define DEFAULT_M_IGNORE "0"
#endif // !XASH_MOBILE_PLATFORM
#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_M_IGNORE "1"
#define DEFAULT_MODE_WIDTH 960
#define DEFAULT_MODE_HEIGHT 544
#define DEFAULT_ALLOWCONSOLE 1
#elif XASH_ANDROID
#define DEFAULT_TOUCH_ENABLE "1"
#elif XASH_MOBILE_PLATFORM
#define DEFAULT_TOUCH_ENABLE "1"
#define DEFAULT_M_IGNORE "1"
#endif // !XASH_MOBILE_PLATFORM && !XASH_NSWITCH
#if XASH_ANDROID || XASH_IOS || XASH_EMSCRIPTEN
#define XASH_INTERNAL_GAMELIBS
// 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
// 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
#endif // XASH_ANDROID || XASH_IOS || XASH_EMSCRIPTEN
// allow override for developer/debug builds
// Defaults
#ifndef DEFAULT_TOUCH_ENABLE
#define DEFAULT_TOUCH_ENABLE "0"
#endif // DEFAULT_TOUCH_ENABLE
#ifndef DEFAULT_M_IGNORE
#define DEFAULT_M_IGNORE "0"
#endif // DEFAULT_M_IGNORE
#ifndef DEFAULT_JOY_DEADZONE
#define DEFAULT_JOY_DEADZONE "4096"
#endif // DEFAULT_JOY_DEADZONE
#ifndef DEFAULT_DEV
#define DEFAULT_DEV 0
#endif // DEFAULT_DEV
#ifndef DEFAULT_ALLOWCONSOLE
#define DEFAULT_ALLOWCONSOLE 0
#endif // DEFAULT_ALLOWCONSOLE
#ifndef DEFAULT_FULLSCREEN
#define DEFAULT_FULLSCREEN 1
#define DEFAULT_FULLSCREEN "1" // must be a string
#endif // DEFAULT_FULLSCREEN
#endif // DEFAULTS_H

View File

@@ -16,22 +16,61 @@
#ifndef NETADR_H
#define NETADR_H
#include "build.h"
#include STDINT_H
typedef enum
{
NA_UNUSED,
NA_UNUSED = 0,
NA_LOOPBACK,
NA_BROADCAST,
NA_IP,
NA_IPX,
NA_BROADCAST_IPX
NA_BROADCAST_IPX,
NA_IP6,
NA_MULTICAST_IP6, // all nodes multicast
} netadrtype_t;
// Original structure:
// typedef struct netadr_s
// {
// netadrtype_t type;
// unsigned char ip[4];
// unsigned char ipx[10];
// unsigned short port;
// } netadr_t;
#pragma pack( push, 1 )
typedef struct netadr_s
{
netadrtype_t type;
unsigned char ip[4];
unsigned char ipx[10];
unsigned short port;
union
{
struct
{
uint32_t type;
union
{
uint8_t ip[4];
uint32_t ip4;
};
uint8_t ipx[10];
};
struct
{
#if XASH_LITTLE_ENDIAN
uint16_t type6;
uint8_t ip6[16];
#elif XASH_BIG_ENDIAN
uint8_t ip6_0[2];
uint16_t type6;
uint8_t ip6_2[14];
#endif
};
};
uint16_t port;
} netadr_t;
#pragma pack( pop )
STATIC_ASSERT( sizeof( netadr_t ) == 20, "invalid netadr_t size" );
#endif//NETADR_H

View File

@@ -39,16 +39,20 @@ GNU General Public License for more details.
#if XASH_POSIX
#include <unistd.h>
#include <dlfcn.h>
#define PATH_SPLITTER "/"
#define HAVE_DUP
#define O_BINARY 0
#define O_TEXT 0
#if XASH_NSWITCH
#define SOLDER_LIBDL_COMPAT
#include <solder.h>
#elif XASH_PSVITA
#define VRTLD_LIBDL_COMPAT
#include <vrtld.h>
#define O_BINARY 0
#else
#include <dlfcn.h>
#define HAVE_DUP
#define O_BINARY 0
#endif
#define O_TEXT 0
#define _mkdir( x ) mkdir( x, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH )
#elif XASH_DOS4GW
#define PATH_SPLITTER "\\"
#endif
typedef void* HANDLE;
@@ -59,7 +63,6 @@ GNU General Public License for more details.
int x, y;
} POINT;
#else // WIN32
#define PATH_SPLITTER "\\"
#ifdef __MINGW32__
#define _inline static inline
#define FORCEINLINE inline __attribute__((always_inline))

View File

@@ -161,7 +161,7 @@ struct ref_viewpass_s;
typedef struct render_api_s
{
// Get renderer info (doesn't changes engine state at all)
int (*RenderGetParm)( int parm, int arg ); // generic
intptr_t (*RenderGetParm)( int parm, int arg ); // generic
void (*GetDetailScaleForTexture)( int texture, float *xScale, float *yScale );
void (*GetExtraParmsForTexture)( int texture, byte *red, byte *green, byte *blue, byte *alpha );
lightstyle_t* (*GetLightStyle)( int number );

24
common/synctype.h Normal file
View File

@@ -0,0 +1,24 @@
/*
synctype.h -- shared synctype_t definition
Copyright (C) 1996-1997 Id Software, Inc.
Copyright (C) 2023 Alibek Omarov
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef SYNCTYPE_H
#define SYNCTYPE_H
typedef enum {ST_SYNC=0, ST_RAND } synctype_t;
#endif

View File

@@ -4,12 +4,17 @@
#include "build.h"
#if XASH_IRIX
#include <port.h>
#endif
#if XASH_WIN32
#include <wchar.h> // off_t
#endif // _WIN32
#include <sys/types.h> // off_t
#include STDINT_H
#include <assert.h>
typedef unsigned char byte;
typedef int sound_t;
@@ -22,7 +27,12 @@ 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];
#if XASH_64BIT
typedef uint32_t poolhandle_t;
#else
typedef void* poolhandle_t;
#endif
#undef true
#undef false
@@ -40,12 +50,14 @@ typedef uint64_t longtime_t;
#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 BIT( n ) ( 1U << ( n ))
#define BIT64( n ) ( 1ULL << ( n ))
#define GAMMA ( 2.2f ) // Valve Software gamma
#define INVGAMMA ( 1.0f / 2.2f ) // back to 1.0
#define TEXGAMMA ( 0.9f ) // compensate dim textures
@@ -75,16 +87,19 @@ typedef uint64_t longtime_t;
#endif
#define _format(x) __attribute__((format(printf, x, x+1)))
#define NORETURN __attribute__((noreturn))
#define NONNULL __attribute__((nonnull))
#elif defined(_MSC_VER)
#define EXPORT __declspec( dllexport )
#define GAME_EXPORT
#define _format(x)
#define NORETURN
#define NONNULL
#else
#define EXPORT
#define GAME_EXPORT
#define _format(x)
#define NORETURN
#define NONNULL
#endif
#if ( __GNUC__ >= 3 )
@@ -103,6 +118,11 @@ typedef uint64_t longtime_t;
#define likely(x) (x)
#endif
#if defined( static_assert ) // C11 static_assert
#define STATIC_ASSERT static_assert
#else
#define STATIC_ASSERT( x, y ) extern int _static_assert_##__LINE__[( x ) ? 1 : -1]
#endif
#ifdef XASH_BIG_ENDIAN
#define LittleLong(x) (((int)(((x)&255)<<24)) + ((int)((((x)>>8)&255)<<16)) + ((int)(((x)>>16)&255)<<8) + (((x) >> 24)&255))

View File

@@ -1,206 +0,0 @@
#############################################
# Makefile.linux - linux makefile
# Copyright (C) 2017 mittorn
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
##############################################
# Default options - optimized to debug on local machine
CC ?= gcc
CXX ?= g++
CFLAGS ?= -g -O1 -fsigned-char -Wall -Wextra -Wsign-compare -Wno-unknown-pragmas -Wno-missing-field-initializers -Wno-unused-parameter -Wno-unused-but-set-variable
LDFLAGS =
LBITS := $(shell getconf LONG_BIT)
DEPS :=
XASH_COMMIT := $(firstword $(shell git rev-parse --short=6 HEAD) unknown)
ifeq ($(XASH_COMMIT),unknown)
$(warning You seems to build xash3d without git)
$(warning Please use git if you are going to publish your build)
endif
# Pass 64BIT=1 to make arguments to allow amd64 builds
ifneq ($(64BIT),1)
ifeq ($(LBITS),64)
LDFLAGS += -m32
CFLAGS += -m32
endif
endif
TOPDIR = $(PWD)/..
INCLUDES :=
XASH_SINGLE_BINARY ?= 1
INSTALL_DIR ?= ./install/
ifeq ($(NANOGL),1)
INCLUDES += -Inanogl -Inanogl/GL
endif
INCLUDES += -I/usr/include/SDL2 -Icommon -I../common -I. -I../pm_shared -Iclient -Iserver -Iclient/vgui -Icommon/sdl
#############################
# Preprocessor defines:
#############################
DEFINES =
# Specify commit hash in version string
DEFINES += -DXASH_BUILD_COMMIT=\"$(XASH_COMMIT)\"
# Only SDL backend exists on linux
ifeq ($(XASH_DEDICATED),1)
DEFINES += -DXASH_DEDICATED
else
DEFINES += -DXASH_SDL
LIBS += -lSDL2
endif
#############################################
# GL/GLES translators.
# You need clone it to engine folder to use
# Only one translator should be enabled
#############################################
ifeq ($(NANOGL),1)
DEFINES += -DXASH_NANOGL -D__MULTITEXTURE_SUPPORT__ -DEGL_LIB=\"libEGL.so\"
endif
ifeq ($(WES),1)
DEFINES += -DXASH_WES -D__MULTITEXTURE_SUPPORT__ -DEGL_LIB=\"libEGL.so\"
endif
ifeq ($(REGAL),1)
DEFINES += -DXASH_REGAL -D__MULTITEXTURE_SUPPORT__ -DEGL_LIB=\"regal/lib/linux-32/libRegal.so\"
LIBS += regal/lib/linux-32/libRegal.so
endif
# Some libc implementations cannot use libdl in static builds, so disable it by default
ifeq ($(XASH_STATIC),1)
ifneq ($(XASH_STATIC_LIBDL),1)
DEFINES += -DNO_LIBDL
endif
XASH_SINGLE_BINARY := 1
endif
ifneq ($(XASH_STATIC),1)
LIBS += -ldl
endif
ifeq ($(XASH_STATIC_LIBDL),1)
LIBS += -ldl
endif
LIBS += -lm -pthread
ifeq ($(XASH_SINGLE_BINARY),1)
DEFINES += -DSINGLE_BINARY
endif
# Collect files
SRCS_CPP =
SRCS = $(wildcard server/*.c) $(wildcard client/vgui/*.c) $(wildcard client/avi/*.c) $(wildcard common/*.c) $(wildcard common/imagelib/*.c) $(wildcard common/soundlib/*.c) $(wildcard common/soundlib/libmpg/*.c)
ifneq ($(XASH_DEDICATED),1)
SRCS += $(wildcard client/*.c)
SRCS += $(wildcard platform/sdl/*.c)
ifeq ($(WES),1)
SRCS += $(wildcard gl-wes-v2/src/*.c)
endif
ifeq ($(NANOGL),1)
SRCS_CPP += $(wildcard nanogl/*.cpp)
endif
endif
OBJS = $(patsubst %.c,obj/%.o,$(SRCS))
OBJS_CPP = $(patsubst %.cpp,obj/%.o,$(SRCS_CPP))
#################################
# Windows DLL loader
# Should be enabled only on i386 builds
#################################
LOADER :=
ifeq ($(XASH_DLL_LOADER),1)
DEFINES += -DDLL_LOADER
ifeq ($(XASH_SINGLE_BINARY),1)
LOADER = libloader.a
else
LOADER = libloader.so
endif
DEPS += $(LOADER)
LIBS += $(LOADER)
endif
# Rules for binaries
ifeq ($(XASH_SINGLE_BINARY),0)
BINARIES = libxash.so
libxash.so : $(OBJS) $(OBJS_CPP) $(DEPS)
$(CC) -fvisibility=hidden -o libxash.so $(LDFLAGS) -shared $(OBJS) $(OBJS_CPP) $(LIBS)
else
BINARIES = xash
xash: $(OBJS) $(OBJS_CPP) $(DEPS)
ifeq ($(XASH_STATIC),1)
$(CC) -o xash -static $(LDFLAGS) $(OBJS) $(OBJS_CPP) $(LIBS)
else
$(CC) -o xash -fvisibility=hidden $(LDFLAGS) $(OBJS) $(OBJS_CPP) $(LIBS)
endif
endif
ifeq ($(XASH_DLL_LOADER),1)
$(LOADER):
$(MAKE) -f ../loader/Makefile.linux -C ../loader $(LOADER)
cp ../loader/$(LOADER) .
endif
# Create dirs for object files
DIRS := obj obj/server obj/client/avi obj/client/vgui obj/common/sdl obj/common/imagelib obj/common/soundlib/libmpg obj/platform/sdl obj/nanogl
$(OBJS): | $(DIRS)
$(DIRS) :
mkdir -p $(DIRS)
# Object rules
obj/%.o : %.c
$(CC) $(CFLAGS) $(INCLUDES) $(DEFINES) -c "$<" -o "$@" -Wno-unused-result -fvisibility=hidden
obj/%.o : %.cpp
$(CXX) $(CFLAGS) $(INCLUDES) $(DEFINES) -c "$<" -o "$@"
default: $(BINARIES)
.PHONY: depend clean list install
clean:
$(RM) $(OBJS) $(OBJS_CPP) $(BINARIES) ../loader/*.o ../loader/*.a ../loader/*.so $(LOADER)
list:
@echo Sources:
@echo $(SRCS)
@echo C++ Sources:
@echo $(SRCS_CPP)
@echo Objects:
@echo $(OBJS) $(OBJS_CPP)
@echo Dirs:
@echo $(DIRS)
@echo Dependencies:
@echo $(DEPS)
# Simple install rule
install: $(BINARIES)
mkdir -p $(INSTALL_DIR)
ifeq ($(XASH_SINGLE_BINARY),1)
cp xash $(INSTALL_DIR)/xash_bin
else
cp libxash.so $(INSTALL_DIR)/
cp libloader.so $(INSTALL_DIR)/
endif

View File

@@ -1,269 +0,0 @@
**Table of Contents** *generated with [DocToc](http://doctoc.herokuapp.com/)*
- [Building](#building)
- [Manual build (without CMake)](#manual-build-without-cmake)
- [Building Engine](#building-engine)
- [Building launch binary](#building-launch-binary)
- [Building on Windows](#building-on-windows)
- [Visual Studio 2013 (recommended for Windows)](#visual-studio-2013-recommended-for-windows)
- [Visual Studio 6](#visual-studio-6)
- [MinGW](#mingw)
- [Building Game mods](#building-game-mods)
- [Linux](#linux)
- [microndk](#microndk)
- [Makefile.linux](#makefile-linux)
- [Windows](#windows)
- [Running](#running)
- [Manual running](#manual-running)
- [Running with GDB](#running-with-gdb)
- [Using DLL Loader](#using-dll-loader)
- [Running MinGW builds](#running-mingw-builds)
- [Running MinGW builds under GDB](#running-mingw-builds-under-gdb)
# Building
## Manual build (without CMake)
### Building engine
Clone Xash3D repository using git:
git clone https://github.com/FWGS/xash3d
Move to the Xash3D folder:
cd xash3d/engine
make -f Makefile.linux XASH_VGUI=1
or same for dedicated
make -f Makefile.linux XASH_DEDICATED=1
To enable dll support on linux, build loader library:
cd ../loader
make -f Makefile.linux libloader.so libloader.a
cp libloader.so libloader.a ../engine/
And built engine with XASH_DLL_LOADER=1:
cd ../engine
make -f Makefile.linux XASH_VGUI=1 XASH_SDL=1 XASH_DLL_LOADER=1
or same for dedicated server
cd ../engine
make -f Makefile.linux XASH_DEDICATED=1 XASH_DLL_LOADER=1
### Building engine in separate library
Some old distros does not support hidden symbol visibility
This results in crash when loading server library
Building launch binary
cd (xash3d)/game_launch
gcc xash.c -o xash -ldl -lrt -lm
Building engine library:
make -f Makefile.linux XASH_SINGLE_BINARY=0
## Building on Windows
### Visual Studio 2013 (recommended for Windows)
Download latest prebuilt SDL2 from
https://www.libsdl.org/release/SDL2-devel-2.0.4-VC.zip
Unzip and rename `SDL2-2.0.4` folder to `SDL2` and put it next to xash3d project folder.
..\xash3d\
..\SDL2\
Open `xash.sln` with Visual Studio 2013 and make a build. After building, copy contents of `Debug` or
`Release` folder to directory you choose. Copy `valve` folder and `vgui.dll` from your Half Life game
installation folder and `SDL2.dll` form `\SDL2\lib\x86\` to it.
Move `vgui_support.dll` into `valve` folder.
..\valve\
..\valve\vgui_support.dll
..\menu.dll
..\SDL2.dll
..\vgui.dll
..\xash.dll
..\xash.exe
Now you good to go, just run `xash.exe`.
### Visual Studio 6
This is legacy configuration, but msvc6 seems to generate more stable and more effective code
Setup your msvc6 enviroment, unpack SDL2-2.0.4 to xash3d folder and do:
cd (xash3d)\engine
..\msvc6\build.bat
cd (xash3d)\game_launch
..\msvc6\build_launch.bat
### MinGW
The most effective configuration, but maybe unstable.
Setup your MinGW environment and run:
cd (xash3d)\engine\
CC=gcc mingw32-make -f Makefile.mingw
engine will be built to single exe binary
## Building game mods
### Linux
#### microndk
All mods that ported to android may be build to linux using Android.mk with microndk:
[https://github.com/SDLash3D/microndk]
Clone microndk repo somewhere, change xash3d_config to preffered configuration (change arch to x86
for example)
Go to dlls folder if you are building server or cl_dlls if you are building client and do:
make -f /path/to/microndk/microndk.mk -j4
Do:
make -f /path/to/microndk/microndk.mk -j4 clean
every time when you build client after building server
#### Makefile.linux
### Windows
On windows common way is using Visual Studio as many mods does not correctly work with mingw.
Just open project and build it.
Other is using mingw and microndk, but it was not tested yet.
hlsdk-xash3d based mods may work fine with mingw.
You may use microndk to build it. Build process is very similar to linux one.
After setting up MinGW enviroment, do:<br>
`mingw32-make -f \path\to\microndk\Microndk.mk`
to build 64-bit library, use:<br>
`mingw32-make -f \path\to\microndk\Microndk.mk 64BIT=1`
Edit xash3d_config.mk to set optimal CFLAGS if you are running server
# Running
Copy **valve** folder from Half-Life:
cp -r $HOME/.steam/steam/steamapps/common/Half-Life/valve $HOME/Games/Xash3D
**NOTE**: If you build with CMake, you can now use `make install`. It will install binaries where
they must be located. So just run `xash3d` from command line in directory where is gamedata is located.
For additional info look to the CMakeLists.txt in repo root and xash3d.sh script.
After a successful build, copy the next files to some other directory where you want to run Xash3D:
cp engine/libxash.so game_launch/xash3d mainui/libxashmenu.so $HOME/Games/Xash3D
If you built it with XASH_VGUI, also copy vgui.so:
cp ../hlsdk/linux/vgui.so vgui_support/libvgui_support.so $HOME/Games/Xash3D
Copy script:
cp ../xash3d.sh $HOME/Games/Xash3D
Run:
cd $HOME/Games/Xash3D
./xash3d.sh
## Manual running
Put xash3d binaries and vgui(optionally) to you game data directory and run:
LD_LIBRARY_PATH=. ./xash -dev 5
## Running under GDB
LD_LIBRARY_PATH=. gdb --args ./xash -dev 5
## Using DLL Loader
Put vgui_support.dll from windows build to your game data folder and run:
LD_LIBRARY_PATH=. ./xash -dev 5 -vguilib vgui.dll -clientlib valve/cl_dlls/client.dll -dll dlls/hl.dll
## Running MinGW builds
Put exe file to your game data directory
cd (game)\
xash_bin -dev 5
### Running MinGW builds under GDB
gdb --args ./xash_bin.exe -dev 5
# Useful GDB commands
Start or restart process:
(gdb) r
Show backtrace:
(gdb) bt
Full backtrace:
(gdb) bt full
Continue execution:
(gdb) c
Recover from segmentation fault:
Skipping function:
(gdb) handle SIGSEGV nopass
(gdb) ret
(gdb) c
Restart frame for beginning:
(gdb) handle SIGSEGV nopass
(gdb) jump *Host_AbortCurrentFrame
Anti-Crash script (useful for scripting servers):
```
cd /path/to/rootdir
file xash
set args xash -dev 5 -nowcon
handle SIGSEGV nopass
catch signal SIGSEGV
set $crashes=0
commands
print $crashes++
if $crashes > 500
set $crashes=0
run
else
jump *Host_AbortCurrentFrame
end
end
run
```

View File

@@ -1,7 +0,0 @@
#!/bin/sh
SCRIPTDIR=$(dirname "$0")
TOPDIR=$SCRIPTDIR/../../
cp $SCRIPTDIR/Makefile.dllloader $TOPDIR/loader/
cp $SCRIPTDIR/Makefile.emscripten $TOPDIR/engine/
cp $SCRIPTDIR/Makefile.linux $TOPDIR/engine/
cp $SCRIPTDIR/wscript $TOPDIR/engine/

View File

@@ -1,73 +0,0 @@
#! /usr/bin/env python
# encoding: utf-8
# mittorn, 2018
VERSION='0.99'
APPNAME='xash3d-fwgs'
top = '.'
def options(opt):
opt.load('compiler_c')
# opt.load('msvs')
opt.add_option('--dedicated', action = 'store_true', help = 'build dedicated server only' )
opt.add_option('--64bits', dest = 'amd64', action = 'store_true', help = 'build 64-bit engine on x86_64' )
def configure(conf):
conf.load('compiler_c')
conf.env.append_unique('CFLAGS', '-O2')
conf.env.append_unique('DEFINES', 'SINGLE_BINARY')
conf.env.append_value('LINKFLAGS', '-ldl')
conf.env.append_value('LINKFLAGS', '-lm')
conf.env.append_value('LINKFLAGS', '-pthread')
# check for 64-bit builds
# TODO: check 32-bit toolchain and dependencies
if conf.env.DEST_CPU == 'x86_64' and not conf.options.amd64:
conf.env.append_value('LINKFLAGS', '-m32')
conf.env.append_value('CFLAGS', '-m32')
print('NOTE: will build engine with 64-bit toolchain using -m32')
else:
print('Warning: 64bit engine may be unstable')
# check for dedicated server build
if conf.options.dedicated:
conf.env.append_unique('DEFINES', 'XASH_DEDICATED')
conf.env.dedicated = True
else:
# TODO: add way to specify SDL2 path, move to separate function
try:
conf.check_cfg(path='sdl2-config', args='--cflags --libs', package='', msg='Checking for SDL2', uselib_store='SDL2')
except conf.errors.ConfigurationError:
conf.fatal('SDL2 not availiable! If you want to build dedicated server, specify --dedicated')
conf.env.append_unique('DEFINES', 'XASH_SDL')
def build(bld):
# basic build: dedicated only, no dependencies
use = [];
source = bld.path.ant_glob([
'common/*.c',
'common/imagelib/*.c',
'common/soundlib/*.c',
'common/soundlib/libmpg/*.c',
'server/*.c'])
# add client files and sdl2 library
if not bld.env.dedicated:
use += ['SDL2']
source += bld.path.ant_glob([
'client/*.c',
'client/vgui/*.c',
'client/avi/*.c',
'platform/sdl/*.c'])
bld(
target = 'xash',
features = 'c cprogram',
includes = ['../common', '../pm_shared', 'common', 'server', 'client', 'client/vgui', '.' ],
source = source,
use = use
)

View File

@@ -16,6 +16,10 @@
#ifndef ALIAS_H
#define ALIAS_H
#include "build.h"
#include STDINT_H
#include "synctype.h"
/*
==============================================================================
@@ -39,16 +43,6 @@ Alias models are position independent, so the cache manager can move them.
#define ALIAS_TRACER2 0x0040 // orange split trail + rotate
#define ALIAS_TRACER3 0x0080 // purple trail
// must match definition in sprite.h
#ifndef SYNCTYPE_T
#define SYNCTYPE_T
typedef enum
{
ST_SYNC = 0,
ST_RAND
} synctype_t;
#endif
typedef enum
{
ALIAS_SINGLE = 0,
@@ -63,36 +57,42 @@ typedef enum
typedef struct
{
int ident;
int version;
int32_t ident;
int32_t version;
vec3_t scale;
vec3_t scale_origin;
float boundingradius;
vec3_t eyeposition;
int numskins;
int skinwidth;
int skinheight;
int numverts;
int numtris;
int numframes;
synctype_t synctype;
int flags;
int32_t numskins;
int32_t skinwidth;
int32_t skinheight;
int32_t numverts;
int32_t numtris;
int32_t numframes;
uint32_t synctype; // was synctype_t
int32_t flags;
float size;
} daliashdr_t;
STATIC_ASSERT( sizeof( daliashdr_t ) == 84, "invalid daliashdr_t size" );
typedef struct
{
int onseam;
int s;
int t;
int32_t onseam;
int32_t s;
int32_t t;
} stvert_t;
STATIC_ASSERT( sizeof( stvert_t ) == 12, "invalid stvert_t size" );
typedef struct dtriangle_s
{
int facesfront;
int vertindex[3];
int32_t facesfront;
int32_t vertindex[3];
} dtriangle_t;
STATIC_ASSERT( sizeof( dtriangle_t ) == 16, "invalid dtriangle_t size" );
#define DT_FACES_FRONT 0x0010
#define ALIAS_ONSEAM 0x0020
@@ -103,36 +103,50 @@ typedef struct
char name[16]; // frame name from grabbing
} daliasframe_t;
STATIC_ASSERT( sizeof( daliasframe_t ) == 24, "invalid daliasframe_t size" );
typedef struct
{
int numframes;
int32_t numframes;
trivertex_t bboxmin; // lightnormal isn't used
trivertex_t bboxmax; // lightnormal isn't used
} daliasgroup_t;
STATIC_ASSERT( sizeof( daliasgroup_t ) == 12, "invalid daliasgrou_t size" );
typedef struct
{
int numskins;
int32_t numskins;
} daliasskingroup_t;
STATIC_ASSERT( sizeof( daliasskingroup_t ) == 4, "invalid daliasskingroup_t size" );
typedef struct
{
float interval;
} daliasinterval_t;
STATIC_ASSERT( sizeof( daliasinterval_t ) == 4, "invalid daliasinterval_t size" );
typedef struct
{
float interval;
} daliasskininterval_t;
STATIC_ASSERT( sizeof( daliasskininterval_t ) == 4, "invalid daliasskininterval_t size" );
typedef struct
{
aliasframetype_t type;
uint32_t type; // was aliasframetype_t
} daliasframetype_t;
STATIC_ASSERT( sizeof( daliasframetype_t ) == 4, "invalid daliasframetype_t size" );
typedef struct
{
aliasskintype_t type;
uint32_t type; // was aliasskintype_t
} daliasskintype_t;
STATIC_ASSERT( sizeof( daliasskintype_t ) == 4, "invalid daliasskintype_t size" );
#endif//ALIAS_H

View File

@@ -27,7 +27,6 @@ int AVI_GetAudioChunk( movie_state_t *Avi, char *audiodata, int offset, int leng
void AVI_OpenVideo( movie_state_t *Avi, const char *filename, qboolean load_audio, int quiet );
movie_state_t *AVI_LoadVideo( const char *filename, qboolean load_audio );
int AVI_TimeToSoundPosition( movie_state_t *Avi, int time );
int AVI_GetVideoFrameCount( movie_state_t *Avi );
void AVI_CloseVideo( movie_state_t *Avi );
qboolean AVI_IsActive( movie_state_t *Avi );
void AVI_FreeVideo( movie_state_t *Avi );

View File

@@ -57,11 +57,6 @@ int AVI_TimeToSoundPosition( movie_state_t *Avi, int time )
return 0;
}
int AVI_GetVideoFrameCount( movie_state_t *Avi )
{
return 0;
}
void AVI_CloseVideo( movie_state_t *Avi )
{
;

View File

@@ -1,5 +1,6 @@
/*
avi_win.c - playing AVI files (based on original AVIKit code, Win32 version)
Copyright (c) 2003-2004, Ruari O'Sullivan
Copyright (C) 2010 Uncle Mike
This program is free software: you can redistribute it and/or modify
@@ -63,7 +64,7 @@ static int (_stdcall *pAVIStreamTimeToSample)( PAVISTREAM pavi, LONG lTime );
static void* (_stdcall *pAVIStreamGetFrame)( PGETFRAME pg, LONG lPos );
static int (_stdcall *pAVIStreamGetFrameClose)( PGETFRAME pg );
static dword (_stdcall *pAVIStreamRelease)( PAVISTREAM pavi );
static int (_stdcall *pAVIFileOpen)( PAVIFILE *ppfile, LPCSTR szFile, UINT uMode, LPCLSID lpHandler );
static int (_stdcall *pAVIFileOpenW)( PAVIFILE *ppfile, LPCWSTR szFile, UINT uMode, LPCLSID lpHandler );
static int (_stdcall *pAVIFileGetStream)( PAVIFILE pfile, PAVISTREAM *ppavi, DWORD fccType, LONG lParam );
static int (_stdcall *pAVIStreamReadFormat)( PAVISTREAM pavi, LONG lPos,LPVOID lpFormat, LONG *lpcbFormat );
static int (_stdcall *pAVIStreamStart)( PAVISTREAM pavi );
@@ -76,7 +77,7 @@ static dllfunc_t avifile_funcs[] =
{ "AVIFileExit", (void **) &pAVIFileExit },
{ "AVIFileGetStream", (void **) &pAVIFileGetStream },
{ "AVIFileInit", (void **) &pAVIFileInit },
{ "AVIFileOpenA", (void **) &pAVIFileOpen },
{ "AVIFileOpenW", (void **) &pAVIFileOpenW },
{ "AVIFileRelease", (void **) &pAVIFileRelease },
{ "AVIStreamGetFrame", (void **) &pAVIStreamGetFrame },
{ "AVIStreamGetFrameClose", (void **) &pAVIStreamGetFrameClose },
@@ -278,14 +279,6 @@ int AVI_GetVideoFrameNumber( movie_state_t *Avi, float time )
return (time * Avi->video_fps);
}
int AVI_GetVideoFrameCount( movie_state_t *Avi )
{
if( !Avi->active )
return 0;
return Avi->video_frames;
}
int AVI_TimeToSoundPosition( movie_state_t *Avi, int time )
{
if( !Avi->active || !Avi->audio_stream )
@@ -493,6 +486,7 @@ void AVI_OpenVideo( movie_state_t *Avi, const char *filename, qboolean load_audi
AVISTREAMINFO stream_info;
int opened_streams = 0;
LONG hr;
wchar_t pathBuffer[MAX_PATH];
// default state: non-working.
Avi->active = false;
@@ -501,8 +495,15 @@ void AVI_OpenVideo( movie_state_t *Avi, const char *filename, qboolean load_audi
// can't load Video For Windows :-(
if( !avi_initialized ) return;
// convert to wide char
if( MultiByteToWideChar( CP_UTF8, 0, filename, -1, pathBuffer, ARRAYSIZE( pathBuffer )) <= 0 )
{
Con_DPrintf( S_ERROR "filename buffer limit exceeded\n" );
return;
}
// load the AVI
hr = pAVIFileOpen( &Avi->pfile, filename, OF_SHARE_DENY_WRITE, 0L );
hr = pAVIFileOpenW( &Avi->pfile, pathBuffer, OF_SHARE_DENY_WRITE, 0L );
if( hr != 0 ) // error opening AVI:
{
@@ -657,7 +658,7 @@ movie_state_t *AVI_LoadVideo( const char *filename, qboolean load_audio )
// open cinematic
Q_snprintf( path, sizeof( path ), "media/%s", filename );
COM_DefaultExtension( path, ".avi" );
COM_DefaultExtension( path, ".avi", sizeof( path ));
fullpath = FS_GetDiskPath( path, false );
if( FS_FileExists( path, false ) && !fullpath )

View File

@@ -145,7 +145,7 @@ void CL_PlayCDTrack_f( void )
CL_ScreenshotGetName
==================
*/
qboolean CL_ScreenshotGetName( int lastnum, char *filename )
static qboolean CL_ScreenshotGetName( int lastnum, char *filename, size_t size )
{
if( lastnum < 0 || lastnum > 9999 )
{
@@ -153,9 +153,7 @@ qboolean CL_ScreenshotGetName( int lastnum, char *filename )
return false;
}
Q_sprintf( filename, "scrshots/%s_shot%04d.png", clgame.mapname, lastnum );
return true;
return Q_snprintf( filename, size, "scrshots/%s_shot%04d.png", clgame.mapname, lastnum ) > 0;
}
/*
@@ -163,7 +161,7 @@ qboolean CL_ScreenshotGetName( int lastnum, char *filename )
CL_SnapshotGetName
==================
*/
qboolean CL_SnapshotGetName( int lastnum, char *filename )
static qboolean CL_SnapshotGetName( int lastnum, char *filename, size_t size )
{
if( lastnum < 0 || lastnum > 9999 )
{
@@ -172,9 +170,7 @@ qboolean CL_SnapshotGetName( int lastnum, char *filename )
return false;
}
Q_sprintf( filename, "../%s_%04d.png", clgame.mapname, lastnum );
return true;
return Q_snprintf( filename, size, "../%s_%04d.png", clgame.mapname, lastnum ) > 0;
}
/*
@@ -207,10 +203,10 @@ void CL_ScreenShot_f( void )
// scan for a free filename
for( i = 0; i < 9999; i++ )
{
if( !CL_ScreenshotGetName( i, checkname ))
if( !CL_ScreenshotGetName( i, checkname, sizeof( checkname )))
return; // no namespace
if( !FS_FileExists( checkname, false ))
if( !FS_FileExists( checkname, true ))
break;
}
@@ -247,10 +243,10 @@ void CL_SnapShot_f( void )
// scan for a free filename
for( i = 0; i < 9999; i++ )
{
if( !CL_SnapshotGetName( i, checkname ))
if( !CL_SnapshotGetName( i, checkname, sizeof( checkname )))
return; // no namespace
if( !FS_FileExists( checkname, false ))
if( !FS_FileExists( checkname, true ))
break;
}
@@ -278,7 +274,7 @@ void CL_EnvShot_f( void )
return;
}
Q_sprintf( cls.shotname, "gfx/env/%s", Cmd_Argv( 1 ));
Q_snprintf( cls.shotname, sizeof( cls.shotname ), "gfx/env/%s", Cmd_Argv( 1 ));
cls.scrshot_action = scrshot_envshot; // build new frame for envshot
cls.envshot_vieworg = NULL; // no custom view
cls.envshot_viewsize = 0;
@@ -299,7 +295,7 @@ void CL_SkyShot_f( void )
return;
}
Q_sprintf( cls.shotname, "gfx/env/%s", Cmd_Argv( 1 ));
Q_snprintf( cls.shotname, sizeof( cls.shotname ),"gfx/env/%s", Cmd_Argv( 1 ));
cls.scrshot_action = scrshot_skyshot; // build new frame for skyshot
cls.envshot_vieworg = NULL; // no custom view
cls.envshot_viewsize = 0;
@@ -323,7 +319,8 @@ void CL_LevelShot_f( void )
// check for exist
if( cls.demoplayback && ( cls.demonum != -1 ))
{
Q_sprintf( cls.shotname, "levelshots/%s_%s.bmp", cls.demoname, refState.wideScreen ? "16x9" : "4x3" );
Q_snprintf( cls.shotname, sizeof( cls.shotname ),
"levelshots/%s_%s.bmp", cls.demoname, refState.wideScreen ? "16x9" : "4x3" );
Q_snprintf( filename, sizeof( filename ), "%s.dem", cls.demoname );
// make sure what levelshot is newer than demo
@@ -332,7 +329,8 @@ void CL_LevelShot_f( void )
}
else
{
Q_sprintf( cls.shotname, "levelshots/%s_%s.bmp", clgame.mapname, refState.wideScreen ? "16x9" : "4x3" );
Q_snprintf( cls.shotname, sizeof( cls.shotname ),
"levelshots/%s_%s.bmp", clgame.mapname, refState.wideScreen ? "16x9" : "4x3" );
// make sure what levelshot is newer than bsp
ft1 = FS_FileTime( cl.worldmodel->name, false );
@@ -360,7 +358,7 @@ void CL_SaveShot_f( void )
return;
}
Q_sprintf( cls.shotname, DEFAULT_SAVE_DIRECTORY "%s.bmp", Cmd_Argv( 1 ));
Q_snprintf( cls.shotname, sizeof( cls.shotname ), DEFAULT_SAVE_DIRECTORY "%s.bmp", Cmd_Argv( 1 ));
cls.scrshot_action = scrshot_savegame; // build new frame for saveshot
}

View File

@@ -78,7 +78,7 @@ qboolean CL_CheckFile( sizebuf_t *msg, resource_t *pResource )
}
MSG_BeginClientCmd( msg, clc_stringcmd );
MSG_WriteString( msg, va( "dlfile %s", filepath ));
MSG_WriteStringf( msg, "dlfile %s", filepath );
host.downloadcount++;
return false;

View File

@@ -25,70 +25,6 @@ GNU General Public License for more details.
#define MSG_COUNT 32 // last 32 messages parsed
#define MSG_MASK (MSG_COUNT - 1)
const char *svc_strings[svc_lastmsg+1] =
{
"svc_bad",
"svc_nop",
"svc_disconnect",
"svc_event",
"svc_changing",
"svc_setview",
"svc_sound",
"svc_time",
"svc_print",
"svc_stufftext",
"svc_setangle",
"svc_serverdata",
"svc_lightstyle",
"svc_updateuserinfo",
"svc_deltatable",
"svc_clientdata",
"svc_resource",
"svc_pings",
"svc_particle",
"svc_restoresound",
"svc_spawnstatic",
"svc_event_reliable",
"svc_spawnbaseline",
"svc_temp_entity",
"svc_setpause",
"svc_signonnum",
"svc_centerprint",
"svc_unused27",
"svc_unused28",
"svc_unused29",
"svc_intermission",
"svc_finale",
"svc_cdtrack",
"svc_restore",
"svc_cutscene",
"svc_weaponanim",
"svc_bspdecal",
"svc_roomtype",
"svc_addangle",
"svc_usermessage",
"svc_packetentities",
"svc_deltapacketentities",
"svc_choke",
"svc_resourcelist",
"svc_deltamovevars",
"svc_resourcerequest",
"svc_customization",
"svc_crosshairangle",
"svc_soundfade",
"svc_filetxferfailed",
"svc_hltv",
"svc_director",
"svc_voiceinit",
"svc_voicedata",
"svc_deltapacketbones",
"svc_unused55",
"svc_resourcelocation",
"svc_querycvarvalue",
"svc_querycvarvalue2",
"svc_exec",
};
typedef struct
{
int command;
@@ -109,7 +45,7 @@ const char *CL_MsgInfo( int cmd )
{
static string sz;
Q_strcpy( sz, "???" );
Q_strncpy( sz, "???", sizeof( sz ));
if( cmd >= 0 && cmd <= svc_lastmsg )
{

View File

@@ -372,7 +372,7 @@ void CL_WriteDemoHeader( const char *name )
demo.header.id = IDEMOHEADER;
demo.header.dem_protocol = DEMO_PROTOCOL;
demo.header.net_protocol = cls.legacymode ? PROTOCOL_LEGACY_VERSION : PROTOCOL_VERSION;
demo.header.host_fps = bound( MIN_FPS, host_maxfps->value, MAX_FPS );
demo.header.host_fps = bound( MIN_FPS, host_maxfps.value, MAX_FPS );
Q_strncpy( demo.header.mapname, clgame.mapname, sizeof( demo.header.mapname ));
Q_strncpy( demo.header.comment, clgame.maptitle, sizeof( demo.header.comment ));
Q_strncpy( demo.header.gamedir, FS_Gamedir(), sizeof( demo.header.gamedir ));
@@ -518,14 +518,26 @@ CL_ReadDemoCmdHeader
read the demo command
=================
*/
void CL_ReadDemoCmdHeader( byte *cmd, float *dt )
qboolean CL_ReadDemoCmdHeader( byte *cmd, float *dt )
{
// read the command
FS_Read( cls.demofile, cmd, sizeof( byte ));
Assert( *cmd >= 1 && *cmd <= dem_lastcmd );
// HACKHACK: skip NOPs
do
{
FS_Read( cls.demofile, cmd, sizeof( byte ));
} while( *cmd == dem_unknown );
if( *cmd > dem_lastcmd )
{
Con_Printf( S_ERROR "Demo cmd %d > %d, file offset = %d\n", *cmd, dem_lastcmd, (int)FS_Tell( cls.demofile ));
CL_DemoCompleted();
return false;
}
// read the timestamp
FS_Read( cls.demofile, dt, sizeof( float ));
return true;
}
/*
@@ -636,11 +648,13 @@ void CL_DemoStartPlayback( int mode )
{
if( cls.changedemo )
{
int maxclients = cl.maxclients;
S_StopAllSounds( true );
SCR_BeginLoadingPlaque( false );
CL_ClearState ();
CL_InitEdicts (); // re-arrange edicts
CL_ClearState( );
CL_InitEdicts( maxclients ); // re-arrange edicts
}
else
{
@@ -686,7 +700,7 @@ void CL_DemoAborted( void )
cls.demofile = NULL;
cls.demonum = -1;
Cvar_SetValue( "v_dark", 0.0f );
Cvar_DirectSet( &v_dark, "0" );
}
/*
@@ -704,7 +718,7 @@ void CL_DemoCompleted( void )
if( !CL_NextDemo() && !cls.changedemo )
UI_SetActiveMenu( true );
Cvar_SetValue( "v_dark", 0.0f );
Cvar_DirectSet( &v_dark, "0" );
}
/*
@@ -913,7 +927,8 @@ qboolean CL_DemoReadMessage( byte *buffer, size_t *length )
if( !cls.demofile ) break;
curpos = FS_Tell( cls.demofile );
CL_ReadDemoCmdHeader( &cmd, &demo.timestamp );
if( !CL_ReadDemoCmdHeader( &cmd, &demo.timestamp ))
return false;
fElapsedTime = CL_GetDemoPlaybackClock() - demo.starttime;
if( !cls.timedemo ) bSkipMessage = ((demo.timestamp - cl_serverframetime()) >= fElapsedTime) ? true : false;
@@ -1109,7 +1124,10 @@ void CL_FinishTimeDemo( void )
time = host.realtime - cls.td_starttime;
if( !time ) time = 1.0;
Con_Printf( "%i frames %5.3f seconds %5.3f fps\n", frames, time, frames / time );
Con_Printf( "timedemo result: %i frames %5.3f seconds %5.3f fps\n", frames, time, frames / time );
if( Sys_CheckParm( "-timedemo" ))
CL_Quit_f();
}
/*
@@ -1293,7 +1311,7 @@ void CL_CheckStartupDemos( void )
}
// run demos loop in background mode
Cvar_SetValue( "v_dark", 1.0f );
Cvar_DirectSet( &v_dark, "1" );
cls.demos_pending = false;
cls.demonum = 0;
CL_NextDemo ();
@@ -1304,16 +1322,16 @@ void CL_CheckStartupDemos( void )
CL_DemoGetName
==================
*/
static void CL_DemoGetName( int lastnum, char *filename )
static void CL_DemoGetName( int lastnum, char *filename, size_t size )
{
if( lastnum < 0 || lastnum > 9999 )
{
// bound
Q_strcpy( filename, "demo9999" );
Q_strncpy( filename, "demo9999", size );
return;
}
Q_sprintf( filename, "demo%04d", lastnum );
Q_snprintf( filename, size, "demo%04d", lastnum );
}
/*
@@ -1367,8 +1385,10 @@ void CL_Record_f( void )
// scan for a free filename
for( n = 0; n < 10000; n++ )
{
CL_DemoGetName( n, demoname );
if( !FS_FileExists( va( "%s.dem", demoname ), true ))
CL_DemoGetName( n, demoname, sizeof( demoname ));
Q_snprintf( demopath, sizeof( demopath ), "%s.dem", demoname );
if( !FS_FileExists( demopath, true ))
break;
}
@@ -1381,7 +1401,7 @@ void CL_Record_f( void )
else Q_strncpy( demoname, name, sizeof( demoname ));
// open the demo file
Q_sprintf( demopath, "%s.dem", demoname );
Q_snprintf( demopath, sizeof( demopath ), "%s.dem", demoname );
// make sure that old demo is removed
if( FS_FileExists( demopath, false ))
@@ -1408,7 +1428,7 @@ void CL_PlayDemo_f( void )
if( Cmd_Argc() < 2 )
{
Con_Printf( S_USAGE "playdemo <demoname>\n" );
Con_Printf( S_USAGE "%s <demoname>\n", Cmd_Argv( 0 ));
return;
}
@@ -1455,7 +1475,7 @@ void CL_PlayDemo_f( void )
{
int c, neg = false;
demo.header.host_fps = host_maxfps->value;
demo.header.host_fps = host_maxfps.value;
while(( c = FS_Getc( cls.demofile )) != '\n' )
{
@@ -1535,12 +1555,6 @@ timedemo <demoname>
*/
void CL_TimeDemo_f( void )
{
if( Cmd_Argc() != 2 )
{
Con_Printf( S_USAGE "timedemo <demoname>\n" );
return;
}
CL_PlayDemo_f ();
// cls.td_starttime will be grabbed at the second frame of the demo, so

View File

@@ -33,46 +33,6 @@ static mnode_t *r_pefragtopnode;
static vec3_t r_emins, r_emaxs;
static cl_entity_t *r_addent;
/*
================
R_RemoveEfrags
Call when removing an object from the world or moving it to another position
================
*/
void R_RemoveEfrags( cl_entity_t *ent )
{
efrag_t *ef, *old, *walk, **prev;
ef = ent->efrag;
while( ef )
{
prev = &ef->leaf->efrags;
while( 1 )
{
walk = *prev;
if( !walk ) break;
if( walk == ef )
{
// remove this fragment
*prev = ef->leafnext;
break;
}
else prev = &walk->leafnext;
}
old = ef;
ef = ef->entnext;
// put it on the free list
old->entnext = clgame.free_efrags;
clgame.free_efrags = old;
}
ent->efrag = NULL;
}
/*
===================
R_SplitEntityOnNode

View File

@@ -6,7 +6,7 @@
#include "r_efx.h"
#include "cl_tent.h"
#include "pm_local.h"
#define PART_SIZE Q_max( 0.5f, cl_draw_particles->value )
#define PART_SIZE Q_max( 0.5f, cl_draw_particles.value )
/*
==============================================================
@@ -21,9 +21,9 @@ static int ramp2[8] = { 0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x68, 0x66 };
static int ramp3[6] = { 0x6d, 0x6b, 6, 5, 4, 3 };
static int gSparkRamp[9] = { 0xfe, 0xfd, 0xfc, 0x6f, 0x6e, 0x6d, 0x6c, 0x67, 0x60 };
convar_t *tracerspeed;
convar_t *tracerlength;
convar_t *traceroffset;
static CVAR_DEFINE_AUTO( tracerspeed, "6000", 0, "tracer speed" );
static CVAR_DEFINE_AUTO( tracerlength, "0.8", 0, "tracer length factor" );
static CVAR_DEFINE_AUTO( traceroffset, "30", 0, "tracer starting offset" );
particle_t *cl_active_particles;
particle_t *cl_active_tracers;
@@ -100,9 +100,9 @@ void CL_InitParticles( void )
cl_avelocities[i][2] = COM_RandomFloat( 0.0f, 2.55f );
}
tracerspeed = Cvar_Get( "tracerspeed", "6000", 0, "tracer speed" );
tracerlength = Cvar_Get( "tracerlength", "0.8", 0, "tracer length factor" );
traceroffset = Cvar_Get( "traceroffset", "30", 0, "tracer starting offset" );
Cvar_RegisterVariable( &tracerspeed );
Cvar_RegisterVariable( &tracerlength );
Cvar_RegisterVariable( &traceroffset );
}
/*
@@ -140,26 +140,6 @@ void CL_FreeParticles( void )
cl_particles = NULL;
}
/*
================
CL_FreeParticle
move particle to freelist
================
*/
void CL_FreeParticle( particle_t *p )
{
if( p->deathfunc )
{
// call right the deathfunc before die
p->deathfunc( p );
p->deathfunc = NULL;
}
p->next = cl_free_particles;
cl_free_particles = p;
}
/*
================
CL_AllocParticleFast
@@ -191,7 +171,7 @@ particle_t * GAME_EXPORT R_AllocParticle( void (*callback)( particle_t*, float )
{
particle_t *p;
if( !cl_draw_particles->value )
if( !cl_draw_particles.value )
return NULL;
// never alloc particles when we not in game
@@ -242,7 +222,7 @@ particle_t *R_AllocTracer( const vec3_t org, const vec3_t vel, float life )
{
particle_t *p;
if( !cl_draw_tracers->value )
if( !cl_draw_tracers.value )
return NULL;
// never alloc particles when we not in game
@@ -269,7 +249,7 @@ particle_t *R_AllocTracer( const vec3_t org, const vec3_t vel, float life )
VectorCopy( org, p->org );
VectorCopy( vel, p->vel );
p->die = cl.time + life;
p->ramp = tracerlength->value;
p->ramp = tracerlength.value;
p->color = 4; // select custom color
p->packedColor = 255; // alpha
@@ -1256,12 +1236,15 @@ R_BloodStream
particle spray 2
===============
*/
void GAME_EXPORT R_BloodStream( const vec3_t org, const vec3_t dir, int pcolor, int speed )
void GAME_EXPORT R_BloodStream( const vec3_t org, const vec3_t ndir, int pcolor, int speed )
{
particle_t *p;
int i, j;
float arc;
int accel = speed; // must be integer due to bug in GoldSrc
vec3_t dir;
VectorNormalize2( ndir, dir );
for( arc = 0.05f, i = 0; i < 100; i++ )
{
@@ -1824,14 +1807,14 @@ void GAME_EXPORT R_TracerEffect( const vec3_t start, const vec3_t end )
float len, speed;
float offset;
speed = Q_max( tracerspeed->value, 3.0f );
speed = Q_max( tracerspeed.value, 3.0f );
VectorSubtract( end, start, dir );
len = VectorLength( dir );
if( len == 0.0f ) return;
VectorScale( dir, 1.0f / len, dir ); // normalize
offset = COM_RandomFloat( -10.0f, 9.0f ) + traceroffset->value;
offset = COM_RandomFloat( -10.0f, 9.0f ) + traceroffset.value;
VectorScale( dir, offset, vel );
VectorAdd( start, vel, pos );
VectorScale( dir, speed, vel );
@@ -2087,16 +2070,16 @@ void CL_FreeDeadBeams( void )
void CL_DrawEFX( float time, qboolean fTrans )
{
CL_FreeDeadBeams();
if( CVAR_TO_BOOL( cl_draw_beams ))
if( cl_draw_beams.value )
ref.dllFuncs.CL_DrawBeams( fTrans, cl_active_beams );
if( fTrans )
{
R_FreeDeadParticles( &cl_active_particles );
if( CVAR_TO_BOOL( cl_draw_particles ))
if( cl_draw_particles.value )
ref.dllFuncs.CL_DrawParticles( time, cl_active_particles, PART_SIZE );
R_FreeDeadParticles( &cl_active_tracers );
if( CVAR_TO_BOOL( cl_draw_tracers ))
if( cl_draw_tracers.value )
ref.dllFuncs.CL_DrawTracers( time, cl_active_tracers );
}
}

View File

@@ -84,7 +84,7 @@ void CL_DescribeEvent( event_info_t *ei, int slot )
con_nprint_t info;
string origin_str = { 0 }; //, angles_str = { 0 };
if( !cl_showevents->value )
if( !cl_showevents.value )
return;
info.time_to_live = 1.0f;
@@ -225,6 +225,18 @@ qboolean CL_FireEvent( event_info_t *ei, int slot )
if( ev->index == ei->index )
{
name = cl.event_precache[ei->index];
if( cl_trace_events.value )
{
Con_Printf( "^3EVENT %s AT %.2f %.2f %.2f\n" // event name
"\t%.2f %.2f %i %i %s %s\n", // bool params
name, ei->args.origin[0], ei->args.origin[1], ei->args.origin[2],
ei->args.fparam1, ei->args.fparam2,
ei->args.iparam1, ei->args.iparam2,
ei->args.bparam1 ? "TRUE" : "FALSE", ei->args.bparam2 ? "TRUE" : "FALSE" );
}
if( ev->func )
{
CL_DescribeEvent( ei, slot );
@@ -232,7 +244,6 @@ qboolean CL_FireEvent( event_info_t *ei, int slot )
return true;
}
name = cl.event_precache[ei->index];
Con_Reportf( S_ERROR "CL_FireEvent: %s not hooked\n", name );
break;
}

350
engine/client/cl_font.c Normal file
View File

@@ -0,0 +1,350 @@
/*
cl_font.c - bare bones engine font manager
Copyright (C) 2023 Alibek Omarov
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#include "common.h"
#include "filesystem.h"
#include "client.h"
#include "qfont.h"
qboolean CL_FixedFont( cl_font_t *font )
{
return font && font->valid && font->type == FONT_FIXED;
}
static int CL_LoadFontTexture( const char *fontname, uint texFlags, int *width )
{
int font_width;
int tex;
if( !g_fsapi.FileExists( fontname, false ))
return 0;
tex = ref.dllFuncs.GL_LoadTexture( fontname, NULL, 0, texFlags );
if( !tex )
return 0;
font_width = REF_GET_PARM( PARM_TEX_WIDTH, tex );
if( !font_width )
{
ref.dllFuncs.GL_FreeTexture( tex );
return 0;
}
*width = font_width;
return tex;
}
qboolean Con_LoadFixedWidthFont( const char *fontname, cl_font_t *font, float scale, int rendermode, uint texFlags )
{
int font_width, i;
if( font->valid )
return true; // already loaded
font->hFontTexture = CL_LoadFontTexture( fontname, texFlags, &font_width );
if( !font->hFontTexture )
return false;
font->type = FONT_FIXED;
font->valid = true;
font->scale = scale;
font->nearest = FBitSet( texFlags, TF_NEAREST );
font->rendermode = rendermode;
font->charHeight = Q_rint( font_width / 16 * scale );
for( i = 0; i < ARRAYSIZE( font->fontRc ); i++ )
{
font->fontRc[i].left = ( i * font_width / 16 ) % font_width;
font->fontRc[i].right = font->fontRc[i].left + font_width / 16;
font->fontRc[i].top = ( i / 16 ) * ( font_width / 16 );
font->fontRc[i].bottom = font->fontRc[i].top + font_width / 16;
font->charWidths[i] = Q_rint( font_width / 16 * scale );
}
return true;
}
qboolean Con_LoadVariableWidthFont( const char *fontname, cl_font_t *font, float scale, int rendermode, uint texFlags )
{
fs_offset_t length;
qfont_t src;
byte *pfile;
int font_width, i;
if( font->valid )
return true;
pfile = g_fsapi.LoadFile( fontname, &length, false );
if( !pfile )
return false;
if( length < sizeof( src ))
{
Mem_Free( pfile );
return false;
}
memcpy( &src, pfile, sizeof( src ));
Mem_Free( pfile );
font->hFontTexture = CL_LoadFontTexture( fontname, texFlags, &font_width );
if( !font->hFontTexture )
return false;
font->type = FONT_VARIABLE;
font->valid = true;
font->scale = scale;
font->nearest = FBitSet( texFlags, TF_NEAREST );
font->rendermode = rendermode;
font->charHeight = Q_rint( src.rowheight * scale );
for( i = 0; i < ARRAYSIZE( font->fontRc ); i++ )
{
const charinfo *ci = &src.fontinfo[i];
font->fontRc[i].left = (word)ci->startoffset % font_width;
font->fontRc[i].right = font->fontRc[i].left + ci->charwidth;
font->fontRc[i].top = (word)ci->startoffset / font_width;
font->fontRc[i].bottom = font->fontRc[i].top + src.rowheight;
font->charWidths[i] = Q_rint( src.fontinfo[i].charwidth * scale );
}
return true;
}
void CL_FreeFont( cl_font_t *font )
{
if( !font || !font->valid )
return;
ref.dllFuncs.GL_FreeTexture( font->hFontTexture );
memset( font, 0, sizeof( *font ));
}
static int CL_CalcTabStop( const cl_font_t *font, int x )
{
int space = font->charWidths[' '];
int tab = space * 6; // 6 spaces
int stop = tab - x % tab;
if( stop < space )
return tab * 2 - x % tab; // select next
return stop;
}
int CL_DrawCharacter( float x, float y, int number, rgba_t color, cl_font_t *font, int flags )
{
wrect_t *rc;
float w, h;
float s1, t1, s2, t2, half = 0.5f;
int texw, texh;
if( !font || !font->valid || y < -font->charHeight )
return 0;
// check if printable
if( number <= 32 )
{
if( number == ' ' )
return font->charWidths[' '];
else if( number == '\t' )
return CL_CalcTabStop( font, x );
return 0;
}
if( FBitSet( flags, FONT_DRAW_UTF8 ))
number = Con_UtfProcessChar( number & 255 );
else number &= 255;
if( !number || !font->charWidths[number])
return 0;
R_GetTextureParms( &texw, &texh, font->hFontTexture );
if( !texw || !texh )
return font->charWidths[number];
rc = &font->fontRc[number];
if( font->nearest || font->scale <= 1.0f )
half = 0;
s1 = ((float)rc->left + half ) / texw;
t1 = ((float)rc->top + half ) / texh;
s2 = ((float)rc->right - half ) / texw;
t2 = ((float)rc->bottom - half ) / texh;
w = ( rc->right - rc->left ) * font->scale;
h = ( rc->bottom - rc->top ) * font->scale;
if( FBitSet( flags, FONT_DRAW_HUD ))
SPR_AdjustSize( &x, &y, &w, &h );
if( !FBitSet( flags, FONT_DRAW_NORENDERMODE ))
ref.dllFuncs.GL_SetRenderMode( font->rendermode );
// don't apply color to fixed fonts it's already colored
if( font->type != FONT_FIXED || REF_GET_PARM( PARM_TEX_GLFORMAT, font->hFontTexture ) == 0x8045 ) // GL_LUMINANCE8_ALPHA8
ref.dllFuncs.Color4ub( color[0], color[1], color[2], color[3] );
else ref.dllFuncs.Color4ub( 255, 255, 255, color[3] );
ref.dllFuncs.R_DrawStretchPic( x, y, w, h, s1, t1, s2, t2, font->hFontTexture );
return font->charWidths[number];
}
int CL_DrawString( float x, float y, const char *s, rgba_t color, cl_font_t *font, int flags )
{
rgba_t current_color;
int draw_len = 0;
if( !font || !font->valid )
return 0;
if( FBitSet( flags, FONT_DRAW_UTF8 ))
Con_UtfProcessChar( 0 ); // clear utf state
if( !FBitSet( flags, FONT_DRAW_NORENDERMODE ))
ref.dllFuncs.GL_SetRenderMode( font->rendermode );
Vector4Copy( color, current_color );
while( *s )
{
if( *s == '\n' )
{
s++;
if( !*s )
break;
// some client functions ignore newlines
if( !FBitSet( flags, FONT_DRAW_NOLF ))
{
draw_len = 0;
y += font->charHeight;
}
if( FBitSet( flags, FONT_DRAW_RESETCOLORONLF ))
Vector4Copy( color, current_color );
continue;
}
if( IsColorString( s ))
{
// don't copy alpha
if( !FBitSet( flags, FONT_DRAW_FORCECOL ))
VectorCopy( g_color_table[ColorIndex(*( s + 1 ))], current_color );
s += 2;
continue;
}
// skip setting rendermode, it was changed for this string already
draw_len += CL_DrawCharacter( x + draw_len, y, (byte)*s, current_color, font, flags | FONT_DRAW_NORENDERMODE );
s++;
}
return draw_len;
}
int CL_DrawStringf( cl_font_t *font, float x, float y, rgba_t color, int flags, const char *fmt, ... )
{
va_list va;
char buf[MAX_VA_STRING];
va_start( va, fmt );
Q_vsnprintf( buf, sizeof( buf ), fmt, va );
va_end( va );
return CL_DrawString( x, y, buf, color, font, flags );
}
void CL_DrawCharacterLen( cl_font_t *font, int number, int *width, int *height )
{
if( !font || !font->valid ) return;
if( width )
{
if( number == '\t' )
*width = CL_CalcTabStop( font, 0 ); // at least return max tabstop
else *width = font->charWidths[number & 255];
}
if( height ) *height = font->charHeight;
}
void CL_DrawStringLen( cl_font_t *font, const char *s, int *width, int *height, int flags )
{
int draw_len = 0;
if( !font || !font->valid )
return;
if( height )
*height = font->charHeight;
if( width )
*width = 0;
if( !COM_CheckString( s ))
return;
if( FBitSet( flags, FONT_DRAW_UTF8 ))
Con_UtfProcessChar( 0 ); // reset utf state
while( *s )
{
int number;
if( *s == '\n' )
{
// BUG: no check for end string here
// but high chances somebody's relying on this
s++;
draw_len = 0;
if( !FBitSet( flags, FONT_DRAW_NOLF ))
{
if( height )
*height += font->charHeight;
}
continue;
}
else if( *s == '\t' )
{
draw_len += CL_CalcTabStop( font, 0 ); // at least return max tabstop
s++;
continue;
}
if( IsColorString( s ))
{
s += 2;
continue;
}
if( FBitSet( flags, FONT_DRAW_UTF8 ))
number = Con_UtfProcessChar( (byte)*s );
else number = (byte)*s;
if( number )
{
draw_len += font->charWidths[number];
if( draw_len > *width )
*width = draw_len;
}
s++;
}
}

View File

@@ -134,7 +134,7 @@ some ents will be ignore lerping
*/
qboolean CL_EntityIgnoreLerp( cl_entity_t *e )
{
if( cl_nointerp->value > 0.f )
if( cl_nointerp.value > 0.f )
return true;
if( e->model && e->model->type == mod_alias )
@@ -241,7 +241,7 @@ CL_GetStudioEstimatedFrame
====================
*/
float CL_GetStudioEstimatedFrame( cl_entity_t *ent )
static float CL_GetStudioEstimatedFrame( cl_entity_t *ent )
{
studiohdr_t *pstudiohdr;
mstudioseqdesc_t *pseqdesc;
@@ -255,7 +255,7 @@ float CL_GetStudioEstimatedFrame( cl_entity_t *ent )
{
sequence = bound( 0, ent->curstate.sequence, pstudiohdr->numseq - 1 );
pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + sequence;
return ref.dllFuncs.R_StudioEstimateFrame( ent, pseqdesc );
return ref.dllFuncs.R_StudioEstimateFrame( ent, pseqdesc, cl.time );
}
}
@@ -464,13 +464,13 @@ int CL_InterpolateModel( cl_entity_t *e )
if( cl.maxclients <= 1 )
return 1;
if( e->model->type == mod_brush && !cl_bmodelinterp->value )
if( e->model->type == mod_brush && !cl_bmodelinterp.value )
return 1;
if( cl.local.moving && cl.local.onground == e->index )
return 1;
t = cl.time - cl_interp->value;
t = cl.time - cl_interp.value;
CL_FindInterpolationUpdates( e, t, &ph0, &ph1 );
if( ph0 == NULL || ph1 == NULL )
@@ -537,7 +537,7 @@ void CL_ComputePlayerOrigin( cl_entity_t *ent )
if( !ent->player )
return;
if( cl_nointerp->value > 0.f )
if( cl_nointerp.value > 0.f )
{
VectorCopy( ent->curstate.angles, ent->angles );
VectorCopy( ent->curstate.origin, ent->origin );
@@ -555,7 +555,7 @@ void CL_ComputePlayerOrigin( cl_entity_t *ent )
return;
}
targettime = cl.time - cl_interp->value;
targettime = cl.time - cl_interp.value;
CL_PureOrigin( ent, targettime, origin, angles );
VectorCopy( angles, ent->angles );
@@ -654,6 +654,24 @@ FRAME PARSING
=========================================================================
*/
static qboolean CL_ParseEntityNumFromPacket( sizebuf_t *msg, int *newnum )
{
if( cls.legacymode )
{
*newnum = MSG_ReadWord( msg );
if( *newnum == 0 )
return false;
}
else
{
*newnum = MSG_ReadUBitLong( msg, MAX_ENTITY_BITS );
if( *newnum == LAST_EDICT )
return false;
}
return true;
}
/*
=================
CL_FlushEntityPacket
@@ -674,8 +692,8 @@ void CL_FlushEntityPacket( sizebuf_t *msg )
// read it all, but ignore it
while( 1 )
{
newnum = MSG_ReadUBitLong( msg, MAX_ENTITY_BITS );
if( newnum == LAST_EDICT ) break; // done
if( !CL_ParseEntityNumFromPacket( msg, &newnum ))
break; // done
if( MSG_CheckOverflow( msg ))
Host_Error( "CL_FlushEntityPacket: overflow\n" );
@@ -847,21 +865,12 @@ int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta )
while( 1 )
{
int lastedict;
if( cls.legacymode )
{
newnum = MSG_ReadWord( msg );
lastedict = 0;
}
else
{
newnum = MSG_ReadUBitLong( msg, MAX_ENTITY_BITS );
lastedict = LAST_EDICT;
}
if( !CL_ParseEntityNumFromPacket( msg, &newnum ))
break; // done
if( newnum == lastedict ) break; // end of packet entities
if( MSG_CheckOverflow( msg ))
Host_Error( "CL_ParsePacketEntities: overflow\n" );
player = CL_IsPlayerIndex( newnum );
while( oldnum < newnum )
@@ -970,9 +979,25 @@ all the visible entities should pass this filter
*/
qboolean CL_AddVisibleEntity( cl_entity_t *ent, int entityType )
{
qboolean draw_player = true;
if( !ent || !ent->model )
return false;
// don't add the player in firstperson mode
if( RP_LOCALCLIENT( ent ))
{
cl.local.apply_effects = true;
if( !CL_IsThirdPerson( ) && ( ent->index == cl.viewentity ))
{
// we don't draw player in default renderer in firstperson mode
// but let the client.dll know about player entity anyway
// for use in custom renderers
draw_player = false;
}
}
// check for adding this entity
if( !clgame.dllFuncs.pfnAddEntity( entityType, ent, ent->model->name ))
{
@@ -982,14 +1007,8 @@ qboolean CL_AddVisibleEntity( cl_entity_t *ent, int entityType )
return false;
}
// don't add the player in firstperson mode
if( RP_LOCALCLIENT( ent ))
{
cl.local.apply_effects = true;
if( !CL_IsThirdPerson( ) && ( ent->index == cl.viewentity ))
return false;
}
if( !draw_player )
return false;
if( entityType == ET_BEAM )
{

File diff suppressed because it is too large Load Diff

View File

@@ -309,7 +309,7 @@ static void GAME_EXPORT UI_DrawLogo( const char *filename, float x, float y, flo
// run cinematic if not
Q_snprintf( path, sizeof( path ), "media/%s", filename );
COM_DefaultExtension( path, ".avi" );
COM_DefaultExtension( path, ".avi", sizeof( path ));
fullpath = FS_GetDiskPath( path, false );
if( FS_FileExists( path, false ) && !fullpath )
@@ -421,54 +421,6 @@ static void UI_ConvertGameInfo( GAMEINFO *out, gameinfo_t *in )
out->flags |= GFL_RENDER_PICBUTTON_TEXT;
}
static qboolean PIC_Scissor( float *x, float *y, float *width, float *height, float *u0, float *v0, float *u1, float *v1 )
{
float dudx, dvdy;
// clip sub rect to sprite
if(( width == 0 ) || ( height == 0 ))
return false;
if( *x + *width <= gameui.ds.scissor_x )
return false;
if( *x >= gameui.ds.scissor_x + gameui.ds.scissor_width )
return false;
if( *y + *height <= gameui.ds.scissor_y )
return false;
if( *y >= gameui.ds.scissor_y + gameui.ds.scissor_height )
return false;
dudx = (*u1 - *u0) / *width;
dvdy = (*v1 - *v0) / *height;
if( *x < gameui.ds.scissor_x )
{
*u0 += (gameui.ds.scissor_x - *x) * dudx;
*width -= gameui.ds.scissor_x - *x;
*x = gameui.ds.scissor_x;
}
if( *x + *width > gameui.ds.scissor_x + gameui.ds.scissor_width )
{
*u1 -= (*x + *width - (gameui.ds.scissor_x + gameui.ds.scissor_width)) * dudx;
*width = gameui.ds.scissor_x + gameui.ds.scissor_width - *x;
}
if( *y < gameui.ds.scissor_y )
{
*v0 += (gameui.ds.scissor_y - *y) * dvdy;
*height -= gameui.ds.scissor_y - *y;
*y = gameui.ds.scissor_y;
}
if( *y + *height > gameui.ds.scissor_y + gameui.ds.scissor_height )
{
*v1 -= (*y + *height - (gameui.ds.scissor_y + gameui.ds.scissor_height)) * dvdy;
*height = gameui.ds.scissor_y + gameui.ds.scissor_height - *y;
}
return true;
}
/*
====================
PIC_DrawGeneric
@@ -487,10 +439,10 @@ static void PIC_DrawGeneric( float x, float y, float width, float height, const
if( prc )
{
// calc user-defined rectangle
s1 = (float)prc->left / (float)w;
t1 = (float)prc->top / (float)h;
s2 = (float)prc->right / (float)w;
t2 = (float)prc->bottom / (float)h;
s1 = prc->left / (float)w;
t1 = prc->top / (float)h;
s2 = prc->right / (float)w;
t2 = prc->bottom / (float)h;
if( width == -1 && height == -1 )
{
@@ -511,10 +463,9 @@ static void PIC_DrawGeneric( float x, float y, float width, float height, const
}
// pass scissor test if supposed
if( gameui.ds.scissor_test && !PIC_Scissor( &x, &y, &width, &height, &s1, &t1, &s2, &t2 ))
if( !CL_Scissor( &gameui.ds.scissor, &x, &y, &width, &height, &s1, &t1, &s2, &t2 ))
return;
PicAdjustSize( &x, &y, &width, &height );
ref.dllFuncs.R_DrawStretchPic( x, y, width, height, s1, t1, s2, t2, gameui.ds.gl_texturenum );
ref.dllFuncs.Color4ub( 255, 255, 255, 255 );
}
@@ -659,11 +610,7 @@ static void GAME_EXPORT pfnPIC_EnableScissor( int x, int y, int width, int heigh
width = bound( 0, width, gameui.globals->scrWidth - x );
height = bound( 0, height, gameui.globals->scrHeight - y );
gameui.ds.scissor_x = x;
gameui.ds.scissor_width = width;
gameui.ds.scissor_y = y;
gameui.ds.scissor_height = height;
gameui.ds.scissor_test = true;
CL_EnableScissor( &gameui.ds.scissor, x, y, width, height );
}
/*
@@ -674,11 +621,7 @@ pfnPIC_DisableScissor
*/
static void GAME_EXPORT pfnPIC_DisableScissor( void )
{
gameui.ds.scissor_x = 0;
gameui.ds.scissor_width = 0;
gameui.ds.scissor_y = 0;
gameui.ds.scissor_height = 0;
gameui.ds.scissor_test = false;
CL_DisableScissor( &gameui.ds.scissor );
}
/*
@@ -699,6 +642,17 @@ static void GAME_EXPORT pfnFillRGBA( int x, int y, int width, int height, int r,
ref.dllFuncs.Color4ub( 255, 255, 255, 255 );
}
/*
=============
pfnCvar_RegisterVariable
=============
*/
static cvar_t *GAME_EXPORT pfnCvar_RegisterGameUIVariable( const char *szName, const char *szValue, int flags )
{
return (cvar_t *)Cvar_Get( szName, szValue, flags|FCVAR_GAMEUIDLL, Cvar_BuildAutoDescription( szName, flags|FCVAR_GAMEUIDLL ));
}
/*
=============
pfnClientCmd
@@ -766,7 +720,7 @@ static void GAME_EXPORT pfnDrawCharacter( int ix, int iy, int iwidth, int iheigh
t2 = t1 + size;
// pass scissor test if supposed
if( gameui.ds.scissor_test && !PIC_Scissor( &x, &y, &width, &height, &s1, &t1, &s2, &t2 ))
if( !CL_Scissor( &gameui.ds.scissor, &x, &y, &width, &height, &s1, &t1, &s2, &t2 ))
return;
ref.dllFuncs.GL_SetRenderMode( kRenderTransTexture );
@@ -895,7 +849,7 @@ send client connect
*/
static void GAME_EXPORT pfnClientJoin( const netadr_t adr )
{
Cbuf_AddText( va( "connect %s\n", NET_AdrToString( adr )));
Cbuf_AddTextf( "connect %s\n", NET_AdrToString( adr ));
}
/*
@@ -1028,28 +982,21 @@ pfnCheckGameDll
*/
int GAME_EXPORT pfnCheckGameDll( void )
{
string dllpath;
void *hInst;
#if TARGET_OS_IPHONE
// loading server library drains too many ram
// so 512MB iPod Touch cannot even connect to
// to servers in cstrike
#if XASH_INTERNAL_GAMELIBS
return true;
#endif
#else
string dllpath;
if( svgame.hInstance )
return true;
COM_GetCommonLibraryPath( LIBRARY_SERVER, dllpath, sizeof( dllpath ));
if(( hInst = COM_LoadLibrary( dllpath, true, false )) != NULL )
{
COM_FreeLibrary( hInst ); // don't increase linker's reference counter
if( FS_FileExists( dllpath, false ))
return true;
}
Con_Reportf( S_WARN "Could not load server library: %s\n", COM_GetLibraryError() );
return false;
#endif
}
/*
@@ -1262,7 +1209,8 @@ static ui_extendedfuncs_t gExtendedfuncs =
pfnGetRenderers,
Sys_DoubleTime,
pfnParseFileSafe,
NET_AdrToString
NET_AdrToString,
NET_CompareAdrSort,
};
void UI_UnloadProgs( void )
@@ -1274,12 +1222,12 @@ void UI_UnloadProgs( void )
Cvar_FullSet( "host_gameuiloaded", "0", FCVAR_READ_ONLY );
Cvar_Unlink( FCVAR_GAMEUIDLL );
Cmd_Unlink( CMD_GAMEUIDLL );
COM_FreeLibrary( gameui.hInstance );
Mem_FreePool( &gameui.mempool );
memset( &gameui, 0, sizeof( gameui ));
Cvar_Unlink( FCVAR_GAMEUIDLL );
Cmd_Unlink( CMD_GAMEUIDLL );
}
qboolean UI_LoadProgs( void )

File diff suppressed because it is too large Load Diff

View File

@@ -20,14 +20,17 @@ GNU General Public License for more details.
#include "input.h"
#include "platform/platform.h"
mobile_engfuncs_t *gMobileEngfuncs;
static mobile_engfuncs_t *gMobileEngfuncs;
convar_t *vibration_length;
convar_t *vibration_enable;
static CVAR_DEFINE_AUTO( vibration_length, "1.0", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "vibration length" );
static CVAR_DEFINE_AUTO( vibration_enable, "1", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "enable vibration" );
static cl_font_t g_scaled_font;
static float g_font_scale;
static void pfnVibrate( float life, char flags )
{
if( !vibration_enable->value )
if( !vibration_enable.value )
return;
if( life < 0.0f )
@@ -39,7 +42,7 @@ static void pfnVibrate( float life, char flags )
//Con_Reportf( "Vibrate: %f %d\n", life, flags );
// here goes platform-specific backends
Platform_Vibrate( life * vibration_length->value, flags );
Platform_Vibrate( life * vibration_length.value, flags );
}
static void Vibrate_f( void )
@@ -60,28 +63,28 @@ static void pfnEnableTextInput( int enable )
static int pfnDrawScaledCharacter( int x, int y, int number, int r, int g, int b, float scale )
{
int width = clgame.scrInfo.charWidths[number] * scale * hud_scale->value;
int height = clgame.scrInfo.iCharHeight * scale * hud_scale->value;
// this call is very ineffective and possibly broken!
rgba_t color = { r, g, b, 255 };
int flags = FONT_DRAW_HUD;
if( !cls.creditsFont.valid )
return 0;
if( hud_utf8.value )
SetBits( flags, FONT_DRAW_UTF8 );
x *= hud_scale->value;
y *= hud_scale->value;
if( fabs( g_font_scale - scale ) > 0.1f ||
g_scaled_font.hFontTexture != cls.creditsFont.hFontTexture )
{
int i;
number &= 255;
number = Con_UtfProcessChar( number );
g_scaled_font = cls.creditsFont;
g_scaled_font.scale *= scale;
g_scaled_font.charHeight *= scale;
for( i = 0; i < ARRAYSIZE( g_scaled_font.charWidths ); i++ )
g_scaled_font.charWidths[i] *= scale;
if( number < 32 )
return 0;
g_font_scale = scale;
}
if( y < -height )
return 0;
pfnPIC_Set( cls.creditsFont.hFontTexture, r, g, b, 255 );
pfnPIC_DrawAdditive( x, y, width, height, &cls.creditsFont.fontRc[number] );
return width;
return CL_DrawCharacter( x, y, number, color, &g_scaled_font, flags );
}
static void *pfnGetNativeObject( const char *obj )
@@ -139,8 +142,8 @@ qboolean Mobile_Init( void )
success = true;
Cmd_AddCommand( "vibrate", (xcommand_t)Vibrate_f, "Vibrate for specified time");
vibration_length = Cvar_Get( "vibration_length", "1.0", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "Vibration length");
vibration_enable = Cvar_Get( "vibration_enable", "1", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "Enable vibration");
Cvar_RegisterVariable( &vibration_length );
Cvar_RegisterVariable( &vibration_enable );
return success;
}

View File

@@ -33,12 +33,12 @@ GNU General Public License for more details.
#define NETGRAPH_NET_COLORS 5
#define NUM_LATENCY_SAMPLES 8
convar_t *net_graph;
static convar_t *net_graphpos;
static convar_t *net_graphwidth;
static convar_t *net_graphheight;
static convar_t *net_graphsolid;
static convar_t *net_scale;
CVAR_DEFINE_AUTO( net_graph, "0", FCVAR_ARCHIVE, "draw network usage graph" );
static CVAR_DEFINE_AUTO( net_graphpos, "1", FCVAR_ARCHIVE, "network usage graph position" );
static CVAR_DEFINE_AUTO( net_scale, "5", FCVAR_ARCHIVE, "network usage graph scale level" );
static CVAR_DEFINE_AUTO( net_graphwidth, "192", FCVAR_ARCHIVE, "network usage graph width" );
static CVAR_DEFINE_AUTO( net_graphheight, "64", FCVAR_ARCHIVE, "network usage graph height" );
static CVAR_DEFINE_AUTO( net_graphsolid, "1", FCVAR_ARCHIVE, "fill segments in network usage graph" );
static struct packet_latency_t
{
@@ -211,7 +211,7 @@ static void NetGraph_GetFrameData( float *latency, int *latency_count )
else
{
int frame_latency = Q_min( 1.0f, f->latency );
p->latency = (( frame_latency + 0.1f ) / 1.1f ) * ( net_graphheight->value - NETGRAPH_LERP_HEIGHT - 2 );
p->latency = (( frame_latency + 0.1f ) / 1.1f ) * ( net_graphheight.value - NETGRAPH_LERP_HEIGHT - 2 );
if( i > cls.netchan.incoming_sequence - NUM_LATENCY_SAMPLES )
{
@@ -260,7 +260,7 @@ static void NetGraph_DrawTimes( wrect_t rect, int x, int w )
for( a = 0; a < w; a++ )
{
i = ( cls.netchan.outgoing_sequence - a ) & NET_TIMINGS_MASK;
h = Q_min(( netstat_cmdinfo[i].cmd_lerp / 3.0f ) * NETGRAPH_LERP_HEIGHT, net_graphheight->value * 0.7f);
h = Q_min(( netstat_cmdinfo[i].cmd_lerp / 3.0f ) * NETGRAPH_LERP_HEIGHT, net_graphheight.value * 0.7f);
fill.left = x + w - a - 1;
fill.right = fill.bottom = 1;
@@ -273,7 +273,7 @@ static void NetGraph_DrawTimes( wrect_t rect, int x, int w )
h -= extrap_point;
fill.top -= extrap_point;
if( !net_graphsolid->value )
if( !net_graphsolid.value )
{
fill.top -= (h - 1);
start = (h - 1);
@@ -281,7 +281,10 @@ static void NetGraph_DrawTimes( wrect_t rect, int x, int w )
for( j = start; j < h; j++ )
{
NetGraph_DrawRect( &fill, netcolors[NETGRAPH_NET_COLORS + j + extrap_point] );
int color = NETGRAPH_NET_COLORS + j + extrap_point;
color = Q_min( color, ARRAYSIZE( netcolors ) - 1 );
NetGraph_DrawRect( &fill, netcolors[color] );
fill.top--;
}
}
@@ -292,12 +295,15 @@ static void NetGraph_DrawTimes( wrect_t rect, int x, int w )
fill.top -= h;
h = extrap_point - h;
if( !net_graphsolid->value )
if( !net_graphsolid.value )
h = 1;
for( j = 0; j < h; j++ )
{
NetGraph_DrawRect( &fill, netcolors[NETGRAPH_NET_COLORS + j + oldh] );
int color = NETGRAPH_NET_COLORS + j + oldh;
color = Q_min( color, ARRAYSIZE( netcolors ) - 1 );
NetGraph_DrawRect( &fill, netcolors[color] );
fill.top--;
}
}
@@ -328,7 +334,7 @@ NetGraph_DrawHatches
*/
static void NetGraph_DrawHatches( int x, int y )
{
int ystep = (int)( 10.0f / net_scale->value );
int ystep = (int)( 10.0f / net_scale.value );
byte colorminor[4] = { 0, 63, 63, 200 };
byte color[4] = { 0, 200, 0, 255 };
wrect_t hatch = { x, 4, y, 1 };
@@ -336,9 +342,9 @@ static void NetGraph_DrawHatches( int x, int y )
ystep = Q_max( ystep, 1 );
for( starty = hatch.top; hatch.top > 0 && ((starty - hatch.top) * net_scale->value < (maxmsgbytes + 50)); hatch.top -= ystep )
for( starty = hatch.top; hatch.top > 0 && ((starty - hatch.top) * net_scale.value < (maxmsgbytes + 50)); hatch.top -= ystep )
{
if(!((int)((starty - hatch.top) * net_scale->value ) % 50 ))
if(!((int)((starty - hatch.top) * net_scale.value ) % 50 ))
{
NetGraph_DrawRect( &hatch, color );
}
@@ -358,19 +364,20 @@ NetGraph_DrawTextFields
static void NetGraph_DrawTextFields( int x, int y, int w, wrect_t rect, int count, float avg, int packet_loss, int packet_choke, int graphtype )
{
static int lastout;
cl_font_t *font = Con_GetFont( 0 );
rgba_t colors = { 0.9 * 255, 0.9 * 255, 0.7 * 255, 255 };
int ptx = Q_max( x + w - NETGRAPH_LERP_HEIGHT - 1, 1 );
int pty = Q_max( rect.top + rect.bottom - NETGRAPH_LERP_HEIGHT - 3, 1 );
int out, i = ( cls.netchan.outgoing_sequence - 1 ) & NET_TIMINGS_MASK;
int j = cls.netchan.incoming_sequence & NET_TIMINGS_MASK;
int last_y = y - net_graphheight->value;
int last_y = y - net_graphheight.value;
if( count > 0 )
{
avg = avg / (float)( count - ( host.frametime * FRAMERATE_AVG_FRAC ));
if( cl_updaterate->value > 0.0f )
avg -= 1000.0f / cl_updaterate->value;
if( cl_updaterate.value > 0.0f )
avg -= 1000.0f / cl_updaterate.value;
// can't be below zero
avg = Q_max( 0.0f, avg );
@@ -379,16 +386,17 @@ static void NetGraph_DrawTextFields( int x, int y, int w, wrect_t rect, int coun
// move rolling average
framerate = FRAMERATE_AVG_FRAC * host.frametime + ( 1.0f - FRAMERATE_AVG_FRAC ) * framerate;
Con_SetFont( 0 );
ref.dllFuncs.GL_SetRenderMode( font->rendermode );
if( framerate > 0.0f )
{
y -= net_graphheight->value;
y -= net_graphheight.value;
Con_DrawString( x, y, va( "%.1f fps" , 1.0f / framerate ), colors );
CL_DrawStringf( font, x, y, colors, FONT_DRAW_NORENDERMODE, "%.1f fps" , 1.0f / framerate);
if( avg > 1.0f )
Con_DrawString( x + 75, y, va( "%i ms" , (int)avg ), colors );
CL_DrawStringf( font, x + 75, y, colors, FONT_DRAW_NORENDERMODE, "%i ms" , (int)avg );
y += 15;
@@ -396,10 +404,12 @@ static void NetGraph_DrawTextFields( int x, int y, int w, wrect_t rect, int coun
if( !out ) out = lastout;
else lastout = out;
Con_DrawString( x, y, va( "in : %i %.2f kb/s", netstat_graph[j].msgbytes, cls.netchan.flow[FLOW_INCOMING].avgkbytespersec ), colors );
CL_DrawStringf( font, x, y, colors, FONT_DRAW_NORENDERMODE,
"in : %i %.2f kb/s", netstat_graph[j].msgbytes, cls.netchan.flow[FLOW_INCOMING].avgkbytespersec );
y += 15;
Con_DrawString( x, y, va( "out: %i %.2f kb/s", out, cls.netchan.flow[FLOW_OUTGOING].avgkbytespersec ), colors );
CL_DrawStringf( font, x, y, colors, FONT_DRAW_NORENDERMODE,
"out: %i %.2f kb/s", out, cls.netchan.flow[FLOW_OUTGOING].avgkbytespersec );
y += 15;
if( graphtype > 2 )
@@ -407,16 +417,14 @@ static void NetGraph_DrawTextFields( int x, int y, int w, wrect_t rect, int coun
int loss = (int)(( packet_loss + PACKETLOSS_AVG_FRAC ) - 0.01f );
int choke = (int)(( packet_choke + PACKETCHOKE_AVG_FRAC ) - 0.01f );
Con_DrawString( x, y, va( "loss: %i choke: %i", loss, choke ), colors );
CL_DrawStringf( font, x, y, colors, FONT_DRAW_NORENDERMODE, "loss: %i choke: %i", loss, choke );
}
}
if( graphtype < 3 )
Con_DrawString( ptx, pty, va( "%i/s", (int)cl_cmdrate->value ), colors );
CL_DrawStringf( font, ptx, pty, colors, FONT_DRAW_NORENDERMODE, "%i/s", (int)cl_cmdrate.value );
Con_DrawString( ptx, last_y, va( "%i/s" , (int)cl_updaterate->value ), colors );
Con_RestoreFont();
CL_DrawStringf( font, ptx, last_y, colors, FONT_DRAW_NORENDERMODE, "%i/s" , (int)cl_updaterate.value );
}
/*
@@ -427,12 +435,12 @@ NetGraph_DrawDataSegment
*/
static int NetGraph_DrawDataSegment( wrect_t *fill, int bytes, byte r, byte g, byte b, byte a )
{
float h = bytes / net_scale->value;
float h = bytes / net_scale.value;
byte colors[4] = { r, g, b, a };
fill->top -= (int)h;
if( net_graphsolid->value )
if( net_graphsolid.value )
fill->bottom = (int)h;
else fill->bottom = 1;
@@ -490,7 +498,7 @@ NetGraph_DrawDataUsage
static void NetGraph_DrawDataUsage( int x, int y, int w, int graphtype )
{
int a, i, h, lastvalidh = 0, ping;
int pingheight = net_graphheight->value - NETGRAPH_LERP_HEIGHT - 2;
int pingheight = net_graphheight.value - NETGRAPH_LERP_HEIGHT - 2;
wrect_t fill = { 0 };
byte color[4];
@@ -546,7 +554,7 @@ static void NetGraph_DrawDataUsage( int x, int y, int w, int graphtype )
continue;
color[0] = color[1] = color[2] = color[3] = 255;
fill.top = y - net_graphheight->value - 1;
fill.top = y - net_graphheight.value - 1;
fill.bottom = 1;
if( NetGraph_AtEdge( a, w ))
@@ -581,7 +589,7 @@ static void NetGraph_DrawDataUsage( int x, int y, int w, int graphtype )
if( !NetGraph_DrawDataSegment( &fill, netstat_graph[i].voicebytes, 255, 255, 255, 255 ))
continue;
fill.top = y - net_graphheight->value - 1;
fill.top = y - net_graphheight.value - 1;
fill.bottom = 1;
fill.top -= 2;
@@ -590,7 +598,7 @@ static void NetGraph_DrawDataUsage( int x, int y, int w, int graphtype )
}
if( graphtype >= 2 )
NetGraph_DrawHatches( x, y - net_graphheight->value - 1 );
NetGraph_DrawHatches( x, y - net_graphheight.value - 1 );
}
/*
@@ -605,12 +613,12 @@ static void NetGraph_GetScreenPos( wrect_t *rect, int *w, int *x, int *y )
rect->right = refState.width;
rect->bottom = refState.height;
*w = Q_min( NET_TIMINGS, net_graphwidth->value );
*w = Q_min( NET_TIMINGS, net_graphwidth.value );
if( rect->right < *w + 10 )
*w = rect->right - 10;
// detect x and y position
switch( (int)net_graphpos->value )
switch( (int)net_graphpos.value )
{
case 1: // right sided
*x = rect->left + rect->right - 5 - *w;
@@ -653,16 +661,16 @@ void SCR_DrawNetGraph( void )
{
graphtype = 2;
}
else if( net_graph->value != 0.0f )
else if( net_graph.value != 0.0f )
{
graphtype = (int)net_graph->value;
graphtype = (int)net_graph.value;
}
else
{
return;
}
if( net_scale->value <= 0 )
if( net_scale.value <= 0 )
Cvar_SetValue( "net_scale", 0.1f );
NetGraph_GetScreenPos( &rect, &w, &x, &y );
@@ -689,12 +697,12 @@ void SCR_DrawNetGraph( void )
void CL_InitNetgraph( void )
{
net_graph = Cvar_Get( "net_graph", "0", FCVAR_ARCHIVE, "draw network usage graph" );
net_graphpos = Cvar_Get( "net_graphpos", "1", FCVAR_ARCHIVE, "network usage graph position" );
net_scale = Cvar_Get( "net_scale", "5", FCVAR_ARCHIVE, "network usage graph scale level" );
net_graphwidth = Cvar_Get( "net_graphwidth", "192", FCVAR_ARCHIVE, "network usage graph width" );
net_graphheight = Cvar_Get( "net_graphheight", "64", FCVAR_ARCHIVE, "network usage graph height" );
net_graphsolid = Cvar_Get( "net_graphsolid", "1", FCVAR_ARCHIVE, "fill segments in network usage graph" );
Cvar_RegisterVariable( &net_graph );
Cvar_RegisterVariable( &net_graphpos );
Cvar_RegisterVariable( &net_scale );
Cvar_RegisterVariable( &net_graphwidth );
Cvar_RegisterVariable( &net_graphheight );
Cvar_RegisterVariable( &net_graphsolid );
packet_loss = packet_choke = 0.0;
NetGraph_InitColors();

File diff suppressed because it is too large Load Diff

705
engine/client/cl_parse_48.c Normal file
View File

@@ -0,0 +1,705 @@
/*
cl_parse.c - parse a message received from the server
Copyright (C) 2008 Uncle Mike
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#include "common.h"
#include "client.h"
#include "net_encode.h"
#include "particledef.h"
#include "cl_tent.h"
#include "shake.h"
#include "hltv.h"
#include "input.h"
/*
==================
CL_ParseStaticEntity
static client entity
==================
*/
void CL_LegacyParseStaticEntity( sizebuf_t *msg )
{
int i;
entity_state_t state;
cl_entity_t *ent;
memset( &state, 0, sizeof( state ));
state.modelindex = MSG_ReadShort( msg );
state.sequence = MSG_ReadByte( msg );
state.frame = MSG_ReadByte( msg );
state.colormap = MSG_ReadWord( msg );
state.skin = MSG_ReadByte( msg );
for( i = 0; i < 3; i++ )
{
state.origin[i] = MSG_ReadCoord( msg );
state.angles[i] = MSG_ReadBitAngle( msg, 16 );
}
state.rendermode = MSG_ReadByte( msg );
if( state.rendermode != kRenderNormal )
{
state.renderamt = MSG_ReadByte( msg );
state.rendercolor.r = MSG_ReadByte( msg );
state.rendercolor.g = MSG_ReadByte( msg );
state.rendercolor.b = MSG_ReadByte( msg );
state.renderfx = MSG_ReadByte( msg );
}
i = clgame.numStatics;
if( i >= MAX_STATIC_ENTITIES )
{
Con_Printf( S_ERROR "MAX_STATIC_ENTITIES limit exceeded!\n" );
return;
}
ent = &clgame.static_entities[i];
clgame.numStatics++;
// all states are same
ent->baseline = ent->curstate = ent->prevstate = state;
ent->index = 0; // static entities doesn't has the numbers
// statics may be respawned in game e.g. for demo recording
if( cls.state == ca_connected || cls.state == ca_validate )
ent->trivial_accept = INVALID_HANDLE;
// setup the new static entity
VectorCopy( ent->curstate.origin, ent->origin );
VectorCopy( ent->curstate.angles, ent->angles );
ent->model = CL_ModelHandle( state.modelindex );
ent->curstate.framerate = 1.0f;
CL_ResetLatchedVars( ent, true );
if( ent->curstate.rendermode == kRenderNormal && ent->model != NULL )
{
// auto 'solid' faces
if( FBitSet( ent->model->flags, MODEL_TRANSPARENT ) && Host_IsQuakeCompatible( ))
{
ent->curstate.rendermode = kRenderTransAlpha;
ent->curstate.renderamt = 255;
}
}
R_AddEfrags( ent ); // add link
}
void CL_LegacyParseSoundPacket( sizebuf_t *msg, qboolean is_ambient )
{
vec3_t pos;
int chan, sound;
float volume, attn;
int flags, pitch, entnum;
sound_t handle = 0;
flags = MSG_ReadWord( msg );
if( flags & SND_LEGACY_LARGE_INDEX )
{
sound = MSG_ReadWord( msg );
flags &= ~SND_LEGACY_LARGE_INDEX;
}
else
sound = MSG_ReadByte( msg );
chan = MSG_ReadByte( msg );
if( FBitSet( flags, SND_VOLUME ))
volume = (float)MSG_ReadByte( msg ) / 255.0f;
else volume = VOL_NORM;
if( FBitSet( flags, SND_ATTENUATION ))
attn = (float)MSG_ReadByte( msg ) / 64.0f;
else attn = ATTN_NONE;
if( FBitSet( flags, SND_PITCH ))
pitch = MSG_ReadByte( msg );
else pitch = PITCH_NORM;
// entity reletive
entnum = MSG_ReadWord( msg );
// positioned in space
MSG_ReadVec3Coord( msg, pos );
if( FBitSet( flags, SND_SENTENCE ))
{
char sentenceName[32];
//if( FBitSet( flags, SND_SEQUENCE ))
//Q_snprintf( sentenceName, sizeof( sentenceName ), "!#%i", sound + MAX_SOUNDS );
//else
Q_snprintf( sentenceName, sizeof( sentenceName ), "!%i", sound );
handle = S_RegisterSound( sentenceName );
}
else handle = cl.sound_index[sound]; // see precached sound
if( !cl.audio_prepped )
return; // too early
// g-cont. sound and ambient sound have only difference with channel
if( is_ambient )
{
S_AmbientSound( pos, entnum, handle, volume, attn, pitch, flags );
}
else
{
S_StartSound( pos, entnum, chan, handle, volume, attn, pitch, flags );
}
}
/*
================
CL_PrecacheSound
prceache sound from server
================
*/
void CL_LegacyPrecacheSound( sizebuf_t *msg )
{
int soundIndex;
soundIndex = MSG_ReadUBitLong( msg, MAX_SOUND_BITS );
if( soundIndex < 0 || soundIndex >= MAX_SOUNDS )
Host_Error( "CL_PrecacheSound: bad soundindex %i\n", soundIndex );
Q_strncpy( cl.sound_precache[soundIndex], MSG_ReadString( msg ), sizeof( cl.sound_precache[0] ));
// when we loading map all resources is precached sequentially
//if( !cl.audio_prepped ) return;
cl.sound_index[soundIndex] = S_RegisterSound( cl.sound_precache[soundIndex] );
}
void CL_LegacyPrecacheModel( sizebuf_t *msg )
{
int modelIndex;
string model;
modelIndex = MSG_ReadUBitLong( msg, MAX_LEGACY_MODEL_BITS );
if( modelIndex < 0 || modelIndex >= MAX_MODELS )
Host_Error( "CL_PrecacheModel: bad modelindex %i\n", modelIndex );
Q_strncpy( model, MSG_ReadString( msg ), MAX_STRING );
//Q_strncpy( cl.model_precache[modelIndex], BF_ReadString( msg ), sizeof( cl.model_precache[0] ));
// when we loading map all resources is precached sequentially
//if( !cl.video_prepped ) return;
if( modelIndex == 1 && !cl.worldmodel )
{
CL_ClearWorld ();
cl.models[modelIndex] = cl.worldmodel = Mod_LoadWorld( model, true );
return;
}
//Mod_RegisterModel( cl.model_precache[modelIndex], modelIndex );
cl.models[modelIndex] = Mod_ForName( model, false, false );
cl.nummodels = Q_max( cl.nummodels, modelIndex );
}
void CL_LegacyPrecacheEvent( sizebuf_t *msg )
{
int eventIndex;
eventIndex = MSG_ReadUBitLong( msg, MAX_EVENT_BITS );
if( eventIndex < 0 || eventIndex >= MAX_EVENTS )
Host_Error( "CL_PrecacheEvent: bad eventindex %i\n", eventIndex );
Q_strncpy( cl.event_precache[eventIndex], MSG_ReadString( msg ), sizeof( cl.event_precache[0] ));
// can be set now
CL_SetEventIndex( cl.event_precache[eventIndex], eventIndex );
}
#if XASH_LOW_MEMORY == 0
#define MAX_LEGACY_RESOURCES 2048
#elif XASH_LOW_MEMORY == 2
#define MAX_LEGACY_RESOURCES 1
#elif XASH_LOW_MEMORY == 1
#define MAX_LEGACY_RESOURCES 512
#endif
/*
==============
CL_ParseResourceList
==============
*/
void CL_LegacyParseResourceList( sizebuf_t *msg )
{
int i = 0;
static struct
{
int rescount;
int restype[MAX_LEGACY_RESOURCES];
char resnames[MAX_LEGACY_RESOURCES][MAX_QPATH];
} reslist;
memset( &reslist, 0, sizeof( reslist ));
reslist.rescount = MSG_ReadWord( msg ) - 1;
if( reslist.rescount > MAX_LEGACY_RESOURCES )
Host_Error("MAX_RESOURCES reached\n");
for( i = 0; i < reslist.rescount; i++ )
{
reslist.restype[i] = MSG_ReadWord( msg );
Q_strncpy( reslist.resnames[i], MSG_ReadString( msg ), MAX_QPATH );
}
if( CL_IsPlaybackDemo() )
return;
if( !cl_allow_download.value )
{
Con_DPrintf( "Refusing new resource, cl_allow_download set to 0\n" );
reslist.rescount = 0;
}
if( cls.state == ca_active && !cl_download_ingame.value )
{
Con_DPrintf( "Refusing new resource, cl_download_ingame set to 0\n" );
reslist.rescount = 0;
}
HTTP_ResetProcessState();
host.downloadcount = 0;
for( i = 0; i < reslist.rescount; i++ )
{
char soundpath[MAX_VA_STRING];
const char *path;
if( reslist.restype[i] == t_sound )
{
Q_snprintf( soundpath, sizeof( soundpath ), DEFAULT_SOUNDPATH "%s", reslist.resnames[i] );
path = soundpath;
}
else path = reslist.resnames[i];
if( FS_FileExists( path, false ))
continue; // already exists
host.downloadcount++;
HTTP_AddDownload( path, -1, true );
}
if( !host.downloadcount )
{
MSG_WriteByte( &cls.netchan.message, clc_stringcmd );
MSG_WriteString( &cls.netchan.message, "continueloading" );
}
}
/*
=====================
CL_ParseLegacyServerMessage
dispatch messages
=====================
*/
void CL_ParseLegacyServerMessage( sizebuf_t *msg, qboolean normal_message )
{
size_t bufStart, playerbytes;
int cmd, param1, param2;
int old_background;
const char *s;
cls.starting_count = MSG_GetNumBytesRead( msg ); // updates each frame
CL_Parse_Debug( true ); // begin parsing
if( normal_message )
{
// assume no entity/player update this packet
if( cls.state == ca_active )
{
cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].valid = false;
cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].choked = false;
}
else
{
CL_ResetFrame( &cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK] );
}
}
// parse the message
while( 1 )
{
if( MSG_CheckOverflow( msg ))
{
Host_Error( "CL_ParseServerMessage: overflow!\n" );
return;
}
// mark start position
bufStart = MSG_GetNumBytesRead( msg );
// end of message (align bits)
if( MSG_GetNumBitsLeft( msg ) < 8 )
break;
cmd = MSG_ReadServerCmd( msg );
// record command for debugging spew on parse problem
CL_Parse_RecordCommand( cmd, bufStart );
// other commands
switch( cmd )
{
case svc_bad:
Host_Error( "svc_bad\n" );
break;
case svc_nop:
// this does nothing
break;
case svc_disconnect:
CL_Drop ();
Host_AbortCurrentFrame ();
break;
case svc_legacy_event:
CL_ParseEvent( msg );
cl.frames[cl.parsecountmod].graphdata.event += MSG_GetNumBytesRead( msg ) - bufStart;
break;
case svc_legacy_changing:
old_background = cl.background;
if( MSG_ReadOneBit( msg ))
{
int maxclients = cl.maxclients;
cls.changelevel = true;
S_StopAllSounds( true );
Con_Printf( "Server changing, reconnecting\n" );
if( cls.demoplayback )
{
SCR_BeginLoadingPlaque( cl.background );
cls.changedemo = true;
}
CL_ClearState( );
// a1ba: need to restore cl.maxclients because engine chooses
// frame backups count depending on this value
// In general, it's incorrect to call CL_InitEdicts right after
// CL_ClearState because of this bug. Some time later this logic
// should be re-done.
CL_InitEdicts( maxclients ); // re-arrange edicts
}
else Con_Printf( "Server disconnected, reconnecting\n" );
if( cls.demoplayback )
{
cl.background = (cls.demonum != -1) ? true : false;
cls.state = ca_connected;
}
else
{
// g-cont. local client skip the challenge
if( SV_Active( ))
cls.state = ca_disconnected;
else cls.state = ca_connecting;
cl.background = old_background;
cls.connect_time = MAX_HEARTBEAT;
cls.connect_retry = 0;
}
break;
case svc_setview:
CL_ParseViewEntity( msg );
break;
case svc_sound:
CL_LegacyParseSoundPacket( msg, false );
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
break;
case svc_legacy_ambientsound:
CL_LegacyParseSoundPacket( msg, true );
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
break;
case svc_time:
CL_ParseServerTime( msg );
break;
case svc_print:
Con_Printf( "%s", MSG_ReadString( msg ));
break;
case svc_stufftext:
s = MSG_ReadString( msg );
#ifdef HACKS_RELATED_HLMODS
// disable Cry Of Fear antisave protection
if( !Q_strnicmp( s, "disconnect", 10 ) && cls.signon != SIGNONS )
break; // too early
#endif
Con_Reportf( "Stufftext: %s", s );
Cbuf_AddFilteredText( s );
break;
case svc_setangle:
CL_ParseSetAngle( msg );
break;
case svc_serverdata:
Cbuf_Execute(); // make sure any stuffed commands are done
CL_ParseServerData( msg, true );
break;
case svc_lightstyle:
CL_ParseLightStyle( msg );
break;
case svc_updateuserinfo:
CL_UpdateUserinfo( msg, true );
break;
case svc_deltatable:
Delta_ParseTableField( msg );
break;
case svc_clientdata:
CL_ParseClientData( msg );
cl.frames[cl.parsecountmod].graphdata.client += MSG_GetNumBytesRead( msg ) - bufStart;
break;
case svc_resource:
CL_ParseResource( msg );
break;
case svc_pings:
CL_UpdateUserPings( msg );
break;
case svc_particle:
CL_ParseParticles( msg );
break;
case svc_restoresound:
CL_ParseRestoreSoundPacket( msg );
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
break;
case svc_spawnstatic:
CL_LegacyParseStaticEntity( msg );
break;
case svc_event_reliable:
CL_ParseReliableEvent( msg );
cl.frames[cl.parsecountmod].graphdata.event += MSG_GetNumBytesRead( msg ) - bufStart;
break;
case svc_spawnbaseline:
CL_ParseBaseline( msg, true );
break;
case svc_temp_entity:
CL_ParseTempEntity( msg );
cl.frames[cl.parsecountmod].graphdata.tentities += MSG_GetNumBytesRead( msg ) - bufStart;
break;
case svc_setpause:
cl.paused = ( MSG_ReadOneBit( msg ) != 0 );
break;
case svc_signonnum:
CL_ParseSignon( msg );
break;
case svc_centerprint:
CL_CenterPrint( MSG_ReadString( msg ), 0.25f );
break;
case svc_intermission:
cl.intermission = 1;
break;
case svc_legacy_modelindex:
CL_LegacyPrecacheModel( msg );
break;
case svc_legacy_soundindex:
CL_LegacyPrecacheSound( msg );
break;
case svc_cdtrack:
param1 = MSG_ReadByte( msg );
param1 = bound( 1, param1, MAX_CDTRACKS ); // tracknum
param2 = MSG_ReadByte( msg );
param2 = bound( 1, param2, MAX_CDTRACKS ); // loopnum
S_StartBackgroundTrack( clgame.cdtracks[param1-1], clgame.cdtracks[param2-1], 0, false );
break;
case svc_restore:
CL_ParseRestore( msg );
break;
case svc_legacy_eventindex:
CL_LegacyPrecacheEvent(msg);
break;
case svc_weaponanim:
param1 = MSG_ReadByte( msg ); // iAnim
param2 = MSG_ReadByte( msg ); // body
CL_WeaponAnim( param1, param2 );
break;
case svc_bspdecal:
CL_ParseStaticDecal( msg );
break;
case svc_roomtype:
param1 = MSG_ReadShort( msg );
Cvar_SetValue( "room_type", param1 );
break;
case svc_addangle:
CL_ParseAddAngle( msg );
break;
case svc_usermessage:
CL_RegisterUserMessage( msg );
break;
case svc_packetentities:
playerbytes = CL_ParsePacketEntities( msg, false );
cl.frames[cl.parsecountmod].graphdata.players += playerbytes;
cl.frames[cl.parsecountmod].graphdata.entities += MSG_GetNumBytesRead( msg ) - bufStart - playerbytes;
break;
case svc_deltapacketentities:
playerbytes = CL_ParsePacketEntities( msg, true );
cl.frames[cl.parsecountmod].graphdata.players += playerbytes;
cl.frames[cl.parsecountmod].graphdata.entities += MSG_GetNumBytesRead( msg ) - bufStart - playerbytes;
break;
case svc_legacy_chokecount:
{
int i, j;
i = MSG_ReadByte( msg );
j = cls.netchan.incoming_acknowledged - 1;
for( ; i > 0 && j > cls.netchan.outgoing_sequence - CL_UPDATE_BACKUP; j-- )
{
if( cl.frames[j & CL_UPDATE_MASK].receivedtime != -3.0 )
{
cl.frames[j & CL_UPDATE_MASK].choked = true;
cl.frames[j & CL_UPDATE_MASK].receivedtime = -2.0;
i--;
}
}
break;
}
//cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].choked = true;
//cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].receivedtime = -2.0;
break;
case svc_resourcelist:
CL_LegacyParseResourceList( msg );
break;
case svc_deltamovevars:
CL_ParseMovevars( msg );
break;
case svc_resourcerequest:
CL_ParseResourceRequest( msg );
break;
case svc_customization:
CL_ParseCustomization( msg );
break;
case svc_crosshairangle:
CL_ParseCrosshairAngle( msg );
break;
case svc_soundfade:
CL_ParseSoundFade( msg );
break;
case svc_filetxferfailed:
CL_ParseFileTransferFailed( msg );
break;
case svc_hltv:
CL_ParseHLTV( msg );
break;
case svc_director:
CL_ParseDirector( msg );
break;
case svc_resourcelocation:
CL_ParseResLocation( msg );
break;
case svc_querycvarvalue:
CL_ParseCvarValue( msg, false );
break;
case svc_querycvarvalue2:
CL_ParseCvarValue( msg, true );
break;
default:
CL_ParseUserMessage( msg, cmd );
cl.frames[cl.parsecountmod].graphdata.usr += MSG_GetNumBytesRead( msg ) - bufStart;
break;
}
}
cl.frames[cl.parsecountmod].graphdata.msgbytes += MSG_GetNumBytesRead( msg ) - cls.starting_count;
CL_Parse_Debug( false ); // done
// we don't know if it is ok to save a demo message until
// after we have parsed the frame
if( !cls.demoplayback )
{
if( cls.demorecording && !cls.demowaiting )
{
CL_WriteDemoMessage( false, cls.starting_count, msg );
}
else if( cls.state != ca_active )
{
CL_WriteDemoMessage( true, cls.starting_count, msg );
}
}
}
void CL_LegacyPrecache_f( void )
{
int spawncount, i;
model_t *mod;
if( !cls.legacymode )
return;
spawncount = Q_atoi( Cmd_Argv( 1 ));
Con_Printf( "Setting up renderer...\n" );
// load tempent sprites (glowshell, muzzleflashes etc)
CL_LoadClientSprites ();
// invalidate all decal indexes
memset( cl.decal_index, 0, sizeof( cl.decal_index ));
cl.video_prepped = true;
cl.audio_prepped = true;
if( clgame.entities )
clgame.entities->model = cl.worldmodel;
// update the ref state.
R_UpdateRefState ();
// tell rendering system we have a new set of models.
ref.dllFuncs.R_NewMap ();
CL_SetupOverviewParams();
// release unused SpriteTextures
for( i = 1, mod = clgame.sprites; i < MAX_CLIENT_SPRITES; i++, mod++ )
{
if( mod->needload == NL_UNREFERENCED && COM_CheckString( mod->name ))
Mod_FreeModel( mod );
}
// Mod_FreeUnused ();
if( host_developer.value <= DEV_NONE )
Con_ClearNotify(); // clear any lines of console text
// done with all resources, issue prespawn command.
// Include server count in case server disconnects and changes level during d/l
MSG_BeginClientCmd( &cls.netchan.message, clc_stringcmd );
MSG_WriteStringf( &cls.netchan.message, "begin %i", spawncount );
cls.signon = SIGNONS;
}
void CL_LegacyUpdateInfo( void )
{
if( !cls.legacymode )
return;
if( cls.state != ca_active )
return;
MSG_BeginClientCmd( &cls.netchan.message, clc_legacy_userinfo );
MSG_WriteString( &cls.netchan.message, cls.userinfo );
}
qboolean CL_LegacyMode( void )
{
return cls.legacymode;
}

View File

@@ -26,20 +26,6 @@ GNU General Public License for more details.
#define MIN_PREDICTION_EPSILON 0.5f // complain if error is > this and we have cl_showerror set
#define MAX_PREDICTION_ERROR 64.0f // above this is assumed to be a teleport, don't smooth, etc.
/*
=============
CL_ClearPhysEnts
=============
*/
void CL_ClearPhysEnts( void )
{
clgame.pmove->numtouch = 0;
clgame.pmove->numvisent = 0;
clgame.pmove->nummoveent = 0;
clgame.pmove->numphysent = 0;
}
/*
=============
CL_PushPMStates
@@ -100,7 +86,7 @@ CL_IsPredicted
*/
qboolean CL_IsPredicted( void )
{
if( cl_nopred->value || cl.intermission )
if( cl_nopred.value || cl.intermission )
return false;
// never predict the quake demos
@@ -197,7 +183,7 @@ void CL_SetIdealPitch( void )
}
if( steps < 2 ) return;
cl.local.idealpitch = -dir * cl_idealpitchscale->value;
cl.local.idealpitch = -dir * cl_idealpitchscale.value;
}
/*
@@ -208,7 +194,7 @@ check for instant movement in case
we don't want interpolate this
==================
*/
qboolean CL_PlayerTeleported( local_state_t *from, local_state_t *to )
static qboolean CL_PlayerTeleported( local_state_t *from, local_state_t *to )
{
int len, maxlen;
vec3_t delta;
@@ -248,7 +234,7 @@ void CL_CheckPredictionError( void )
// save the prediction error for interpolation
if( dist > MAX_PREDICTION_ERROR )
{
if( cl_showerror->value && host_developer.value )
if( cl_showerror.value && host_developer.value )
Con_NPrintf( 10 + ( ++pos & 3 ), "^3player teleported:^7 %.3f units\n", dist );
// a teleport or something or gamepaused
@@ -256,7 +242,7 @@ void CL_CheckPredictionError( void )
}
else
{
if( cl_showerror->value && dist > MIN_PREDICTION_EPSILON && host_developer.value )
if( cl_showerror.value && dist > MIN_PREDICTION_EPSILON && host_developer.value )
Con_NPrintf( 10 + ( ++pos & 3 ), "^1prediction error:^7 %.3f units\n", dist );
VectorCopy( cl.frames[cmd].playerstate[cl.playernum].origin, cl.local.predicted_origins[frame] );
@@ -267,7 +253,7 @@ void CL_CheckPredictionError( void )
// GoldSrc checks for singleplayer
// we would check for local server
if( dist > MIN_CORRECTION_DISTANCE && !SV_Active() )
cls.correction_time = cl_smoothtime->value;
cls.correction_time = cl_smoothtime.value;
}
}
@@ -547,7 +533,7 @@ void GAME_EXPORT CL_SetSolidPlayers( int playernum )
physent_t *pe;
int i;
if( !cl_solid_players->value )
if( !cl_solid_players.value )
return;
for( i = 0; i < MAX_CLIENTS; i++ )
@@ -713,33 +699,7 @@ static int GAME_EXPORT pfnTestPlayerPosition( float *pos, pmtrace_t *ptrace )
static void GAME_EXPORT pfnStuckTouch( int hitent, pmtrace_t *tr )
{
int i;
for( i = 0; i < clgame.pmove->numtouch; i++ )
{
if( clgame.pmove->touchindex[i].ent == hitent )
return;
}
if( clgame.pmove->numtouch >= MAX_PHYSENTS )
return;
VectorCopy( clgame.pmove->velocity, tr->deltavelocity );
tr->ent = hitent;
clgame.pmove->touchindex[clgame.pmove->numtouch++] = *tr;
}
static int GAME_EXPORT pfnPointContents( float *p, int *truecontents )
{
int cont, truecont;
truecont = cont = PM_PointContents( clgame.pmove, p );
if( truecontents ) *truecontents = truecont;
if( cont <= CONTENTS_CURRENT_0 && cont >= CONTENTS_CURRENT_DOWN )
cont = CONTENTS_WATER;
return cont;
PM_StuckTouch( clgame.pmove, hitent, tr );
}
static int GAME_EXPORT pfnTruePointContents( float *p )
@@ -747,101 +707,19 @@ static int GAME_EXPORT pfnTruePointContents( float *p )
return PM_TruePointContents( clgame.pmove, p );
}
static int GAME_EXPORT pfnHullPointContents( struct hull_s *hull, int num, float *p )
{
return PM_HullPointContents( hull, num, p );
}
static pmtrace_t GAME_EXPORT pfnPlayerTrace( float *start, float *end, int traceFlags, int ignore_pe )
{
return PM_PlayerTraceExt( clgame.pmove, start, end, traceFlags, clgame.pmove->numphysent, clgame.pmove->physents, ignore_pe, NULL );
}
pmtrace_t *PM_TraceLine( float *start, float *end, int flags, int usehull, int ignore_pe )
{
static pmtrace_t tr;
int old_usehull;
old_usehull = clgame.pmove->usehull;
clgame.pmove->usehull = usehull;
switch( flags )
{
case PM_TRACELINE_PHYSENTSONLY:
tr = PM_PlayerTraceExt( clgame.pmove, start, end, 0, clgame.pmove->numphysent, clgame.pmove->physents, ignore_pe, NULL );
break;
case PM_TRACELINE_ANYVISIBLE:
tr = PM_PlayerTraceExt( clgame.pmove, start, end, 0, clgame.pmove->numvisent, clgame.pmove->visents, ignore_pe, NULL );
break;
}
clgame.pmove->usehull = old_usehull;
return &tr;
}
static hull_t *pfnHullForBsp( physent_t *pe, float *offset )
static void *pfnHullForBsp( physent_t *pe, float *offset )
{
return PM_HullForBsp( pe, clgame.pmove, offset );
}
static float GAME_EXPORT pfnTraceModel( physent_t *pe, float *start, float *end, trace_t *trace )
{
int old_usehull;
vec3_t start_l, end_l;
vec3_t offset, temp;
qboolean rotated;
matrix4x4 matrix;
hull_t *hull;
PM_InitTrace( trace, end );
old_usehull = clgame.pmove->usehull;
clgame.pmove->usehull = 2;
hull = PM_HullForBsp( pe, clgame.pmove, offset );
clgame.pmove->usehull = old_usehull;
if( pe->solid == SOLID_BSP && !VectorIsNull( pe->angles ))
rotated = true;
else rotated = false;
if( rotated )
{
Matrix4x4_CreateFromEntity( matrix, pe->angles, offset, 1.0f );
Matrix4x4_VectorITransform( matrix, start, start_l );
Matrix4x4_VectorITransform( matrix, end, end_l );
}
else
{
VectorSubtract( start, offset, start_l );
VectorSubtract( end, offset, end_l );
}
PM_RecursiveHullCheck( hull, hull->firstclipnode, 0, 1, start_l, end_l, (pmtrace_t *)trace );
trace->ent = NULL;
if( rotated )
{
VectorCopy( trace->plane.normal, temp );
Matrix4x4_TransformPositivePlane( matrix, temp, trace->plane.dist, trace->plane.normal, &trace->plane.dist );
}
VectorLerp( start, trace->fraction, end, trace->endpos );
return trace->fraction;
}
static const char *pfnTraceTexture( int ground, float *vstart, float *vend )
{
physent_t *pe;
if( ground < 0 || ground >= clgame.pmove->numphysent )
return NULL; // bad ground
pe = &clgame.pmove->physents[ground];
return PM_TraceTexture( pe, vstart, vend );
return PM_TraceModel( clgame.pmove, pe, start, end, trace );
}
static void GAME_EXPORT pfnPlaySound( int channel, const char *sample, float volume, float attenuation, int fFlags, int pitch )
@@ -870,25 +748,7 @@ static int GAME_EXPORT pfnTestPlayerPositionEx( float *pos, pmtrace_t *ptrace, p
static pmtrace_t *pfnTraceLineEx( float *start, float *end, int flags, int usehull, pfnIgnore pmFilter )
{
static pmtrace_t tr;
int old_usehull;
old_usehull = clgame.pmove->usehull;
clgame.pmove->usehull = usehull;
switch( flags )
{
case PM_TRACELINE_PHYSENTSONLY:
tr = PM_PlayerTraceExt( clgame.pmove, start, end, 0, clgame.pmove->numphysent, clgame.pmove->physents, -1, pmFilter );
break;
case PM_TRACELINE_ANYVISIBLE:
tr = PM_PlayerTraceExt( clgame.pmove, start, end, 0, clgame.pmove->numvisent, clgame.pmove->visents, -1, pmFilter );
break;
}
clgame.pmove->usehull = old_usehull;
return &tr;
return PM_TraceLineEx( clgame.pmove, start, end, flags, usehull, pmFilter );
}
/*
@@ -928,23 +788,23 @@ void CL_InitClientMove( void )
clgame.pmove->Con_Printf = Con_Printf;
clgame.pmove->Sys_FloatTime = Sys_DoubleTime;
clgame.pmove->PM_StuckTouch = pfnStuckTouch;
clgame.pmove->PM_PointContents = pfnPointContents;
clgame.pmove->PM_PointContents = (void*)PM_CL_PointContents;
clgame.pmove->PM_TruePointContents = pfnTruePointContents;
clgame.pmove->PM_HullPointContents = pfnHullPointContents;
clgame.pmove->PM_HullPointContents = (void*)PM_HullPointContents;
clgame.pmove->PM_PlayerTrace = pfnPlayerTrace;
clgame.pmove->PM_TraceLine = PM_TraceLine;
clgame.pmove->PM_TraceLine = PM_CL_TraceLine;
clgame.pmove->RandomLong = COM_RandomLong;
clgame.pmove->RandomFloat = COM_RandomFloat;
clgame.pmove->PM_GetModelType = pfnGetModelType;
clgame.pmove->PM_GetModelBounds = pfnGetModelBounds;
clgame.pmove->PM_HullForBsp = (void*)pfnHullForBsp;
clgame.pmove->PM_HullForBsp = pfnHullForBsp;
clgame.pmove->PM_TraceModel = pfnTraceModel;
clgame.pmove->COM_FileSize = COM_FileSize;
clgame.pmove->COM_LoadFile = COM_LoadFile;
clgame.pmove->COM_FreeFile = COM_FreeFile;
clgame.pmove->memfgets = COM_MemFgets;
clgame.pmove->PM_PlaySound = pfnPlaySound;
clgame.pmove->PM_TraceTexture = pfnTraceTexture;
clgame.pmove->PM_TraceTexture = PM_CL_TraceTexture;
clgame.pmove->PM_PlaybackEventFull = pfnPlaybackEventFull;
clgame.pmove->PM_PlayerTraceEx = pfnPlayerTraceEx;
clgame.pmove->PM_TestPlayerPositionEx = pfnTestPlayerPositionEx;
@@ -955,21 +815,10 @@ void CL_InitClientMove( void )
clgame.dllFuncs.pfnPlayerMoveInit( clgame.pmove );
}
static void PM_CheckMovingGround( clientdata_t *cd, entity_state_t *state, float frametime )
static void CL_SetupPMove( playermove_t *pmove, const local_state_t *from, const usercmd_t *ucmd, qboolean runfuncs, double time )
{
if(!( cd->flags & FL_BASEVELOCITY ))
{
// apply momentum (add in half of the previous frame of velocity first)
VectorMA( cd->velocity, 1.0f + (frametime * 0.5f), state->basevelocity, cd->velocity );
VectorClear( state->basevelocity );
}
cd->flags &= ~FL_BASEVELOCITY;
}
void CL_SetupPMove( playermove_t *pmove, local_state_t *from, usercmd_t *ucmd, qboolean runfuncs, double time )
{
entity_state_t *ps;
clientdata_t *cd;
const entity_state_t *ps;
const clientdata_t *cd;
ps = &from->playerstate;
cd = &from->client;
@@ -986,13 +835,13 @@ void CL_SetupPMove( playermove_t *pmove, local_state_t *from, usercmd_t *ucmd, q
VectorCopy( ps->basevelocity, pmove->basevelocity );
VectorCopy( cd->view_ofs, pmove->view_ofs );
VectorClear( pmove->movedir );
pmove->flDuckTime = cd->flDuckTime;
pmove->flDuckTime = (float)cd->flDuckTime;
pmove->bInDuck = cd->bInDuck;
pmove->usehull = ps->usehull;
pmove->flTimeStepSound = cd->flTimeStepSound;
pmove->iStepLeft = ps->iStepLeft;
pmove->flFallVelocity = ps->flFallVelocity;
pmove->flSwimTime = cd->flSwimTime;
pmove->flSwimTime = (float)cd->flSwimTime;
VectorCopy( cd->punchangle, pmove->punchangle );
pmove->flNextPrimaryAttack = 0.0f; // not used by PM_ code
pmove->effects = ps->effects;
@@ -1000,7 +849,7 @@ void CL_SetupPMove( playermove_t *pmove, local_state_t *from, usercmd_t *ucmd, q
pmove->gravity = ps->gravity;
pmove->friction = ps->friction;
pmove->oldbuttons = ps->oldbuttons;
pmove->waterjumptime = cd->waterjumptime;
pmove->waterjumptime = (float)cd->waterjumptime;
pmove->dead = (cl.local.health <= 0);
pmove->deadflag = cd->deadflag;
pmove->spectator = (cls.spectator != 0);
@@ -1027,7 +876,7 @@ void CL_SetupPMove( playermove_t *pmove, local_state_t *from, usercmd_t *ucmd, q
Q_strncpy( pmove->physinfo, cls.physinfo, MAX_INFO_STRING );
}
void CL_FinishPMove( playermove_t *pmove, local_state_t *to )
const void CL_FinishPMove( const playermove_t *pmove, local_state_t *to )
{
entity_state_t *ps;
clientdata_t *cd;
@@ -1038,7 +887,7 @@ void CL_FinishPMove( playermove_t *pmove, local_state_t *to )
cd->flags = pmove->flags;
cd->bInDuck = pmove->bInDuck;
cd->flTimeStepSound = pmove->flTimeStepSound;
cd->flDuckTime = pmove->flDuckTime;
cd->flDuckTime = (int)pmove->flDuckTime;
cd->flSwimTime = (int)pmove->flSwimTime;
cd->waterjumptime = (int)pmove->waterjumptime;
cd->watertype = pmove->watertype;
@@ -1051,7 +900,7 @@ void CL_FinishPMove( playermove_t *pmove, local_state_t *to )
VectorCopy( pmove->angles, ps->angles );
VectorCopy( pmove->basevelocity, ps->basevelocity );
VectorCopy( pmove->punchangle, cd->punchangle );
ps->oldbuttons = pmove->cmd.buttons;
ps->oldbuttons = (uint)pmove->cmd.buttons;
ps->friction = pmove->friction;
ps->movetype = pmove->movetype;
ps->onground = pmove->onground;
@@ -1159,13 +1008,9 @@ void CL_PredictMovement( qboolean repredicting )
{
runcmd_t *to_cmd = NULL, *from_cmd;
local_state_t *from = NULL, *to = NULL;
uint current_command;
uint current_command_mod;
frame_t *frame = NULL;
frame_t *frame = NULL;
uint i, stoppoint;
qboolean runfuncs;
double f = 1.0;
cl_entity_t *ent;
double time;
if( cls.state != ca_active || cls.spectator )
@@ -1176,7 +1021,7 @@ void CL_PredictMovement( qboolean repredicting )
CL_SetUpPlayerPrediction( false, false );
if( cls.state != ca_active || !cl.validsequence )
if( !cl.validsequence )
return;
if(( cls.netchan.outgoing_sequence - cls.netchan.incoming_acknowledged ) >= CL_UPDATE_MASK )
@@ -1217,6 +1062,10 @@ void CL_PredictMovement( qboolean repredicting )
for( i = 1; i < CL_UPDATE_MASK && cls.netchan.incoming_acknowledged + i < cls.netchan.outgoing_sequence + stoppoint; i++ )
{
uint current_command;
uint current_command_mod;
qboolean runfuncs;
current_command = cls.netchan.incoming_acknowledged + i;
current_command_mod = current_command & CL_UPDATE_MASK;
@@ -1256,7 +1105,7 @@ void CL_PredictMovement( qboolean repredicting )
cl.local.onground = frame->playerstate[cl.playernum].onground;
else cl.local.onground = -1;
if( !repredicting || !CVAR_TO_BOOL( cl_lw ))
if( !repredicting || !cl_lw.value )
cl.local.viewmodel = to->client.viewmodel;
cl.local.repredicting = false;
cl.local.moving = false;
@@ -1288,12 +1137,12 @@ void CL_PredictMovement( qboolean repredicting )
cl.local.waterlevel = to->client.waterlevel;
cl.local.usehull = to->playerstate.usehull;
if( !repredicting || !CVAR_TO_BOOL( cl_lw ))
if( !repredicting || !cl_lw.value )
cl.local.viewmodel = to->client.viewmodel;
if( FBitSet( to->client.flags, FL_ONGROUND ))
{
ent = CL_GetEntityByIndex( cl.local.lastground );
cl_entity_t *ent = CL_GetEntityByIndex( cl.local.lastground );
cl.local.onground = cl.local.lastground;
cl.local.moving = false;
@@ -1315,27 +1164,27 @@ void CL_PredictMovement( qboolean repredicting )
else
{
cl.local.onground = -1;
cl.local.moving = 0;
cl.local.moving = false;
}
if( cls.correction_time > 0 && !cl_nosmooth->value && cl_smoothtime->value )
if( cls.correction_time > 0 && !cl_nosmooth.value && cl_smoothtime.value )
{
vec3_t delta;
float frac;
vec3_t delta;
float frac;
// only decay timer once per frame
if( !repredicting )
cls.correction_time -= host.frametime;
// Make sure smoothtime is postive
if( cl_smoothtime->value <= 0.0f )
Cvar_DirectSet( cl_smoothtime, "0.1" );
if( cl_smoothtime.value <= 0.0f )
Cvar_DirectSet( &cl_smoothtime, "0.1" );
// Clamp from 0 to cl_smoothtime.value
cls.correction_time = bound( 0.0, cls.correction_time, cl_smoothtime->value );
cls.correction_time = bound( 0.0, cls.correction_time, cl_smoothtime.value );
// Compute backward interpolation fraction along full correction
frac = 1.0f - cls.correction_time / cl_smoothtime->value;
frac = 1.0f - cls.correction_time / cl_smoothtime.value;
// Determine how much error we still have to make up for
VectorSubtract( cl.simorg, cl.local.lastorigin, delta );

View File

@@ -232,14 +232,10 @@ static void CL_ParseQuakeServerInfo( sizebuf_t *msg )
// loading user settings
CSCR_LoadDefaultCVars( "user.scr" );
if( r_decals->value > mp_decals.value )
Cvar_SetValue( "r_decals", mp_decals.value );
if( r_decals.value > mp_decals.value )
Cvar_DirectSet( &r_decals, mp_decals.string );
}
else Cvar_Reset( "r_decals" );
// re-init mouse
if( cl.background )
host.mouse_visible = false;
else Cvar_DirectSet( &r_decals, NULL );
if( cl.background ) // tell the game parts about background state
Cvar_FullSet( "cl_background", "1", FCVAR_READ_ONLY );
@@ -262,7 +258,7 @@ static void CL_ParseQuakeServerInfo( sizebuf_t *msg )
Q_strncpy( gameui.globals->maptitle, clgame.maptitle, sizeof( gameui.globals->maptitle ));
if( !cls.changelevel && !cls.changedemo )
CL_InitEdicts (); // re-arrange edicts
CL_InitEdicts( cl.maxclients ); // re-arrange edicts
// Quake just have a large packet of initialization data
for( i = 1; i < MAX_MODELS; i++ )
@@ -306,9 +302,9 @@ static void CL_ParseQuakeServerInfo( sizebuf_t *msg )
else Cvar_Set( "cl_levelshot_name", va( "levelshots/%s_%s", clgame.mapname, refState.wideScreen ? "16x9" : "4x3" ));
Cvar_SetValue( "scr_loading", 0.0f ); // reset progress bar
if(( cl_allow_levelshots->value && !cls.changelevel ) || cl.background )
if(( cl_allow_levelshots.value && !cls.changelevel ) || cl.background )
{
if( !FS_FileExists( va( "%s.bmp", cl_levelshot_name->string ), true ))
if( !FS_FileExists( va( "%s.bmp", cl_levelshot_name.string ), true ))
Cvar_Set( "cl_levelshot_name", "*black" ); // render a black screen
cls.scrshot_request = scrshot_plaque; // request levelshot even if exist (check filetime)
}
@@ -698,17 +694,13 @@ static void CL_ParseQuakeBaseline( sizebuf_t *msg )
cl_entity_t *ent;
int newnum;
memset( &state, 0, sizeof( state ));
newnum = MSG_ReadWord( msg ); // entnum
if( newnum >= clgame.maxEntities )
Host_Error( "CL_AllocEdict: no free edicts\n" );
ent = CL_EDICT_NUM( newnum );
memset( &ent->prevstate, 0, sizeof( ent->prevstate ));
ent->index = newnum;
// parse baseline
memset( &state, 0, sizeof( state ));
state.modelindex = MSG_ReadByte( msg );
state.frame = MSG_ReadByte( msg );
state.colormap = MSG_ReadByte( msg );
@@ -719,8 +711,10 @@ static void CL_ParseQuakeBaseline( sizebuf_t *msg )
state.angles[1] = MSG_ReadAngle( msg );
state.origin[2] = MSG_ReadCoord( msg );
state.angles[2] = MSG_ReadAngle( msg );
ent->player = CL_IsPlayerIndex( newnum );
ent = CL_EDICT_NUM( newnum );
ent->index = newnum;
ent->player = CL_IsPlayerIndex( newnum );
memcpy( &ent->baseline, &state, sizeof( entity_state_t ));
memcpy( &ent->prevstate, &state, sizeof( entity_state_t ));
}

View File

@@ -41,11 +41,24 @@ CL_CmpStudioTextures
return true if equal
====================
*/
qboolean CL_CmpStudioTextures( int numtexs, mstudiotexture_t *p1, mstudiotexture_t *p2 )
static qboolean CL_CmpStudioTextures( int numtexs, mstudiotexture_t *p1, remap_info_t *remap )
{
int i;
mstudiotexture_t *p2;
if( !p1 || !p2 ) return false;
if( !p1 ) // no textures
return false;
if( !remap ) // current model has no remap
return false;
if( !remap->textures ) // shouldn't happen, just in case
return false;
if( numtexs != remap->numtextures ) // amount of textures differs, it's a different model
return false;
p2 = remap->ptexture;
for( i = 0; i < numtexs; i++, p1++, p2++ )
{
@@ -157,7 +170,7 @@ void CL_UpdateStudioTexture( cl_entity_t *entity, mstudiotexture_t *ptexture, in
// build name of original texture
Q_strncpy( mdlname, entity->model->name, sizeof( mdlname ));
COM_FileBase( ptexture->name, name );
COM_FileBase( ptexture->name, name, sizeof( name ));
COM_StripExtension( mdlname );
Q_snprintf( texname, sizeof( texname ), "#%s/%s.mdl", mdlname, name );
@@ -282,10 +295,9 @@ void CL_AllocRemapInfo( cl_entity_t *entity, model_t *model, int topcolor, int b
if( !phdr ) return; // bad model?
src = (mstudiotexture_t *)(((byte *)phdr) + phdr->textureindex);
dst = (clgame.remap_info[i] ? clgame.remap_info[i]->ptexture : NULL);
// NOTE: we must copy all the structures 'mstudiotexture_t' for easy access when model is rendering
if( !CL_CmpStudioTextures( phdr->numtextures, src, dst ) || clgame.remap_info[i]->model != model )
if( !CL_CmpStudioTextures( phdr->numtextures, src, clgame.remap_info[i] ) || clgame.remap_info[i]->model != model )
{
// this code catches studiomodel change with another studiomodel with remap textures
// e.g. playermodel 'barney' with playermodel 'gordon'

View File

@@ -133,7 +133,7 @@ const char *CL_GenericHandle( int fileindex )
return cl.files_precache[fileindex];
}
int CL_RenderGetParm( const int parm, const int arg, const qboolean checkRef )
intptr_t CL_RenderGetParm( const int parm, const int arg, const qboolean checkRef )
{
switch( parm )
{
@@ -161,9 +161,17 @@ int CL_RenderGetParm( const int parm, const int arg, const qboolean checkRef )
case PARM_WATER_ALPHA:
return FBitSet( world.flags, FWORLD_WATERALPHA );
case PARM_DELUXEDATA:
return *(int *)&world.deluxedata;
return (intptr_t)world.deluxedata;
case PARM_SHADOWDATA:
return *(int *)&world.shadowdata;
return (intptr_t)world.shadowdata;
case PARM_FULLSCREEN:
return refState.fullScreen;
case PARM_WIDESCREEN:
return refState.wideScreen;
case PARM_SCREEN_WIDTH:
return refState.width;
case PARM_SCREEN_HEIGHT:
return refState.height;
default:
// indicates call from client.dll
if( checkRef )
@@ -204,7 +212,7 @@ int CL_RenderGetParm( const int parm, const int arg, const qboolean checkRef )
return 0;
}
static int pfnRenderGetParm( int parm, int arg )
static intptr_t pfnRenderGetParm( int parm, int arg )
{
return CL_RenderGetParm( parm, arg, true );
}

View File

@@ -20,18 +20,18 @@ GNU General Public License for more details.
#include "input.h"
#include "library.h"
convar_t *scr_centertime;
convar_t *scr_loading;
convar_t *scr_download;
convar_t *scr_viewsize;
convar_t *cl_testlights;
convar_t *cl_allow_levelshots;
convar_t *cl_levelshot_name;
static convar_t *cl_envshot_size;
convar_t *v_dark;
static convar_t *net_speeds;
static convar_t *cl_showfps;
static convar_t *cl_showpos;
CVAR_DEFINE_AUTO( scr_centertime, "2.5", 0, "centerprint hold time" );
CVAR_DEFINE_AUTO( scr_loading, "0", 0, "loading bar progress" );
CVAR_DEFINE_AUTO( scr_download, "-1", 0, "downloading bar progress" );
CVAR_DEFINE( scr_viewsize, "viewsize", "120", FCVAR_ARCHIVE, "screen size (quake only)" );
CVAR_DEFINE_AUTO( cl_testlights, "0", 0, "test dynamic lights" );
CVAR_DEFINE( cl_allow_levelshots, "allow_levelshots", "0", FCVAR_ARCHIVE, "allow engine to use indivdual levelshots instead of 'loading' image" );
CVAR_DEFINE_AUTO( cl_levelshot_name, "*black", 0, "contains path to current levelshot" );
static CVAR_DEFINE_AUTO( cl_envshot_size, "256", FCVAR_ARCHIVE, "envshot size of cube side" );
CVAR_DEFINE_AUTO( v_dark, "0", 0, "starts level from dark screen" );
static CVAR_DEFINE_AUTO( net_speeds, "0", FCVAR_ARCHIVE, "show network packets" );
static CVAR_DEFINE_AUTO( cl_showfps, "0", FCVAR_ARCHIVE, "show client fps" );
static CVAR_DEFINE_AUTO( cl_showpos, "0", FCVAR_ARCHIVE, "show local player position and velocity" );
typedef struct
{
@@ -59,7 +59,7 @@ void SCR_DrawFPS( int height )
char fpsstring[64];
int offset;
if( cls.state != ca_active || !cl_showfps->value || cl.background )
if( cls.state != ca_active || !cl_showfps.value || cl.background )
return;
switch( cls.scrshot_action )
@@ -95,7 +95,7 @@ void SCR_DrawFPS( int height )
if( curfps < minfps ) minfps = curfps;
if( curfps > maxfps ) maxfps = curfps;
if( cl_showfps->value == 2 )
if( cl_showfps.value == 2 )
Q_snprintf( fpsstring, sizeof( fpsstring ), "fps: ^1%4i min, ^3%4i cur, ^2%4i max", minfps, curfps, maxfps );
else Q_snprintf( fpsstring, sizeof( fpsstring ), "%4i fps", curfps );
MakeRGBA( color, 255, 255, 255, 255 );
@@ -119,7 +119,7 @@ void SCR_DrawPos( void )
cl_entity_t *ent;
rgba_t color;
if( cls.state != ca_active || !cl_showpos->value || cl.background )
if( cls.state != ca_active || !cl_showpos.value || cl.background )
return;
ent = CL_GetLocalPlayer();
@@ -150,8 +150,7 @@ same as r_speeds but for network channel
void SCR_NetSpeeds( void )
{
static char msg[MAX_SYSPATH];
int x, y, height;
char *p, *start, *end;
int x, y;
float time = cl.mtime[0];
static int min_svfps = 100;
static int max_svfps = 0;
@@ -160,11 +159,12 @@ void SCR_NetSpeeds( void )
static int max_clfps = 0;
int cur_clfps = 0;
rgba_t color;
cl_font_t *font = Con_GetCurFont();
if( !host.allow_console )
return;
if( !net_speeds->value || cls.state != ca_active )
if( !net_speeds.value || cls.state != ca_active )
return;
// prevent to get too big values at max
@@ -196,25 +196,11 @@ void SCR_NetSpeeds( void )
Q_memprint( cls.netchan.total_sended )
);
x = refState.width - 320;
x = refState.width - 320 * font->scale;
y = 384;
Con_DrawStringLen( NULL, NULL, &height );
MakeRGBA( color, 255, 255, 255, 255 );
p = start = msg;
do
{
end = Q_strchr( p, '\n' );
if( end ) msg[end-start] = '\0';
Con_DrawString( x, y, p, color );
y += height;
if( end ) p = end + 1;
else break;
} while( 1 );
CL_DrawString( x, y, msg, color, font, FONT_DRAW_RESETCOLORONLF );
}
/*
@@ -231,31 +217,15 @@ void SCR_RSpeeds( void )
if( ref.dllFuncs.R_SpeedsMessage( msg, sizeof( msg )))
{
int x, y, height;
char *p, *start, *end;
int x, y;
rgba_t color;
cl_font_t *font = Con_GetCurFont();
x = refState.width - 340;
x = refState.width - 340 * font->scale;
y = 64;
Con_DrawStringLen( NULL, NULL, &height );
MakeRGBA( color, 255, 255, 255, 255 );
p = start = msg;
do
{
end = Q_strchr( p, '\n' );
if( end ) msg[end-start] = '\0';
Con_DrawString( x, y, p, color );
y += height;
// handle '\n\n'
if( *p == '\n' )
y += height;
if( end ) p = end + 1;
else break;
} while( 1 );
CL_DrawString( x, y, msg, color, font, FONT_DRAW_RESETCOLORONLF );
}
}
@@ -320,7 +290,7 @@ void SCR_MakeScreenShot( void )
if( cls.envshot_viewsize > 0 )
viewsize = cls.envshot_viewsize;
else viewsize = cl_envshot_size->value;
else viewsize = cl_envshot_size.value;
switch( cls.scrshot_action )
{
@@ -374,9 +344,9 @@ SCR_DrawPlaque
*/
void SCR_DrawPlaque( void )
{
if(( cl_allow_levelshots->value && !cls.changelevel ) || cl.background )
if(( cl_allow_levelshots.value && !cls.changelevel ) || cl.background )
{
int levelshot = ref.dllFuncs.GL_LoadTexture( cl_levelshot_name->string, NULL, 0, TF_IMAGE );
int levelshot = ref.dllFuncs.GL_LoadTexture( cl_levelshot_name.string, NULL, 0, TF_IMAGE );
ref.dllFuncs.GL_SetRenderMode( kRenderNormal );
ref.dllFuncs.R_DrawStretchPic( 0, 0, refState.width, refState.height, 0, 0, 1, 1, levelshot );
if( !cl.background ) CL_DrawHUD( CL_LOADING );
@@ -396,7 +366,7 @@ void SCR_BeginLoadingPlaque( qboolean is_background )
cl.video_prepped = false;
if( !Host_IsDedicated() )
oldclear = gl_clear->value;
oldclear = gl_clear.value;
if( CL_IsInMenu( ) && !cls.changedemo && !is_background )
{
@@ -412,7 +382,7 @@ void SCR_BeginLoadingPlaque( qboolean is_background )
return;
if( !Host_IsDedicated() )
gl_clear->value = 0.0f;
gl_clear.value = 0.0f;
if( is_background ) IN_MouseSavePos( );
cls.draw_changelevel = !is_background;
@@ -421,7 +391,7 @@ void SCR_BeginLoadingPlaque( qboolean is_background )
cl.background = is_background; // set right state before svc_serverdata is came
if( !Host_IsDedicated() )
gl_clear->value = oldclear;
gl_clear.value = oldclear;
// SNDDMA_LockSound();
}
@@ -472,7 +442,7 @@ void SCR_TileClear( void )
int i, top, bottom, left, right;
dirty_t clear;
if( scr_viewsize->value >= 120 )
if( scr_viewsize.value >= 120 )
return; // full screen rendering
// erase rect will be the union of the past three frames
@@ -577,77 +547,6 @@ void SCR_UpdateScreen( void )
V_PostRender();
}
qboolean SCR_LoadFixedWidthFont( const char *fontname )
{
int i, fontWidth;
if( cls.creditsFont.valid )
return true; // already loaded
if( !FS_FileExists( fontname, false ))
return false;
cls.creditsFont.hFontTexture = ref.dllFuncs.GL_LoadTexture( fontname, NULL, 0, TF_IMAGE|TF_KEEP_SOURCE );
R_GetTextureParms( &fontWidth, NULL, cls.creditsFont.hFontTexture );
cls.creditsFont.charHeight = clgame.scrInfo.iCharHeight = fontWidth / 16;
cls.creditsFont.type = FONT_FIXED;
cls.creditsFont.valid = true;
// build fixed rectangles
for( i = 0; i < 256; i++ )
{
cls.creditsFont.fontRc[i].left = (i * (fontWidth / 16)) % fontWidth;
cls.creditsFont.fontRc[i].right = cls.creditsFont.fontRc[i].left + fontWidth / 16;
cls.creditsFont.fontRc[i].top = (i / 16) * (fontWidth / 16);
cls.creditsFont.fontRc[i].bottom = cls.creditsFont.fontRc[i].top + fontWidth / 16;
cls.creditsFont.charWidths[i] = clgame.scrInfo.charWidths[i] = fontWidth / 16;
}
return true;
}
qboolean SCR_LoadVariableWidthFont( const char *fontname )
{
int i, fontWidth;
byte *buffer;
fs_offset_t length;
qfont_t *src;
if( cls.creditsFont.valid )
return true; // already loaded
if( !FS_FileExists( fontname, false ))
return false;
cls.creditsFont.hFontTexture = ref.dllFuncs.GL_LoadTexture( fontname, NULL, 0, TF_IMAGE );
R_GetTextureParms( &fontWidth, NULL, cls.creditsFont.hFontTexture );
// half-life font with variable chars witdh
buffer = FS_LoadFile( fontname, &length, false );
// setup creditsfont
if( buffer && length >= sizeof( qfont_t ))
{
src = (qfont_t *)buffer;
cls.creditsFont.charHeight = clgame.scrInfo.iCharHeight = src->rowheight;
cls.creditsFont.type = FONT_VARIABLE;
// build rectangles
for( i = 0; i < 256; i++ )
{
cls.creditsFont.fontRc[i].left = (word)src->fontinfo[i].startoffset % fontWidth;
cls.creditsFont.fontRc[i].right = cls.creditsFont.fontRc[i].left + src->fontinfo[i].charwidth;
cls.creditsFont.fontRc[i].top = (word)src->fontinfo[i].startoffset / fontWidth;
cls.creditsFont.fontRc[i].bottom = cls.creditsFont.fontRc[i].top + src->rowheight;
cls.creditsFont.charWidths[i] = clgame.scrInfo.charWidths[i] = src->fontinfo[i].charwidth;
}
cls.creditsFont.valid = true;
}
if( buffer ) Mem_Free( buffer );
return true;
}
/*
================
SCR_LoadCreditsFont
@@ -657,22 +556,41 @@ INTERNAL RESOURCE
*/
void SCR_LoadCreditsFont( void )
{
const char *path = "gfx/creditsfont.fnt";
dword crc;
cl_font_t *const font = &cls.creditsFont;
qboolean success = false;
float scale = hud_fontscale.value;
dword crc = 0;
// replace default gfx.wad textures by current charset's font
if( !CRC32_File( &crc, "gfx.wad" ) || crc == 0x49eb9f16 )
{
const char *path2 = va("creditsfont_%s.fnt", Cvar_VariableString( "con_charset" ) );
if( FS_FileExists( path2, false ) )
path = path2;
string charsetFnt;
if( Q_snprintf( charsetFnt, sizeof( charsetFnt ),
"creditsfont_%s.fnt", Cvar_VariableString( "con_charset" )) > 0 )
{
if( FS_FileExists( charsetFnt, false ))
success = Con_LoadVariableWidthFont( charsetFnt, font, scale, kRenderTransAdd, TF_FONT );
}
}
if( !SCR_LoadVariableWidthFont( path ))
if( !success )
success = Con_LoadVariableWidthFont( "gfx/creditsfont.fnt", font, scale, kRenderTransAdd, TF_FONT );
if( !success )
success = Con_LoadFixedWidthFont( "gfx/conchars", font, scale, kRenderTransAdd, TF_FONT );
// copy font size for client.dll
if( success )
{
if( !SCR_LoadFixedWidthFont( "gfx/conchars" ))
Con_DPrintf( S_ERROR "failed to load HUD font\n" );
int i;
clgame.scrInfo.iCharHeight = cls.creditsFont.charHeight;
for( i = 0; i < ARRAYSIZE( cls.creditsFont.charWidths ); i++ )
clgame.scrInfo.charWidths[i] = cls.creditsFont.charWidths[i];
}
else Con_DPrintf( S_ERROR "failed to load HUD font\n" );
}
/*
@@ -734,13 +652,13 @@ void SCR_RegisterTextures( void )
if( FS_FileExists( "gfx/lambda.lmp", false ))
{
if( cl_allow_levelshots->value )
if( cl_allow_levelshots.value )
cls.loadingBar = ref.dllFuncs.GL_LoadTexture( "gfx/lambda.lmp", NULL, 0, TF_IMAGE|TF_LUMINANCE );
else cls.loadingBar = ref.dllFuncs.GL_LoadTexture( "gfx/lambda.lmp", NULL, 0, TF_IMAGE );
}
else if( FS_FileExists( "gfx/loading.lmp", false ))
{
if( cl_allow_levelshots->value )
if( cl_allow_levelshots.value )
cls.loadingBar = ref.dllFuncs.GL_LoadTexture( "gfx/loading.lmp", NULL, 0, TF_IMAGE|TF_LUMINANCE );
else cls.loadingBar = ref.dllFuncs.GL_LoadTexture( "gfx/loading.lmp", NULL, 0, TF_IMAGE );
}
@@ -757,7 +675,7 @@ Keybinding command
*/
void SCR_SizeUp_f( void )
{
Cvar_SetValue( "viewsize", Q_min( scr_viewsize->value + 10, 120 ));
Cvar_SetValue( "viewsize", Q_min( scr_viewsize.value + 10, 120 ));
}
@@ -770,7 +688,7 @@ Keybinding command
*/
void SCR_SizeDown_f( void )
{
Cvar_SetValue( "viewsize", Q_max( scr_viewsize->value - 10, 30 ));
Cvar_SetValue( "viewsize", Q_max( scr_viewsize.value - 10, 30 ));
}
/*
@@ -780,7 +698,6 @@ SCR_VidInit
*/
void SCR_VidInit( void )
{
string libpath;
if( !ref.initialized ) // don't call VidInit too soon
return;
@@ -795,8 +712,11 @@ void SCR_VidInit( void )
gameui.globals->scrHeight = refState.height;
}
COM_GetCommonLibraryPath( LIBRARY_CLIENT, libpath, sizeof( libpath ));
VGui_Startup( libpath, refState.width, refState.height );
// notify vgui about screen size change
if( clgame.hInstance )
{
VGui_Startup( refState.width, refState.height );
}
CL_ClearSpriteTextures(); // now all hud sprites are invalid
@@ -806,6 +726,7 @@ void SCR_VidInit( void )
// restart console size
Con_VidInit ();
Touch_NotifyResize();
}
/*
@@ -817,18 +738,18 @@ void SCR_Init( void )
{
if( scr_init ) return;
scr_centertime = Cvar_Get( "scr_centertime", "2.5", 0, "centerprint hold time" );
cl_levelshot_name = Cvar_Get( "cl_levelshot_name", "*black", 0, "contains path to current levelshot" );
cl_allow_levelshots = Cvar_Get( "allow_levelshots", "0", FCVAR_ARCHIVE, "allow engine to use indivdual levelshots instead of 'loading' image" );
scr_loading = Cvar_Get( "scr_loading", "0", 0, "loading bar progress" );
scr_download = Cvar_Get( "scr_download", "-1", 0, "downloading bar progress" );
cl_testlights = Cvar_Get( "cl_testlights", "0", 0, "test dynamic lights" );
cl_envshot_size = Cvar_Get( "cl_envshot_size", "256", FCVAR_ARCHIVE, "envshot size of cube side" );
v_dark = Cvar_Get( "v_dark", "0", 0, "starts level from dark screen" );
scr_viewsize = Cvar_Get( "viewsize", "120", FCVAR_ARCHIVE, "screen size" );
net_speeds = Cvar_Get( "net_speeds", "0", FCVAR_ARCHIVE, "show network packets" );
cl_showfps = Cvar_Get( "cl_showfps", "1", FCVAR_ARCHIVE, "show client fps" );
cl_showpos = Cvar_Get( "cl_showpos", "0", FCVAR_ARCHIVE, "show local player position and velocity" );
Cvar_RegisterVariable( &scr_centertime );
Cvar_RegisterVariable( &cl_levelshot_name );
Cvar_RegisterVariable( &cl_allow_levelshots );
Cvar_RegisterVariable( &scr_loading );
Cvar_RegisterVariable( &scr_download );
Cvar_RegisterVariable( &cl_testlights );
Cvar_RegisterVariable( &cl_envshot_size );
Cvar_RegisterVariable( &v_dark );
Cvar_RegisterVariable( &scr_viewsize );
Cvar_RegisterVariable( &net_speeds );
Cvar_RegisterVariable( &cl_showfps );
Cvar_RegisterVariable( &cl_showpos );
// register our commands
Cmd_AddCommand( "skyname", CL_SetSky_f, "set new skybox by basename" );

View File

@@ -405,12 +405,15 @@ static cldll_func_dst_t cldllFuncDst =
void CL_GetSecuredClientAPI( CL_EXPORT_FUNCS F )
{
cldll_func_src_t cldllFuncSrc = { 0 };
modfuncs_t modFuncs = { 0 };
// secured client dlls need these
*(cldll_func_dst_t **)&cldllFuncSrc.pfnVidInit = &cldllFuncDst;
*(modfuncs_t **)&cldllFuncSrc.pfnInitialize = &modFuncs;
cldll_func_src_t cldllFuncSrc =
{
(void *)&modFuncs,
NULL,
(void *)&cldllFuncDst
};
// trying to fill interface now
F( &cldllFuncSrc );

View File

@@ -1037,7 +1037,7 @@ void GAME_EXPORT R_BreakModel( const vec3_t pos, const vec3_t size, const vec3_t
vecSpot[1] = pos[1] + COM_RandomFloat( -0.5f, 0.5f ) * size[1];
vecSpot[2] = pos[2] + COM_RandomFloat( -0.5f, 0.5f ) * size[2];
if( CL_PointContents( vecSpot ) != CONTENTS_SOLID )
if( PM_CL_PointContents( vecSpot, NULL ) != CONTENTS_SOLID )
break; // valid spot
}
@@ -1245,37 +1245,28 @@ apply params for exploding sprite
*/
void GAME_EXPORT R_Sprite_Explode( TEMPENTITY *pTemp, float scale, int flags )
{
if( !pTemp ) return;
qboolean noadditive, drawalpha, rotate;
if( FBitSet( flags, TE_EXPLFLAG_NOADDITIVE ))
{
// solid sprite
pTemp->entity.curstate.rendermode = kRenderNormal;
pTemp->entity.curstate.renderamt = 255;
}
else if( FBitSet( flags, TE_EXPLFLAG_DRAWALPHA ))
{
// alpha sprite (came from hl2)
pTemp->entity.curstate.rendermode = kRenderTransAlpha;
pTemp->entity.curstate.renderamt = 180;
}
else
{
// additive sprite
pTemp->entity.curstate.rendermode = kRenderTransAdd;
pTemp->entity.curstate.renderamt = 180;
}
if( !pTemp )
return;
if( FBitSet( flags, TE_EXPLFLAG_ROTATE ))
{
// came from hl2
pTemp->entity.angles[2] = COM_RandomLong( 0, 360 );
}
noadditive = FBitSet( flags, TE_EXPLFLAG_NOADDITIVE );
drawalpha = FBitSet( flags, TE_EXPLFLAG_DRAWALPHA );
rotate = FBitSet( flags, TE_EXPLFLAG_ROTATE );
pTemp->entity.curstate.renderfx = kRenderFxNone;
pTemp->entity.baseline.origin[2] = 8;
pTemp->entity.origin[2] += 10;
pTemp->entity.curstate.scale = scale;
pTemp->entity.baseline.origin[2] = 8.0f;
pTemp->entity.origin[2] = pTemp->entity.origin[2] + 10.0f;
if( rotate )
pTemp->entity.angles[2] = COM_RandomFloat( 0.0, 360.0f );
pTemp->entity.curstate.rendermode = noadditive ? kRenderNormal :
drawalpha ? kRenderTransAlpha : kRenderTransAdd;
pTemp->entity.curstate.renderamt = noadditive ? 0xff : 0xb4;
pTemp->entity.curstate.renderfx = 0;
pTemp->entity.curstate.rendercolor.r = 0;
pTemp->entity.curstate.rendercolor.g = 0;
pTemp->entity.curstate.rendercolor.b = 0;
}
/*
@@ -2638,7 +2629,7 @@ void CL_UpdateFlashlight( cl_entity_t *ent )
vec3_t forward, view_ofs;
vec3_t vecSrc, vecEnd;
float falloff;
pmtrace_t *trace;
pmtrace_t trace;
cl_entity_t *hit;
dlight_t *dl;
@@ -2669,28 +2660,26 @@ void CL_UpdateFlashlight( cl_entity_t *ent )
VectorAdd( ent->origin, view_ofs, vecSrc );
VectorMA( vecSrc, FLASHLIGHT_DISTANCE, forward, vecEnd );
trace = CL_VisTraceLine( vecSrc, vecEnd, PM_STUDIO_BOX );
trace = CL_TraceLine( vecSrc, vecEnd, PM_STUDIO_BOX );
// update flashlight endpos
dl = CL_AllocDlight( ent->index );
#if 1
hit = CL_GetEntityByIndex( clgame.pmove->visents[trace->ent].info );
hit = CL_GetEntityByIndex( clgame.pmove->visents[trace.ent].info );
if( hit && hit->model && ( hit->model->type == mod_alias || hit->model->type == mod_studio ))
VectorCopy( hit->origin, dl->origin );
else VectorCopy( trace->endpos, dl->origin );
else VectorCopy( trace.endpos, dl->origin );
#else
VectorCopy( trace->endpos, dl->origin );
#endif
// compute falloff
falloff = trace->fraction * FLASHLIGHT_DISTANCE;
falloff = trace.fraction * FLASHLIGHT_DISTANCE;
if( falloff < 500.0f ) falloff = 1.0f;
else falloff = 500.0f / falloff;
falloff *= falloff;
// apply brigthness to dlight
dl->color.r = bound( 0, falloff * 255, 255 );
dl->color.g = bound( 0, falloff * 255, 255 );
dl->color.b = bound( 0, falloff * 255, 255 );
dl->color.r = dl->color.g = dl->color.b = bound( 0, falloff * 255, 255 );
dl->die = cl.time + 0.01f; // die on next frame
dl->radius = 80;
}
@@ -2852,10 +2841,10 @@ void CL_TestLights( void )
float f, r;
dlight_t *dl;
if( !CVAR_TO_BOOL( cl_testlights ))
if( !cl_testlights.value )
return;
numLights = bound( 1, cl_testlights->value, MAX_DLIGHTS );
numLights = bound( 1, cl_testlights.value, MAX_DLIGHTS );
AngleVectors( cl.viewangles, forward, right, NULL );
for( i = 0; i < numLights; i++ )
@@ -2928,7 +2917,15 @@ void CL_PlayerDecal( int playernum, int customIndex, int entityIndex, float *pos
{
if( !pCust->nUserData1 )
{
const char *decalname = va( "player%dlogo%d", playernum, customIndex );
int sprayTextureIndex;
char decalname[MAX_VA_STRING];
Q_snprintf( decalname, sizeof( decalname ), "player%dlogo%d", playernum, customIndex );
sprayTextureIndex = ref.dllFuncs.GL_FindTexture( decalname );
if( sprayTextureIndex != 0 )
{
ref.dllFuncs.GL_FreeTexture( sprayTextureIndex );
}
pCust->nUserData1 = GL_LoadTextureInternal( decalname, pCust->pInfo, TF_DECAL );
}
textureIndex = pCust->nUserData1;

View File

@@ -209,7 +209,7 @@ qboolean SCR_PlayCinematic( const char *arg )
if( FS_FileExists( arg, false ) && !fullpath )
{
Con_Printf( S_ERROR "Couldn't load %s from packfile. Please extract it\n", path );
Con_Printf( S_ERROR "Couldn't load %s from packfile. Please extract it\n", arg );
return false;
}

View File

@@ -39,7 +39,7 @@ void V_CalcViewRect( void )
{
// intermission is always full screen
if( cl.intermission ) size = 120.0f;
else size = scr_viewsize->value;
else size = scr_viewsize.value;
if( size >= 120.0f )
sb_lines = 0; // no status bar at all
@@ -47,12 +47,12 @@ void V_CalcViewRect( void )
sb_lines = 24; // no inventory
else sb_lines = 48;
if( scr_viewsize->value >= 100.0f )
if( scr_viewsize.value >= 100.0f )
{
full = true;
size = 100.0f;
}
else size = scr_viewsize->value;
else size = scr_viewsize.value;
if( cl.intermission )
{
@@ -144,7 +144,7 @@ void V_SetRefParams( ref_params_t *fd )
VectorCopy( cl.viewangles, fd->cl_viewangles );
fd->health = cl.local.health;
VectorCopy( cl.crosshairangle, fd->crosshairangle );
fd->viewsize = scr_viewsize->value;
fd->viewsize = scr_viewsize.value;
VectorCopy( cl.punchangle, fd->punchangle );
fd->maxclients = cl.maxclients;
@@ -229,6 +229,53 @@ void V_RefApplyOverview( ref_viewpass_t *rvp )
ref.dllFuncs.GL_OrthoBounds( mins, maxs );
}
/*
====================
V_CalcFov
====================
*/
static float V_CalcFov( float *fov_x, float width, float height )
{
float x, half_fov_y;
if( *fov_x < 1.0f || *fov_x > 179.0f )
*fov_x = 90.0f; // default value
x = width / tan( DEG2RAD( *fov_x ) * 0.5f );
half_fov_y = atan( height / x );
return RAD2DEG( half_fov_y ) * 2;
}
/*
====================
V_AdjustFov
====================
*/
static void V_AdjustFov( float *fov_x, float *fov_y, float width, float height, qboolean lock_x )
{
float x, y;
if( width * 3 == 4 * height || width * 4 == height * 5 )
{
// 4:3 or 5:4 ratio
return;
}
if( lock_x )
{
*fov_y = 2 * atan((width * 3) / (height * 4) * tan( *fov_y * M_PI_F / 360.0f * 0.5f )) * 360 / M_PI_F;
return;
}
y = V_CalcFov( fov_x, 640, 480 );
x = *fov_x;
*fov_x = V_CalcFov( &y, height, width );
if( *fov_x < x ) *fov_x = x;
else *fov_y = y;
}
/*
=============
V_GetRefParams
@@ -264,7 +311,7 @@ void V_GetRefParams( ref_params_t *fd, ref_viewpass_t *rvp )
rvp->fov_y = V_CalcFov( &rvp->fov_x, clgame.viewport[2], clgame.viewport[3] );
// adjust FOV for widescreen
if( refState.wideScreen && r_adjust_fov->value )
if( refState.wideScreen && r_adjust_fov.value )
V_AdjustFov( &rvp->fov_x, &rvp->fov_y, clgame.viewport[2], clgame.viewport[3], false );
rvp->flags = 0;
@@ -292,7 +339,7 @@ qboolean V_PreRender( void )
// if the screen is disabled (loading plaque is up)
if( cls.disable_screen )
{
if(( host.realtime - cls.disable_screen ) > cl_timeout->value )
if(( host.realtime - cls.disable_screen ) > cl_timeout.value )
{
Con_Reportf( "V_PreRender: loading plaque timed out\n" );
cls.disable_screen = 0.0f;
@@ -317,11 +364,13 @@ V_RenderView
*/
void V_RenderView( void )
{
ref_params_t rp;
// HACKHACK: make ref params static
// not really critical but allows client.dll to take address of refdef and don't trigger ASan
static ref_params_t rp;
ref_viewpass_t rvp;
int viewnum = 0;
if( !cl.video_prepped || ( !ui_renderworld->value && UI_IsVisible() && !cl.background ))
if( !cl.video_prepped || ( !ui_renderworld.value && UI_IsVisible() && !cl.background ))
return; // still loading
V_CalcViewRect (); // compute viewport rectangle
@@ -425,7 +474,7 @@ void R_ShowTree( void )
float y = NODE_INTERVAL_Y(1.0f);
mleaf_t *viewleaf;
if( !cl.worldmodel || !CVAR_TO_BOOL( r_showtree ))
if( !cl.worldmodel || !r_showtree.value )
return;
world.recursion_level = 0;

View File

@@ -108,7 +108,6 @@ extern int CL_UPDATE_BACKUP;
#define MIN_UPDATERATE 10.0f
#define MAX_UPDATERATE 102.0f
#define MIN_EX_INTERP 0.005f
#define MAX_EX_INTERP 0.1f
#define CL_MIN_RESEND_TIME 1.5f // mininum time gap (in seconds) before a subsequent connection request is sent.
@@ -139,7 +138,7 @@ typedef struct
int light_level;
int waterlevel;
int usehull;
int moving;
qboolean moving;
int pushmsec;
int weapons;
float maxspeed;
@@ -211,7 +210,7 @@ typedef struct
// a lerp point for other data
double oldtime; // previous cl.time, time-oldtime is used
// to decay light values and smooth step ups
float timedelta; // floating delta between two updates
double timedelta; // floating delta between two updates
char serverinfo[MAX_SERVERINFO_STRING];
player_info_t players[MAX_CLIENTS]; // collected info about all other players include himself
@@ -319,32 +318,46 @@ typedef struct
pfnEventHook func; // user-defined function
} cl_user_event_t;
#define FONT_FIXED 0
#define FONT_VARIABLE 1
#define FONT_FIXED 0
#define FONT_VARIABLE 1
#define FONT_DRAW_HUD BIT( 0 ) // pass to drawing function to apply hud_scale
#define FONT_DRAW_UTF8 BIT( 1 ) // call UtfProcessChar
#define FONT_DRAW_FORCECOL BIT( 2 ) // ignore colorcodes
#define FONT_DRAW_NORENDERMODE BIT( 3 ) // ignore font's default rendermode
#define FONT_DRAW_NOLF BIT( 4 ) // ignore \n
#define FONT_DRAW_RESETCOLORONLF BIT( 5 ) // yet another flag to simulate consecutive Con_DrawString calls...
typedef struct
{
int hFontTexture; // handle to texture
wrect_t fontRc[256]; // rectangles
byte charWidths[256];
int charHeight;
int type;
qboolean valid; // all rectangles are valid
int hFontTexture; // handle to texture
wrect_t fontRc[256]; // tex coords
float scale; // scale factor
byte charWidths[256]; // scaled widths
int charHeight; // scaled height
int type; // fixed width font or variable
int rendermode; // default rendermode
qboolean nearest; // nearest filtering enabled
qboolean valid; // all rectangles are valid
} cl_font_t;
typedef struct scissor_state_s
{
int x;
int y;
int width;
int height;
qboolean test;
} scissor_state_t;
typedef struct
{
// scissor test
scissor_state_t scissor;
// temp handle
const model_t *pSprite; // pointer to current SpriteTexture
// scissor test
int scissor_x;
int scissor_y;
int scissor_width;
int scissor_height;
qboolean scissor_test;
qboolean adjust_size; // allow to adjust scale for fonts
int renderMode; // override kRenderMode from TriAPI
TRICULLSTYLE cullMode; // override CULL FACE from TriAPI
@@ -371,14 +384,10 @@ typedef struct cl_predicted_player_s
typedef struct
{
int gl_texturenum; // this is a real texnum
// scissor test
int scissor_x;
int scissor_y;
int scissor_width;
int scissor_height;
qboolean scissor_test;
scissor_state_t scissor;
int gl_texturenum; // this is a real texnum
// holds text color
rgba_t textColor;
@@ -414,13 +423,6 @@ typedef struct
float applied_angle;
} screen_shake_t;
typedef enum
{
NET_REQUEST_CANCEL = 0, // request was cancelled for some reasons
NET_REQUEST_GAMEUI, // called from GameUI
NET_REQUEST_CLIENT, // called from Client
} net_request_type_t;
typedef struct
{
net_response_t resp;
@@ -482,9 +484,7 @@ typedef struct
client_textmessage_t *titles; // title messages, not network messages
int numTitles;
net_request_type_t request_type; // filter the requests
net_request_t net_requests[MAX_REQUESTS]; // no reason to keep more
net_request_t *master_request; // queued master request
efrag_t *free_efrags; // linked efrags
cl_entity_t viewent; // viewmodel
@@ -618,7 +618,10 @@ typedef struct
file_t *demofile;
file_t *demoheader; // contain demo startup info in case we record a demo on this level
qboolean internetservers_wait; // internetservers is waiting for dns request
qboolean internetservers_pending; // internetservers is waiting for dns request
qboolean internetservers_pending; // if true, clean master server pings
uint32_t internetservers_key; // compare key to validate master server reply
char internetservers_query[512]; // cached query
uint32_t internetservers_query_len;
// legacy mode support
qboolean legacymode; // one-way 48 protocol compatibility
@@ -650,45 +653,47 @@ extern convar_t cl_logocolor;
extern convar_t cl_allow_download;
extern convar_t cl_allow_upload;
extern convar_t cl_download_ingame;
extern convar_t *cl_nopred;
extern convar_t *cl_timeout;
extern convar_t *cl_nodelta;
extern convar_t *cl_interp;
extern convar_t *cl_nointerp;
extern convar_t *cl_showerror;
extern convar_t *cl_nosmooth;
extern convar_t *cl_smoothtime;
extern convar_t *cl_crosshair;
extern convar_t *cl_testlights;
extern convar_t *cl_cmdrate;
extern convar_t *cl_updaterate;
extern convar_t *cl_solid_players;
extern convar_t *cl_idealpitchscale;
extern convar_t *cl_allow_levelshots;
extern convar_t *cl_lightstyle_lerping;
extern convar_t *cl_draw_particles;
extern convar_t *cl_draw_tracers;
extern convar_t *cl_levelshot_name;
extern convar_t *cl_draw_beams;
extern convar_t *cl_clockreset;
extern convar_t *cl_fixtimerate;
extern convar_t *hud_scale;
extern convar_t *gl_showtextures;
extern convar_t *cl_bmodelinterp;
extern convar_t *cl_lw; // local weapons
extern convar_t *cl_charset;
extern convar_t *cl_trace_messages;
extern convar_t *hud_utf8;
extern convar_t *cl_showevents;
extern convar_t *scr_centertime;
extern convar_t *scr_viewsize;
extern convar_t *scr_loading;
extern convar_t *v_dark; // start from dark
extern convar_t *net_graph;
extern convar_t *rate;
extern convar_t *m_ignore;
extern convar_t *r_showtree;
extern convar_t *ui_renderworld;
extern convar_t cl_nopred;
extern convar_t cl_timeout;
extern convar_t cl_nodelta;
extern convar_t cl_interp;
extern convar_t cl_nointerp;
extern convar_t cl_showerror;
extern convar_t cl_nosmooth;
extern convar_t cl_smoothtime;
extern convar_t cl_crosshair;
extern convar_t cl_testlights;
extern convar_t cl_cmdrate;
extern convar_t cl_updaterate;
extern convar_t cl_solid_players;
extern convar_t cl_idealpitchscale;
extern convar_t cl_allow_levelshots;
extern convar_t cl_lightstyle_lerping;
extern convar_t cl_draw_particles;
extern convar_t cl_draw_tracers;
extern convar_t cl_levelshot_name;
extern convar_t cl_draw_beams;
extern convar_t cl_clockreset;
extern convar_t cl_fixtimerate;
extern convar_t hud_fontscale;
extern convar_t hud_scale;
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_messages;
extern convar_t cl_trace_events;
extern convar_t hud_utf8;
extern convar_t cl_showevents;
extern convar_t scr_centertime;
extern convar_t scr_viewsize;
extern convar_t scr_loading;
extern convar_t v_dark; // start from dark
extern convar_t net_graph;
extern convar_t rate;
extern convar_t m_ignore;
extern convar_t r_showtree;
extern convar_t ui_renderworld;
//=============================================================================
@@ -795,6 +800,20 @@ void CL_ResetEvent( event_info_t *ei );
word CL_EventIndex( const char *name );
void CL_FireEvents( void );
//
// cl_font.c
//
qboolean CL_FixedFont( cl_font_t *font );
qboolean Con_LoadFixedWidthFont( const char *fontname, cl_font_t *font, float scale, int rendermode, uint texFlags );
qboolean Con_LoadVariableWidthFont( const char *fontname, cl_font_t *font, float scale, int rendermode, uint texFlags );
void CL_FreeFont( 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 );
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( 6 );
//
// cl_game.c
//
@@ -805,37 +824,35 @@ void CL_LinkUserMessage( char *pszName, const int svc_num, int iSize );
void CL_ParseFinaleCutscene( sizebuf_t *msg, int level );
void CL_ParseTextMessage( sizebuf_t *msg );
void CL_DrawHUD( int state );
void CL_InitEdicts( void );
void CL_InitEdicts( int maxclients );
void CL_FreeEdicts( void );
void CL_ClearWorld( void );
void CL_DrawCenterPrint( void );
void CL_ClearSpriteTextures( void );
void CL_FreeEntity( cl_entity_t *pEdict );
void CL_CenterPrint( const char *text, float y );
void CL_TextMessageParse( byte *pMemFile, int fileSize );
client_textmessage_t *CL_TextMessageGet( const char *pName );
int pfnDecalIndexFromName( const char *szDecalName );
int pfnIndexFromTrace( struct pmtrace_s *pTrace );
model_t *CL_ModelHandle( int modelindex );
void NetAPI_CancelAllRequests( void );
int CL_FindModelIndex( const char *m );
cl_entity_t *CL_GetLocalPlayer( void );
model_t *CL_LoadClientSprite( const char *filename );
model_t *CL_LoadModel( const char *modelname, int *index );
HSPRITE EXPORT pfnSPR_Load( const char *szPicName );
HSPRITE pfnSPR_LoadExt( const char *szPicName, uint texFlags );
void PicAdjustSize( float *x, float *y, float *w, float *h );
void SPR_AdjustSize( float *x, float *y, float *w, float *h );
void SPR_AdjustTexCoords( float width, float height, float *s1, float *t1, float *s2, float *t2 );
int CL_GetScreenInfo( SCREENINFO *pscrinfo );
void CL_FillRGBA( int x, int y, int width, int height, int r, int g, int b, int a );
void CL_PlayerTrace( float *start, float *end, int traceFlags, int ignore_pe, pmtrace_t *tr );
void CL_PlayerTraceExt( float *start, float *end, int traceFlags, int (*pfnIgnore)( physent_t *pe ), pmtrace_t *tr );
void CL_SetTraceHull( int hull );
pmtrace_t *PM_CL_TraceLine( float *start, float *end, int flags, int usehull, int ignore_pe );
const char *PM_CL_TraceTexture( int ground, float *vstart, float *vend );
int PM_CL_PointContents( const float *p, int *truecontents );
void CL_GetMousePosition( int *mx, int *my ); // TODO: move to input
cl_entity_t* CL_GetViewModel( void );
void pfnGetScreenFade( struct screenfade_s *fade );
physent_t *pfnGetPhysent( int idx );
struct msurface_s *pfnTraceSurface( int ground, float *vstart, float *vend );
movevars_t *pfnGetMoveVars( void );
void CL_EnableScissor( scissor_state_t *scissor, int x, int y, int width, int height );
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 );
_inline cl_entity_t *CL_EDICT_NUM( int n )
{
@@ -855,18 +872,45 @@ _inline cl_entity_t *CL_EDICT_NUM( int n )
//
// cl_parse.c
//
void CL_ParseSetAngle( sizebuf_t *msg );
void CL_ParseServerData( sizebuf_t *msg, qboolean legacy );
void CL_ParseLightStyle( sizebuf_t *msg );
void CL_UpdateUserinfo( sizebuf_t *msg, qboolean legacy );
void CL_ParseResource( sizebuf_t *msg );
void CL_ParseClientData( sizebuf_t *msg );
void CL_UpdateUserPings( sizebuf_t *msg );
void CL_ParseParticles( sizebuf_t *msg );
void CL_ParseRestoreSoundPacket( sizebuf_t *msg );
void CL_ParseBaseline( sizebuf_t *msg, qboolean legacy );
void CL_ParseSignon( sizebuf_t *msg );
void CL_ParseRestore( sizebuf_t *msg );
void CL_ParseStaticDecal( sizebuf_t *msg );
void CL_ParseAddAngle( sizebuf_t *msg );
void CL_RegisterUserMessage( sizebuf_t *msg );
void CL_ParseMovevars( sizebuf_t *msg );
void CL_ParseResourceRequest( sizebuf_t *msg );
void CL_ParseCustomization( sizebuf_t *msg );
void CL_ParseCrosshairAngle( sizebuf_t *msg );
void CL_ParseSoundFade( sizebuf_t *msg );
void CL_ParseFileTransferFailed( sizebuf_t *msg );
void CL_ParseHLTV( sizebuf_t *msg );
void CL_ParseDirector( sizebuf_t *msg );
void CL_ParseResLocation( sizebuf_t *msg );
void CL_ParseCvarValue( sizebuf_t *msg, const qboolean ext );
void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message );
void CL_ParseLegacyServerMessage( sizebuf_t *msg, qboolean normal_message );
void CL_LegacyPrecache_f( void );
void CL_ParseTempEntity( sizebuf_t *msg );
void CL_StartResourceDownloading( const char *pszMessage, qboolean bCustom );
qboolean CL_DispatchUserMessage( const char *pszName, int iSize, void *pbuf );
qboolean CL_RequestMissingResources( void );
void CL_RegisterResources ( sizebuf_t *msg );
void CL_ParseViewEntity( sizebuf_t *msg );
void CL_ParseServerTime( sizebuf_t *msg );
//
// cl_parse_48.c
//
void CL_ParseLegacyServerMessage( sizebuf_t *msg, qboolean normal_message );
void CL_LegacyPrecache_f( void );
//
// cl_scrn.c
//
@@ -911,10 +955,8 @@ void CL_PredictMovement( qboolean repredicting );
void CL_CheckPredictionError( void );
qboolean CL_IsPredicted( void );
int CL_TruePointContents( const vec3_t p );
int CL_PointContents( const vec3_t p );
int CL_WaterEntity( const float *rgflPos );
cl_entity_t *CL_GetWaterEntity( const float *rgflPos );
void CL_SetupPMove( playermove_t *pmove, local_state_t *from, usercmd_t *ucmd, qboolean runfuncs, double time );
int CL_TestLine( const vec3_t start, const vec3_t end, int flags );
pmtrace_t *CL_VisTraceLine( vec3_t start, vec3_t end, int flags );
pmtrace_t CL_TraceLine( vec3_t start, vec3_t end, int flags );
@@ -923,7 +965,6 @@ void CL_PopTraceBounds( void );
void CL_MoveSpectatorCamera( void );
void CL_SetLastUpdate( void );
void CL_RedoPrediction( void );
void CL_ClearPhysEnts( void );
void CL_PushPMStates( void );
void CL_PopPMStates( void );
void CL_SetUpPlayerPrediction( int dopred, int bIncludeLocalClient );
@@ -964,7 +1005,7 @@ void CL_ClearAllRemaps( void );
// cl_render.c
//
qboolean R_InitRenderAPI( void );
int CL_RenderGetParm( const int parm, const int arg, const qboolean checkRef );
intptr_t CL_RenderGetParm( const int parm, const int arg, const qboolean checkRef );
lightstyle_t *CL_GetLightStyle( int number );
int R_FatPVS( const vec3_t org, float radius, byte *visbuffer, qboolean merge, qboolean fullvis );
const ref_overview_t *GL_GetOverviewParms( void );
@@ -974,12 +1015,10 @@ const ref_overview_t *GL_GetOverviewParms( void );
//
void R_StoreEfrags( efrag_t **ppefrag, int framecount );
void R_AddEfrags( cl_entity_t *ent );
void R_RemoveEfrags( cl_entity_t *ent );
//
// cl_tent.c
//
struct particle_s;
int CL_AddEntity( int entityType, cl_entity_t *pEnt );
void CL_WeaponAnim( int iAnim, int body );
void CL_ClearEffects( void );
void CL_ClearEfrags( void );
@@ -1013,7 +1052,7 @@ void CL_RunLightStyles( void );
//
// console.c
//
extern convar_t *con_fontsize;
extern convar_t con_fontsize;
int Con_Visible( void );
qboolean Con_FixedFont( void );
void Con_VidInit( void );
@@ -1028,13 +1067,13 @@ int Con_UtfProcessChar( int in );
int Con_UtfProcessCharForce( int in );
int Con_UtfMoveLeft( char *str, int pos );
int Con_UtfMoveRight( char *str, int pos, int length );
void Con_DrawStringLen( const char *pText, int *length, int *height );
int Con_DrawString( int x, int y, const char *string, rgba_t setColor );
int Con_DrawCharacter( int x, int y, int number, rgba_t color );
void Con_DrawCharacterLen( int number, int *width, int *height );
void Con_DefaultColor( int r, int g, int b );
void Con_InvalidateFonts( void );
void Con_SetFont( int fontNum );
cl_font_t *Con_GetCurFont( void );
cl_font_t *Con_GetFont( int num );
void Con_DrawCharacterLen( int number, int *width, int *height );
int Con_DrawString( int x, int y, const char *string, 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 Con_RestoreFont( void );
void Key_Console( int key );
@@ -1129,7 +1168,6 @@ void CL_PlayVideo_f( void );
// keys.c
//
int Key_IsDown( int keynum );
const char *Key_IsBind( int keynum );
void Key_Event( int key, int down );
void Key_Init( void );
void Key_WriteBindings( file_t *f );

View File

@@ -22,13 +22,14 @@ GNU General Public License for more details.
#include "wadfile.h"
#include "input.h"
convar_t *con_notifytime;
convar_t *scr_conspeed;
convar_t *con_fontsize;
convar_t *con_charset;
convar_t *con_fontscale;
convar_t *con_fontnum;
convar_t *con_color;
static CVAR_DEFINE_AUTO( scr_conspeed, "600", FCVAR_ARCHIVE, "console moving speed" );
static CVAR_DEFINE_AUTO( con_notifytime, "3", FCVAR_ARCHIVE, "notify time to live" );
CVAR_DEFINE_AUTO( con_fontsize, "1", FCVAR_ARCHIVE, "console font number (0, 1 or 2)" );
static CVAR_DEFINE_AUTO( con_charset, "cp1251", FCVAR_ARCHIVE, "console font charset (only cp1251 supported now)" );
static CVAR_DEFINE_AUTO( con_fontscale, "1.0", FCVAR_ARCHIVE, "scale font texture" );
static CVAR_DEFINE_AUTO( con_fontnum, "-1", FCVAR_ARCHIVE, "console font number (0, 1 or 2), -1 for autoselect" );
static CVAR_DEFINE_AUTO( con_color, "240 180 24", FCVAR_ARCHIVE, "set a custom console color" );
static int g_codepage = 0;
static qboolean g_utf8 = false;
@@ -116,7 +117,7 @@ typedef struct
// console fonts
cl_font_t chars[CON_NUMFONTS];// fonts.wad/font1.fnt
cl_font_t *curFont, *lastUsedFont;
cl_font_t *curFont;
// console input
field_t input;
@@ -162,14 +163,13 @@ Con_SetColor
*/
static void Con_SetColor( void )
{
vec3_t color;
int r, g, b;
int num;
if( !FBitSet( con_color->flags, FCVAR_CHANGED ))
if( !FBitSet( con_color.flags, FCVAR_CHANGED ))
return;
num = sscanf( con_color->string, "%i %i %i", &r, &g, &b );
num = sscanf( con_color.string, "%i %i %i", &r, &g, &b );
switch( num )
{
@@ -180,11 +180,11 @@ static void Con_SetColor( void )
Con_DefaultColor( r, g, b );
break;
default:
Cvar_DirectSet( con_color, con_color->def_string );
Cvar_DirectSet( &con_color, con_color.def_string );
break;
}
ClearBits( con_color->flags, FCVAR_CHANGED );
ClearBits( con_color.flags, FCVAR_CHANGED );
}
/*
@@ -213,37 +213,6 @@ void Con_ClearTyping( void )
Cmd_AutoCompleteClear();
}
/*
============
Con_StringLength
skipped color prefixes
============
*/
int Con_StringLength( const char *string )
{
int len;
const char *p;
if( !string ) return 0;
len = 0;
p = string;
while( *p )
{
if( IsColorString( p ))
{
p += 2;
continue;
}
len++;
p++;
}
return len;
}
/*
================
Con_MessageMode_f
@@ -555,89 +524,9 @@ Con_FixedFont
*/
qboolean Con_FixedFont( void )
{
if( con.curFont && con.curFont->valid && con.curFont->type == FONT_FIXED )
return true;
return false;
return CL_FixedFont( con.curFont );
}
static qboolean Con_LoadFixedWidthFont( const char *fontname, cl_font_t *font )
{
int i, fontWidth;
if( font->valid )
return true; // already loaded
if( !FS_FileExists( fontname, false ))
return false;
// keep source to print directly into conback image
font->hFontTexture = ref.dllFuncs.GL_LoadTexture( fontname, NULL, 0, TF_FONT|TF_KEEP_SOURCE );
R_GetTextureParms( &fontWidth, NULL, font->hFontTexture );
if( font->hFontTexture && fontWidth != 0 )
{
font->charHeight = fontWidth / 16 * con_fontscale->value;
font->type = FONT_FIXED;
// build fixed rectangles
for( i = 0; i < 256; i++ )
{
font->fontRc[i].left = (i * (fontWidth / 16)) % fontWidth;
font->fontRc[i].right = font->fontRc[i].left + fontWidth / 16;
font->fontRc[i].top = (i / 16) * (fontWidth / 16);
font->fontRc[i].bottom = font->fontRc[i].top + fontWidth / 16;
font->charWidths[i] = fontWidth / 16 * con_fontscale->value;
}
font->valid = true;
}
return true;
}
static qboolean Con_LoadVariableWidthFont( const char *fontname, cl_font_t *font )
{
int i, fontWidth;
byte *buffer;
fs_offset_t length;
qfont_t *src;
if( font->valid )
return true; // already loaded
if( !FS_FileExists( fontname, false ))
return false;
font->hFontTexture = ref.dllFuncs.GL_LoadTexture( fontname, NULL, 0, TF_FONT|TF_NEAREST );
R_GetTextureParms( &fontWidth, NULL, font->hFontTexture );
// setup consolefont
if( font->hFontTexture && fontWidth != 0 )
{
// half-life font with variable chars witdh
buffer = FS_LoadFile( fontname, &length, false );
if( buffer && length >= sizeof( qfont_t ))
{
src = (qfont_t *)buffer;
font->charHeight = src->rowheight * con_fontscale->value;
font->type = FONT_VARIABLE;
// build rectangles
for( i = 0; i < 256; i++ )
{
font->fontRc[i].left = (word)src->fontinfo[i].startoffset % fontWidth;
font->fontRc[i].right = font->fontRc[i].left + src->fontinfo[i].charwidth;
font->fontRc[i].top = (word)src->fontinfo[i].startoffset / fontWidth;
font->fontRc[i].bottom = font->fontRc[i].top + src->rowheight;
font->charWidths[i] = src->fontinfo[i].charwidth * con_fontscale->value;
}
font->valid = true;
}
if( buffer ) Mem_Free( buffer );
}
return true;
}
/*
================
@@ -648,32 +537,46 @@ INTERNAL RESOURCE
*/
static void Con_LoadConsoleFont( int fontNumber, cl_font_t *font )
{
const char *path = NULL;
dword crc = 0;
qboolean success = false;
float scale = con_fontscale.value;
if( font->valid ) return; // already loaded
// replace default fonts.wad textures by current charset's font
if( !CRC32_File( &crc, "fonts.wad" ) || crc == 0x3c0a0029 )
{
const char *path2 = va("font%i_%s.fnt", fontNumber, Cvar_VariableString( "con_charset" ) );
if( FS_FileExists( path2, false ) )
path = path2;
}
if( font->valid )
return; // already loaded
// loading conchars
if( Sys_CheckParm( "-oldfont" ))
Con_LoadVariableWidthFont( "gfx/conchars.fnt", font );
{
success = Con_LoadVariableWidthFont( "gfx/conchars.fnt", font, scale, kRenderTransTexture, TF_FONT|TF_NEAREST );
}
else
{
if( !path )
path = va( "fonts/font%i", fontNumber );
string path;
dword crc = 0;
Con_LoadVariableWidthFont( path, font );
// replace default fonts.wad textures by current charset's font
if( !CRC32_File( &crc, "fonts.wad" ) || crc == 0x3c0a0029 )
{
if( Q_snprintf( path, sizeof( path ),
"font%i_%s.fnt", fontNumber, Cvar_VariableString( "con_charset" )) > 0 )
{
success = Con_LoadVariableWidthFont( path, font, scale, kRenderTransTexture, TF_FONT|TF_NEAREST );
}
}
if( !success )
{
Q_snprintf( path, sizeof( path ), "fonts/font%i", fontNumber );
success = Con_LoadVariableWidthFont( path, font, scale, kRenderTransTexture, TF_FONT|TF_NEAREST );
}
}
// quake fixed font as fallback
if( !font->valid ) Con_LoadFixedWidthFont( "gfx/conchars", font );
if( !success )
{
// quake fixed font as fallback
// keep source to print directly into conback image
if( !Con_LoadFixedWidthFont( "gfx/conchars", font, scale, kRenderTransTexture, TF_FONT|TF_KEEP_SOURCE ))
Con_DPrintf( S_ERROR "failed to load console font\n" );
}
}
/*
@@ -690,8 +593,8 @@ static void Con_LoadConchars( void )
Con_LoadConsoleFont( i, con.chars + i );
// select properly fontsize
if( con_fontnum->value >= 0 && con_fontnum->value <= CON_NUMFONTS - 1 )
fontSize = con_fontnum->value;
if( con_fontnum.value >= 0 && con_fontnum.value <= CON_NUMFONTS - 1 )
fontSize = con_fontnum.value;
else if( refState.width <= 640 )
fontSize = 0;
else if( refState.width >= 1280 )
@@ -702,7 +605,7 @@ static void Con_LoadConchars( void )
fontSize = CON_NUMFONTS - 1;
// sets the current font
con.lastUsedFont = con.curFont = &con.chars[fontSize];
con.curFont = &con.chars[fontSize];
}
// CP1251 table
@@ -875,129 +778,25 @@ static void Con_DrawCharToConback( int num, const byte *conchars, byte *dest )
/*
====================
Con_TextAdjustSize
Con_GetFont
draw charcters routine
====================
*/
static void Con_TextAdjustSize( int *x, int *y, int *w, int *h )
cl_font_t *Con_GetFont( int num )
{
float xscale, yscale;
if( !x && !y && !w && !h ) return;
// scale for screen sizes
xscale = (float)refState.width / (float)clgame.scrInfo.iWidth;
yscale = (float)refState.height / (float)clgame.scrInfo.iHeight;
if( x ) *x *= xscale;
if( y ) *y *= yscale;
if( w ) *w *= xscale;
if( h ) *h *= yscale;
num = bound( 0, num, CON_NUMFONTS - 1 );
return &con.chars[num];
}
/*
====================
Con_DrawGenericChar
Con_GetCurFont
draw console single character
====================
*/
static int Con_DrawGenericChar( int x, int y, int number, rgba_t color )
cl_font_t *Con_GetCurFont( void )
{
int width, height;
float s1, t1, s2, t2;
wrect_t *rc;
number &= 255;
if( !con.curFont || !con.curFont->valid )
return 0;
number = Con_UtfProcessChar( number );
if( !number )
return 0;
if( y < -con.curFont->charHeight )
return 0;
rc = &con.curFont->fontRc[number];
R_GetTextureParms( &width, &height, con.curFont->hFontTexture );
if( !width || !height )
return con.curFont->charWidths[number];
// don't apply color to fixed fonts it's already colored
if( con.curFont->type != FONT_FIXED || REF_GET_PARM( PARM_TEX_GLFORMAT, con.curFont->hFontTexture ) == 0x8045 ) // GL_LUMINANCE8_ALPHA8
ref.dllFuncs.Color4ub( color[0], color[1], color[2], color[3] );
else ref.dllFuncs.Color4ub( 255, 255, 255, color[3] );
// calc rectangle
s1 = (float)rc->left / width;
t1 = (float)rc->top / height;
s2 = (float)rc->right / width;
t2 = (float)rc->bottom / height;
width = ( rc->right - rc->left ) * con_fontscale->value;
height = ( rc->bottom - rc->top ) * con_fontscale->value;
if( clgame.ds.adjust_size )
Con_TextAdjustSize( &x, &y, &width, &height );
ref.dllFuncs.R_DrawStretchPic( x, y, width, height, s1, t1, s2, t2, con.curFont->hFontTexture );
ref.dllFuncs.Color4ub( 255, 255, 255, 255 ); // don't forget reset color
return con.curFont->charWidths[number];
}
/*
====================
Con_SetFont
choose font size
====================
*/
void Con_SetFont( int fontNum )
{
fontNum = bound( 0, fontNum, CON_NUMFONTS - 1 );
con.curFont = &con.chars[fontNum];
}
/*
====================
Con_RestoreFont
restore auto-selected console font
(that based on screen resolution)
====================
*/
void Con_RestoreFont( void )
{
con.curFont = con.lastUsedFont;
}
/*
====================
Con_DrawCharacter
client version of routine
====================
*/
int Con_DrawCharacter( int x, int y, int number, rgba_t color )
{
ref.dllFuncs.GL_SetRenderMode( kRenderTransTexture );
return Con_DrawGenericChar( x, y, number, color );
}
/*
====================
Con_DrawCharacterLen
returns character sizes in screen pixels
====================
*/
void Con_DrawCharacterLen( int number, int *width, int *height )
{
if( width && con.curFont ) *width = con.curFont->charWidths[number];
if( height && con.curFont ) *height = con.curFont->charHeight;
return con.curFont;
}
/*
@@ -1009,105 +808,7 @@ compute string width and height in screen pixels
*/
void GAME_EXPORT Con_DrawStringLen( const char *pText, int *length, int *height )
{
int curLength = 0;
if( !con.curFont )
return;
if( height )
*height = con.curFont->charHeight;
if (!length)
return;
*length = 0;
while( *pText )
{
byte c = *pText;
if( *pText == '\n' )
{
pText++;
curLength = 0;
}
// skip color strings they are not drawing
if( IsColorString( pText ))
{
pText += 2;
continue;
}
// Convert to unicode
c = Con_UtfProcessChar( c );
if( c )
curLength += con.curFont->charWidths[c];
pText++;
if( curLength > *length )
*length = curLength;
}
}
/*
==================
Con_DrawString
Draws a multi-colored string, optionally forcing
to a fixed color.
==================
*/
int Con_DrawGenericString( int x, int y, const char *string, rgba_t setColor, qboolean forceColor, int hideChar )
{
rgba_t color;
int drawLen = 0;
int numDraws = 0;
const char *s;
if( !con.curFont ) return 0; // no font set
Con_UtfProcessChar( 0 );
// draw the colored text
memcpy( color, setColor, sizeof( color ));
s = string;
while( *s )
{
if( *s == '\n' )
{
s++;
if( !*s ) break; // at end the string
drawLen = 0; // begin new row
y += con.curFont->charHeight;
}
if( IsColorString( s ))
{
if( !forceColor )
{
memcpy( color, g_color_table[ColorIndex(*(s+1))], sizeof( color ));
color[3] = setColor[3];
}
s += 2;
numDraws++;
continue;
}
// hide char for overstrike mode
if( hideChar == numDraws )
drawLen += con.curFont->charWidths[*s];
else drawLen += Con_DrawCharacter( x + drawLen, y, *s, color );
numDraws++;
s++;
}
ref.dllFuncs.Color4ub( 255, 255, 255, 255 );
return drawLen;
CL_DrawStringLen( con.curFont, pText, length, height, FONT_DRAW_UTF8 );
}
/*
@@ -1119,10 +820,9 @@ client version of routine
*/
int Con_DrawString( int x, int y, const char *string, rgba_t setColor )
{
return Con_DrawGenericString( x, y, string, setColor, false, -1 );
return CL_DrawString( x, y, string, setColor, con.curFont, FONT_DRAW_UTF8 );
}
/*
================
Con_Init
@@ -1130,19 +830,17 @@ Con_Init
*/
void Con_Init( void )
{
int i;
if( host.type == HOST_DEDICATED )
return; // dedicated server already have console
// must be init before startup video subsystem
scr_conspeed = Cvar_Get( "scr_conspeed", "600", FCVAR_ARCHIVE, "console moving speed" );
con_notifytime = Cvar_Get( "con_notifytime", "3", FCVAR_ARCHIVE, "notify time to live" );
con_fontsize = Cvar_Get( "con_fontsize", "1", FCVAR_ARCHIVE, "console font number (0, 1 or 2)" );
con_charset = Cvar_Get( "con_charset", "cp1251", FCVAR_ARCHIVE, "console font charset (only cp1251 supported now)" );
con_fontscale = Cvar_Get( "con_fontscale", "1.0", FCVAR_ARCHIVE, "scale font texture" );
con_fontnum = Cvar_Get( "con_fontnum", "-1", FCVAR_ARCHIVE, "console font number (0, 1 or 2), -1 for autoselect" );
con_color = Cvar_Get( "con_color", "240 180 24", FCVAR_ARCHIVE, "set a custom console color" );
Cvar_RegisterVariable( &scr_conspeed );
Cvar_RegisterVariable( &con_notifytime );
Cvar_RegisterVariable( &con_fontsize );
Cvar_RegisterVariable( &con_charset );
Cvar_RegisterVariable( &con_fontscale );
Cvar_RegisterVariable( &con_fontnum );
Cvar_RegisterVariable( &con_color );
// init the console buffer
con.bufsize = CON_TEXTSIZE;
@@ -1499,7 +1197,7 @@ void Field_KeyDownEvent( field_t *edit, int key )
return;
}
if( key == K_BACKSPACE )
if( key == K_BACKSPACE || key == K_X_BUTTON )
{
if( edit->cursor > 0 )
{
@@ -1511,7 +1209,7 @@ void Field_KeyDownEvent( field_t *edit, int key )
return;
}
if( key == K_RIGHTARROW )
if( key == K_RIGHTARROW || key == K_DPAD_RIGHT )
{
if( edit->cursor < len ) edit->cursor = Con_UtfMoveRight( edit->buffer, edit->cursor, edit->widthInChars );
if( edit->cursor >= edit->scroll + edit->widthInChars && edit->cursor <= len )
@@ -1519,7 +1217,7 @@ void Field_KeyDownEvent( field_t *edit, int key )
return;
}
if( key == K_LEFTARROW )
if( key == K_LEFTARROW || key == K_DPAD_LEFT )
{
if( edit->cursor > 0 ) edit->cursor = Con_UtfMoveLeft( edit->buffer, edit->cursor );
if( edit->cursor < edit->scroll ) edit->scroll--;
@@ -1614,7 +1312,7 @@ Field_DrawInputLine
void Field_DrawInputLine( int x, int y, field_t *edit )
{
int len, cursorChar;
int drawLen, hideChar = -1;
int drawLen;
int prestep, curPos;
char str[MAX_SYSPATH];
byte *colorDefault;
@@ -1651,35 +1349,23 @@ void Field_DrawInputLine( int x, int y, field_t *edit )
// save char for overstrike
cursorChar = str[edit->cursor - prestep];
if( host.key_overstrike && cursorChar && !((int)( host.realtime * 4 ) & 1 ))
hideChar = edit->cursor - prestep; // skip this char
// draw it
Con_DrawGenericString( x, y, str, colorDefault, false, hideChar );
CL_DrawString( x, y, str, colorDefault, con.curFont, FONT_DRAW_UTF8 );
// draw the cursor
if((int)( host.realtime * 4 ) & 1 ) return; // off blink
// calc cursor position
str[edit->cursor - prestep] = 0;
Con_DrawStringLen( str, &curPos, NULL );
Con_UtfProcessChar( 0 );
CL_DrawStringLen( con.curFont, str, &curPos, NULL, FONT_DRAW_UTF8 );
if( host.key_overstrike && cursorChar )
if( host.key_overstrike )
{
// overstrike cursor
#if 0
pglEnable( GL_BLEND );
pglDisable( GL_ALPHA_TEST );
pglBlendFunc( GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA );
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
#endif
Con_DrawGenericChar( x + curPos, y, cursorChar, colorDefault );
CL_DrawCharacter( x + curPos, y, '|', colorDefault, con.curFont, 0 );
}
else
{
Con_UtfProcessChar( 0 );
Con_DrawCharacter( x + curPos, y, '_', colorDefault );
CL_DrawCharacter( x + curPos, y, '_', colorDefault, con.curFont, 0 );
}
}
@@ -1793,6 +1479,10 @@ static void Con_SaveHistory( con_history_t *self )
int historyStart = self->next - CON_HISTORY, i;
file_t *f;
// do not save history if nothing was executed
if( self->next == 0 )
return;
if( historyStart < 0 )
historyStart = 0;
@@ -1828,8 +1518,8 @@ void Key_Console( int key )
return;
}
// enter finishes the line
if( key == K_ENTER || key == K_KP_ENTER )
// enter or A finish the line
if( key == K_ENTER || key == K_KP_ENTER || key == K_A_BUTTON )
{
// backslash text are commands, else chat
if( con.input.buffer[0] == '\\' || con.input.buffer[0] == '/' )
@@ -1856,7 +1546,7 @@ void Key_Console( int key )
}
// command completion
if( key == K_TAB )
if( key == K_TAB || key == K_L2_BUTTON )
{
Con_CompleteCommand( &con.input );
Con_Bottom();
@@ -1877,13 +1567,13 @@ void Key_Console( int key )
}
// console scrolling
if( key == K_PGUP )
if( key == K_PGUP || key == K_DPAD_UP )
{
Con_PageUp( 1 );
return;
}
if( key == K_PGDN )
if( key == K_PGDN || key == K_DPAD_DOWN )
{
Con_PageDown( 1 );
return;
@@ -1919,6 +1609,23 @@ void Key_Console( int key )
return;
}
// enable the OSK with button press
if( key == K_Y_BUTTON )
{
Key_EnableTextInput( true, true );
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 );
}
@@ -1934,14 +1641,14 @@ void Key_Message( int key )
{
char buffer[MAX_SYSPATH];
if( key == K_ESCAPE )
if( key == K_ESCAPE || key == K_BACK_BUTTON )
{
Key_SetKeyDest( key_game );
Con_ClearField( &con.chat );
return;
}
if( key == K_ENTER || key == K_KP_ENTER )
if( key == K_ENTER || key == K_KP_ENTER || key == K_A_BUTTON )
{
if( con.chat.buffer[0] && cls.state == ca_active )
{
@@ -1983,7 +1690,7 @@ void Con_DrawInput( int lines )
return;
y = lines - ( con.curFont->charHeight * 2 );
Con_DrawCharacter( con.curFont->charWidths[' '], y, ']', g_color_table[7] );
CL_DrawCharacter( con.curFont->charWidths[' '], y, ']', g_color_table[7], con.curFont, 0 );
Field_DrawInputLine( con.curFont->charWidths[' ']*2, y, &con.input );
}
@@ -1996,30 +1703,37 @@ Custom debug messages
*/
int Con_DrawDebugLines( void )
{
notify_t *notify = con.notify;
int i, count = 0;
int defaultX;
int y = 20;
int fontTall;
if( !con.curFont || !con.curFont->valid )
return 0;
defaultX = refState.width / 4;
fontTall = con.curFont->charHeight + 1;
for( i = 0; i < MAX_DBG_NOTIFY; i++ )
for( i = 0; i < ARRAYSIZE( con.notify ); i++, notify++ )
{
if( host.realtime < con.notify[i].expire && con.notify[i].key_dest == cls.key_dest )
{
int x, len;
int fontTall = 0;
int x, len;
Con_DrawStringLen( con.notify[i].szNotify, &len, &fontTall );
x = refState.width - Q_max( defaultX, len ) - 10;
fontTall += 1;
if( host.realtime > notify->expire )
continue;
if( y + fontTall > refState.height - 20 )
return count;
if( notify->key_dest != cls.key_dest )
continue;
count++;
y = 20 + fontTall * i;
Con_DrawString( x, y, con.notify[i].szNotify, con.notify[i].color );
}
Con_DrawStringLen( notify->szNotify, &len, NULL );
x = refState.width - Q_max( defaultX, len ) - 10;
if( y + fontTall > refState.height - 20 )
return count;
count++;
y += fontTall;
CL_DrawString( x, y, notify->szNotify, notify->color, con.curFont, FONT_DRAW_UTF8 | FONT_DRAW_NOLF );
}
return count;
@@ -2038,17 +1752,21 @@ void Con_DrawDebug( void )
string dlstring;
int x, y;
if( scr_download->value != -1.0f )
if( scr_download.value != -1.0f )
{
int length;
Q_snprintf( dlstring, sizeof( dlstring ), "Downloading [%d remaining]: ^2%s^7 %5.1f%% time %.f secs",
host.downloadcount, host.downloadfile, scr_download->value, Sys_DoubleTime() - timeStart );
x = refState.width - 500;
host.downloadcount, host.downloadfile, scr_download.value, Sys_DoubleTime() - timeStart );
Con_DrawStringLen( dlstring, &length, NULL );
length = Q_max( length, 500 );
x = refState.width - length * 1.05f;
y = con.curFont->charHeight * 1.05f;
Con_DrawString( x, y, dlstring, g_color_table[7] );
}
else
{
timeStart = Sys_DoubleTime();
timeStart = host.realtime;
}
if( !host.allow_console || Cvar_VariableInteger( "cl_background" ) || Cvar_VariableInteger( "sv_background" ))
@@ -2083,7 +1801,7 @@ void Con_DrawNotify( void )
{
con_lineinfo_t *l = &CON_LINES( i );
if( l->addtime < ( time - con_notifytime->value ))
if( l->addtime < ( time - con_notifytime.value ))
continue;
Con_DrawString( x, y, l->start, g_color_table[7] );
@@ -2128,7 +1846,11 @@ int Con_DrawConsoleLine( int y, int lineno )
return 0; // this string will be shown only at notify
if( y >= con.curFont->charHeight )
Con_DrawGenericString( con.curFont->charWidths[' '], y, li->start, g_color_table[7], false, -1 );
{
float x = con.curFont->charWidths[' '];
CL_DrawString( x, y, li->start, g_color_table[7], con.curFont, FONT_DRAW_UTF8 );
}
return con.curFont->charHeight;
}
@@ -2195,17 +1917,15 @@ void Con_DrawSolidConsole( int lines )
// draw current version
memcpy( color, g_color_table[7], sizeof( color ));
Q_snprintf( curbuild, MAX_STRING, "%s %i/%s (%s-%s build %i)", XASH_ENGINE_NAME, PROTOCOL_VERSION, XASH_VERSION, Q_buildos(), Q_buildarch(), Q_buildnum( ));
Q_snprintf( curbuild, MAX_STRING, XASH_ENGINE_NAME " %i/" XASH_VERSION " (%s-%s build %i)", PROTOCOL_VERSION, Q_buildos(), Q_buildarch(), Q_buildnum( ));
Con_DrawStringLen( curbuild, &stringLen, &charH );
start = refState.width - stringLen;
stringLen = Con_StringLength( curbuild );
start = refState.width - stringLen;
fraction = lines / (float)refState.height;
color[3] = Q_min( fraction * 2.0f, 1.0f ) * 255; // fadeout version number
for( i = 0; i < stringLen; i++ )
width += Con_DrawCharacter( start + width, 0, curbuild[i], color );
Con_DrawString( start, 0, curbuild, color );
// draw the text
if( CON_LINES_COUNT > 0 )
@@ -2222,7 +1942,7 @@ void Con_DrawSolidConsole( int lines )
// draw red arrows to show the buffer is backscrolled
for( x = 0; x < con.linewidth; x += 4 )
Con_DrawCharacter(( x + 1 ) * start, y, '^', g_color_table[1] );
CL_DrawCharacter( ( x + 1 ) * start, y, '^', g_color_table[1], con.curFont, 0 );
y -= con.curFont->charHeight;
}
x = lastline;
@@ -2263,7 +1983,7 @@ void Con_DrawConsole( void )
if( cls.state == ca_connecting || cls.state == ca_connected )
{
if( !cl_allow_levelshots->value )
if( !cl_allow_levelshots.value && !cls.timedemo )
{
if(( Cvar_VariableInteger( "cl_background" ) || Cvar_VariableInteger( "sv_background" )) && cls.key_dest != key_console )
con.vislines = con.showlines = 0;
@@ -2273,7 +1993,7 @@ void Con_DrawConsole( void )
{
con.showlines = 0;
if( host_developer.value >= DEV_EXTENDED )
if( host_developer.value >= DEV_EXTENDED && !cls.timedemo )
Con_DrawNotify(); // draw notify lines
}
}
@@ -2305,7 +2025,7 @@ void Con_DrawConsole( void )
{
if( con.vislines )
Con_DrawSolidConsole( con.vislines );
else if( cls.state == ca_active && ( cls.key_dest == key_game || cls.key_dest == key_message ))
else if( cls.state == ca_active && ( cls.key_dest == key_game || cls.key_dest == key_message ) && !cls.timedemo )
Con_DrawNotify(); // draw notify lines
}
break;
@@ -2325,7 +2045,7 @@ void Con_DrawVersion( void )
{
// draws the current build
byte *color = g_color_table[7];
int i, stringLen, width = 0, charH = 0;
int stringLen, charH = 0;
int start, height = refState.height;
qboolean draw_version = false;
string curbuild;
@@ -2338,26 +2058,21 @@ void Con_DrawVersion( void )
break;
}
if( !host.force_draw_version )
{
if(( cls.key_dest != key_menu && !draw_version ) || CL_IsDevOverviewMode() == 2 || net_graph->value )
return;
}
if( host.force_draw_version_time > host.realtime )
host.force_draw_version = false;
draw_version = true;
if( host.force_draw_version || draw_version )
Q_snprintf( curbuild, MAX_STRING, "%s v%i/%s (%s-%s build %i)", XASH_ENGINE_NAME, PROTOCOL_VERSION, XASH_VERSION, Q_buildos(), Q_buildarch(), Q_buildnum( ));
else Q_snprintf( curbuild, MAX_STRING, "v%i/%s (%s-%s build %i)", PROTOCOL_VERSION, XASH_VERSION, Q_buildos(), Q_buildarch(), Q_buildnum( ));
if(( cls.key_dest != key_menu && !draw_version ) || CL_IsDevOverviewMode() == 2 || net_graph.value )
return;
if( draw_version )
Q_snprintf( curbuild, MAX_STRING, XASH_ENGINE_NAME " v%i/" XASH_VERSION " (%s-%s build %i)", PROTOCOL_VERSION, Q_buildos(), Q_buildarch(), Q_buildnum( ));
else Q_snprintf( curbuild, MAX_STRING, "v%i/" XASH_VERSION " (%s-%s build %i)", PROTOCOL_VERSION, Q_buildos(), Q_buildarch(), Q_buildnum( ));
Con_DrawStringLen( curbuild, &stringLen, &charH );
start = refState.width - stringLen * 1.05f;
stringLen = Con_StringLength( curbuild );
height -= charH * 1.05f;
for( i = 0; i < stringLen; i++ )
width += Con_DrawCharacter( start + width, height, curbuild[i], color );
Con_DrawString( start, height, curbuild, color );
}
/*
@@ -2382,7 +2097,7 @@ void Con_RunConsole( void )
}
else con.showlines = 0; // none visible
lines_per_frame = fabs( scr_conspeed->value ) * host.realframetime;
lines_per_frame = fabs( scr_conspeed.value ) * host.realframetime;
if( con.showlines < con.vislines )
{
@@ -2397,38 +2112,35 @@ void Con_RunConsole( void )
con.vislines = con.showlines;
}
if( FBitSet( con_charset->flags, FCVAR_CHANGED ) ||
FBitSet( con_fontscale->flags, FCVAR_CHANGED ) ||
FBitSet( con_fontnum->flags, FCVAR_CHANGED ) ||
FBitSet( cl_charset->flags, FCVAR_CHANGED ) )
if( FBitSet( con_charset.flags, FCVAR_CHANGED ) ||
FBitSet( con_fontscale.flags, FCVAR_CHANGED ) ||
FBitSet( con_fontnum.flags, FCVAR_CHANGED ) ||
FBitSet( cl_charset.flags, FCVAR_CHANGED ))
{
// update codepage parameters
if( !Q_stricmp( con_charset->string, "cp1251" ))
if( !Q_stricmp( con_charset.string, "cp1251" ))
{
g_codepage = 1251;
}
else if( !Q_stricmp( con_charset->string, "cp1252" ))
else if( !Q_stricmp( con_charset.string, "cp1252" ))
{
g_codepage = 1252;
}
else
{
Con_Printf( S_WARN "Unknown charset %s, defaulting to cp1252", con_charset->string );
Con_Printf( S_WARN "Unknown charset %s, defaulting to cp1252", con_charset.string );
Cvar_DirectSet( con_charset, "cp1252" );
Cvar_DirectSet( &con_charset, "cp1252" );
g_codepage = 1252;
}
g_utf8 = !Q_stricmp( cl_charset->string, "utf-8" );
g_utf8 = !Q_stricmp( cl_charset.string, "utf-8" );
Con_InvalidateFonts();
Con_LoadConchars();
cls.creditsFont.valid = false;
SCR_LoadCreditsFont();
ClearBits( con_charset->flags, FCVAR_CHANGED );
ClearBits( con_fontnum->flags, FCVAR_CHANGED );
ClearBits( con_fontscale->flags, FCVAR_CHANGED );
ClearBits( cl_charset->flags, FCVAR_CHANGED );
ClearBits( con_charset.flags, FCVAR_CHANGED );
ClearBits( con_fontnum.flags, FCVAR_CHANGED );
ClearBits( con_fontscale.flags, FCVAR_CHANGED );
ClearBits( cl_charset.flags, FCVAR_CHANGED );
}
}
@@ -2563,8 +2275,10 @@ Con_InvalidateFonts
*/
void Con_InvalidateFonts( void )
{
memset( con.chars, 0, sizeof( con.chars ));
con.curFont = con.lastUsedFont = NULL;
int i;
for( i = 0; i < ARRAYSIZE( con.chars ); i++ )
CL_FreeFont( &con.chars[i] );
con.curFont = NULL;
}
/*

View File

@@ -44,22 +44,25 @@ static struct joy_axis_s
short prevval;
} joyaxis[MAX_AXES] = { 0 };
static byte currentbinding; // add posibility to remap keys, to place it in joykeys[]
convar_t *joy_enable;
static convar_t *joy_pitch;
static convar_t *joy_yaw;
static convar_t *joy_forward;
static convar_t *joy_side;
static convar_t *joy_found;
static convar_t *joy_index;
static convar_t *joy_lt_threshold;
static convar_t *joy_rt_threshold;
static convar_t *joy_side_deadzone;
static convar_t *joy_forward_deadzone;
static convar_t *joy_side_key_threshold;
static convar_t *joy_forward_key_threshold;
static convar_t *joy_pitch_deadzone;
static convar_t *joy_yaw_deadzone;
static convar_t *joy_axis_binding;
static qboolean joy_initialized;
static CVAR_DEFINE_AUTO( joy_pitch, "100.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "joystick pitch sensitivity" );
static CVAR_DEFINE_AUTO( joy_yaw, "100.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "joystick yaw sensitivity" );
static CVAR_DEFINE_AUTO( joy_side, "1.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "joystick side sensitivity. Values from -1.0 to 1.0" );
static CVAR_DEFINE_AUTO( joy_forward, "1.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "joystick forward sensitivity. Values from -1.0 to 1.0" );
static CVAR_DEFINE_AUTO( joy_lt_threshold, "16384", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "left trigger threshold. Value from 0 to 32767");
static CVAR_DEFINE_AUTO( joy_rt_threshold, "16384", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "right trigger threshold. Value from 0 to 32767" );
static CVAR_DEFINE_AUTO( joy_side_key_threshold, "24576", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "side axis key event emit threshold. Value from 0 to 32767" );
static CVAR_DEFINE_AUTO( joy_forward_key_threshold, "24576", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "forward axis key event emit threshold. Value from 0 to 32767");
static CVAR_DEFINE_AUTO( joy_side_deadzone, DEFAULT_JOY_DEADZONE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "side axis deadzone. Value from 0 to 32767" );
static CVAR_DEFINE_AUTO( joy_forward_deadzone, DEFAULT_JOY_DEADZONE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "forward axis deadzone. Value from 0 to 32767");
static CVAR_DEFINE_AUTO( joy_pitch_deadzone, DEFAULT_JOY_DEADZONE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "pitch axis deadzone. Value from 0 to 32767");
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" );
/*
============
@@ -68,7 +71,7 @@ Joy_IsActive
*/
qboolean Joy_IsActive( void )
{
return joy_found->value && joy_enable->value;
return joy_found.value && joy_enable.value;
}
/*
@@ -93,7 +96,7 @@ void Joy_HatMotionEvent( byte hat, byte value )
};
int i;
if( !joy_found->value )
if( !joy_found.value )
return;
for( i = 0; i < ARRAYSIZE( keys ); i++ )
@@ -124,11 +127,11 @@ static void Joy_ProcessTrigger( const engineAxis_t engineAxis, short value )
{
case JOY_AXIS_RT:
trigButton = K_JOY2;
trigThreshold = joy_rt_threshold->value;
trigThreshold = joy_rt_threshold.value;
break;
case JOY_AXIS_LT:
trigButton = K_JOY1;
trigThreshold = joy_lt_threshold->value;
trigThreshold = joy_lt_threshold.value;
break;
default:
Con_Reportf( S_ERROR "Joy_ProcessTrigger: invalid axis = %i", engineAxis );
@@ -158,12 +161,12 @@ static int Joy_GetHatValueForAxis( const engineAxis_t engineAxis )
switch( engineAxis )
{
case JOY_AXIS_SIDE:
threshold = joy_side_key_threshold->value;
threshold = joy_side_key_threshold.value;
negative = JOY_HAT_LEFT;
positive = JOY_HAT_RIGHT;
break;
case JOY_AXIS_FWD:
threshold = joy_side_key_threshold->value;
threshold = joy_side_key_threshold.value;
negative = JOY_HAT_UP;
positive = JOY_HAT_DOWN;
break;
@@ -197,10 +200,10 @@ static void Joy_ProcessStick( const engineAxis_t engineAxis, short value )
switch( engineAxis )
{
case JOY_AXIS_FWD: deadzone = joy_forward_deadzone->value; break;
case JOY_AXIS_SIDE: deadzone = joy_side_deadzone->value; break;
case JOY_AXIS_PITCH: deadzone = joy_pitch_deadzone->value; break;
case JOY_AXIS_YAW: deadzone = joy_yaw_deadzone->value; break;
case JOY_AXIS_FWD: deadzone = joy_forward_deadzone.value; break;
case JOY_AXIS_SIDE: deadzone = joy_side_deadzone.value; break;
case JOY_AXIS_PITCH: deadzone = joy_pitch_deadzone.value; break;
case JOY_AXIS_YAW: deadzone = joy_yaw_deadzone.value; break;
default:
Con_Reportf( S_ERROR "Joy_ProcessStick: invalid axis = %i", engineAxis );
break;
@@ -235,7 +238,7 @@ Axis events
*/
void Joy_AxisMotionEvent( byte axis, short value )
{
if( !joy_found->value )
if( !joy_found.value )
return;
if( axis >= MAX_AXES )
@@ -244,7 +247,7 @@ void Joy_AxisMotionEvent( byte axis, short value )
return;
}
return Joy_KnownAxisMotionEvent( joyaxesmap[axis], value );
Joy_KnownAxisMotionEvent( joyaxesmap[axis], value );
}
void Joy_KnownAxisMotionEvent( engineAxis_t engineAxis, short value )
@@ -270,7 +273,7 @@ Trackball events. UNDONE
*/
void Joy_BallMotionEvent( byte ball, short xrel, short yrel )
{
//if( !joy_found->value )
//if( !joy_found.value )
// return;
}
@@ -283,7 +286,7 @@ Button events
*/
void Joy_ButtonEvent( byte button, byte down )
{
if( !joy_found->value )
if( !joy_found.value )
return;
// generic game button code.
@@ -308,7 +311,7 @@ Called when joystick is removed. For future expansion
*/
void Joy_RemoveEvent( void )
{
if( joy_found->value )
if( joy_found.value )
Cvar_FullSet( "joy_found", "0", FCVAR_READ_ONLY );
}
@@ -321,7 +324,7 @@ Called when joystick is removed. For future expansion
*/
void Joy_AddEvent( void )
{
if( joy_enable->value && !joy_found->value )
if( joy_enable.value && !joy_found.value )
Cvar_FullSet( "joy_found", "1", FCVAR_READ_ONLY );
}
@@ -337,9 +340,9 @@ void Joy_FinalizeMove( float *fw, float *side, float *dpitch, float *dyaw )
if( !Joy_IsActive() )
return;
if( FBitSet( joy_axis_binding->flags, FCVAR_CHANGED ) )
if( FBitSet( joy_axis_binding.flags, FCVAR_CHANGED ) )
{
const char *bind = joy_axis_binding->string;
const char *bind = joy_axis_binding.string;
size_t i;
for( i = 0; bind[i]; i++ )
@@ -356,18 +359,18 @@ void Joy_FinalizeMove( float *fw, float *side, float *dpitch, float *dyaw )
}
}
ClearBits( joy_axis_binding->flags, FCVAR_CHANGED );
ClearBits( joy_axis_binding.flags, FCVAR_CHANGED );
}
*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;
*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;
*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;
*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
}
@@ -380,40 +383,43 @@ Main init procedure
*/
void Joy_Init( void )
{
joy_pitch = Cvar_Get( "joy_pitch", "100.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "joystick pitch sensitivity" );
joy_yaw = Cvar_Get( "joy_yaw", "100.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "joystick yaw sensitivity" );
joy_side = Cvar_Get( "joy_side", "1.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "joystick side sensitivity. Values from -1.0 to 1.0" );
joy_forward = Cvar_Get( "joy_forward", "1.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "joystick forward sensitivity. Values from -1.0 to 1.0" );
Cvar_RegisterVariable( &joy_pitch );
Cvar_RegisterVariable( &joy_yaw );
Cvar_RegisterVariable( &joy_side );
Cvar_RegisterVariable( &joy_forward );
joy_lt_threshold = Cvar_Get( "joy_lt_threshold", "16384", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "left trigger threshold. Value from 0 to 32767");
joy_rt_threshold = Cvar_Get( "joy_rt_threshold", "16384", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "right trigger threshold. Value from 0 to 32767" );
Cvar_RegisterVariable( &joy_lt_threshold );
Cvar_RegisterVariable( &joy_rt_threshold );
// emit a key event at 75% axis move
joy_side_key_threshold = Cvar_Get( "joy_side_key_threshold", "24576", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "side axis key event emit threshold. Value from 0 to 32767" );
joy_forward_key_threshold = Cvar_Get( "joy_forward_key_threshold", "24576", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "forward axis key event emit threshold. Value from 0 to 32767");
Cvar_RegisterVariable( &joy_side_key_threshold );
Cvar_RegisterVariable( &joy_forward_key_threshold );
// by default, we rely on deadzone detection come from system, but some glitchy devices report false deadzones
joy_side_deadzone = Cvar_Get( "joy_side_deadzone", "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "side axis deadzone. Value from 0 to 32767" );
joy_forward_deadzone = Cvar_Get( "joy_forward_deadzone", "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "forward axis deadzone. Value from 0 to 32767");
joy_pitch_deadzone = Cvar_Get( "joy_pitch_deadzone", "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "pitch axis deadzone. Value from 0 to 32767");
joy_yaw_deadzone = Cvar_Get( "joy_yaw_deadzone", "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "yaw axis deadzone. Value from 0 to 32767" );
Cvar_RegisterVariable( &joy_side_deadzone );
Cvar_RegisterVariable( &joy_forward_deadzone );
Cvar_RegisterVariable( &joy_pitch_deadzone );
Cvar_RegisterVariable( &joy_yaw_deadzone );
joy_axis_binding = Cvar_Get( "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" );
joy_found = Cvar_Get( "joy_found", "0", FCVAR_READ_ONLY, "is joystick is connected" );
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
joy_index = Cvar_Get( "joy_index", "0", FCVAR_READ_ONLY, "current active joystick" );
Cvar_RegisterVariable( &joy_index );
joy_enable = Cvar_Get( "joy_enable", "1", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enable joystick" );
Cvar_RegisterVariable( &joy_enable );
if( Sys_CheckParm( "-nojoy" ))
// renamed from -nojoy to -noenginejoy to not conflict with
// client.dll's joystick support
if( Sys_CheckParm( "-noenginejoy" ))
{
Cvar_FullSet( "joy_enable", "0", FCVAR_READ_ONLY );
return;
}
Cvar_FullSet( "joy_found", va( "%d", Platform_JoyInit( joy_index->value )), FCVAR_READ_ONLY );
Cvar_FullSet( "joy_found", va( "%d", Platform_JoyInit( joy_index.value )), FCVAR_READ_ONLY );
joy_initialized = true;
}
/*
@@ -425,5 +431,8 @@ Shutdown joystick code
*/
void Joy_Shutdown( void )
{
Cvar_FullSet( "joy_found", 0, FCVAR_READ_ONLY );
if( joy_initialized )
{
Cvar_FullSet( "joy_found", 0, FCVAR_READ_ONLY );
}
}

View File

@@ -87,7 +87,7 @@ typedef struct touchbuttonlist_s
touch_button_t *last;
} touchbuttonlist_t;
struct touch_s
static struct touch_s
{
qboolean initialized;
qboolean config_loaded;
@@ -132,6 +132,8 @@ struct touch_s
int whitetexture;
int joytexture; // touch indicator
qboolean configchanged;
float actual_aspect_ratio; // maximum aspect ratio from launch, or aspect ratio when entering editor
float config_aspect_ratio; // aspect ratio set by command from config or after entering editor
} touch;
// private to the engine flags
@@ -140,41 +142,70 @@ struct touch_s
touchdefaultbutton_t g_DefaultButtons[256];
int g_LastDefaultButton;
convar_t *touch_pitch;
convar_t *touch_yaw;
convar_t *touch_forwardzone;
convar_t *touch_sidezone;
convar_t *touch_nonlinear_look;
convar_t *touch_pow_mult;
convar_t *touch_pow_factor;
convar_t *touch_exp_mult;
convar_t *touch_grid_enable;
convar_t *touch_grid_count;
convar_t *touch_config_file;
convar_t *touch_enable;
convar_t *touch_in_menu;
convar_t *touch_joy_radius;
convar_t *touch_dpad_radius;
convar_t *touch_move_indicator;
convar_t *touch_highlight_r;
convar_t *touch_highlight_g;
convar_t *touch_highlight_b;
convar_t *touch_highlight_a;
convar_t *touch_precise_amount;
convar_t *touch_joy_texture;
convar_t *touch_emulate;
static CVAR_DEFINE_AUTO( touch_in_menu, "0", FCVAR_FILTERABLE, "draw touch in menu (for internal use only)" );
static CVAR_DEFINE_AUTO( touch_forwardzone, "0.06", FCVAR_FILTERABLE, "forward touch zone" );
static CVAR_DEFINE_AUTO( touch_sidezone, "0.06", FCVAR_FILTERABLE, "side touch zone" );
static CVAR_DEFINE_AUTO( touch_pitch, "90", FCVAR_FILTERABLE, "touch pitch sensitivity" );
static CVAR_DEFINE_AUTO( touch_yaw, "120", FCVAR_FILTERABLE, "touch yaw sensitivity" );
static CVAR_DEFINE_AUTO( touch_nonlinear_look, "0", FCVAR_FILTERABLE, "enable nonlinear touch look" );
static CVAR_DEFINE_AUTO( touch_pow_factor, "1.3", FCVAR_FILTERABLE, "set > 1 to enable" );
static CVAR_DEFINE_AUTO( touch_pow_mult, "400.0", FCVAR_FILTERABLE, "power multiplier, usually 200-1000" );
static CVAR_DEFINE_AUTO( touch_exp_mult, "0", FCVAR_FILTERABLE, "exponent multiplier, usually 20-200, 0 to disable" );
static CVAR_DEFINE_AUTO( touch_grid_count, "50", FCVAR_FILTERABLE, "touch grid count" );
static CVAR_DEFINE_AUTO( touch_grid_enable, "1", FCVAR_FILTERABLE, "enable touch grid" );
static CVAR_DEFINE_AUTO( touch_config_file, "touch.cfg", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "current touch profile file" );
static CVAR_DEFINE_AUTO( touch_precise_amount, "0.5", FCVAR_FILTERABLE, "sensitivity multiplier for precise-look" );
static CVAR_DEFINE_AUTO( touch_highlight_r, "1.0", 0, "highlight r color" );
static CVAR_DEFINE_AUTO( touch_highlight_g, "1.0", 0, "highlight g color" );
static CVAR_DEFINE_AUTO( touch_highlight_b, "1.0", 0, "highlight b color" );
static CVAR_DEFINE_AUTO( touch_highlight_a, "1.0", 0, "highlight alpha" );
static CVAR_DEFINE_AUTO( touch_dpad_radius, "1.0", FCVAR_FILTERABLE, "dpad radius multiplier" );
static CVAR_DEFINE_AUTO( touch_joy_radius, "1.0", FCVAR_FILTERABLE, "joy radius multiplier" );
static CVAR_DEFINE_AUTO( touch_move_indicator, "0.0", FCVAR_FILTERABLE, "indicate move events (0 to disable)" );
static CVAR_DEFINE_AUTO( touch_joy_texture, "touch_default/joy", FCVAR_FILTERABLE, "texture for move indicator");
CVAR_DEFINE_AUTO( touch_enable, DEFAULT_TOUCH_ENABLE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enable touch controls" );
CVAR_DEFINE_AUTO( touch_emulate, "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "emulate touch with mouse" );
// code looks smaller with it
#define B(x) (button->x)
#define SCR_W ((float)refState.width)
#define SCR_H ((float)refState.height)
#define TO_SCRN_Y(x) (refState.height * (x))
#define TO_SCRN_Y(x) (refState.width * (x) * Touch_AspectRatio())
#define TO_SCRN_X(x) (refState.width * (x))
static void IN_TouchCheckCoords( float *x1, float *y1, float *x2, float *y2 );
static void IN_TouchEditClear( void );
static void Touch_InitConfig( void );
void Touch_NotifyResize( void )
{
if( refState.width && refState.height && ( !touch.configchanged || !touch.actual_aspect_ratio ))
{
float aspect_ratio = SCR_H/SCR_W;
if( aspect_ratio < 0.99 && aspect_ratio > touch.actual_aspect_ratio )
touch.actual_aspect_ratio = aspect_ratio;
}
}
static inline float Touch_AspectRatio( void )
{
if( touch.config_aspect_ratio )
return touch.config_aspect_ratio;
else if( touch.actual_aspect_ratio )
return touch.actual_aspect_ratio;
else if( refState.width && refState.height )
return SCR_H/SCR_W;
else
return 9.0f / 16.0f;
}
static void Touch_ConfigAspectRatio_f( void )
{
touch.config_aspect_ratio = Q_atof( Cmd_Argv( 1 ));
}
/*
==========================
Touch_ExportButtonToConfig
@@ -206,7 +237,7 @@ static inline int Touch_ExportButtonToConfig( file_t *f, touch_button_t *button,
if( keepAspect )
{
float aspect = ( B(y2) - B(y1) ) / ( ( B(x2) - B(x1) ) /(SCR_H/SCR_W) );
float aspect = ( B(y2) - B(y1) ) / ( ( B(x2) - B(x1) ) /(Touch_AspectRatio()) );
FS_Printf( f, " %f\n", aspect );
}
else FS_Printf( f, "\n" );
@@ -214,6 +245,76 @@ static inline int Touch_ExportButtonToConfig( file_t *f, touch_button_t *button,
return 0;
}
/*
=================
Touch_DumpConfig
Dump config to file
=================
*/
qboolean Touch_DumpConfig( const char *name, const char *profilename )
{
file_t *f;
touch_button_t *button;
f = FS_Open( name, "w", true );
if( !f )
{
Con_Printf( S_ERROR "Couldn't write %s.\n", name );
return false;
}
FS_Printf( f, "//=======================================================================\n");
FS_Printf( f, "//\tCopyright FWGS & XashXT group %s (c)\n", Q_timestamp( TIME_YEAR_ONLY ));
FS_Printf( f, "//\t\t\ttouchscreen config\n" );
FS_Printf( f, "//=======================================================================\n" );
FS_Printf( f, "\ntouch_config_file \"%s\"\n", profilename );
FS_Printf( f, "\n// touch cvars\n" );
FS_Printf( f, "\n// sensitivity settings\n" );
FS_Printf( f, "touch_pitch \"%f\"\n", touch_pitch.value );
FS_Printf( f, "touch_yaw \"%f\"\n", touch_yaw.value );
FS_Printf( f, "touch_forwardzone \"%f\"\n", touch_forwardzone.value );
FS_Printf( f, "touch_sidezone \"%f\"\n", touch_sidezone.value );
FS_Printf( f, "touch_nonlinear_look \"%d\"\n", touch_nonlinear_look.value ? 1 : 0 );
FS_Printf( f, "touch_pow_factor \"%f\"\n", touch_pow_factor.value );
FS_Printf( f, "touch_pow_mult \"%f\"\n", touch_pow_mult.value );
FS_Printf( f, "touch_exp_mult \"%f\"\n", touch_exp_mult.value );
FS_Printf( f, "\n// grid settings\n" );
FS_Printf( f, "touch_grid_count \"%d\"\n", (int)touch_grid_count.value );
FS_Printf( f, "touch_grid_enable \"%d\"\n", touch_grid_enable.value ? 1 : 0 );
FS_Printf( f, "\n// global overstroke (width, r, g, b, a)\n" );
FS_Printf( f, "touch_set_stroke %d %d %d %d %d\n", touch.swidth, touch.scolor[0], touch.scolor[1], touch.scolor[2], touch.scolor[3] );
FS_Printf( f, "\n// highlight when pressed\n" );
FS_Printf( f, "touch_highlight_r \"%f\"\n", touch_highlight_r.value );
FS_Printf( f, "touch_highlight_g \"%f\"\n", touch_highlight_g.value );
FS_Printf( f, "touch_highlight_b \"%f\"\n", touch_highlight_b.value );
FS_Printf( f, "touch_highlight_a \"%f\"\n", touch_highlight_a.value );
FS_Printf( f, "\n// _joy and _dpad options\n" );
FS_Printf( f, "touch_dpad_radius \"%f\"\n", touch_dpad_radius.value );
FS_Printf( f, "touch_joy_radius \"%f\"\n", touch_joy_radius.value );
FS_Printf( f, "\n// how much slowdown when Precise Look button pressed\n" );
FS_Printf( f, "touch_precise_amount \"%f\"\n", touch_precise_amount.value );
FS_Printf( f, "\n// enable/disable move indicator\n" );
FS_Printf( f, "touch_move_indicator \"%f\"\n", touch_move_indicator.value );
FS_Printf( f, "\n// reset menu state when execing config\n" );
FS_Printf( f, "touch_setclientonly 0\n" );
FS_Printf( f, "\n// touch buttons\n" );
FS_Printf( f, "touch_removeall\n" );
FS_Printf( f, "touch_aspectratio %f\n", Touch_AspectRatio());
for( button = touch.list_user.first; button; button = button->next )
{
Touch_ExportButtonToConfig( f, button, false );
}
FS_Close( f );
return true;
}
/*
=================
Touch_WriteConfig
@@ -232,66 +333,19 @@ void Touch_WriteConfig( void )
if( Sys_CheckParm( "-nowriteconfig" ) || !touch.configchanged || !touch.config_loaded )
return;
Con_DPrintf( "Touch_WriteConfig(): %s\n", touch_config_file->string );
Con_DPrintf( "Touch_WriteConfig(): %s\n", touch_config_file.string );
Q_snprintf( newconfigfile, sizeof( newconfigfile ), "%s.new", touch_config_file->string );
Q_snprintf( oldconfigfile, sizeof( oldconfigfile ), "%s.bak", touch_config_file->string );
Q_snprintf( newconfigfile, sizeof( newconfigfile ), "%s.new", touch_config_file.string );
Q_snprintf( oldconfigfile, sizeof( oldconfigfile ), "%s.bak", touch_config_file.string );
f = FS_Open( newconfigfile, "w", true );
if( f )
if( Touch_DumpConfig( newconfigfile, touch_config_file.string ))
{
touch_button_t *button;
FS_Printf( f, "//=======================================================================\n");
FS_Printf( f, "//\tCopyright FWGS & XashXT group %s (c)\n", Q_timestamp( TIME_YEAR_ONLY ));
FS_Printf( f, "//\t\t\ttouchscreen config\n" );
FS_Printf( f, "//=======================================================================\n" );
FS_Printf( f, "\ntouch_config_file \"%s\"\n", touch_config_file->string );
FS_Printf( f, "\n// touch cvars\n" );
FS_Printf( f, "\n// sensitivity settings\n" );
FS_Printf( f, "touch_pitch \"%f\"\n", touch_pitch->value );
FS_Printf( f, "touch_yaw \"%f\"\n", touch_yaw->value );
FS_Printf( f, "touch_forwardzone \"%f\"\n", touch_forwardzone->value );
FS_Printf( f, "touch_sidezone \"%f\"\n", touch_sidezone->value );
FS_Printf( f, "touch_nonlinear_look \"%d\"\n", CVAR_TO_BOOL(touch_nonlinear_look));
FS_Printf( f, "touch_pow_factor \"%f\"\n", touch_pow_factor->value );
FS_Printf( f, "touch_pow_mult \"%f\"\n", touch_pow_mult->value );
FS_Printf( f, "touch_exp_mult \"%f\"\n", touch_exp_mult->value );
FS_Printf( f, "\n// grid settings\n" );
FS_Printf( f, "touch_grid_count \"%d\"\n", (int)touch_grid_count->value );
FS_Printf( f, "touch_grid_enable \"%d\"\n", CVAR_TO_BOOL(touch_grid_enable));
FS_Printf( f, "\n// global overstroke (width, r, g, b, a)\n" );
FS_Printf( f, "touch_set_stroke %d %d %d %d %d\n", touch.swidth, touch.scolor[0], touch.scolor[1], touch.scolor[2], touch.scolor[3] );
FS_Printf( f, "\n// highlight when pressed\n" );
FS_Printf( f, "touch_highlight_r \"%f\"\n", touch_highlight_r->value );
FS_Printf( f, "touch_highlight_g \"%f\"\n", touch_highlight_g->value );
FS_Printf( f, "touch_highlight_b \"%f\"\n", touch_highlight_b->value );
FS_Printf( f, "touch_highlight_a \"%f\"\n", touch_highlight_a->value );
FS_Printf( f, "\n// _joy and _dpad options\n" );
FS_Printf( f, "touch_dpad_radius \"%f\"\n", touch_dpad_radius->value );
FS_Printf( f, "touch_joy_radius \"%f\"\n", touch_joy_radius->value );
FS_Printf( f, "\n// how much slowdown when Precise Look button pressed\n" );
FS_Printf( f, "touch_precise_amount \"%f\"\n", touch_precise_amount->value );
FS_Printf( f, "\n// enable/disable move indicator\n" );
FS_Printf( f, "touch_move_indicator \"%f\"\n", touch_move_indicator->value );
FS_Printf( f, "\n// reset menu state when execing config\n" );
FS_Printf( f, "touch_setclientonly 0\n" );
FS_Printf( f, "\n// touch buttons\n" );
FS_Printf( f, "touch_removeall\n" );
for( button = touch.list_user.first; button; button = button->next )
{
Touch_ExportButtonToConfig( f, button, false );
}
FS_Close( f );
FS_Delete( oldconfigfile );
FS_Rename( touch_config_file->string, oldconfigfile );
FS_Delete( touch_config_file->string );
FS_Rename( newconfigfile, touch_config_file->string );
FS_Rename( touch_config_file.string, oldconfigfile );
FS_Delete( touch_config_file.string );
FS_Rename( newconfigfile, touch_config_file.string );
}
else Con_Printf( S_ERROR "Couldn't write %s.\n", touch_config_file->string );
}
/*
@@ -303,8 +357,8 @@ export current touch configuration into profile
*/
static void Touch_ExportConfig_f( void )
{
file_t *f;
const char *name;
string profilename, profilebase;
if( Cmd_Argc() != 2 )
{
@@ -316,65 +370,15 @@ static void Touch_ExportConfig_f( void )
name = Cmd_Argv( 1 );
Con_Reportf( "Exporting config to %s\n", name );
f = FS_Open( name, "w", true );
if( f )
if( Q_strstr( name, "touch_presets/" ))
{
string profilename, profilebase;
touch_button_t *button;
if( Q_strstr( name, "touch_presets/" ) )
{
COM_FileBase( name, profilebase );
Q_snprintf( profilename, sizeof( profilebase ), "touch_profiles/%s (copy).cfg", profilebase );
}
else Q_strncpy( profilename, name, sizeof( profilename ));
FS_Printf( f, "//=======================================================================\n");
FS_Printf( f, "//\tCopyright FWGS & XashXT group %s (c)\n", Q_timestamp( TIME_YEAR_ONLY ));
FS_Printf( f, "//\t\t\ttouchscreen preset\n" );
FS_Printf( f, "//=======================================================================\n" );
FS_Printf( f, "\ntouch_config_file \"%s\"\n", profilename );
FS_Printf( f, "\n// touch cvars\n" );
FS_Printf( f, "\n// sensitivity settings\n" );
FS_Printf( f, "touch_pitch \"%f\"\n", touch_pitch->value );
FS_Printf( f, "touch_yaw \"%f\"\n", touch_yaw->value );
FS_Printf( f, "touch_forwardzone \"%f\"\n", touch_forwardzone->value );
FS_Printf( f, "touch_sidezone \"%f\"\n", touch_sidezone->value );
FS_Printf( f, "touch_nonlinear_look \"%d\"\n", CVAR_TO_BOOL(touch_nonlinear_look) );
FS_Printf( f, "touch_pow_factor \"%f\"\n", touch_pow_factor->value );
FS_Printf( f, "touch_pow_mult \"%f\"\n", touch_pow_mult->value );
FS_Printf( f, "touch_exp_mult \"%f\"\n", touch_exp_mult->value );
FS_Printf( f, "\n// grid settings\n" );
FS_Printf( f, "touch_grid_count \"%d\"\n", (int)touch_grid_count->value );
FS_Printf( f, "touch_grid_enable \"%d\"\n", CVAR_TO_BOOL(touch_grid_enable) );
FS_Printf( f, "\n// global overstroke (width, r, g, b, a)\n" );
FS_Printf( f, "touch_set_stroke %d %d %d %d %d\n", touch.swidth, touch.scolor[0], touch.scolor[1], touch.scolor[2], touch.scolor[3] );
FS_Printf( f, "\n// highlight when pressed\n" );
FS_Printf( f, "touch_highlight_r \"%f\"\n", touch_highlight_r->value );
FS_Printf( f, "touch_highlight_g \"%f\"\n", touch_highlight_g->value );
FS_Printf( f, "touch_highlight_b \"%f\"\n", touch_highlight_b->value );
FS_Printf( f, "touch_highlight_a \"%f\"\n", touch_highlight_a->value );
FS_Printf( f, "\n// _joy and _dpad options\n" );
FS_Printf( f, "touch_dpad_radius \"%f\"\n", touch_dpad_radius->value );
FS_Printf( f, "touch_joy_radius \"%f\"\n", touch_joy_radius->value );
FS_Printf( f, "\n// how much slowdown when Precise Look button pressed\n" );
FS_Printf( f, "touch_precise_amount \"%f\"\n", touch_precise_amount->value );
FS_Printf( f, "\n// enable/disable move indicator\n" );
FS_Printf( f, "touch_move_indicator \"%f\"\n", touch_move_indicator->value );
FS_Printf( f, "\n// reset menu state when execing config\n" );
FS_Printf( f, "touch_setclientonly 0\n" );
FS_Printf( f, "\n// touch buttons\n" );
FS_Printf( f, "touch_removeall\n" );
for( button = touch.list_user.first; button; button = button->next )
{
Touch_ExportButtonToConfig( f, button, true );
}
FS_Printf( f, "\n// round button coordinates to grid\n" );
FS_Printf( f, "touch_roundall\n" );
FS_Close( f );
COM_FileBase( name, profilebase, sizeof( profilebase ));
Q_snprintf( profilename, sizeof( profilebase ), "touch_profiles/%s (copy).cfg", profilebase );
}
else Con_Printf( S_ERROR "Couldn't write %s.\n", name );
else Q_strncpy( profilename, name, sizeof( profilename ));
Con_Reportf( "Exporting config to \"%s\", profile name \"%s\"\n", name, profilename );
Touch_DumpConfig( name, profilename );
}
/*
@@ -405,7 +409,7 @@ static void Touch_GenerateCode_f( void )
if( FBitSet( flags, TOUCH_FL_DEF_HIDE ))
SetBits( flags, TOUCH_FL_HIDE );
aspect = ( B(y2) - B(y1) ) / ( ( B(x2) - B(x1) ) /(SCR_H/SCR_W) );
aspect = ( B(y2) - B(y1) ) / ( ( B(x2) - B(x1) ) /(Touch_AspectRatio()) );
if( memcmp( &c, &B(color), sizeof( rgba_t ) ) )
{
Con_Printf( "unsigned char color[] = { %d, %d, %d, %d };\n", B(color[0]), B(color[1]), B(color[2]), B(color[3]) );
@@ -421,7 +425,7 @@ static void Touch_RoundAll_f( void )
{
touch_button_t *button;
if( !touch_grid_enable->value )
if( !touch_grid_enable.value )
return;
for( button = touch.list_user.first; button; button = button->next )
@@ -497,8 +501,8 @@ static touch_button_t *Touch_FindFirst( touchbuttonlist_t *list, const char *nam
void Touch_SetClientOnly( byte state )
{
// TODO: fix clash with vgui cursors
touch.clientonly = state;
host.mouse_visible = state;
touch.move_finger = touch.look_finger = -1;
touch.forward = touch.side = 0;
@@ -578,6 +582,7 @@ static void Touch_RemoveAll_f( void )
{
IN_TouchEditClear();
Touch_ClearList( &touch.list_user );
touch.config_aspect_ratio = 0.0f;
}
static void Touch_SetColor( touchbuttonlist_t *list, const char *name, byte *color )
@@ -755,6 +760,8 @@ static void Touch_SetCommand_f( void )
Con_Printf( S_USAGE "touch_setcommand <name> <command>\n" );
}
static void Touch_LoadDefaults_f( void );
static void Touch_ReloadConfig_f( void )
{
touch.state = state_none;
@@ -764,8 +771,15 @@ static void Touch_ReloadConfig_f( void )
touch.selection->finger = -1;
touch.edit = touch.selection = NULL;
touch.resize_finger = touch.move_finger = touch.look_finger = touch.wheel_finger = -1;
Cbuf_AddText( va("exec %s\n", touch_config_file->string ) );
if( FS_FileExists( touch_config_file.string, true ) )
{
Cbuf_AddTextf( "exec \"%s\"\n", touch_config_file.string );
}
else
{
Touch_LoadDefaults_f();
touch.configchanged = true;
}
}
static touch_button_t *Touch_AddButton( touchbuttonlist_t *list,
@@ -813,7 +827,7 @@ void Touch_AddClientButton( const char *name, const char *texture, const char *c
IN_TouchCheckCoords( &x1, &y1, &x2, &y2 );
if( round == round_aspect )
{
y2 = y1 + ( x2 - x1 ) * (SCR_W/SCR_H) * aspect;
y2 = y1 + ( x2 - x1 ) / (Touch_AspectRatio()) * aspect;
}
button = Touch_AddButton( &touch.list_user, name, texture, command, x1, y1, x2, y2, color, true );
button->flags |= flags | TOUCH_FL_CLIENT | TOUCH_FL_NOEDIT;
@@ -838,7 +852,7 @@ static void Touch_LoadDefaults_f( void )
if( g_DefaultButtons[i].texturefile[0] == '#' )
y2 = y1 + ( (float)clgame.scrInfo.iCharHeight / (float)clgame.scrInfo.iHeight ) * g_DefaultButtons[i].aspect + touch.swidth*2/SCR_H;
else
y2 = y1 + ( x2 - x1 ) * (SCR_W/SCR_H) * g_DefaultButtons[i].aspect;
y2 = y1 + (( x2 - x1 ) / Touch_AspectRatio()) * g_DefaultButtons[i].aspect;
}
IN_TouchCheckCoords( &x1, &y1, &x2, &y2 );
@@ -846,6 +860,7 @@ static void Touch_LoadDefaults_f( void )
button->flags |= g_DefaultButtons[i].flags;
button->aspect = g_DefaultButtons[i].aspect;
}
touch.configchanged = true;
}
// Add default button from client
@@ -938,7 +953,7 @@ static void Touch_AddButton_f( void )
if( aspect )
{
if( B( texturefile )[0] != '#' )
B( y2 ) = B( y1 ) + ( B( x2 ) - B( x1 )) * ( SCR_W / SCR_H ) * aspect;
B( y2 ) = B( y1 ) + (( B( x2 ) - B( x1 )) / Touch_AspectRatio() ) * aspect;
B( aspect ) = aspect;
}
}
@@ -946,11 +961,39 @@ static void Touch_AddButton_f( void )
static void Touch_EnableEdit_f( void )
{
touch_button_t *button;
float current_ratio = SCR_H/SCR_W;
if( touch.state == state_none )
touch.state = state_edit;
touch.resize_finger = touch.move_finger = touch.look_finger = touch.wheel_finger = -1;
touch.move_button = NULL;
touch.configchanged = true;
/* try determine the best ratio
* User enters editor. Window now have correct size. Need to fix aspect ratio in some cases */
// Case A: no config was loaded, touch was generated with lower height, but window was resized higher, reset it to actual size
if( touch.actual_aspect_ratio > current_ratio )
touch.actual_aspect_ratio = current_ratio;
if( !touch.config_aspect_ratio )
touch.config_aspect_ratio = touch.actual_aspect_ratio;
// Case B: config was loaded, but window may be resized later, so keep y coordinate as is
touch.actual_aspect_ratio = current_ratio;
// convert coordinates to actual aspect ratio after it was updated
if( touch.config_aspect_ratio != touch.actual_aspect_ratio )
{
for( button = touch.list_user.first; button; button = button->next )
{
B(y1) /= touch.actual_aspect_ratio / touch.config_aspect_ratio;
B(y2) /= touch.actual_aspect_ratio / touch.config_aspect_ratio;
// clamp positions to make buttons visible by user
if( B(y2) > 1.0f )
{
B(y1) -= B(y2) - 1.0f;
B(y2) -= B(y2) - 1.0f;
}
}
touch.config_aspect_ratio = touch.actual_aspect_ratio;
}
}
static void Touch_DisableEdit_f( void )
@@ -963,7 +1006,7 @@ static void Touch_DisableEdit_f( void )
touch.edit = touch.selection = NULL;
touch.resize_finger = touch.move_finger = touch.look_finger = touch.wheel_finger = -1;
if( CVAR_TO_BOOL( touch_in_menu ))
if( touch_in_menu.value )
{
Cvar_Set( "touch_in_menu", "0" );
}
@@ -985,7 +1028,7 @@ static void Touch_DeleteProfile_f( void )
static void Touch_InitEditor( void )
{
float x = 0.1f * (SCR_H/SCR_W);
float x = 0.1f * (Touch_AspectRatio());
float y = 0.05f;
touch_button_t *temp;
rgba_t color;
@@ -1044,18 +1087,18 @@ void Touch_Init( void )
Touch_AddDefaultButton( "jump", "touch_default/jump", "+jump", 0.880000, 0.227228, 1.000000, 0.454457, color, 2, 1, 0 );
Touch_AddDefaultButton( "attack", "touch_default/shoot", "+attack", 0.760000, 0.530200, 0.880000, 0.757428, color, 2, 1, 0 );
Touch_AddDefaultButton( "attack2", "touch_default/shoot_alt", "+attack2", 0.760000, 0.302971, 0.880000, 0.530200, color, 2, 1, 0 );
Touch_AddDefaultButton( "loadquick", "touch_default/load", "loadquick", 0.760000, 0.000000, 0.840000, 0.151486, color, 2, 1, 16 );
Touch_AddDefaultButton( "savequick", "touch_default/save", "savequick", 0.840000, 0.000000, 0.920000, 0.151486, color, 2, 1, 16 );
Touch_AddDefaultButton( "messagemode", "touch_default/keyboard", "messagemode", 0.840000, 0.000000, 0.920000, 0.151486, color, 2, 1, 8 );
Touch_AddDefaultButton( "loadquick", "touch_default/load", "loadquick", 0.680000, 0.000000, 0.760000, 0.151486, color, 2, 1, 16 );
Touch_AddDefaultButton( "savequick", "touch_default/save", "savequick", 0.760000, 0.000000, 0.840000, 0.151486, color, 2, 1, 16 );
Touch_AddDefaultButton( "messagemode", "touch_default/keyboard", "messagemode", 0.760000, 0.000000, 0.840000, 0.151486, color, 2, 1, 8 );
Touch_AddDefaultButton( "reload", "touch_default/reload", "+reload", 0.000000, 0.302971, 0.120000, 0.530200, color, 2, 1, 0 );
Touch_AddDefaultButton( "flashlight", "touch_default/flash_light_filled", "impulse 100", 0.920000, 0.000000, 1.000000, 0.151486, color, 2, 1, 0 );
Touch_AddDefaultButton( "scores", "touch_default/map", "+showscores", 0.760000, 0.000000, 0.840000, 0.151486, color, 2, 1, 8 );
Touch_AddDefaultButton( "scores", "touch_default/map", "+showscores", 0.680000, 0.000000, 0.760000, 0.151486, color, 2, 1, 8 );
Touch_AddDefaultButton( "show_numbers", "touch_default/show_weapons", "exec touch_default/numbers.cfg", 0.440000, 0.833171, 0.520000, 0.984656, color, 2, 1, 0 );
Touch_AddDefaultButton( "duck", "touch_default/crouch", "+duck", 0.880000, 0.757428, 1.000000, 0.984656, color, 2, 1, 0 );
Touch_AddDefaultButton( "tduck", "touch_default/tduck", ";+duck", 0.560000, 0.833171, 0.620000, 0.946785, color, 2, 1, 0 );
Touch_AddDefaultButton( "edit", "touch_default/settings", "touch_enableedit", 0.420000, 0.000000, 0.500000, 0.151486, color, 2, 1, 32 );
Touch_AddDefaultButton( "menu", "touch_default/menu", "escape", 0.000000, 0.833171, 0.080000, 0.984656, color, 2, 1, 0 );
Touch_AddDefaultButton( "spray", "touch_default/spray", "impulse 201", 0.840000, 0.000000, 0.920000, 0.151486, color, 2, 1, 0 );
Cmd_AddCommand( "touch_addbutton", Touch_AddButton_f, "add native touch button" );
Cmd_AddCommand( "touch_removebutton", IN_TouchRemoveButton_f, "remove native touch button" );
@@ -1080,40 +1123,46 @@ void Touch_Init( void )
Cmd_AddRestrictedCommand( "touch_generate_code", Touch_GenerateCode_f, "create code sample for mobility API" );
Cmd_AddCommand( "touch_fade", Touch_Fade_f, "start fade animation for selected buttons" );
Cmd_AddRestrictedCommand( "touch_toggleselection", Touch_ToggleSelection_f, "toggle vidibility on selected button in editor" );
Cmd_AddRestrictedCommand( "touch_aspectratio", Touch_ConfigAspectRatio_f, "set current aspect ratio" );
// not saved, just runtime state for scripting
touch_in_menu = Cvar_Get( "touch_in_menu", "0", FCVAR_FILTERABLE, "draw touch in menu (for internal use only)" );
Cvar_RegisterVariable( &touch_in_menu );
// sensitivity configuration
touch_forwardzone = Cvar_Get( "touch_forwardzone", "0.06", FCVAR_FILTERABLE, "forward touch zone" );
touch_sidezone = Cvar_Get( "touch_sidezone", "0.06", FCVAR_FILTERABLE, "side touch zone" );
touch_pitch = Cvar_Get( "touch_pitch", "90", FCVAR_FILTERABLE, "touch pitch sensitivity" );
touch_yaw = Cvar_Get( "touch_yaw", "120", FCVAR_FILTERABLE, "touch yaw sensitivity" );
touch_nonlinear_look = Cvar_Get( "touch_nonlinear_look", "0", FCVAR_FILTERABLE, "enable nonlinear touch look" );
touch_pow_factor = Cvar_Get( "touch_pow_factor", "1.3", FCVAR_FILTERABLE, "set > 1 to enable" );
touch_pow_mult = Cvar_Get( "touch_pow_mult", "400.0", FCVAR_FILTERABLE, "power multiplier, usually 200-1000" );
touch_exp_mult = Cvar_Get( "touch_exp_mult", "0", FCVAR_FILTERABLE, "exponent multiplier, usually 20-200, 0 to disable" );
Cvar_RegisterVariable( &touch_forwardzone );
Cvar_RegisterVariable( &touch_sidezone );
Cvar_RegisterVariable( &touch_pitch );
Cvar_RegisterVariable( &touch_yaw );
Cvar_RegisterVariable( &touch_nonlinear_look );
Cvar_RegisterVariable( &touch_pow_factor );
Cvar_RegisterVariable( &touch_pow_mult );
Cvar_RegisterVariable( &touch_exp_mult );
// touch.cfg
touch_grid_count = Cvar_Get( "touch_grid_count", "50", FCVAR_FILTERABLE, "touch grid count" );
touch_grid_enable = Cvar_Get( "touch_grid_enable", "1", FCVAR_FILTERABLE, "enable touch grid" );
touch_config_file = Cvar_Get( "touch_config_file", "touch.cfg", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "current touch profile file" );
touch_precise_amount = Cvar_Get( "touch_precise_amount", "0.5", FCVAR_FILTERABLE, "sensitivity multiplier for precise-look" );
touch_highlight_r = Cvar_Get( "touch_highlight_r", "1.0", 0, "highlight r color" );
touch_highlight_g = Cvar_Get( "touch_highlight_g", "1.0", 0, "highlight g color" );
touch_highlight_b = Cvar_Get( "touch_highlight_b", "1.0", 0, "highlight b color" );
touch_highlight_a = Cvar_Get( "touch_highlight_a", "1.0", 0, "highlight alpha" );
touch_dpad_radius = Cvar_Get( "touch_dpad_radius", "1.0", FCVAR_FILTERABLE, "dpad radius multiplier" );
touch_joy_radius = Cvar_Get( "touch_joy_radius", "1.0", FCVAR_FILTERABLE, "joy radius multiplier" );
touch_move_indicator = Cvar_Get( "touch_move_indicator", "0.0", FCVAR_FILTERABLE, "indicate move events (0 to disable)" );
touch_joy_texture = Cvar_Get( "touch_joy_texture", "touch_default/joy", FCVAR_FILTERABLE, "texture for move indicator");
Cvar_RegisterVariable( &touch_grid_count );
Cvar_RegisterVariable( &touch_grid_enable );
Cvar_RegisterVariable( &touch_config_file );
Cvar_RegisterVariable( &touch_precise_amount );
Cvar_RegisterVariable( &touch_highlight_r );
Cvar_RegisterVariable( &touch_highlight_g );
Cvar_RegisterVariable( &touch_highlight_b );
Cvar_RegisterVariable( &touch_highlight_a );
Cvar_RegisterVariable( &touch_dpad_radius );
Cvar_RegisterVariable( &touch_joy_radius );
Cvar_RegisterVariable( &touch_move_indicator );
Cvar_RegisterVariable( &touch_joy_texture );
// input devices cvar
touch_enable = Cvar_Get( "touch_enable", DEFAULT_TOUCH_ENABLE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enable touch controls" );
touch_emulate = Cvar_Get( "touch_emulate", "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "emulate touch with mouse" );
Cvar_RegisterVariable( &touch_enable );
Cvar_RegisterVariable( &touch_emulate );
/// TODO: touch sdl platform
// SDL_SetHint( SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH, "1" );
// TODO: touch platform
#if SDL_VERSION_ATLEAST( 2, 0, 10 )
SDL_SetHint( SDL_HINT_MOUSE_TOUCH_EVENTS, "0" );
SDL_SetHint( SDL_HINT_TOUCH_MOUSE_EVENTS, "0" );
#elif defined(SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH)
SDL_SetHint( SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH, "1" );
#endif
touch.initialized = true;
}
@@ -1132,12 +1181,18 @@ static void Touch_InitConfig( void )
/// TODO: hud font
//pfnGetScreenInfo( NULL ); //HACK: update hud screen parameters like iHeight
if( FS_FileExists( touch_config_file->string, true ) )
Cbuf_AddText( va( "exec \"%s\"\n", touch_config_file->string ) );
else Touch_LoadDefaults_f( );
if( FS_FileExists( touch_config_file.string, true ) )
{
Cbuf_AddTextf( "exec \"%s\"\n", touch_config_file.string );
Cbuf_Execute();
}
else
{
Touch_LoadDefaults_f();
}
Touch_InitEditor();
touch.joytexture = ref.dllFuncs.GL_LoadTexture( touch_joy_texture->string, NULL, 0, TF_NOMIPMAP );
touch.joytexture = ref.dllFuncs.GL_LoadTexture( touch_joy_texture.string, NULL, 0, TF_NOMIPMAP );
touch.whitetexture = R_GetBuiltinTexture( REF_WHITE_TEXTURE );
touch.configchanged = false;
touch.config_loaded = true;
@@ -1187,10 +1242,10 @@ static void Touch_DrawTexture ( float x1, float y1, float x2, float y2, int text
0, 0, 1, 1, texture );
}
#define GRID_COUNT_X ((int)touch_grid_count->value)
#define GRID_COUNT_Y (((int)touch_grid_count->value) * SCR_H / SCR_W)
#define GRID_COUNT_X ((int)touch_grid_count.value)
#define GRID_COUNT_Y (((int)touch_grid_count.value) * Touch_AspectRatio())
#define GRID_X (1.0f/GRID_COUNT_X)
#define GRID_Y (SCR_W/SCR_H/GRID_COUNT_X)
#define GRID_Y (1.0f/Touch_AspectRatio()/GRID_COUNT_X)
#define GRID_ROUND_X(x) ((float)round( x * GRID_COUNT_X ) / GRID_COUNT_X)
#define GRID_ROUND_Y(x) ((float)round( x * GRID_COUNT_Y ) / GRID_COUNT_Y)
@@ -1209,7 +1264,7 @@ static void IN_TouchCheckCoords( float *x1, float *y1, float *x2, float *y2 )
*y1 -= *y2 - 1, *y2 = 1;
if( *x2 > 1 )
*x1 -= *x2 - 1, *x2 = 1;
if( CVAR_TO_BOOL( touch_grid_enable ))
if( touch_grid_enable.value )
{
*x1 = GRID_ROUND_X( *x1 );
*x2 = GRID_ROUND_X( *x2 );
@@ -1268,7 +1323,7 @@ static float Touch_DrawText( float x1, float y1, float x2, float y2, const char
{
while( *s && ( *s != '\n' ) && ( *s != ';' ) && ( x1 < maxx ) )
x1 += Touch_DrawCharacter( x1, y1, *s++, size );
y1 += cls.creditsFont.charHeight / 1024.f * size / SCR_H * SCR_W;
y1 += cls.creditsFont.charHeight / 1024.f * size / Touch_AspectRatio();
if( y1 >= maxy )
break;
@@ -1305,10 +1360,10 @@ static void Touch_DrawButtons( touchbuttonlist_t *list )
if( ( B( finger ) != -1 ) && !FBitSet( B( flags ), TOUCH_FL_CLIENT ) )
{
color[0] = bound( 0,(float) color[0] * touch_highlight_r->value, 255 );
color[1] = bound( 0,(float) color[1] * touch_highlight_g->value, 255 );
color[2] = bound( 0,(float) color[2] * touch_highlight_b->value, 255 );
color[3] = bound( 0,(float) color[3] * touch_highlight_a->value, 255 );
color[0] = bound( 0,(float) color[0] * touch_highlight_r.value, 255 );
color[1] = bound( 0,(float) color[1] * touch_highlight_g.value, 255 );
color[2] = bound( 0,(float) color[2] * touch_highlight_b.value, 255 );
color[3] = bound( 0,(float) color[3] * touch_highlight_a.value, 255 );
}
color[3] *= B( fade );
@@ -1372,20 +1427,21 @@ void Touch_Draw( void )
{
touch_button_t *button;
if( !touch.initialized || (!CVAR_TO_BOOL(touch_enable) && !touch.clientonly) )
if( !touch.initialized || ( !touch_enable.value && !touch.clientonly ))
return;
if( cls.key_dest != key_game && !touch_in_menu.value )
return;
Touch_InitConfig();
if( cls.key_dest != key_game && !CVAR_TO_BOOL(touch_in_menu) )
return;
ref.dllFuncs.GL_SetRenderMode( kRenderTransTexture );
if( touch.state >= state_edit && CVAR_TO_BOOL(touch_grid_enable) )
if( touch.state >= state_edit && touch_grid_enable.value )
{
float x;
if( CVAR_TO_BOOL(touch_in_menu) )
if( touch_in_menu.value )
Touch_DrawTexture( 0, 0, 1, 1, touch.whitetexture, 32, 32, 32, 255 );
else
Touch_DrawTexture( 0, 0, 1, 1, touch.whitetexture, 0, 0, 0, 112 );
@@ -1446,19 +1502,19 @@ void Touch_Draw( void )
ref.dllFuncs.Color4ub( 255, 255, 255, 255 );
if( ( touch.move_finger != -1 ) && touch.move_button && touch_move_indicator->value )
if( ( touch.move_finger != -1 ) && touch.move_button && touch_move_indicator.value )
{
float width;
float height;
if( FBitSet( touch_joy_texture->flags, FCVAR_CHANGED ) )
if( FBitSet( touch_joy_texture.flags, FCVAR_CHANGED ) )
{
ClearBits( touch_joy_texture->flags, FCVAR_CHANGED );
touch.joytexture = ref.dllFuncs.GL_LoadTexture( touch_joy_texture->string, NULL, 0, TF_NOMIPMAP );
ClearBits( touch_joy_texture.flags, FCVAR_CHANGED );
touch.joytexture = ref.dllFuncs.GL_LoadTexture( touch_joy_texture.string, NULL, 0, TF_NOMIPMAP );
}
if( touch.move_button->type == touch_move )
{
width = touch_sidezone->value;
height = touch_forwardzone->value;
width = touch_sidezone.value;
height = touch_forwardzone.value;
}
else
{
@@ -1466,13 +1522,13 @@ void Touch_Draw( void )
height = (touch.move_button->y2 - touch.move_button->y1)/2;
}
ref.dllFuncs.Color4ub( 255, 255, 255, 128 );
ref.dllFuncs.R_DrawStretchPic( TO_SCRN_X( touch.move_start_x - GRID_X * touch_move_indicator->value ),
TO_SCRN_Y( touch.move_start_y - GRID_Y * touch_move_indicator->value ),
TO_SCRN_X( GRID_X * 2 * touch_move_indicator->value ), TO_SCRN_Y( GRID_Y * 2 * touch_move_indicator->value ), 0, 0, 1, 1, touch.joytexture );
ref.dllFuncs.R_DrawStretchPic( TO_SCRN_X( touch.move_start_x - GRID_X * touch_move_indicator.value ),
TO_SCRN_Y( touch.move_start_y - GRID_Y * touch_move_indicator.value ),
TO_SCRN_X( GRID_X * 2 * touch_move_indicator.value ), TO_SCRN_Y( GRID_Y * 2 * touch_move_indicator.value ), 0, 0, 1, 1, touch.joytexture );
ref.dllFuncs.Color4ub( 255, 255, 255, 255 );
ref.dllFuncs.R_DrawStretchPic( TO_SCRN_X( touch.move_start_x + touch.side * width - GRID_X * touch_move_indicator->value ),
TO_SCRN_Y( touch.move_start_y - touch.forward * height - GRID_Y * touch_move_indicator->value ),
TO_SCRN_X( GRID_X * 2 * touch_move_indicator->value ), TO_SCRN_Y( GRID_Y * 2 * touch_move_indicator->value ), 0, 0, 1, 1, touch.joytexture );
ref.dllFuncs.R_DrawStretchPic( TO_SCRN_X( touch.move_start_x + touch.side * width - GRID_X * touch_move_indicator.value ),
TO_SCRN_Y( touch.move_start_y - touch.forward * height - GRID_Y * touch_move_indicator.value ),
TO_SCRN_X( GRID_X * 2 * touch_move_indicator.value ), TO_SCRN_Y( GRID_Y * 2 * touch_move_indicator.value ), 0, 0, 1, 1, touch.joytexture );
}
@@ -1515,9 +1571,9 @@ static void Touch_EditMove( touchEventType type, int fingerID, float x, float y,
touch.hidebutton->flags &= ~TOUCH_FL_HIDE;
if( FBitSet( button->flags, TOUCH_FL_HIDE ))
Q_strcpy( touch.hidebutton->texturefile, "touch_default/edit_show" );
Q_strncpy( touch.hidebutton->texturefile, "touch_default/edit_show", sizeof( touch.hidebutton->texturefile ));
else
Q_strcpy( touch.hidebutton->texturefile, "touch_default/edit_hide" );
Q_strncpy( touch.hidebutton->texturefile, "touch_default/edit_hide", sizeof( touch.hidebutton->texturefile ));
}
}
if( type == event_motion ) // shutdown button move
@@ -1581,28 +1637,28 @@ static void Touch_Motion( touchEventType type, int fingerID, float x, float y, f
if( fingerID == touch.move_finger )
{
// check bounds
if( touch_forwardzone->value <= 0 )
if( touch_forwardzone.value <= 0 )
Cvar_SetValue( "touch_forwardzone", 0.5 );
if( touch_sidezone->value <= 0 )
if( touch_sidezone.value <= 0 )
Cvar_SetValue( "touch_sidezone", 0.3 );
if( !touch.move_button || touch.move_button->type == touch_move )
{
// move relative to touch start
touch.forward = ( touch.move_start_y - y ) / touch_forwardzone->value;
touch.side = ( x - touch.move_start_x ) / touch_sidezone->value;
touch.forward = ( touch.move_start_y - y ) / touch_forwardzone.value;
touch.side = ( x - touch.move_start_x ) / touch_sidezone.value;
}
else if( touch.move_button->type == touch_joy )
{
// move relative to joy center
touch.forward = ( ( touch.move_button->y2 + touch.move_button->y1 ) - y * 2 ) / ( touch.move_button->y2 - touch.move_button->y1 ) * touch_joy_radius->value;
touch.side = ( x * 2 - ( touch.move_button->x2 + touch.move_button->x1 ) ) / ( touch.move_button->x2 - touch.move_button->x1 ) * touch_joy_radius->value;
touch.forward = ( ( touch.move_button->y2 + touch.move_button->y1 ) - y * 2 ) / ( touch.move_button->y2 - touch.move_button->y1 ) * touch_joy_radius.value;
touch.side = ( x * 2 - ( touch.move_button->x2 + touch.move_button->x1 ) ) / ( touch.move_button->x2 - touch.move_button->x1 ) * touch_joy_radius.value;
}
else if( touch.move_button->type == touch_dpad )
{
// like joy, but without acceleration. useful for bhop
touch.forward = round( ( (touch.move_button->y2 + touch.move_button->y1) - y * 2 ) / ( touch.move_button->y2 - touch.move_button->y1 ) * touch_dpad_radius->value );
touch.side = round( ( x * 2 - (touch.move_button->x2 + touch.move_button->x1) ) / ( touch.move_button->x2 - touch.move_button->x1 ) * touch_dpad_radius->value );
touch.forward = round( ( (touch.move_button->y2 + touch.move_button->y1) - y * 2 ) / ( touch.move_button->y2 - touch.move_button->y1 ) * touch_dpad_radius.value );
touch.side = round( ( x * 2 - (touch.move_button->x2 + touch.move_button->x1) ) / ( touch.move_button->x2 - touch.move_button->x1 ) * touch_dpad_radius.value );
}
touch.forward = bound( -1, touch.forward, 1 );
@@ -1613,9 +1669,9 @@ static void Touch_Motion( touchEventType type, int fingerID, float x, float y, f
if( fingerID == touch.look_finger )
{
if( touch.precision )
dx *= touch_precise_amount->value, dy *= touch_precise_amount->value;
dx *= touch_precise_amount.value, dy *= touch_precise_amount.value;
if( CVAR_TO_BOOL(touch_nonlinear_look) )
if( touch_nonlinear_look.value )
{
float dabs, dcos, dsin;
@@ -1628,11 +1684,11 @@ static void Touch_Motion( touchEventType type, int fingerID, float x, float y, f
dcos = dx / dabs;
dsin = dy / dabs;
if( touch_exp_mult->value > 1 )
dabs = ( exp( dabs * touch_exp_mult->value ) - 1 ) / touch_exp_mult->value;
if( touch_exp_mult.value > 1 )
dabs = ( exp( dabs * touch_exp_mult.value ) - 1 ) / touch_exp_mult.value;
if( touch_pow_mult->value > 1 && touch_pow_factor->value > 1 )
dabs = pow( dabs * touch_pow_mult->value, touch_pow_factor->value ) / touch_pow_mult->value;
if( touch_pow_mult.value > 1 && touch_pow_factor.value > 1 )
dabs = pow( dabs * touch_pow_mult.value, touch_pow_factor.value ) / touch_pow_mult.value;
dx = dabs * dcos;
dy = dabs * dsin;
@@ -1643,7 +1699,7 @@ static void Touch_Motion( touchEventType type, int fingerID, float x, float y, f
return;
// accumulate
touch.yaw -= dx * touch_yaw->value, touch.pitch += dy * touch_pitch->value;
touch.yaw -= dx * touch_yaw.value, touch.pitch += dy * touch_pitch.value;
}
}
@@ -1966,15 +2022,17 @@ static int Touch_ControlsEvent( touchEventType type, int fingerID, float x, floa
int IN_TouchEvent( touchEventType type, int fingerID, float x, float y, float dx, float dy )
{
y *= SCR_H/SCR_W/Touch_AspectRatio();
// Con_Printf("%f %f\n", TO_SCRN_X(x), TO_SCRN_Y(y));
// simulate menu mouse click
if( cls.key_dest != key_game && !CVAR_TO_BOOL(touch_in_menu) )
if( cls.key_dest != key_game && !touch_in_menu.value )
{
touch.move_finger = touch.resize_finger = touch.look_finger = -1;
// Hack for keyboard, hope it help
if( cls.key_dest == key_console || cls.key_dest == key_message )
{
Key_EnableTextInput( true, true );
if ( type == event_down ) // don't pop it again on event_up
Key_EnableTextInput( true, true );
if( cls.key_dest == key_console )
{
static float y1 = 0;
@@ -2011,25 +2069,20 @@ int IN_TouchEvent( touchEventType type, int fingerID, float x, float y, float dx
{
VGui_MouseMove( TO_SCRN_X(x), TO_SCRN_Y(y) );
if( type != event_motion )
VGui_KeyEvent( K_MOUSE1, type == event_down ? 1 : 0 );
// allow scoreboard scroll
if( host.mouse_visible && type == event_motion )
return 0;
switch( type )
{
case event_down:
VGui_MouseEvent( K_MOUSE1, 1 );
break;
case event_up:
VGui_MouseEvent( K_MOUSE1, 0 );
break;
default: break;
}
}
if( !touch.initialized || (!CVAR_TO_BOOL(touch_enable) && !touch.clientonly) )
{
#if 0
if( type == event_down )
Key_Event( K_MOUSE1, true );
if( type == event_up )
Key_Event( K_MOUSE1, false );
Android_AddMove( dx * (float)refState.width, dy * (float)refState.height );
#endif
if( !touch.initialized || ( !touch_enable.value && !touch.clientonly ))
return 0;
}
if( clgame.dllFuncs.pfnTouchEvent && clgame.dllFuncs.pfnTouchEvent( type, fingerID, x, y, dx, dy ) )
return true;
@@ -2048,35 +2101,65 @@ void Touch_GetMove( float *forward, float *side, float *yaw, float *pitch )
void Touch_KeyEvent( int key, int down )
{
int xi, yi;
float x, y;
static float lx, ly;
static int kidNamedFinger = -1;
touchEventType event;
float x, y;
int finger, xi, yi;
if( !CVAR_TO_BOOL(touch_emulate) )
if( !touch_emulate.value )
{
if( CVAR_TO_BOOL(touch_enable) )
if( touch_enable.value )
return;
if( !touch.clientonly )
return;
}
Platform_GetMousePos( &xi, &yi );
x = xi/SCR_W;
y = yi/SCR_H;
if( cls.key_dest == key_menu && down < 2 && key == K_MOUSE1 )
if( !key )
{
UI_MouseMove( xi, yi );
UI_KeyEvent( key, down );
if( kidNamedFinger < 0 )
return;
finger = kidNamedFinger;
event = event_motion;
}
else
{
finger = key == K_MOUSE1 ? 0 : 1;
if( down )
{
event = event_down;
kidNamedFinger = finger;
}
else
{
event = event_up;
kidNamedFinger = -1;
}
}
if( down == 1 )
Touch_ControlsEvent( event_down, key == K_MOUSE1?0:1, x, y, 0, 0 );
else
Touch_ControlsEvent( down? event_motion: event_up, key == K_MOUSE1?0:1, x, y, x-lx, y-ly );
lx = x, ly = y;
// don't deactivate mouse in game
// checking a case when mouse and touchscreen
// can be used simultaneously
Platform_SetCursorType( dc_arrow );
Platform_GetMousePos( &xi, &yi );
x = xi / SCR_W;
y = yi / SCR_H;
Con_DPrintf( "event %d %.2f %.2f %.2f %.2f\n",
event, x, y, x - lx, y - ly );
IN_TouchEvent( event, finger, x, y, x - lx, y - ly );
lx = x;
ly = y;
}
qboolean Touch_WantVisibleCursor( void )
{
return ( touch_enable.value && touch_emulate.value ) || touch.clientonly;
}
void Touch_Shutdown( void )

View File

@@ -36,18 +36,15 @@ static struct inputstate_s
float lastpitch, lastyaw;
} inputstate;
extern convar_t *vid_fullscreen;
convar_t *m_pitch;
convar_t *m_yaw;
CVAR_DEFINE_AUTO( m_pitch, "0.022", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "mouse pitch value" );
CVAR_DEFINE_AUTO( m_yaw, "0.022", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "mouse yaw value" );
CVAR_DEFINE_AUTO( m_ignore, DEFAULT_M_IGNORE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "ignore mouse events" );
static CVAR_DEFINE_AUTO( look_filter, "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "filter look events making it smoother" );
static CVAR_DEFINE_AUTO( m_rawinput, "1", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enable mouse raw input" );
convar_t *m_ignore;
convar_t *cl_forwardspeed;
convar_t *cl_sidespeed;
convar_t *cl_backspeed;
convar_t *look_filter;
convar_t *m_rawinput;
static qboolean s_bRawInput, s_bMouseGrab;
static CVAR_DEFINE_AUTO( cl_forwardspeed, "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL | FCVAR_FILTERABLE, "Default forward move speed" );
static CVAR_DEFINE_AUTO( cl_backspeed, "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL | FCVAR_FILTERABLE, "Default back move speed" );
static CVAR_DEFINE_AUTO( cl_sidespeed, "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL | FCVAR_FILTERABLE, "Default side move speed" );
/*
================
@@ -60,10 +57,10 @@ uint IN_CollectInputDevices( void )
{
uint ret = 0;
if( !m_ignore->value ) // no way to check is mouse connected, so use cvar only
if( !m_ignore.value ) // no way to check is mouse connected, so use cvar only
ret |= INPUT_DEVICE_MOUSE;
if( CVAR_TO_BOOL(touch_enable) )
if( touch_enable.value )
ret |= INPUT_DEVICE_TOUCH;
if( Joy_IsActive() ) // connected or enabled
@@ -88,19 +85,19 @@ player is connected to the server
*/
void IN_LockInputDevices( qboolean lock )
{
extern convar_t *joy_enable; // private to input system
extern convar_t joy_enable; // private to input system
if( lock )
{
SetBits( m_ignore->flags, FCVAR_READ_ONLY );
SetBits( joy_enable->flags, FCVAR_READ_ONLY );
SetBits( touch_enable->flags, FCVAR_READ_ONLY );
SetBits( m_ignore.flags, FCVAR_READ_ONLY );
SetBits( joy_enable.flags, FCVAR_READ_ONLY );
SetBits( touch_enable.flags, FCVAR_READ_ONLY );
}
else
{
ClearBits( m_ignore->flags, FCVAR_READ_ONLY );
ClearBits( joy_enable->flags, FCVAR_READ_ONLY );
ClearBits( touch_enable->flags, FCVAR_READ_ONLY );
ClearBits( m_ignore.flags, FCVAR_READ_ONLY );
ClearBits( joy_enable.flags, FCVAR_READ_ONLY );
ClearBits( touch_enable.flags, FCVAR_READ_ONLY );
}
}
@@ -112,12 +109,12 @@ IN_StartupMouse
*/
void IN_StartupMouse( void )
{
m_ignore = Cvar_Get( "m_ignore", DEFAULT_M_IGNORE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "ignore mouse events" );
Cvar_RegisterVariable( &m_ignore );
m_pitch = Cvar_Get( "m_pitch", "0.022", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "mouse pitch value" );
m_yaw = Cvar_Get( "m_yaw", "0.022", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "mouse yaw value" );
look_filter = Cvar_Get( "look_filter", "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "filter look events making it smoother" );
m_rawinput = Cvar_Get( "m_rawinput", "1", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enable mouse raw input" );
Cvar_RegisterVariable( &m_pitch );
Cvar_RegisterVariable( &m_yaw );
Cvar_RegisterVariable( &look_filter );
Cvar_RegisterVariable( &m_rawinput );
// You can use -nomouse argument to prevent using mouse from client
// -noenginemouse will disable all mouse input
@@ -173,7 +170,29 @@ Called when key_dest is changed
*/
void IN_ToggleClientMouse( int newstate, int oldstate )
{
if( newstate == oldstate ) return;
if( newstate == oldstate )
return;
if( m_ignore.value )
return;
// since SetCursorType controls cursor visibility
// execute it first, and then check mouse grab state
if( newstate == key_menu || newstate == key_console )
{
Platform_SetCursorType( dc_arrow );
#if XASH_USE_EVDEV
Evdev_SetGrab( false );
#endif
}
else
{
Platform_SetCursorType( dc_none );
#if XASH_USE_EVDEV
Evdev_SetGrab( true );
#endif
}
if( oldstate == key_game )
{
@@ -183,35 +202,21 @@ void IN_ToggleClientMouse( int newstate, int oldstate )
{
IN_ActivateMouse();
}
if( ( newstate == key_menu || newstate == key_console || newstate == key_message ) && ( !CL_IsBackgroundMap() || CL_IsBackgroundDemo( )))
{
#if XASH_ANDROID
Android_ShowMouse( true );
#endif
#ifdef XASH_USE_EVDEV
Evdev_SetGrab( false );
#endif
}
else
{
#if XASH_ANDROID
Android_ShowMouse( false );
#endif
#ifdef XASH_USE_EVDEV
Evdev_SetGrab( true );
#endif
}
}
void IN_CheckMouseState( qboolean active )
{
static qboolean s_bRawInput, s_bMouseGrab;
#if XASH_WIN32
qboolean useRawInput = CVAR_TO_BOOL( m_rawinput ) && clgame.client_dll_uses_sdl || clgame.dllFuncs.pfnLookEvent;
qboolean useRawInput = ( m_rawinput.value && clgame.client_dll_uses_sdl ) || clgame.dllFuncs.pfnLookEvent != NULL;
#else
qboolean useRawInput = true; // always use SDL code
#endif
if( m_ignore.value )
return;
if( active && useRawInput && !host.mouse_visible && cls.state == ca_active )
{
if( !s_bRawInput )
@@ -308,25 +313,25 @@ IN_MouseMove
*/
void IN_MouseMove( void )
{
POINT current_pos;
int x, y;
if( !in_mouseinitialized )
return;
if( touch_emulate.value )
{
// touch emulation overrides all input
Touch_KeyEvent( 0, 0 );
return;
}
// find mouse movement
Platform_GetMousePos( &current_pos.x, &current_pos.y );
Platform_GetMousePos( &x, &y );
VGui_MouseMove( current_pos.x, current_pos.y );
// HACKHACK: show cursor in UI, as mainui doesn't call
// platform-dependent SetCursor anymore
#if XASH_SDL
if( UI_IsVisible() )
SDL_ShowCursor( SDL_TRUE );
#endif
VGui_MouseMove( x, y );
// if the menu is visible, move the menu cursor
UI_MouseMove( current_pos.x, current_pos.y );
UI_MouseMove( x, y );
}
/*
@@ -336,8 +341,6 @@ IN_MouseEvent
*/
void IN_MouseEvent( int key, int down )
{
int i;
if( !in_mouseinitialized )
return;
@@ -345,10 +348,15 @@ void IN_MouseEvent( int key, int down )
SetBits( in_mstate, BIT( key ));
else ClearBits( in_mstate, BIT( key ));
if( cls.key_dest == key_game )
// touch emulation overrides all input
if( touch_emulate.value )
{
Touch_KeyEvent( K_MOUSE1 + key, down );
}
else if( cls.key_dest == key_game )
{
// perform button actions
VGui_KeyEvent( K_MOUSE1 + key, down );
VGui_MouseEvent( K_MOUSE1 + key, down );
// don't do Key_Event here
// client may override IN_MouseEvent
@@ -363,6 +371,23 @@ void IN_MouseEvent( int key, int down )
}
}
/*
==============
IN_MWheelEvent
direction is negative for wheel down, otherwise wheel up
==============
*/
void IN_MWheelEvent( int y )
{
int b = y > 0 ? K_MWHEELUP : K_MWHEELDOWN;
VGui_MWheelEvent( y );
Key_Event( b, true );
Key_Event( b, false );
}
/*
===========
IN_Shutdown
@@ -372,7 +397,7 @@ void IN_Shutdown( void )
{
IN_DeactivateMouse( );
#ifdef XASH_USE_EVDEV
#if XASH_USE_EVDEV
Evdev_Shutdown();
#endif
@@ -387,9 +412,9 @@ IN_Init
*/
void IN_Init( void )
{
cl_forwardspeed = Cvar_Get( "cl_forwardspeed", "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL | FCVAR_FILTERABLE, "Default forward move speed" );
cl_backspeed = Cvar_Get( "cl_backspeed", "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL | FCVAR_FILTERABLE, "Default back move speed" );
cl_sidespeed = Cvar_Get( "cl_sidespeed", "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL | FCVAR_FILTERABLE, "Default side move speed" );
Cvar_RegisterVariable( &cl_forwardspeed );
Cvar_RegisterVariable( &cl_backspeed );
Cvar_RegisterVariable( &cl_sidespeed );
if( !Host_IsDedicated() )
{
@@ -399,7 +424,7 @@ void IN_Init( void )
Touch_Init();
#ifdef XASH_USE_EVDEV
#if XASH_USE_EVDEV
Evdev_Init();
#endif
}
@@ -426,8 +451,8 @@ static void IN_JoyAppendMove( usercmd_t *cmd, float forwardmove, float sidemove
{
static uint moveflags = T | S;
if( forwardmove ) cmd->forwardmove = forwardmove * cl_forwardspeed->value;
if( sidemove ) cmd->sidemove = sidemove * cl_sidespeed->value;
if( forwardmove ) cmd->forwardmove = forwardmove * cl_forwardspeed.value;
if( sidemove ) cmd->sidemove = sidemove * cl_sidespeed.value;
if( forwardmove )
{
@@ -502,10 +527,10 @@ static void IN_CollectInput( float *forward, float *side, float *pitch, float *y
{
float x, y;
Platform_MouseMove( &x, &y );
*pitch += y * m_pitch->value;
*yaw -= x * m_yaw->value;
*pitch += y * m_pitch.value;
*yaw -= x * m_yaw.value;
#ifdef XASH_USE_EVDEV
#if XASH_USE_EVDEV
IN_EvdevMove( yaw, pitch );
#endif
}
@@ -513,7 +538,7 @@ static void IN_CollectInput( float *forward, float *side, float *pitch, float *y
Joy_FinalizeMove( forward, side, yaw, pitch );
Touch_GetMove( forward, side, yaw, pitch );
if( look_filter->value )
if( look_filter.value )
{
*pitch = ( inputstate.lastpitch + *pitch ) / 2;
*yaw = ( inputstate.lastyaw + *yaw ) / 2;
@@ -563,7 +588,7 @@ void IN_EngineAppendMove( float frametime, void *cmd1, qboolean active )
void IN_Commands( void )
{
#ifdef XASH_USE_EVDEV
#if XASH_USE_EVDEV
IN_EvdevFrame();
#endif
@@ -571,7 +596,7 @@ void IN_Commands( void )
{
float forward = 0, side = 0, pitch = 0, yaw = 0;
IN_CollectInput( &forward, &side, &pitch, &yaw, in_mouseinitialized && !CVAR_TO_BOOL( m_ignore ) );
IN_CollectInput( &forward, &side, &pitch, &yaw, in_mouseinitialized && !m_ignore.value );
if( cls.key_dest == key_game )
{

View File

@@ -34,6 +34,7 @@ void IN_Init( void );
void Host_InputFrame( void );
void IN_Shutdown( void );
void IN_MouseEvent( int key, int down );
void IN_MWheelEvent( int direction );
void IN_ActivateMouse( void );
void IN_DeactivateMouse( void );
void IN_MouseSavePos( void );
@@ -45,8 +46,8 @@ uint IN_CollectInputDevices( void );
void IN_LockInputDevices( qboolean lock );
void IN_EngineAppendMove( float frametime, void *cmd, qboolean active );
extern convar_t *m_yaw;
extern convar_t *m_pitch;
extern convar_t m_yaw;
extern convar_t m_pitch;
//
// in_touch.c
//
@@ -57,8 +58,8 @@ typedef enum
event_motion
} touchEventType;
extern convar_t *touch_enable;
extern convar_t *touch_emulate;
extern convar_t touch_enable;
extern convar_t touch_emulate;
void Touch_Draw( void );
void Touch_SetClientOnly( byte state );
@@ -73,6 +74,8 @@ void Touch_GetMove( float * forward, float *side, float *yaw, float *pitch );
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 );
void Touch_NotifyResize( void );
//
// in_joy.c

View File

@@ -104,9 +104,9 @@ keyname_t keynames[] =
{"B_BUTTON", K_B_BUTTON, "+use"},
{"X_BUTTON", K_X_BUTTON, "+reload"},
{"Y_BUTTON", K_Y_BUTTON, "impulse 100"}, // Flashlight
{"BACK", K_BACK_BUTTON, "cancelselect"}, // Menu
{"BACK", K_BACK_BUTTON, "pause"}, // Menu
{"MODE", K_MODE_BUTTON, ""},
{"START", K_START_BUTTON, "pause"},
{"START", K_START_BUTTON, "escape"},
{"STICK1", K_LSTICK, "+speed"},
{"STICK2", K_RSTICK, "+duck"},
{"L1_BUTTON", K_L1_BUTTON, "+duck"},
@@ -123,13 +123,13 @@ keyname_t keynames[] =
{"JOY4" , K_JOY4 , ""},
{"C_BUTTON", K_C_BUTTON, ""},
{"Z_BUTTON", K_Z_BUTTON, ""},
{"AUX20", K_AUX20, ""}, // generic
{"AUX21", K_AUX21, ""},
{"AUX22", K_AUX22, ""},
{"AUX23", K_AUX23, ""},
{"AUX24", K_AUX24, ""},
{"AUX25", K_AUX25, ""},
{"AUX26", K_AUX26, ""},
{"MISC_BUTTON", K_MISC_BUTTON, ""},
{"PADDLE1", K_PADDLE1_BUTTON, ""},
{"PADDLE2", K_PADDLE2_BUTTON, ""},
{"PADDLE3", K_PADDLE3_BUTTON, ""},
{"PADDLE4", K_PADDLE4_BUTTON, ""},
{"TOUCHPAD", K_TOUCHPAD, ""},
{"AUX26", K_AUX26, ""}, // generic
{"AUX27", K_AUX27, ""},
{"AUX28", K_AUX28, ""},
{"AUX29", K_AUX29, ""},
@@ -144,8 +144,8 @@ keyname_t keynames[] =
static void OSK_EnableTextInput( qboolean enable, qboolean force );
static qboolean OSK_KeyEvent( int key, int down );
static convar_t *osk_enable;
static convar_t *key_rotate;
static CVAR_DEFINE_AUTO( osk_enable, "0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "enable built-in on-screen keyboard" );
static CVAR_DEFINE_AUTO( key_rotate, "0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "rotate arrow keys (0-3)" );
/*
===================
@@ -159,18 +159,6 @@ int GAME_EXPORT Key_IsDown( int keynum )
return keys[keynum].down;
}
/*
===================
Key_GetBind
===================
*/
const char *Key_IsBind( int keynum )
{
if( keynum == -1 || !keys[keynum].binding )
return NULL;
return keys[keynum].binding;
}
/*
===================
Key_StringToKeynum
@@ -374,7 +362,7 @@ void Key_Unbindall_f( void )
{
int i;
for( i = 0; i < 256; i++ )
for( i = 0; i < ARRAYSIZE( keys ); i++ )
{
if( keys[i].binding )
Key_SetBinding( i, "" );
@@ -382,6 +370,7 @@ void Key_Unbindall_f( void )
// set some defaults
Key_SetBinding( K_ESCAPE, "escape" );
Key_SetBinding( K_START_BUTTON, "escape" );
}
/*
@@ -395,7 +384,7 @@ void Key_Reset_f( void )
int i;
// clear all keys first
for( i = 0; i < 256; i++ )
for( i = 0; i < ARRAYSIZE( keys ); i++ )
{
if( keys[i].binding )
Key_SetBinding( i, "" );
@@ -445,8 +434,8 @@ void Key_Bind_f( void )
for( i = 2; i < c; i++ )
{
Q_strcat( cmd, Cmd_Argv( i ));
if( i != ( c - 1 )) Q_strcat( cmd, " " );
Q_strncat( cmd, Cmd_Argv( i ), sizeof( cmd ));
if( i != ( c - 1 )) Q_strncat( cmd, " ", sizeof( cmd ));
}
Key_SetBinding( b, cmd );
@@ -524,8 +513,8 @@ void Key_Init( void )
// setup default binding. "unbindall" from config.cfg will be reset it
for( kn = keynames; kn->name; kn++ ) Key_SetBinding( kn->keynum, kn->binding );
osk_enable = Cvar_Get( "osk_enable", "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enable built-in on-screen keyboard" );
key_rotate = Cvar_Get( "key_rotate", "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "rotate arrow keys (0-3)" );
Cvar_RegisterVariable( &osk_enable );
Cvar_RegisterVariable( &key_rotate );
}
@@ -552,8 +541,8 @@ void Key_AddKeyCommands( int key, const char *kb, qboolean down )
if( button[0] == '+' )
{
// button commands add keynum as a parm
if( down ) Q_sprintf( cmd, "%s %i\n", button, key );
else Q_sprintf( cmd, "-%s %i\n", button + 1, key );
if( down ) Q_snprintf( cmd, sizeof( cmd ), "%s %i\n", button, key );
else Q_snprintf( cmd, sizeof( cmd ), "-%s %i\n", button + 1, key );
Cbuf_AddText( cmd );
}
else if( down )
@@ -601,7 +590,7 @@ static qboolean Key_IsAllowedAutoRepeat( int key )
static int Key_Rotate( int key )
{
if( key_rotate->value == 1.0f ) // CW
if( key_rotate.value == 1.0f ) // CW
{
if( key == K_UPARROW )
key = K_LEFTARROW;
@@ -613,7 +602,7 @@ static int Key_Rotate( int key )
key = K_RIGHTARROW;
}
else if( key_rotate->value == 3.0f ) // CCW
else if( key_rotate.value == 3.0f ) // CCW
{
if( key == K_UPARROW )
key = K_RIGHTARROW;
@@ -625,7 +614,7 @@ static int Key_Rotate( int key )
key = K_LEFTARROW;
}
else if( key_rotate->value == 2.0f )
else if( key_rotate.value == 2.0f )
{
if( key == K_UPARROW )
key = K_DOWNARROW;
@@ -712,7 +701,6 @@ void GAME_EXPORT Key_Event( int key, int down )
}
VGui_KeyEvent( key, down );
Touch_KeyEvent( key, down );
// console key is hardcoded, so the user can never unbind it
if( key == '`' || key == '~' )
@@ -731,10 +719,10 @@ void GAME_EXPORT Key_Event( int key, int down )
switch( cls.key_dest )
{
case key_game:
if( CVAR_TO_BOOL( gl_showtextures ))
if( r_showtextures.value )
{
// close texture atlas
Cvar_SetValue( "r_showtextures", 0.0f );
Cvar_DirectSet( &r_showtextures, "0" );
return;
}
else if( host.mouse_visible && cls.state != ca_cinematic )
@@ -809,7 +797,7 @@ Key_EnableTextInput
*/
void Key_EnableTextInput( qboolean enable, qboolean force )
{
if( CVAR_TO_BOOL( osk_enable ) )
if( osk_enable.value )
{
OSK_EnableTextInput( enable, force );
return;
@@ -842,7 +830,9 @@ void GAME_EXPORT Key_SetKeyDest( int key_dest )
cls.key_dest = key_menu;
break;
case key_console:
#if !XASH_NSWITCH && !XASH_PSVITA // if we don't disable this, pops up the keyboard during load
Key_EnableTextInput( true, false );
#endif
cls.key_dest = key_console;
break;
case key_message:
@@ -1005,7 +995,7 @@ struct osk_s
static qboolean OSK_KeyEvent( int key, int down )
{
if( !osk.enable || !CVAR_TO_BOOL( osk_enable ) )
if( !osk.enable || !osk_enable.value )
return false;
if( osk.sending )
@@ -1065,7 +1055,7 @@ static qboolean OSK_KeyEvent( int key, int down )
break;
}
if( !Q_stricmp( cl_charset->string, "utf-8" ) )
if( !Q_stricmp( cl_charset.string, "utf-8" ) )
ch = (unsigned char)osk.curbutton.val;
else
ch = Con_UtfProcessCharForce( (unsigned char)osk.curbutton.val );
@@ -1149,7 +1139,7 @@ Draw button with symbol on it
*/
static void OSK_DrawSymbolButton( int symb, float x, float y, float width, float height )
{
char str[] = {symb & 255, 0};
cl_font_t *font = Con_GetCurFont();
byte color[] = { 255, 255, 255, 255 };
int x1 = x * refState.width,
y1 = y * refState.height,
@@ -1157,14 +1147,15 @@ static void OSK_DrawSymbolButton( int symb, float x, float y, float width, float
h = height * refState.height;
if( symb == osk.curbutton.val )
{
ref.dllFuncs.FillRGBABlend( x1, y1, w, h, 255, 160, 0, 100 );
}
if( !symb || symb == ' ' || (symb >= OSK_TAB && symb < OSK_SPECKEY_LAST ) )
return;
Con_DrawCharacter( x1 + 1, y1, symb, color );
CL_DrawCharacter(
x1 + width * 0.4 * refState.width,
y1 + height * 0.4 * refState.height,
symb, color, font, 0 );
}
/*
@@ -1178,7 +1169,11 @@ static void OSK_DrawSpecialButton( const char *name, float x, float y, float wid
{
byte color[] = { 0, 255, 0, 255 };
Con_DrawString( x * refState.width, y * refState.height, name, color );
Con_DrawString(
x * refState.width + width * 0.4 * refState.width,
y * refState.height + height * 0.4 * refState.height,
name,
color );
}
@@ -1195,7 +1190,7 @@ void OSK_Draw( void )
float x, y;
int i, j;
if( !osk.enable || !CVAR_TO_BOOL(osk_enable) || !osk.curbutton.val )
if( !osk.enable || !osk_enable.value || !osk.curbutton.val )
return;
// draw keyboard

View File

@@ -659,7 +659,7 @@ static void make_hull_windings( hull_t *hull, hull_model_t *model )
Con_Reportf( "%i hull polys\n", model->num_polys );
}
void Mod_InitDebugHulls( void )
void Mod_InitDebugHulls( model_t *loadmodel )
{
int i;

View File

@@ -8,14 +8,14 @@
struct ref_state_s ref;
ref_globals_t refState;
convar_t *gl_vsync;
convar_t *gl_showtextures;
convar_t *r_decals;
convar_t *r_adjust_fov;
convar_t *r_showtree;
convar_t *gl_msaa_samples;
convar_t *gl_clear;
convar_t *r_refdll;
CVAR_DEFINE_AUTO( gl_vsync, "0", FCVAR_ARCHIVE, "enable vertical syncronization" );
CVAR_DEFINE_AUTO( r_showtextures, "0", FCVAR_CHEAT, "show all uploaded textures" );
CVAR_DEFINE_AUTO( r_adjust_fov, "1", FCVAR_ARCHIVE, "making FOV adjustment for wide-screens" );
CVAR_DEFINE_AUTO( r_decals, "4096", FCVAR_ARCHIVE, "sets the maximum number of decals" );
CVAR_DEFINE_AUTO( gl_msaa_samples, "0", FCVAR_GLCONFIG, "samples number for multisample anti-aliasing" );
CVAR_DEFINE_AUTO( gl_clear, "0", FCVAR_ARCHIVE, "clearing screen after each frame" );
CVAR_DEFINE_AUTO( r_showtree, "0", FCVAR_ARCHIVE, "build the graph of visible BSP tree" );
static CVAR_DEFINE_AUTO( r_refdll, "", FCVAR_RENDERINFO, "choose renderer implementation, if supported" );
void R_GetTextureParms( int *w, int *h, int texnum )
{
@@ -55,12 +55,11 @@ void GL_RenderFrame( const ref_viewpass_t *rvp )
VectorCopy( rvp->vieworigin, refState.vieworg );
VectorCopy( rvp->viewangles, refState.viewangles );
AngleVectors( refState.viewangles, refState.vforward, refState.vright, refState.vup );
ref.dllFuncs.GL_RenderFrame( rvp );
}
static int pfnEngineGetParm( int parm, int arg )
static intptr_t pfnEngineGetParm( int parm, int arg )
{
return CL_RenderGetParm( parm, arg, false ); // prevent recursion
}
@@ -75,16 +74,6 @@ static void pfnStudioEvent( const mstudioevent_t *event, const cl_entity_t *e )
clgame.dllFuncs.pfnStudioEvent( event, e );
}
static efrag_t* pfnGetEfragsFreeList( void )
{
return clgame.free_efrags;
}
static void pfnSetEfragsFreeList( efrag_t *list )
{
clgame.free_efrags = list;
}
static model_t *pfnGetDefaultSprite( enum ref_defaultsprite_e spr )
{
switch( spr )
@@ -109,16 +98,6 @@ static void *pfnMod_Extradata( int type, model_t *m )
return NULL;
}
static model_t *pfnMod_GetCurrentLoadingModel( void )
{
return loadmodel;
}
static void pfnMod_SetCurrentLoadingModel( model_t *m )
{
loadmodel = m;
}
static void pfnGetPredictedOrigin( vec3_t v )
{
VectorCopy( cl.simorg, v );
@@ -225,7 +204,7 @@ static qboolean R_DoResetGamma( void )
static qboolean R_Init_Video_( const int type )
{
host.apply_opengl_config = true;
Cbuf_AddText( va( "exec %s.cfg", ref.dllFuncs.R_GetConfigName()));
Cbuf_AddTextf( "exec %s.cfg", ref.dllFuncs.R_GetConfigName());
Cbuf_Execute();
host.apply_opengl_config = false;
@@ -242,7 +221,7 @@ static ref_api_t gEngfuncs =
Cvar_VariableString,
Cvar_SetValue,
Cvar_Set,
(void*)Cvar_RegisterVariable,
Cvar_RegisterVariable,
Cvar_FullSet,
Cmd_AddRefCommand,
@@ -279,9 +258,6 @@ static ref_api_t gEngfuncs =
Mod_PointInLeaf,
Mod_CreatePolygonsForHull,
R_StudioSlerpBones,
R_StudioCalcBoneQuaternion,
R_StudioCalcBonePosition,
R_StudioGetAnim,
pfnStudioEvent,
@@ -296,8 +272,6 @@ static ref_api_t gEngfuncs =
Mod_ForName,
pfnMod_Extradata,
CL_ModelHandle,
pfnMod_GetCurrentLoadingModel,
pfnMod_SetCurrentLoadingModel,
CL_GetRemapInfoForEntity,
CL_AllocRemapInfo,
@@ -359,7 +333,7 @@ static ref_api_t gEngfuncs =
pfnGetPhysent,
pfnTraceSurface,
PM_TraceLine,
PM_CL_TraceLine,
CL_VisTraceLine,
CL_TraceLine,
pfnGetMoveVars,
@@ -393,14 +367,14 @@ static void R_UnloadProgs( void )
Cvar_FullSet( "host_refloaded", "0", FCVAR_READ_ONLY );
Cvar_Unlink( FCVAR_RENDERINFO | FCVAR_GLCONFIG );
Cmd_Unlink( CMD_REFDLL );
COM_FreeLibrary( ref.hInstance );
ref.hInstance = NULL;
memset( &refState, 0, sizeof( refState ));
memset( &ref.dllFuncs, 0, sizeof( ref.dllFuncs ));
Cvar_Unlink( FCVAR_RENDERINFO | FCVAR_GLCONFIG );
Cmd_Unlink( CMD_REFDLL );
}
static void CL_FillTriAPIFromRef( triangleapi_t *dst, const ref_interface_t *src )
@@ -526,7 +500,7 @@ static void R_GetRendererName( char *dest, size_t size, const char *opt )
else
{
// full path
Q_strcpy( dest, opt );
Q_strncpy( dest, opt, size );
}
}
@@ -563,72 +537,64 @@ static void SetWidthAndHeightFromCommandLine( void )
return;
}
R_SaveVideoMode( width, height, width, height );
R_SaveVideoMode( width, height, width, height, false );
}
static void SetFullscreenModeFromCommandLine( void )
{
#if !XASH_MOBILE_PLATFORM
if ( Sys_CheckParm("-fullscreen") )
{
Cvar_Set( "fullscreen", "1" );
}
else if ( Sys_CheckParm( "-windowed" ) )
{
Cvar_Set( "fullscreen", "0" );
}
#endif
if( Sys_CheckParm( "-borderless" ))
Cvar_DirectSet( &vid_fullscreen, "2" );
else if( Sys_CheckParm( "-fullscreen" ))
Cvar_DirectSet( &vid_fullscreen, "1" );
else if( Sys_CheckParm( "-windowed" ))
Cvar_DirectSet( &vid_fullscreen, "0" );
}
void R_CollectRendererNames( void )
static void R_CollectRendererNames( void )
{
const char *renderers[] = DEFAULT_RENDERERS;
int i, cur;
cur = 0;
for( i = 0; i < DEFAULT_RENDERERS_LEN; i++ )
// ordering is important!
static const char *shortNames[] =
{
string temp;
void *dll, *pfn;
#if XASH_REF_GL_ENABLED
"gl",
#endif
#if XASH_REF_NANOGL_ENABLED
"gles1",
#endif
#if XASH_REF_GLWES_ENABLED
"gles2",
#endif
#if XASH_REF_GL4ES_ENABLED
"gl4es",
#endif
#if XASH_REF_SOFT_ENABLED
"soft",
#endif
};
R_GetRendererName( temp, sizeof( temp ), renderers[i] );
// ordering is important here too!
static const char *readableNames[ARRAYSIZE( shortNames )] =
{
#if XASH_REF_GL_ENABLED
"OpenGL",
#endif
#if XASH_REF_NANOGL_ENABLED
"GLES1 (NanoGL)",
#endif
#if XASH_REF_GLWES_ENABLED
"GLES2 (gl-wes-v2)",
#endif
#if XASH_REF_GL4ES_ENABLED
"GL4ES",
#endif
#if XASH_REF_SOFT_ENABLED
"Software",
#endif
};
dll = COM_LoadLibrary( temp, false, true );
if( !dll )
{
Con_Reportf( "R_CollectRendererNames: can't load library %s: %s\n", temp, COM_GetLibraryError() );
continue;
}
pfn = COM_GetProcAddress( dll, GET_REF_API );
if( !pfn )
{
Con_Reportf( "R_CollectRendererNames: can't find API entry point in %s\n", temp );
COM_FreeLibrary( dll );
continue;
}
Q_strncpy( ref.shortNames[cur], renderers[i], sizeof( ref.shortNames[cur] ));
pfn = COM_GetProcAddress( dll, GET_REF_HUMANREADABLE_NAME );
if( !pfn ) // just in case
{
Con_Reportf( "R_CollectRendererNames: can't find GetHumanReadableName export in %s\n", temp );
Q_strncpy( ref.readableNames[cur], renderers[i], sizeof( ref.readableNames[cur] ));
}
else
{
REF_HUMANREADABLE_NAME GetHumanReadableName = (REF_HUMANREADABLE_NAME)pfn;
GetHumanReadableName( ref.readableNames[cur], sizeof( ref.readableNames[cur] ));
}
Con_Printf( "Found renderer %s: %s\n", ref.shortNames[cur], ref.readableNames[cur] );
cur++;
COM_FreeLibrary( dll );
}
ref.numRenderers = cur;
ref.numRenderers = ARRAYSIZE( shortNames );
ref.shortNames = shortNames;
ref.readableNames = readableNames;
}
qboolean R_Init( void )
@@ -636,14 +602,14 @@ qboolean R_Init( void )
qboolean success = false;
string requested;
gl_vsync = Cvar_Get( "gl_vsync", "0", FCVAR_ARCHIVE, "enable vertical syncronization" );
gl_showtextures = Cvar_Get( "r_showtextures", "0", FCVAR_CHEAT, "show all uploaded textures" );
r_adjust_fov = Cvar_Get( "r_adjust_fov", "1", FCVAR_ARCHIVE, "making FOV adjustment for wide-screens" );
r_decals = Cvar_Get( "r_decals", "4096", FCVAR_ARCHIVE, "sets the maximum number of decals" );
gl_msaa_samples = Cvar_Get( "gl_msaa_samples", "0", FCVAR_GLCONFIG, "samples number for multisample anti-aliasing" );
gl_clear = Cvar_Get( "gl_clear", "0", FCVAR_ARCHIVE, "clearing screen after each frame" );
r_showtree = Cvar_Get( "r_showtree", "0", FCVAR_ARCHIVE, "build the graph of visible BSP tree" );
r_refdll = Cvar_Get( "r_refdll", "", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "choose renderer implementation, if supported" );
Cvar_RegisterVariable( &gl_vsync );
Cvar_RegisterVariable( &r_showtextures );
Cvar_RegisterVariable( &r_adjust_fov );
Cvar_RegisterVariable( &r_decals );
Cvar_RegisterVariable( &gl_msaa_samples );
Cvar_RegisterVariable( &gl_clear );
Cvar_RegisterVariable( &r_showtree );
Cvar_RegisterVariable( &r_refdll );
// cvars that are expected to exist
Cvar_Get( "r_speeds", "0", FCVAR_ARCHIVE, "shows renderer speeds" );
@@ -682,36 +648,34 @@ qboolean R_Init( void )
// 1. Command line `-ref` argument.
// 2. `ref_dll` cvar.
// 3. Detected renderers in `DEFAULT_RENDERERS` order.
requested[0] = '\0';
if( !Sys_GetParmFromCmdLine( "-ref", requested ) && COM_CheckString( r_refdll->string ) )
// r_refdll is set to empty by default, so we can change hardcoded defaults just in case
Q_strncpy( requested, r_refdll->string, sizeof( requested ) );
requested[0] = 0;
if ( requested[0] )
if( !success && Sys_GetParmFromCmdLine( "-ref", requested ))
success = R_LoadRenderer( requested );
if( !success && COM_CheckString( r_refdll.string ))
{
Q_strncpy( requested, r_refdll.string, sizeof( requested ));
success = R_LoadRenderer( requested );
}
if( !success )
{
int i;
// cycle through renderers that we collected in CollectRendererNames
for( i = 0; i < ref.numRenderers; i++ )
for( i = 0; i < ref.numRenderers && !success; i++ )
{
// skip renderer that was requested but failed to load
if( !Q_strcmp( requested, ref.shortNames[i] ) )
if( !Q_strcmp( requested, ref.shortNames[i] ))
continue;
success = R_LoadRenderer( ref.shortNames[i] );
// yay, found working one
if( success )
break;
}
}
if( !success )
{
Host_Error( "Can't initialize any renderer. Check your video drivers!" );
Host_Error( "Can't initialize any renderer. Check your video drivers!\n" );
return false;
}

View File

@@ -27,9 +27,10 @@ struct ref_state_s
HINSTANCE hInstance;
ref_interface_t dllFuncs;
// depends on build configuration
int numRenderers;
string shortNames[DEFAULT_RENDERERS_LEN];
string readableNames[DEFAULT_RENDERERS_LEN];
const char **shortNames;
const char **readableNames;
};
extern struct ref_state_s ref;
@@ -45,9 +46,9 @@ void R_GetTextureParms( int *w, int *h, int texnum );
void GL_RenderFrame( const struct ref_viewpass_s *rvp );
// common engine and renderer cvars
extern convar_t *r_decals;
extern convar_t *r_adjust_fov;
extern convar_t *gl_clear;
extern convar_t r_decals;
extern convar_t r_adjust_fov;
extern convar_t gl_clear;
qboolean R_Init( void );
void R_Shutdown( void );

View File

@@ -78,7 +78,7 @@ typedef struct dly_s
int *lpdelayline;
} dly_t;
const sx_preset_t rgsxpre[] =
static const sx_preset_t rgsxpre[] =
{
// -------reverb-------- -------delay--------
// lp mod size refl rvblp delay feedback dlylp left
@@ -115,7 +115,7 @@ const sx_preset_t rgsxpre[] =
// 0x0045dca8 enginegl.exe
// SHA256: 42383d32cd712e59ee2c1bd78b7ba48814e680e7026c4223e730111f34a60d66
const sx_preset_t rgsxpre_hlalpha052[] =
static const sx_preset_t rgsxpre_hlalpha052[] =
{
// -------reverb-------- -------delay--------
// lp mod size refl rvblp delay feedback dlylp left
@@ -150,51 +150,50 @@ const sx_preset_t rgsxpre_hlalpha052[] =
{ 0.0, 0.0, 0.001, 0.999, 0.0, 0.2, 0.8, 2.0, 0.05 }, // 28
};
const sx_preset_t *ptable = rgsxpre;
static const sx_preset_t *ptable = rgsxpre;
// cvars
convar_t *dsp_off; // disable dsp
convar_t *roomwater_type; // water room_type
convar_t *room_type; // current room type
convar_t *hisound; // DSP quality
static CVAR_DEFINE_AUTO( dsp_off, "0", FCVAR_ARCHIVE, "disable DSP processing" );
static CVAR_DEFINE_AUTO( dsp_coeff_table, "0", FCVAR_ARCHIVE, "select DSP coefficient table: 0 for release or 1 for alpha 0.52" );
static CVAR_DEFINE_AUTO( room_type, "0", 0, "current room type preset" );
static CVAR_DEFINE( roomwater_type, "waterroom_type", "14", 0, "water room type" );
static CVAR_DEFINE( hisound, "room_hires", "2", FCVAR_ARCHIVE, "dsp quality. 1 for 22k, 2 for 44k(recommended) and 3 for 96k" );
// underwater/special fx modulations
convar_t *sxmod_mod;
convar_t *sxmod_lowpass;
static CVAR_DEFINE( sxmod_mod, "room_mod", "0", 0, "stereo amptitude modulation for room" );
static CVAR_DEFINE( sxmod_lowpass, "room_lp", "0", 0, "for water fx, lowpass for entire room" );
// stereo delay(no feedback)
convar_t *sxste_delay; // straight left delay
static CVAR_DEFINE( sxste_delay, "room_left", "0", 0, "left channel delay time" );
// mono reverb
convar_t *sxrvb_lp; // lowpass
convar_t *sxrvb_feedback; // reverb decay. Higher -- longer
convar_t *sxrvb_size; // room size. Higher -- larger
static CVAR_DEFINE( sxrvb_lp, "room_rvblp", "1", 0, "reverb: low pass filtering level" );
static CVAR_DEFINE( sxrvb_feedback, "room_refl", "0", 0, "reverb: decay time" );
static CVAR_DEFINE( sxrvb_size, "room_size", "0", 0, "reverb: initial reflection size" );
// mono delay
convar_t *sxdly_lp; // lowpass
convar_t *sxdly_feedback; // cycles
convar_t *sxdly_delay; // current delay in seconds
static CVAR_DEFINE( sxdly_lp, "room_dlylp", "1", 0, "mono delay: low pass filtering level" );
static CVAR_DEFINE( sxdly_feedback, "room_feedback", "0.2", 0, "mono delay: decay time" );
static CVAR_DEFINE( sxdly_delay, "room_delay", "0.8", 0, "mono delay: delay time" );
convar_t *dsp_room; // for compability
convar_t *dsp_coeff_table; // use release or 0.52 style
int idsp_dma_speed;
static int idsp_dma_speed;
int idsp_room;
int room_typeprev;
static int room_typeprev;
// routines
int sxamodl, sxamodr; // amplitude modulation values
int sxamodlt, sxamodrt; // modulation targets
int sxmod1cur, sxmod2cur;
int sxmod1, sxmod2;
int sxhires;
static int sxamodl, sxamodr; // amplitude modulation values
static int sxamodlt, sxamodrt; // modulation targets
static int sxmod1cur, sxmod2cur;
static int sxmod1, sxmod2;
static int sxhires;
portable_samplepair_t *paintto = NULL;
static portable_samplepair_t *paintto = NULL;
dly_t rgsxdly[MAXDLY]; // stereo is last
int rgsxlp[MAXLP];
static dly_t rgsxdly[MAXDLY]; // stereo is last
static int rgsxlp[MAXLP];
void SX_Profiling_f( void );
static void SX_Profiling_f( void );
/*
============
@@ -202,14 +201,12 @@ SX_ReloadRoomFX
============
*/
void SX_ReloadRoomFX( void )
static void SX_ReloadRoomFX( void )
{
if( !dsp_room ) return; // not initialized
SetBits( sxste_delay->flags, FCVAR_CHANGED );
SetBits( sxrvb_feedback->flags, FCVAR_CHANGED );
SetBits( sxdly_delay->flags, FCVAR_CHANGED );
SetBits( room_type->flags, FCVAR_CHANGED );
SetBits( sxste_delay.flags, FCVAR_CHANGED );
SetBits( sxrvb_feedback.flags, FCVAR_CHANGED );
SetBits( sxdly_delay.flags, FCVAR_CHANGED );
SetBits( room_type.flags, FCVAR_CHANGED );
}
/*
@@ -227,36 +224,33 @@ void SX_Init( void )
sxamodr = sxamodl = sxamodrt = sxamodlt = 255;
idsp_dma_speed = SOUND_11k;
hisound = Cvar_Get( "room_hires", "2", FCVAR_ARCHIVE, "dsp quality. 1 for 22k, 2 for 44k(recommended) and 3 for 96k" );
Cvar_RegisterVariable( &hisound );
sxhires = 2;
sxmod1cur = sxmod1 = 350 * ( idsp_dma_speed / SOUND_11k );
sxmod2cur = sxmod2 = 450 * ( idsp_dma_speed / SOUND_11k );
dsp_off = Cvar_Get( "dsp_off", "0", FCVAR_ARCHIVE, "disable DSP processing" );
dsp_coeff_table = Cvar_Get( "dsp_coeff_table", "0", FCVAR_ARCHIVE, "select DSP coefficient table: 0 for release or 1 for alpha 0.52" );
Cvar_RegisterVariable( &dsp_off );
Cvar_RegisterVariable( &dsp_coeff_table );
roomwater_type = Cvar_Get( "waterroom_type", "14", 0, "water room type" );
room_type = Cvar_Get( "room_type", "0", 0, "current room type preset" );
Cvar_RegisterVariable( &roomwater_type );
Cvar_RegisterVariable( &room_type );
sxmod_lowpass = Cvar_Get( "room_lp", "0", 0, "for water fx, lowpass for entire room" );
sxmod_mod = Cvar_Get( "room_mod", "0", 0, "stereo amptitude modulation for room" );
Cvar_RegisterVariable( &sxmod_lowpass );
Cvar_RegisterVariable( &sxmod_mod );
sxrvb_size = Cvar_Get( "room_size", "0", 0, "reverb: initial reflection size" );
sxrvb_feedback = Cvar_Get( "room_refl", "0", 0, "reverb: decay time" );
sxrvb_lp = Cvar_Get( "room_rvblp", "1", 0, "reverb: low pass filtering level" );
Cvar_RegisterVariable( &sxrvb_size );
Cvar_RegisterVariable( &sxrvb_feedback );
Cvar_RegisterVariable( &sxrvb_lp );
sxdly_delay = Cvar_Get( "room_delay", "0.8", 0, "mono delay: delay time" );
sxdly_feedback = Cvar_Get( "room_feedback", "0.2", 0, "mono delay: decay time" );
sxdly_lp = Cvar_Get( "room_dlylp", "1", 0, "mono delay: low pass filtering level" );
Cvar_RegisterVariable( &sxdly_delay );
Cvar_RegisterVariable( &sxdly_feedback );
Cvar_RegisterVariable( &sxdly_lp );
sxste_delay = Cvar_Get( "room_left", "0", 0, "left channel delay time" );
Cvar_RegisterVariable( &sxste_delay );
Cmd_AddCommand( "dsp_profile", SX_Profiling_f, "dsp stress-test, first argument is room_type" );
// for compability
dsp_room = room_type;
SX_ReloadRoomFX();
}
@@ -267,7 +261,7 @@ DLY_Free
Free memory allocated for DSP
===========
*/
void DLY_Free( int idelay )
static void DLY_Free( int idelay )
{
Assert( idelay >= 0 && idelay < MAXDLY );
@@ -303,7 +297,7 @@ DLY_Init
Initialize dly
===========
*/
int DLY_Init( int idelay, float delay )
static int DLY_Init( int idelay, float delay )
{
dly_t *cur;
@@ -355,12 +349,12 @@ DLY_CheckNewStereoDelayVal
Update stereo processor settings if we are in new room
=============
*/
void DLY_CheckNewStereoDelayVal( void )
static void DLY_CheckNewStereoDelayVal( void )
{
dly_t *const dly = &rgsxdly[STEREODLY];
float delay = sxste_delay->value;
float delay = sxste_delay.value;
if( !FBitSet( sxste_delay->flags, FCVAR_CHANGED ))
if( !FBitSet( sxste_delay.flags, FCVAR_CHANGED ))
return;
if( delay == 0 )
@@ -403,7 +397,7 @@ DLY_DoStereoDelay
Do stereo processing
=============
*/
void DLY_DoStereoDelay( int count )
static void DLY_DoStereoDelay( int count )
{
int delay, samplexf;
dly_t *const dly = &rgsxdly[STEREODLY];
@@ -468,12 +462,12 @@ DLY_CheckNewDelayVal
Update delay processor settings if we are in new room
=============
*/
void DLY_CheckNewDelayVal( void )
static void DLY_CheckNewDelayVal( void )
{
float delay = sxdly_delay->value;
float delay = sxdly_delay.value;
dly_t *const dly = &rgsxdly[MONODLY];
if( FBitSet( sxdly_delay->flags, FCVAR_CHANGED ))
if( FBitSet( sxdly_delay.flags, FCVAR_CHANGED ))
{
if( delay == 0 )
{
@@ -503,8 +497,8 @@ void DLY_CheckNewDelayVal( void )
}
}
dly->lp = sxdly_lp->value;
dly->delayfeedback = 255 * sxdly_feedback->value;
dly->lp = sxdly_lp.value;
dly->delayfeedback = 255 * sxdly_feedback.value;
}
/*
@@ -514,7 +508,7 @@ DLY_DoDelay
Do delay processing
=============
*/
void DLY_DoDelay( int count )
static void DLY_DoDelay( int count )
{
dly_t *const dly = &rgsxdly[MONODLY];
portable_samplepair_t *paint = paintto;
@@ -565,7 +559,7 @@ RVB_SetUpDly
Set up dly for reverb
===========
*/
void RVB_SetUpDly( int pos, float delay, int kmod )
static void RVB_SetUpDly( int pos, float delay, int kmod )
{
int samples;
@@ -601,13 +595,13 @@ RVB_CheckNewReverbVal
Update reverb settings if we are in new room
===========
*/
void RVB_CheckNewReverbVal( void )
static void RVB_CheckNewReverbVal( void )
{
dly_t *const dly1 = &rgsxdly[REVERBPOS];
dly_t *const dly2 = &rgsxdly[REVERBPOS + 1];
float delay = sxrvb_size->value;
float delay = sxrvb_size.value;
if( FBitSet( sxrvb_size->flags, FCVAR_CHANGED ))
if( FBitSet( sxrvb_size.flags, FCVAR_CHANGED ))
{
if( delay == 0.0f )
{
@@ -616,13 +610,13 @@ void RVB_CheckNewReverbVal( void )
}
else
{
RVB_SetUpDly( REVERBPOS, sxrvb_size->value, 500 );
RVB_SetUpDly( REVERBPOS+1, sxrvb_size->value * 0.71f, 700 );
RVB_SetUpDly( REVERBPOS, sxrvb_size.value, 500 );
RVB_SetUpDly( REVERBPOS+1, sxrvb_size.value * 0.71f, 700 );
}
}
dly1->lp = dly2->lp = sxrvb_lp->value;
dly1->delayfeedback = dly2->delayfeedback = (int)(255 * sxrvb_feedback->value);
dly1->lp = dly2->lp = sxrvb_lp.value;
dly1->delayfeedback = dly2->delayfeedback = (int)(255 * sxrvb_feedback.value);
}
/*
@@ -632,7 +626,7 @@ RVB_DoReverbForOneDly
Do reverberation for one dly
===========
*/
int RVB_DoReverbForOneDly( dly_t *dly, const int vlr, const portable_samplepair_t *samplepair )
static int RVB_DoReverbForOneDly( dly_t *dly, const int vlr, const portable_samplepair_t *samplepair )
{
int delay;
int samplexf;
@@ -706,7 +700,7 @@ RVB_DoReverb
Do reverberation processing
===========
*/
void RVB_DoReverb( int count )
static void RVB_DoReverb( int count )
{
dly_t *const dly1 = &rgsxdly[REVERBPOS];
dly_t *const dly2 = &rgsxdly[REVERBPOS+1];
@@ -723,7 +717,7 @@ void RVB_DoReverb( int count )
voutm = RVB_DoReverbForOneDly( dly1, vlr, paint );
voutm += RVB_DoReverbForOneDly( dly2, vlr, paint );
if( dsp_coeff_table->value == 1.0f )
if( dsp_coeff_table.value == 1.0f )
voutm /= 6; // alpha
else voutm = (11 * voutm) >> 6;
@@ -739,18 +733,18 @@ RVB_DoAMod
Do amplification modulation processing
===========
*/
void RVB_DoAMod( int count )
static void RVB_DoAMod( int count )
{
portable_samplepair_t *paint = paintto;
if( !sxmod_lowpass->value && !sxmod_mod->value )
if( !sxmod_lowpass.value && !sxmod_mod.value )
return;
for( ; count; count--, paint++ )
{
portable_samplepair_t res = *paint;
if( sxmod_lowpass->value )
if( sxmod_lowpass.value )
{
res.left = rgsxlp[0] + rgsxlp[1] + rgsxlp[2] + rgsxlp[3] + rgsxlp[4] + res.left;
res.right = rgsxlp[5] + rgsxlp[6] + rgsxlp[7] + rgsxlp[8] + rgsxlp[9] + res.right;
@@ -772,7 +766,7 @@ void RVB_DoAMod( int count )
rgsxlp[8] = rgsxlp[9];
}
if( sxmod_mod->value )
if( sxmod_mod.value )
{
if( --sxmod1cur < 0 )
sxmod1cur = sxmod1;
@@ -814,7 +808,7 @@ DSP_Process
*/
void DSP_Process( int idsp, portable_samplepair_t *pbfront, int sampleCount )
{
if( dsp_off->value )
if( dsp_off.value )
return;
// don't process DSP while in menu
@@ -852,12 +846,12 @@ CheckNewDspPresets
*/
void CheckNewDspPresets( void )
{
if( dsp_off->value != 0.0f )
if( dsp_off.value != 0.0f )
return;
if( FBitSet( dsp_coeff_table->flags, FCVAR_CHANGED ))
if( FBitSet( dsp_coeff_table.flags, FCVAR_CHANGED ))
{
switch( (int)dsp_coeff_table->value )
switch( (int)dsp_coeff_table.value )
{
case 0: // release
ptable = rgsxpre;
@@ -873,20 +867,20 @@ void CheckNewDspPresets( void )
SX_ReloadRoomFX();
room_typeprev = -1;
ClearBits( dsp_coeff_table->flags, FCVAR_CHANGED );
ClearBits( dsp_coeff_table.flags, FCVAR_CHANGED );
}
if( s_listener.waterlevel > 2 )
idsp_room = roomwater_type->value;
else idsp_room = room_type->value;
idsp_room = roomwater_type.value;
else idsp_room = room_type.value;
// don't pass invalid presets
idsp_room = bound( 0, idsp_room, MAX_ROOM_TYPES );
if( FBitSet( hisound->flags, FCVAR_CHANGED ))
if( FBitSet( hisound.flags, FCVAR_CHANGED ))
{
sxhires = hisound->value;
ClearBits( hisound->flags, FCVAR_CHANGED );
sxhires = hisound.value;
ClearBits( hisound.flags, FCVAR_CHANGED );
}
if( idsp_room == room_typeprev && idsp_room == 0 )
@@ -915,15 +909,15 @@ void CheckNewDspPresets( void )
DLY_CheckNewDelayVal( );
DLY_CheckNewStereoDelayVal();
ClearBits( sxrvb_size->flags, FCVAR_CHANGED );
ClearBits( sxdly_delay->flags, FCVAR_CHANGED );
ClearBits( sxste_delay->flags, FCVAR_CHANGED );
ClearBits( sxrvb_size.flags, FCVAR_CHANGED );
ClearBits( sxdly_delay.flags, FCVAR_CHANGED );
ClearBits( sxste_delay.flags, FCVAR_CHANGED );
}
void SX_Profiling_f( void )
static void SX_Profiling_f( void )
{
portable_samplepair_t testbuffer[512];
float oldroom = room_type->value;
float oldroom = room_type.value;
double start, end;
int i, calls;

View File

@@ -14,6 +14,7 @@ GNU General Public License for more details.
*/
#include "common.h"
#include "client.h"
#include "sound.h"
// during registration it is possible to have more sounds
@@ -28,7 +29,6 @@ static sfx_t s_knownSfx[MAX_SFX];
static sfx_t *s_sfxHashList[MAX_SFX_HASH];
static string s_sentenceImmediateName; // keep dummy sentence name
qboolean s_registering = false;
int s_registration_sequence = 0;
/*
=================
@@ -54,7 +54,7 @@ void S_SoundList_f( void )
if( sc->loopStart >= 0 ) Con_Printf( "L" );
else Con_Printf( " " );
if( sfx->name[0] == '*' )
if( sfx->name[0] == '*' || !Q_strncmp( sfx->name, DEFAULT_SOUNDPATH, sizeof( DEFAULT_SOUNDPATH ) - 1 ))
Con_Printf( " (%2db) %s : %s\n", sc->width * 8, Q_memprint( sc->size ), sfx->name );
else Con_Printf( " (%2db) %s : " DEFAULT_SOUNDPATH "%s\n", sc->width * 8, Q_memprint( sc->size ), sfx->name );
totalSfx++;
@@ -199,7 +199,7 @@ sfx_t *S_FindName( const char *pname, int *pfInCache )
*pfInCache = ( sfx->cache != NULL ) ? true : false;
}
// prolonge registration
sfx->servercount = s_registration_sequence;
sfx->servercount = cl.servercount;
return sfx;
}
}
@@ -219,7 +219,7 @@ sfx_t *S_FindName( const char *pname, int *pfInCache )
memset( sfx, 0, sizeof( *sfx ));
if( pfInCache ) *pfInCache = false;
Q_strncpy( sfx->name, name, MAX_STRING );
sfx->servercount = s_registration_sequence;
sfx->servercount = cl.servercount;
sfx->hashValue = COM_HashKey( sfx->name, MAX_SFX_HASH );
// link it in
@@ -273,7 +273,6 @@ void S_BeginRegistration( void )
{
int i;
s_registration_sequence++;
snd_ambient = false;
// check for automatic ambient sounds
@@ -309,7 +308,7 @@ void S_EndRegistration( void )
if( !sfx->name[0] || !Q_stricmp( sfx->name, "*default" ))
continue; // don't release default sound
if( sfx->servercount != s_registration_sequence )
if( sfx->servercount != cl.servercount )
S_FreeSound( sfx ); // don't need this sound
}
@@ -349,7 +348,7 @@ sound_t S_RegisterSound( const char *name )
sfx = S_FindName( name, NULL );
if( !sfx ) return -1;
sfx->servercount = s_registration_sequence;
sfx->servercount = cl.servercount;
if( !s_registering ) S_LoadSound( sfx );
return sfx - s_knownSfx;

View File

@@ -159,7 +159,7 @@ void S_UpdateSoundFade( void )
}
// spline it.
f = SimpleSpline( f );
f = -( cos( M_PI * f ) - 1 ) / 2;
f = bound( 0.0f, f, 1.0f );
soundfade.percent = soundfade.initial_percent * f;
@@ -197,6 +197,65 @@ qboolean SND_FStreamIsPlaying( sfx_t *sfx )
return false;
}
/*
=================
SND_GetChannelTimeLeft
TODO: this function needs to be removed after whole sound subsystem rewrite
=================
*/
static int SND_GetChannelTimeLeft( const channel_t *ch )
{
int remaining;
if( ch->pMixer.finished || !ch->sfx || !ch->sfx->cache )
return 0;
if( ch->isSentence ) // sentences are special, count all remaining words
{
int i;
if( !ch->currentWord )
return 0;
// current word
remaining = ch->currentWord->forcedEndSample - ch->currentWord->sample;
// here we count all remaining words, stopping if no sfx or sound file is available
// see VOX_LoadWord
for( i = ch->wordIndex + 1; i < ARRAYSIZE( ch->words ); i++ )
{
wavdata_t *sc;
int end;
// don't continue with broken sentences
if( !ch->words[i].sfx )
break;
if( !( sc = S_LoadSound( ch->words[i].sfx )))
break;
end = ch->words[i].end;
if( end )
remaining += sc->samples * 0.01f * end;
else remaining += sc->samples;
}
}
else
{
int curpos;
int samples;
// handle position looping
samples = ch->sfx->cache->samples;
curpos = S_ConvertLoopedPosition( ch->sfx->cache, ch->pMixer.sample, ch->use_loop );
remaining = bound( 0, samples - curpos, samples );
}
return remaining;
}
/*
=================
SND_PickDynamicChannel
@@ -246,11 +305,7 @@ channel_t *SND_PickDynamicChannel( int entnum, int channel, sfx_t *sfx, qboolean
continue;
// try to pick the sound with the least amount of data left to play
timeleft = 0;
if( ch->sfx )
{
timeleft = 1; // ch->end - paintedtime
}
timeleft = SND_GetChannelTimeLeft( ch );
if( timeleft < life_left )
{
@@ -1237,36 +1292,6 @@ void S_StreamAviSamples( void *Avi, int entnum, float fvol, float attn, float sy
}
}
/*
===================
S_GetRawSamplesLength
===================
*/
uint S_GetRawSamplesLength( int entnum )
{
rawchan_t *ch;
if( !( ch = S_FindRawChannel( entnum, false )))
return 0;
return ch->s_rawend <= paintedtime ? 0 : (float)(ch->s_rawend - paintedtime) * DMA_MSEC_PER_SAMPLE;
}
/*
===================
S_ClearRawChannel
===================
*/
void S_ClearRawChannel( int entnum )
{
rawchan_t *ch;
if( !( ch = S_FindRawChannel( entnum, false )))
return;
ch->s_rawend = 0;
}
/*
===================
S_FreeIdleRawChannels
@@ -1787,8 +1812,12 @@ void S_Music_f( void )
for( i = 0; i < 2; i++ )
{
const char *intro_path = va( "media/%s.%s", intro, ext[i] );
const char *main_path = va( "media/%s.%s", main, ext[i] );
char intro_path[MAX_VA_STRING];
char main_path[MAX_VA_STRING];
char track_path[MAX_VA_STRING];
Q_snprintf( intro_path, sizeof( intro_path ), "media/%s.%s", intro, ext[i] );
Q_snprintf( main_path, sizeof( main_path ), "media/%s.%s", main, ext[i] );
if( FS_FileExists( intro_path, false ) && FS_FileExists( main_path, false ))
{
@@ -1796,7 +1825,10 @@ void S_Music_f( void )
S_StartBackgroundTrack( intro, main, 0, false );
break;
}
else if( FS_FileExists( va( "media/%s.%s", track, ext[i] ), false ))
Q_snprintf( track_path, sizeof( track_path ), "media/%s.%s", track, ext[i] );
if( FS_FileExists( track_path, false ))
{
// single non-looped theme
S_StartBackgroundTrack( track, NULL, 0, false );

View File

@@ -117,13 +117,6 @@ _inline void MIX_ActivatePaintbuffer( int ipaintbuffer )
paintbuffers[ipaintbuffer].factive = true;
}
// don't mix into this paintbuffer
_inline void MIX_DeactivatePaintbuffer( int ipaintbuffer )
{
Assert( ipaintbuffer < CPAINTBUFFERS );
paintbuffers[ipaintbuffer].factive = false;
}
_inline void MIX_SetCurrentPaintbuffer( int ipaintbuffer )
{
Assert( ipaintbuffer < CPAINTBUFFERS );
@@ -169,12 +162,6 @@ _inline void MIX_ResetPaintbufferFilterCounters( void )
paintbuffers[i].ifilter = FILTERTYPE_NONE;
}
_inline void MIX_ResetPaintbufferFilterCounter( int ipaintbuffer )
{
Assert( ipaintbuffer < CPAINTBUFFERS );
paintbuffers[ipaintbuffer].ifilter = 0;
}
// return pointer to front paintbuffer pbuf, given index
_inline portable_samplepair_t *MIX_GetPFrontFromIPaint( int ipaintbuffer )
{
@@ -621,7 +608,7 @@ void MIX_MixChannelsToPaintbuffer( int endtime, int rate, int outputRate )
ch->pitch *= ( sys_timescale.value + 1 ) / 2;
if( CL_GetEntityByIndex( ch->entnum ) && ( ch->entchannel == CHAN_VOICE ))
if( CL_GetEntityByIndex( ch->entnum ) && ( ch->entchannel == CHAN_VOICE || ch->entchannel == CHAN_STREAM ))
{
if( pSource->width == 1 )
SND_MoveMouth8( ch, pSource, sampleCount );
@@ -897,43 +884,13 @@ void S_MixUpsample( int sampleCount, int filtertype )
ppaint->ifilter++;
}
void MIX_MixStreamBuffer( int end )
{
portable_samplepair_t *pbuf;
rawchan_t *ch;
pbuf = MIX_GetPFrontFromIPaint( ISTREAMBUFFER );
ch = S_FindRawChannel( S_RAW_SOUND_BACKGROUNDTRACK, false );
// clear the paint buffer
if( s_listener.paused || !ch || ch->s_rawend < paintedtime )
{
memset( pbuf, 0, (end - paintedtime) * sizeof( portable_samplepair_t ));
}
else
{
int i, stop;
// copy from the streaming sound source
stop = (end < ch->s_rawend) ? end : ch->s_rawend;
for( i = paintedtime; i < stop; i++ )
{
pbuf[i-paintedtime].left = ( ch->rawsamples[i & ( ch->max_samples - 1 )].left * ch->leftvol ) >> 8;
pbuf[i-paintedtime].right = ( ch->rawsamples[i & ( ch->max_samples - 1 )].right * ch->rightvol ) >> 8;
}
for( ; i < end; i++ )
pbuf[i-paintedtime].left = pbuf[i-paintedtime].right = 0;
}
}
void MIX_MixRawSamplesBuffer( int end )
{
portable_samplepair_t *pbuf;
portable_samplepair_t *pbuf, *roombuf, *streambuf;
uint i, j, stop;
pbuf = MIX_GetCurrentPaintbufferPtr()->pbuf;
roombuf = MIX_GetPFrontFromIPaint( IROOMBUFFER );
streambuf = MIX_GetPFrontFromIPaint( ISTREAMBUFFER );
if( s_listener.paused ) return;
@@ -941,16 +898,19 @@ void MIX_MixRawSamplesBuffer( int end )
for( i = 0; i < MAX_RAW_CHANNELS; i++ )
{
// copy from the streaming sound source
rawchan_t *ch = raw_channels[i];
rawchan_t *ch = raw_channels[i];
qboolean stream;
// background track should be mixing into another buffer
if( !ch || ch->entnum == S_RAW_SOUND_BACKGROUNDTRACK )
if( !ch )
continue;
// not audible
if( !ch->leftvol && !ch->rightvol )
continue;
stream = ch->entnum == S_RAW_SOUND_BACKGROUNDTRACK || CL_IsPlayerIndex( ch->entnum );
pbuf = stream ? streambuf : roombuf;
stop = (end < ch->s_rawend) ? end : ch->s_rawend;
for( j = paintedtime; j < stop; j++ )
@@ -959,7 +919,7 @@ void MIX_MixRawSamplesBuffer( int end )
pbuf[j-paintedtime].right += ( ch->rawsamples[j & ( ch->max_samples - 1 )].right * ch->rightvol ) >> 8;
}
if ( ch->entnum > 0 )
if( ch->entnum > 0 )
SND_MoveMouthRaw( ch, &ch->rawsamples[paintedtime & ( ch->max_samples - 1 )], stop - paintedtime );
}
}
@@ -970,9 +930,6 @@ void MIX_MixRawSamplesBuffer( int end )
// caller also remixes all into final IPAINTBUFFER output.
void MIX_UpsampleAllPaintbuffers( int end, int count )
{
// process stream buffer
MIX_MixStreamBuffer( end );
// 11khz sounds are mixed into 3 buffers based on distance from listener, and facing direction
// These buffers are facing, facingaway, room
// These 3 mixed buffers are then each upsampled to 22khz.
@@ -1014,7 +971,6 @@ void MIX_UpsampleAllPaintbuffers( int end, int count )
#endif
// mix raw samples from the video streams
MIX_SetCurrentPaintbuffer( IROOMBUFFER );
MIX_MixRawSamplesBuffer( end );
MIX_DeactivateAllPaintbuffers();

View File

@@ -24,17 +24,7 @@ void SND_InitMouth( int entnum, int entchannel )
{
if(( entchannel == CHAN_VOICE || entchannel == CHAN_STREAM ) && entnum > 0 )
{
cl_entity_t *clientEntity;
// init mouth movement vars
clientEntity = CL_GetEntityByIndex( entnum );
if( clientEntity )
{
clientEntity->mouth.mouthopen = 0;
clientEntity->mouth.sndcount = 0;
clientEntity->mouth.sndavg = 0;
}
SND_ForceInitMouth( entnum );
}
}
@@ -42,15 +32,7 @@ void SND_CloseMouth( channel_t *ch )
{
if( ch->entchannel == CHAN_VOICE || ch->entchannel == CHAN_STREAM )
{
cl_entity_t *clientEntity;
clientEntity = CL_GetEntityByIndex( ch->entnum );
if( clientEntity )
{
// shut mouth
clientEntity->mouth.mouthopen = 0;
}
SND_ForceCloseMouth( ch->entnum );
}
}
@@ -157,7 +139,7 @@ void SND_ForceInitMouth( int entnum )
clientEntity = CL_GetEntityByIndex( entnum );
if ( clientEntity )
if( clientEntity )
{
clientEntity->mouth.mouthopen = 0;
clientEntity->mouth.sndavg = 0;
@@ -171,7 +153,7 @@ void SND_ForceCloseMouth( int entnum )
clientEntity = CL_GetEntityByIndex( entnum );
if ( clientEntity )
if( clientEntity )
clientEntity->mouth.mouthopen = 0;
}
@@ -214,4 +196,4 @@ void SND_MoveMouthRaw( rawchan_t *ch, portable_samplepair_t *pData, int count )
pMouth->sndavg = 0;
pMouth->sndcount = 0;
}
}
}

View File

@@ -95,7 +95,7 @@ void S_StartBackgroundTrack( const char *introTrack, const char *mainTrack, int
else Q_strncpy( s_bgTrack.loopName, mainTrack, sizeof( s_bgTrack.loopName ));
// open stream
s_bgTrack.stream = FS_OpenStream( va( "media/%s", introTrack ));
s_bgTrack.stream = FS_OpenStream( introTrack );
Q_strncpy( s_bgTrack.current, introTrack, sizeof( s_bgTrack.current ));
memset( &musicfade, 0, sizeof( musicfade )); // clear any soundfade
s_bgTrack.source = cls.key_dest;
@@ -242,7 +242,7 @@ void S_StreamBackgroundTrack( void )
if( s_bgTrack.loopName[0] )
{
FS_FreeStream( s_bgTrack.stream );
s_bgTrack.stream = FS_OpenStream( va( "media/%s", s_bgTrack.loopName ));
s_bgTrack.stream = FS_OpenStream( s_bgTrack.loopName );
Q_strncpy( s_bgTrack.current, s_bgTrack.loopName, sizeof( s_bgTrack.current ));
if( !s_bgTrack.stream ) return;

View File

@@ -16,7 +16,6 @@ GNU General Public License for more details.
#include "common.h"
#include "sound.h"
#include "const.h"
#include "sequence.h"
#include <ctype.h>
static int cszrawsentences = 0;
@@ -142,7 +141,7 @@ static const char *VOX_GetDirectory( char *szpath, const char *psz, int nsize )
if( !p )
{
Q_strcpy( szpath, "vox/" );
Q_strncpy( szpath, "vox/", nsize );
return psz;
}
@@ -165,23 +164,11 @@ static const char *VOX_LookupString( const char *pszin )
int i = -1, len;
const char *c;
// check if we are a CSCZ or immediate sentence
// check if we are an immediate sentence
if( *pszin == '#' )
{
// Q_atoi is too smart and allows negative values
// so check with Q_isdigit beforehand
if( Q_isdigit( pszin + 1 ))
{
sentenceEntry_s *sentenceEntry;
i = Q_atoi( pszin + 1 );
if(( sentenceEntry = Sequence_GetSentenceByIndex( i )))
return sentenceEntry->data;
}
else
{
// immediate sentence, probably coming from "speak" command
return pszin + 1;
}
// immediate sentence, probably coming from "speak" command
return pszin + 1;
}
// check if we received an index

View File

@@ -219,7 +219,6 @@ extern dma_t dma;
extern convar_t s_musicvolume;
extern convar_t s_lerping;
extern convar_t *dsp_off;
extern convar_t s_test; // cvar to testify new effects
extern convar_t s_samplecount;
extern convar_t snd_mute_losefocus;
@@ -276,8 +275,6 @@ void S_RawEntSamples( int entnum, uint samples, uint rate, word width, word chan
void S_RawSamples( uint samples, uint rate, word width, word channels, const byte *data, int entnum );
void S_StopSound( int entnum, int channel, const char *soundname );
void S_UpdateFrame( struct ref_viewpass_s *rvp );
uint S_GetRawSamplesLength( int entnum );
void S_ClearRawChannel( int entnum );
void S_StopAllSounds( qboolean ambient );
void S_FreeSounds( void );
@@ -306,6 +303,7 @@ void S_FadeMusicVolume( float fadePercent );
//
int S_ZeroCrossingAfter( wavdata_t *pWaveData, int sample );
int S_ZeroCrossingBefore( wavdata_t *pWaveData, int sample );
int S_ConvertLoopedPosition( wavdata_t *pSource, int samplePosition, qboolean use_loop );
int S_GetOutputData( wavdata_t *pSource, void **pData, int samplePosition, int sampleCount, qboolean use_loop );
void S_SetSampleStart( channel_t *pChan, wavdata_t *pSource, int newPosition );
void S_SetSampleEnd( channel_t *pChan, wavdata_t *pSource, int newEndPosition );

View File

@@ -218,6 +218,7 @@ void CL_TextMessageParse( byte *pMemFile, int fileSize )
client_textmessage_t textMessages[MAX_MESSAGES];
int i, nameHeapSize, textHeapSize, messageSize, nameOffset;
int messageCount, lastNamePos;
size_t textHeapSizeRemaining;
lastNamePos = 0;
lineNumber = 0;
@@ -252,7 +253,7 @@ void CL_TextMessageParse( byte *pMemFile, int fileSize )
Con_Reportf( "TextMessage: unexpected '}' found, line %d\n", lineNumber );
return;
}
Q_strcpy( currentName, trim );
Q_strncpy( currentName, trim, sizeof( currentName ));
break;
case MSGFILE_TEXT:
if( IsEndOfText( trim ))
@@ -266,7 +267,7 @@ void CL_TextMessageParse( byte *pMemFile, int fileSize )
return;
}
Q_strcpy( nameHeap + lastNamePos, currentName );
Q_strncpy( nameHeap + lastNamePos, currentName, sizeof( nameHeap ) - lastNamePos );
// terminate text in-place in the memory file
// (it's temporary memory that will be deleted)
@@ -329,15 +330,20 @@ void CL_TextMessageParse( byte *pMemFile, int fileSize )
// copy text & fixup pointers
textHeapSizeRemaining = textHeapSize;
pCurrentText = pNameHeap + nameHeapSize;
for( i = 0; i < messageCount; i++ )
{
size_t currentTextSize = Q_strlen( clgame.titles[i].pMessage ) + 1;
clgame.titles[i].pName = pNameHeap; // adjust name pointer (parallel buffer)
Q_strcpy( pCurrentText, clgame.titles[i].pMessage ); // copy text over
Q_strncpy( pCurrentText, clgame.titles[i].pMessage, textHeapSizeRemaining ); // copy text over
clgame.titles[i].pMessage = pCurrentText;
pNameHeap += Q_strlen( pNameHeap ) + 1;
pCurrentText += Q_strlen( pCurrentText ) + 1;
pCurrentText += currentTextSize;
textHeapSizeRemaining -= currentTextSize;
}
if(( pCurrentText - (char *)clgame.titles ) != ( textHeapSize + nameHeapSize + messageSize ))

View File

@@ -23,93 +23,101 @@ GNU General Public License for more details.
#include "input.h"
#include "platform/platform.h"
static enum VGUI_KeyCode s_pVirtualKeyTrans[256];
static VGUI_DefaultCursor s_currentCursor;
static HINSTANCE s_pVGuiSupport; // vgui_support library
static convar_t *vgui_utf8 = NULL;
CVAR_DEFINE_AUTO( vgui_utf8, "0", FCVAR_ARCHIVE, "enable utf-8 support for vgui text" );
void GAME_EXPORT *VGUI_EngineMalloc(size_t size)
static void GAME_EXPORT *VGUI_EngineMalloc( size_t size );
static void GAME_EXPORT VGUI_GetMousePos( int *, int * );
static void GAME_EXPORT VGUI_CursorSelect( VGUI_DefaultCursor );
static byte GAME_EXPORT VGUI_GetColor( int, int );
static int GAME_EXPORT VGUI_UtfProcessChar( int in );
static qboolean GAME_EXPORT VGUI_IsInGame( void );
static struct
{
qboolean initialized;
vguiapi_t dllFuncs;
VGUI_DefaultCursor cursor;
HINSTANCE hInstance;
enum VGUI_KeyCode virtualKeyTrans[256];
} vgui =
{
false,
{
false, // Not initialized yet
NULL, // VGUI_DrawInit,
NULL, // VGUI_DrawShutdown,
NULL, // VGUI_SetupDrawingText,
NULL, // VGUI_SetupDrawingRect,
NULL, // VGUI_SetupDrawingImage,
NULL, // VGUI_BindTexture,
NULL, // VGUI_EnableTexture,
NULL, // VGUI_CreateTexture,
NULL, // VGUI_UploadTexture,
NULL, // VGUI_UploadTextureBlock,
NULL, // VGUI_DrawQuad,
NULL, // VGUI_GetTextureSizes,
NULL, // VGUI_GenerateTexture,
VGUI_EngineMalloc,
VGUI_CursorSelect,
VGUI_GetColor,
VGUI_IsInGame,
Key_EnableTextInput,
VGUI_GetMousePos,
VGUI_UtfProcessChar,
Platform_GetClipboardText,
Platform_SetClipboardText,
Platform_GetKeyModifiers,
},
-1
};
static void GAME_EXPORT *VGUI_EngineMalloc( size_t size )
{
return Z_Malloc( size );
}
qboolean GAME_EXPORT VGUI_IsInGame( void )
static qboolean GAME_EXPORT VGUI_IsInGame( void )
{
return cls.state == ca_active && cls.key_dest == key_game;
}
void GAME_EXPORT VGUI_GetMousePos( int *_x, int *_y )
static void GAME_EXPORT VGUI_GetMousePos( int *_x, int *_y )
{
float xscale = (float)refState.width / (float)clgame.scrInfo.iWidth;
float yscale = (float)refState.height / (float)clgame.scrInfo.iHeight;
int x, y;
Platform_GetMousePos( &x, &y );
*_x = x / xscale, *_y = y / yscale;
*_x = x / xscale;
*_y = y / yscale;
}
void GAME_EXPORT VGUI_CursorSelect( VGUI_DefaultCursor cursor )
static void GAME_EXPORT VGUI_CursorSelect( VGUI_DefaultCursor cursor )
{
Platform_SetCursorType( cursor );
s_currentCursor = cursor;
if( vgui.cursor != cursor )
Platform_SetCursorType( cursor );
}
byte GAME_EXPORT VGUI_GetColor( int i, int j)
static byte GAME_EXPORT VGUI_GetColor( int i, int j )
{
return g_color_table[i][j];
}
// Define and initialize vgui API
int GAME_EXPORT VGUI_UtfProcessChar( int in )
static int GAME_EXPORT VGUI_UtfProcessChar( int in )
{
if( CVAR_TO_BOOL( vgui_utf8 ))
if( vgui_utf8.value )
return Con_UtfProcessCharForce( in );
else
return in;
return in;
}
vguiapi_t vgui =
{
false, // Not initialized yet
NULL, // VGUI_DrawInit,
NULL, // VGUI_DrawShutdown,
NULL, // VGUI_SetupDrawingText,
NULL, // VGUI_SetupDrawingRect,
NULL, // VGUI_SetupDrawingImage,
NULL, // VGUI_BindTexture,
NULL, // VGUI_EnableTexture,
NULL, // VGUI_CreateTexture,
NULL, // VGUI_UploadTexture,
NULL, // VGUI_UploadTextureBlock,
NULL, // VGUI_DrawQuad,
NULL, // VGUI_GetTextureSizes,
NULL, // VGUI_GenerateTexture,
VGUI_EngineMalloc,
VGUI_CursorSelect,
VGUI_GetColor,
VGUI_IsInGame,
NULL,
VGUI_GetMousePos,
VGUI_UtfProcessChar,
Platform_GetClipboardText,
Platform_SetClipboardText,
Platform_GetKeyModifiers,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
};
qboolean VGui_IsActive( void )
{
return vgui.initialized;
}
void VGui_FillAPIFromRef( vguiapi_t *to, const ref_interface_t *from )
static void VGui_FillAPIFromRef( vguiapi_t *to, const ref_interface_t *from )
{
to->DrawInit = from->VGUI_DrawInit;
to->DrawShutdown = from->VGUI_DrawShutdown;
@@ -126,137 +134,86 @@ void VGui_FillAPIFromRef( vguiapi_t *to, const ref_interface_t *from )
to->GenerateTexture = from->VGUI_GenerateTexture;
}
void VGui_RegisterCvars( void )
{
Cvar_RegisterVariable( &vgui_utf8 );
}
qboolean VGui_LoadProgs( HINSTANCE hInstance )
{
void (*F)( vguiapi_t* );
qboolean client = hInstance != NULL;
// not loading interface from client.dll, load vgui_support.dll instead
if( !client )
{
string vguiloader, vguilib;
// HACKHACK: try to load path from custom path
// to support having different versions of VGUI
if( Sys_GetParmFromCmdLine( "-vguilib", vguilib ) && !COM_LoadLibrary( vguilib, false, false ))
{
Con_Reportf( S_WARN "VGUI preloading failed. Default library will be used! Reason: %s", COM_GetLibraryError());
}
if( !Sys_GetParmFromCmdLine( "-vguiloader", vguiloader ))
{
Q_strncpy( vguiloader, VGUI_SUPPORT_DLL, sizeof( vguiloader ));
}
hInstance = vgui.hInstance = COM_LoadLibrary( vguiloader, false, false );
if( !vgui.hInstance )
{
if( FS_FileExists( vguiloader, false ))
Con_Reportf( S_ERROR "Failed to load vgui_support library: %s\n", COM_GetLibraryError() );
else Con_Reportf( "vgui_support: not found\n" );
return false;
}
}
// try legacy API first
F = COM_GetProcAddress( hInstance, client ? "InitVGUISupportAPI" : "InitAPI" );
if( F )
{
VGui_FillAPIFromRef( &vgui.dllFuncs, &ref.dllFuncs );
F( &vgui.dllFuncs );
vgui.initialized = vgui.dllFuncs.initialized = true;
Con_Reportf( "vgui_support: initialized legacy API in %s module\n", client ? "client" : "support" );
return true;
}
Con_Reportf( S_ERROR "Failed to find VGUI support API entry point in %s module\n", client ? "client" : "support" );
return false;
}
/*
================
VGui_Startup
Load vgui_support library and call VGui_Startup
================
*/
void VGui_Startup( const char *clientlib, int width, int height )
void VGui_Startup( int width, int height )
{
static qboolean failed = false;
void (*F) ( vguiapi_t * );
char vguiloader[256];
char vguilib[256];
vguiloader[0] = vguilib[0] = '\0';
if( failed )
// vgui not initialized from both support and client modules, skip
if( !vgui.initialized )
return;
if( !vgui.initialized )
{
vgui_utf8 = Cvar_Get( "vgui_utf8", "0", FCVAR_ARCHIVE, "enable utf-8 support for vgui text" );
height = Q_max( 480, height );
VGui_FillAPIFromRef( &vgui, &ref.dllFuncs );
if( width <= 640 ) width = 640;
else if( width <= 800 ) width = 800;
else if( width <= 1024 ) width = 1024;
else if( width <= 1152 ) width = 1152;
else if( width <= 1280 ) width = 1280;
else if( width <= 1600 ) width = 1600;
s_pVGuiSupport = COM_LoadLibrary( clientlib, false, false );
if( s_pVGuiSupport )
{
F = COM_GetProcAddress( s_pVGuiSupport, "InitVGUISupportAPI" );
if( F )
{
F( &vgui );
vgui.initialized = true;
Con_Reportf( "vgui_support: found internal client support\n" );
}
else
{
COM_FreeLibrary( s_pVGuiSupport );
}
}
if( !vgui.initialized )
{
// HACKHACK: load vgui with correct path first if specified.
// it will be reused while resolving vgui support and client deps
if( Sys_GetParmFromCmdLine( "-vguilib", vguilib ))
{
if( Q_strstr( vguilib, ".dll" ))
Q_strncpy( vguiloader, "vgui_support.dll", 256 );
else
Q_strncpy( vguiloader, VGUI_SUPPORT_DLL, 256 );
if( !COM_LoadLibrary( vguilib, false, false ))
Con_Reportf( S_WARN "VGUI preloading failed. Default library will be used! Reason: %s\n", COM_GetLibraryError() );
}
if( Q_strstr( clientlib, ".dll" ))
Q_strncpy( vguiloader, "vgui_support.dll", 256 );
if( !vguiloader[0] && !Sys_GetParmFromCmdLine( "-vguiloader", vguiloader ))
Q_strncpy( vguiloader, VGUI_SUPPORT_DLL, 256 );
s_pVGuiSupport = COM_LoadLibrary( vguiloader, false, false );
if( !s_pVGuiSupport )
{
s_pVGuiSupport = COM_LoadLibrary( va( "../%s", vguiloader ), false, false );
}
if( !s_pVGuiSupport )
{
if( FS_FileExists( vguiloader, false ))
{
Con_Reportf( S_ERROR "Failed to load vgui_support library: %s\n", COM_GetLibraryError() );
}
else
{
Con_Reportf( "vgui_support: not found\n" );
}
failed = true;
}
else
{
F = COM_GetProcAddress( s_pVGuiSupport, "InitAPI" );
if( F )
{
F( &vgui );
vgui.initialized = true;
}
else
{
Con_Reportf( S_ERROR "Failed to find vgui_support library entry point!\n" );
failed = true;
COM_FreeLibrary( s_pVGuiSupport );
}
}
}
}
if( height < 480 )
height = 480;
if( width <= 640 )
width = 640;
else if( width <= 800 )
width = 800;
else if( width <= 1024 )
width = 1024;
else if( width <= 1152 )
width = 1152;
else if( width <= 1280 )
width = 1280;
else if( width <= 1600 )
width = 1600;
#ifdef XASH_DLL_LOADER
else if ( Q_strstr( vguiloader, ".dll" ) )
width = 1600;
#endif
if( vgui.initialized )
{
//host.mouse_visible = true;
vgui.Startup( width, height );
}
else if ( COM_CheckString( clientlib ) )
{
failed = true;
}
if( vgui.dllFuncs.Startup )
vgui.dllFuncs.Startup( width, height );
}
@@ -270,214 +227,223 @@ Unload vgui_support library and call VGui_Shutdown
*/
void VGui_Shutdown( void )
{
if( vgui.Shutdown )
vgui.Shutdown();
if( vgui.dllFuncs.Shutdown )
vgui.dllFuncs.Shutdown();
if( s_pVGuiSupport )
COM_FreeLibrary( s_pVGuiSupport );
s_pVGuiSupport = NULL;
if( vgui.hInstance )
COM_FreeLibrary( vgui.hInstance );
vgui.hInstance = NULL;
vgui.initialized = false;
}
void VGUI_InitKeyTranslationTable( void )
static void VGUI_InitKeyTranslationTable( void )
{
static qboolean bInitted = false;
static qboolean initialized = false;
if( bInitted )
return;
bInitted = true;
if( initialized ) return;
initialized = true;
// set virtual key translation table
memset( s_pVirtualKeyTrans, -1, sizeof( s_pVirtualKeyTrans ) );
memset( vgui.virtualKeyTrans, -1, sizeof( vgui.virtualKeyTrans ) );
s_pVirtualKeyTrans['0'] = KEY_0;
s_pVirtualKeyTrans['1'] = KEY_1;
s_pVirtualKeyTrans['2'] = KEY_2;
s_pVirtualKeyTrans['3'] = KEY_3;
s_pVirtualKeyTrans['4'] = KEY_4;
s_pVirtualKeyTrans['5'] = KEY_5;
s_pVirtualKeyTrans['6'] = KEY_6;
s_pVirtualKeyTrans['7'] = KEY_7;
s_pVirtualKeyTrans['8'] = KEY_8;
s_pVirtualKeyTrans['9'] = KEY_9;
s_pVirtualKeyTrans['A'] = s_pVirtualKeyTrans['a'] = KEY_A;
s_pVirtualKeyTrans['B'] = s_pVirtualKeyTrans['b'] = KEY_B;
s_pVirtualKeyTrans['C'] = s_pVirtualKeyTrans['c'] = KEY_C;
s_pVirtualKeyTrans['D'] = s_pVirtualKeyTrans['d'] = KEY_D;
s_pVirtualKeyTrans['E'] = s_pVirtualKeyTrans['e'] = KEY_E;
s_pVirtualKeyTrans['F'] = s_pVirtualKeyTrans['f'] = KEY_F;
s_pVirtualKeyTrans['G'] = s_pVirtualKeyTrans['g'] = KEY_G;
s_pVirtualKeyTrans['H'] = s_pVirtualKeyTrans['h'] = KEY_H;
s_pVirtualKeyTrans['I'] = s_pVirtualKeyTrans['i'] = KEY_I;
s_pVirtualKeyTrans['J'] = s_pVirtualKeyTrans['j'] = KEY_J;
s_pVirtualKeyTrans['K'] = s_pVirtualKeyTrans['k'] = KEY_K;
s_pVirtualKeyTrans['L'] = s_pVirtualKeyTrans['l'] = KEY_L;
s_pVirtualKeyTrans['M'] = s_pVirtualKeyTrans['m'] = KEY_M;
s_pVirtualKeyTrans['N'] = s_pVirtualKeyTrans['n'] = KEY_N;
s_pVirtualKeyTrans['O'] = s_pVirtualKeyTrans['o'] = KEY_O;
s_pVirtualKeyTrans['P'] = s_pVirtualKeyTrans['p'] = KEY_P;
s_pVirtualKeyTrans['Q'] = s_pVirtualKeyTrans['q'] = KEY_Q;
s_pVirtualKeyTrans['R'] = s_pVirtualKeyTrans['r'] = KEY_R;
s_pVirtualKeyTrans['S'] = s_pVirtualKeyTrans['s'] = KEY_S;
s_pVirtualKeyTrans['T'] = s_pVirtualKeyTrans['t'] = KEY_T;
s_pVirtualKeyTrans['U'] = s_pVirtualKeyTrans['u'] = KEY_U;
s_pVirtualKeyTrans['V'] = s_pVirtualKeyTrans['v'] = KEY_V;
s_pVirtualKeyTrans['W'] = s_pVirtualKeyTrans['w'] = KEY_W;
s_pVirtualKeyTrans['X'] = s_pVirtualKeyTrans['x'] = KEY_X;
s_pVirtualKeyTrans['Y'] = s_pVirtualKeyTrans['y'] = KEY_Y;
s_pVirtualKeyTrans['Z'] = s_pVirtualKeyTrans['z'] = KEY_Z;
// TODO: engine keys are not enough here!
// make crossplatform way to pass SDL keys here
s_pVirtualKeyTrans[K_KP_5 - 5] = KEY_PAD_0;
s_pVirtualKeyTrans[K_KP_5 - 4] = KEY_PAD_1;
s_pVirtualKeyTrans[K_KP_5 - 3] = KEY_PAD_2;
s_pVirtualKeyTrans[K_KP_5 - 2] = KEY_PAD_3;
s_pVirtualKeyTrans[K_KP_5 - 1] = KEY_PAD_4;
s_pVirtualKeyTrans[K_KP_5 - 0] = KEY_PAD_5;
s_pVirtualKeyTrans[K_KP_5 + 1] = KEY_PAD_6;
s_pVirtualKeyTrans[K_KP_5 + 2] = KEY_PAD_7;
s_pVirtualKeyTrans[K_KP_5 + 3] = KEY_PAD_8;
s_pVirtualKeyTrans[K_KP_5 + 4] = KEY_PAD_9;
s_pVirtualKeyTrans[K_KP_SLASH] = KEY_PAD_DIVIDE;
s_pVirtualKeyTrans['*'] = KEY_PAD_MULTIPLY;
s_pVirtualKeyTrans[K_KP_MINUS] = KEY_PAD_MINUS;
s_pVirtualKeyTrans[K_KP_PLUS] = KEY_PAD_PLUS;
s_pVirtualKeyTrans[K_KP_ENTER] = KEY_PAD_ENTER;
//s_pVirtualKeyTrans[K_KP_DECIMAL] = KEY_PAD_DECIMAL;
s_pVirtualKeyTrans['['] = KEY_LBRACKET;
s_pVirtualKeyTrans[']'] = KEY_RBRACKET;
s_pVirtualKeyTrans[';'] = KEY_SEMICOLON;
s_pVirtualKeyTrans['\''] = KEY_APOSTROPHE;
s_pVirtualKeyTrans['`'] = KEY_BACKQUOTE;
s_pVirtualKeyTrans[','] = KEY_COMMA;
s_pVirtualKeyTrans['.'] = KEY_PERIOD;
s_pVirtualKeyTrans[K_KP_SLASH] = KEY_SLASH;
s_pVirtualKeyTrans['\\'] = KEY_BACKSLASH;
s_pVirtualKeyTrans['-'] = KEY_MINUS;
s_pVirtualKeyTrans['='] = KEY_EQUAL;
s_pVirtualKeyTrans[K_ENTER] = KEY_ENTER;
s_pVirtualKeyTrans[K_SPACE] = KEY_SPACE;
s_pVirtualKeyTrans[K_BACKSPACE] = KEY_BACKSPACE;
s_pVirtualKeyTrans[K_TAB] = KEY_TAB;
s_pVirtualKeyTrans[K_CAPSLOCK] = KEY_CAPSLOCK;
s_pVirtualKeyTrans[K_KP_NUMLOCK] = KEY_NUMLOCK;
s_pVirtualKeyTrans[K_ESCAPE] = KEY_ESCAPE;
//s_pVirtualKeyTrans[K_KP_SCROLLLOCK] = KEY_SCROLLLOCK;
s_pVirtualKeyTrans[K_INS] = KEY_INSERT;
s_pVirtualKeyTrans[K_DEL] = KEY_DELETE;
s_pVirtualKeyTrans[K_HOME] = KEY_HOME;
s_pVirtualKeyTrans[K_END] = KEY_END;
s_pVirtualKeyTrans[K_PGUP] = KEY_PAGEUP;
s_pVirtualKeyTrans[K_PGDN] = KEY_PAGEDOWN;
s_pVirtualKeyTrans[K_PAUSE] = KEY_BREAK;
//s_pVirtualKeyTrans[K_SHIFT] = KEY_RSHIFT;
s_pVirtualKeyTrans[K_SHIFT] = KEY_LSHIFT; // SHIFT -> left SHIFT
//s_pVirtualKeyTrans[SDLK_RALT] = KEY_RALT;
s_pVirtualKeyTrans[K_ALT] = KEY_LALT; // ALT -> left ALT
//s_pVirtualKeyTrans[SDLK_RCTRL] = KEY_RCONTROL;
s_pVirtualKeyTrans[K_CTRL] = KEY_LCONTROL; // CTRL -> left CTRL
s_pVirtualKeyTrans[K_WIN] = KEY_LWIN;
//s_pVirtualKeyTrans[SDLK_APPLICATION] = KEY_RWIN;
//s_pVirtualKeyTrans[K_WIN] = KEY_APP;
s_pVirtualKeyTrans[K_UPARROW] = KEY_UP;
s_pVirtualKeyTrans[K_LEFTARROW] = KEY_LEFT;
s_pVirtualKeyTrans[K_DOWNARROW] = KEY_DOWN;
s_pVirtualKeyTrans[K_RIGHTARROW] = KEY_RIGHT;
s_pVirtualKeyTrans[K_F1] = KEY_F1;
s_pVirtualKeyTrans[K_F2] = KEY_F2;
s_pVirtualKeyTrans[K_F3] = KEY_F3;
s_pVirtualKeyTrans[K_F4] = KEY_F4;
s_pVirtualKeyTrans[K_F5] = KEY_F5;
s_pVirtualKeyTrans[K_F6] = KEY_F6;
s_pVirtualKeyTrans[K_F7] = KEY_F7;
s_pVirtualKeyTrans[K_F8] = KEY_F8;
s_pVirtualKeyTrans[K_F9] = KEY_F9;
s_pVirtualKeyTrans[K_F10] = KEY_F10;
s_pVirtualKeyTrans[K_F11] = KEY_F11;
s_pVirtualKeyTrans[K_F12] = KEY_F12;
vgui.virtualKeyTrans['0'] = KEY_0;
vgui.virtualKeyTrans['1'] = KEY_1;
vgui.virtualKeyTrans['2'] = KEY_2;
vgui.virtualKeyTrans['3'] = KEY_3;
vgui.virtualKeyTrans['4'] = KEY_4;
vgui.virtualKeyTrans['5'] = KEY_5;
vgui.virtualKeyTrans['6'] = KEY_6;
vgui.virtualKeyTrans['7'] = KEY_7;
vgui.virtualKeyTrans['8'] = KEY_8;
vgui.virtualKeyTrans['9'] = KEY_9;
vgui.virtualKeyTrans['A'] = vgui.virtualKeyTrans['a'] = KEY_A;
vgui.virtualKeyTrans['B'] = vgui.virtualKeyTrans['b'] = KEY_B;
vgui.virtualKeyTrans['C'] = vgui.virtualKeyTrans['c'] = KEY_C;
vgui.virtualKeyTrans['D'] = vgui.virtualKeyTrans['d'] = KEY_D;
vgui.virtualKeyTrans['E'] = vgui.virtualKeyTrans['e'] = KEY_E;
vgui.virtualKeyTrans['F'] = vgui.virtualKeyTrans['f'] = KEY_F;
vgui.virtualKeyTrans['G'] = vgui.virtualKeyTrans['g'] = KEY_G;
vgui.virtualKeyTrans['H'] = vgui.virtualKeyTrans['h'] = KEY_H;
vgui.virtualKeyTrans['I'] = vgui.virtualKeyTrans['i'] = KEY_I;
vgui.virtualKeyTrans['J'] = vgui.virtualKeyTrans['j'] = KEY_J;
vgui.virtualKeyTrans['K'] = vgui.virtualKeyTrans['k'] = KEY_K;
vgui.virtualKeyTrans['L'] = vgui.virtualKeyTrans['l'] = KEY_L;
vgui.virtualKeyTrans['M'] = vgui.virtualKeyTrans['m'] = KEY_M;
vgui.virtualKeyTrans['N'] = vgui.virtualKeyTrans['n'] = KEY_N;
vgui.virtualKeyTrans['O'] = vgui.virtualKeyTrans['o'] = KEY_O;
vgui.virtualKeyTrans['P'] = vgui.virtualKeyTrans['p'] = KEY_P;
vgui.virtualKeyTrans['Q'] = vgui.virtualKeyTrans['q'] = KEY_Q;
vgui.virtualKeyTrans['R'] = vgui.virtualKeyTrans['r'] = KEY_R;
vgui.virtualKeyTrans['S'] = vgui.virtualKeyTrans['s'] = KEY_S;
vgui.virtualKeyTrans['T'] = vgui.virtualKeyTrans['t'] = KEY_T;
vgui.virtualKeyTrans['U'] = vgui.virtualKeyTrans['u'] = KEY_U;
vgui.virtualKeyTrans['V'] = vgui.virtualKeyTrans['v'] = KEY_V;
vgui.virtualKeyTrans['W'] = vgui.virtualKeyTrans['w'] = KEY_W;
vgui.virtualKeyTrans['X'] = vgui.virtualKeyTrans['x'] = KEY_X;
vgui.virtualKeyTrans['Y'] = vgui.virtualKeyTrans['y'] = KEY_Y;
vgui.virtualKeyTrans['Z'] = vgui.virtualKeyTrans['z'] = KEY_Z;
vgui.virtualKeyTrans[K_KP_5 - 5] = KEY_PAD_0;
vgui.virtualKeyTrans[K_KP_5 - 4] = KEY_PAD_1;
vgui.virtualKeyTrans[K_KP_5 - 3] = KEY_PAD_2;
vgui.virtualKeyTrans[K_KP_5 - 2] = KEY_PAD_3;
vgui.virtualKeyTrans[K_KP_5 - 1] = KEY_PAD_4;
vgui.virtualKeyTrans[K_KP_5 - 0] = KEY_PAD_5;
vgui.virtualKeyTrans[K_KP_5 + 1] = KEY_PAD_6;
vgui.virtualKeyTrans[K_KP_5 + 2] = KEY_PAD_7;
vgui.virtualKeyTrans[K_KP_5 + 3] = KEY_PAD_8;
vgui.virtualKeyTrans[K_KP_5 + 4] = KEY_PAD_9;
vgui.virtualKeyTrans[K_KP_SLASH] = KEY_PAD_DIVIDE;
vgui.virtualKeyTrans['*'] = KEY_PAD_MULTIPLY;
vgui.virtualKeyTrans[K_KP_MINUS] = KEY_PAD_MINUS;
vgui.virtualKeyTrans[K_KP_PLUS] = KEY_PAD_PLUS;
vgui.virtualKeyTrans[K_KP_ENTER] = KEY_PAD_ENTER;
vgui.virtualKeyTrans[K_KP_NUMLOCK] = KEY_NUMLOCK;
vgui.virtualKeyTrans['['] = KEY_LBRACKET;
vgui.virtualKeyTrans[']'] = KEY_RBRACKET;
vgui.virtualKeyTrans[';'] = KEY_SEMICOLON;
vgui.virtualKeyTrans['`'] = KEY_BACKQUOTE;
vgui.virtualKeyTrans[','] = KEY_COMMA;
vgui.virtualKeyTrans['.'] = KEY_PERIOD;
vgui.virtualKeyTrans['-'] = KEY_MINUS;
vgui.virtualKeyTrans['='] = KEY_EQUAL;
vgui.virtualKeyTrans['/'] = KEY_SLASH;
vgui.virtualKeyTrans['\\'] = KEY_BACKSLASH;
vgui.virtualKeyTrans['\''] = KEY_APOSTROPHE;
vgui.virtualKeyTrans[K_TAB] = KEY_TAB;
vgui.virtualKeyTrans[K_ENTER] = KEY_ENTER;
vgui.virtualKeyTrans[K_SPACE] = KEY_SPACE;
vgui.virtualKeyTrans[K_CAPSLOCK] = KEY_CAPSLOCK;
vgui.virtualKeyTrans[K_BACKSPACE] = KEY_BACKSPACE;
vgui.virtualKeyTrans[K_ESCAPE] = KEY_ESCAPE;
vgui.virtualKeyTrans[K_INS] = KEY_INSERT;
vgui.virtualKeyTrans[K_DEL] = KEY_DELETE;
vgui.virtualKeyTrans[K_HOME] = KEY_HOME;
vgui.virtualKeyTrans[K_END] = KEY_END;
vgui.virtualKeyTrans[K_PGUP] = KEY_PAGEUP;
vgui.virtualKeyTrans[K_PGDN] = KEY_PAGEDOWN;
vgui.virtualKeyTrans[K_PAUSE] = KEY_BREAK;
vgui.virtualKeyTrans[K_SHIFT] = KEY_LSHIFT; // SHIFT -> left SHIFT
vgui.virtualKeyTrans[K_ALT] = KEY_LALT; // ALT -> left ALT
vgui.virtualKeyTrans[K_CTRL] = KEY_LCONTROL; // CTRL -> left CTRL
vgui.virtualKeyTrans[K_WIN] = KEY_LWIN;
vgui.virtualKeyTrans[K_UPARROW] = KEY_UP;
vgui.virtualKeyTrans[K_LEFTARROW] = KEY_LEFT;
vgui.virtualKeyTrans[K_DOWNARROW] = KEY_DOWN;
vgui.virtualKeyTrans[K_RIGHTARROW] = KEY_RIGHT;
vgui.virtualKeyTrans[K_F1] = KEY_F1;
vgui.virtualKeyTrans[K_F2] = KEY_F2;
vgui.virtualKeyTrans[K_F3] = KEY_F3;
vgui.virtualKeyTrans[K_F4] = KEY_F4;
vgui.virtualKeyTrans[K_F5] = KEY_F5;
vgui.virtualKeyTrans[K_F6] = KEY_F6;
vgui.virtualKeyTrans[K_F7] = KEY_F7;
vgui.virtualKeyTrans[K_F8] = KEY_F8;
vgui.virtualKeyTrans[K_F9] = KEY_F9;
vgui.virtualKeyTrans[K_F10] = KEY_F10;
vgui.virtualKeyTrans[K_F11] = KEY_F11;
vgui.virtualKeyTrans[K_F12] = KEY_F12;
}
enum VGUI_KeyCode VGUI_MapKey( int keyCode )
static enum VGUI_KeyCode VGUI_MapKey( int keyCode )
{
VGUI_InitKeyTranslationTable();
if( keyCode < 0 || keyCode >= (int)sizeof( s_pVirtualKeyTrans ) / (int)sizeof( s_pVirtualKeyTrans[0] ))
{
//Assert( false );
return (enum VGUI_KeyCode)-1;
}
else
{
return s_pVirtualKeyTrans[keyCode];
}
if( keyCode >= 0 && keyCode < ARRAYSIZE( vgui.virtualKeyTrans ))
return vgui.virtualKeyTrans[keyCode];
return (enum VGUI_KeyCode)-1;
}
void VGui_KeyEvent( int key, int down )
void VGui_MouseEvent( int key, int clicks )
{
if( !vgui.initialized )
enum VGUI_MouseAction mact;
enum VGUI_MouseCode code;
if( !vgui.dllFuncs.Mouse )
return;
switch( key )
{
case K_MOUSE1:
if( down && host.mouse_visible ) {
Key_EnableTextInput(true, false);
}
vgui.Mouse( down ? MA_PRESSED : MA_RELEASED, MOUSE_LEFT );
return;
case K_MOUSE2:
vgui.Mouse( down ? MA_PRESSED : MA_RELEASED, MOUSE_RIGHT );
return;
case K_MOUSE3:
vgui.Mouse( down ? MA_PRESSED : MA_RELEASED, MOUSE_MIDDLE );
return;
case K_MWHEELDOWN:
vgui.Mouse( MA_WHEEL, 1 );
return;
case K_MWHEELUP:
vgui.Mouse( MA_WHEEL, -1 );
return;
default:
break;
case K_MOUSE1: code = MOUSE_LEFT; break;
case K_MOUSE2: code = MOUSE_RIGHT; break;
case K_MOUSE3: code = MOUSE_MIDDLE; break;
default: return;
}
if( down == 2 )
vgui.Key( KA_TYPED, VGUI_MapKey( key ) );
if( clicks >= 2 )
mact = MA_DOUBLE;
else if( clicks == 1 )
mact = MA_PRESSED;
else
vgui.Key( down?KA_PRESSED:KA_RELEASED, VGUI_MapKey( key ) );
//Msg("VGui_KeyEvent %d %d %d\n", key, VGUI_MapKey( key ), down );
mact = MA_RELEASED;
vgui.dllFuncs.Mouse( mact, code );
}
void VGui_MWheelEvent( int y )
{
if( !vgui.dllFuncs.Mouse )
return;
vgui.dllFuncs.Mouse( MA_WHEEL, y );
}
void VGui_KeyEvent( int key, int down )
{
enum VGUI_KeyCode code;
if( !vgui.dllFuncs.Key )
return;
if(( code = VGUI_MapKey( key )) < 0 )
return;
if( down )
{
vgui.dllFuncs.Key( KA_PRESSED, code );
vgui.dllFuncs.Key( KA_TYPED, code );
}
else vgui.dllFuncs.Key( KA_RELEASED, code );
}
void VGui_MouseMove( int x, int y )
{
float xscale = (float)refState.width / (float)clgame.scrInfo.iWidth;
float yscale = (float)refState.height / (float)clgame.scrInfo.iHeight;
if( vgui.initialized )
vgui.MouseMove( x / xscale, y / yscale );
if( vgui.dllFuncs.MouseMove )
{
float xscale = (float)refState.width / (float)clgame.scrInfo.iWidth;
float yscale = (float)refState.height / (float)clgame.scrInfo.iHeight;
vgui.dllFuncs.MouseMove( x / xscale, y / yscale );
}
}
void VGui_Paint( void )
{
if( vgui.initialized )
vgui.Paint();
if( vgui.dllFuncs.Paint )
vgui.dllFuncs.Paint();
}
void VGui_RunFrame( void )
void VGui_UpdateInternalCursorState( VGUI_DefaultCursor cursorType )
{
//stub
vgui.cursor = cursorType;
}
void *GAME_EXPORT VGui_GetPanel( void )
{
if( vgui.initialized )
return vgui.GetPanel();
if( vgui.dllFuncs.GetPanel )
return vgui.dllFuncs.GetPanel();
return NULL;
}
void VGui_ReportTextInput( const char *text )
{
if ( vgui.initialized )
vgui.TextInput( text );
if( vgui.dllFuncs.TextInput )
vgui.dllFuncs.TextInput( text );
}

View File

@@ -16,25 +16,22 @@ GNU General Public License for more details.
#ifndef VGUI_DRAW_H
#define VGUI_DRAW_H
#ifdef __cplusplus
extern "C" {
#endif
#include "port.h"
//
// vgui_draw.c
//
void VGui_Startup( const char *clientlib, int width, int height );
void VGui_RegisterCvars( void );
qboolean VGui_LoadProgs( HINSTANCE hInstance );
void VGui_Startup( int width, int height );
void VGui_Shutdown( void );
void VGui_Paint( void );
void VGui_RunFrame( void );
void VGui_MouseEvent( int key, int clicks );
void VGui_MWheelEvent( int y );
void VGui_KeyEvent( int key, int down );
void VGui_MouseMove( int x, int y );
qboolean VGui_IsActive( void );
void *VGui_GetPanel( void );
void VGui_ReportTextInput( const char *text );
#ifdef __cplusplus
}
#endif
#endif//VGUI_DRAW_H
void VGui_UpdateInternalCursorState( VGUI_DefaultCursor cursorType );
#endif // VGUI_DRAW_H

View File

@@ -20,22 +20,22 @@ GNU General Public License for more details.
#include "vid_common.h"
#include "platform/platform.h"
#define WINDOW_NAME XASH_ENGINE_NAME " Window" // Half-Life
convar_t *vid_displayfrequency;
convar_t *vid_fullscreen;
convar_t *vid_mode;
convar_t *vid_brightness;
convar_t *vid_gamma;
convar_t *vid_highdpi;
static CVAR_DEFINE( window_width, "width", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "screen width" );
static CVAR_DEFINE( window_height, "height", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "screen height" );
static CVAR_DEFINE( vid_brightness, "brightness", "0.0", FCVAR_ARCHIVE, "brightness factor" );
static CVAR_DEFINE( vid_gamma, "gamma", "2.5", FCVAR_ARCHIVE, "gamma amount" );
static CVAR_DEFINE_AUTO( vid_mode, "0", FCVAR_RENDERINFO, "current video mode index (used only for storage)" );
static CVAR_DEFINE_AUTO( vid_rotate, "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "screen rotation (0-3)" );
static CVAR_DEFINE_AUTO( vid_scale, "1.0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "pixel scale" );
CVAR_DEFINE_AUTO( vid_highdpi, "1", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "enable High-DPI mode" );
CVAR_DEFINE_AUTO( vid_maximized, "0", FCVAR_RENDERINFO, "window maximized state, read-only" );
CVAR_DEFINE( vid_fullscreen, "fullscreen", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "fullscreen state (0 windowed, 1 fullscreen, 2 borderless)" );
CVAR_DEFINE( window_xpos, "_window_xpos", "-1", FCVAR_RENDERINFO, "window position by horizontal" );
CVAR_DEFINE( window_ypos, "_window_ypos", "-1", FCVAR_RENDERINFO, "window position by vertical" );
glwstate_t glw_state;
convar_t *window_xpos;
convar_t *window_ypos;
convar_t *vid_rotate;
convar_t *vid_scale;
/*
=================
VID_StartupGamma
@@ -43,10 +43,10 @@ VID_StartupGamma
*/
void VID_StartupGamma( void )
{
BuildGammaTable( vid_gamma->value, vid_brightness->value );
Con_Reportf( "VID_StartupGamma: gamma %g brightness %g\n", vid_gamma->value, vid_brightness->value );
ClearBits( vid_brightness->flags, FCVAR_CHANGED );
ClearBits( vid_gamma->flags, FCVAR_CHANGED );
BuildGammaTable( vid_gamma.value, vid_brightness.value );
Con_Reportf( "VID_StartupGamma: gamma %g brightness %g\n", vid_gamma.value, vid_brightness.value );
ClearBits( vid_brightness.flags, FCVAR_CHANGED );
ClearBits( vid_gamma.flags, FCVAR_CHANGED );
}
/*
@@ -67,19 +67,31 @@ void VID_InitDefaultResolution( void )
R_SaveVideoMode
=================
*/
void R_SaveVideoMode( int w, int h , int render_w, int render_h )
void R_SaveVideoMode( int w, int h, int render_w, int render_h, qboolean maximized )
{
if( !w || !h || !render_w || !render_h )
{
host.renderinfo_changed = false;
return;
}
host.window_center_x = w / 2;
host.window_center_y = h / 2;
Cvar_SetValue( "width", w );
Cvar_SetValue( "height", h );
Cvar_DirectSet( &vid_maximized, maximized ? "1" : "0" );
// immediately drop changed state or we may trigger
// video subsystem to reapply settings
host.renderinfo_changed = false;
if( refState.width == render_w && refState.height == render_h )
return;
refState.width = render_w;
refState.height = render_h;
host.renderinfo_changed = false;
// check for 4:3 or 5:4
if( render_w * 3 != render_h * 4 && render_w * 4 != render_h * 5 )
refState.wideScreen = true;
@@ -114,11 +126,11 @@ check vid modes and fullscreen
*/
void VID_CheckChanges( void )
{
if( FBitSet( cl_allow_levelshots->flags, FCVAR_CHANGED ))
if( FBitSet( cl_allow_levelshots.flags, FCVAR_CHANGED ))
{
//GL_FreeTexture( cls.loadingBar );
SCR_RegisterTextures(); // reload 'lambda' image
ClearBits( cl_allow_levelshots->flags, FCVAR_CHANGED );
ClearBits( cl_allow_levelshots.flags, FCVAR_CHANGED );
}
if( host.renderinfo_changed )
@@ -135,6 +147,36 @@ void VID_CheckChanges( void )
}
}
/*
===============
VID_SetDisplayTransform
notify ref dll about screen transformations
===============
*/
void VID_SetDisplayTransform( int *render_w, int *render_h )
{
uint rotate = vid_rotate.value;
if( ref.dllFuncs.R_SetDisplayTransform( rotate, 0, 0, vid_scale.value, vid_scale.value ))
{
if( rotate & 1 )
{
int swap = *render_w;
*render_w = *render_h;
*render_h = swap;
}
*render_h /= vid_scale.value;
*render_w /= vid_scale.value;
}
else
{
Con_Printf( S_WARN "failed to setup screen transform\n" );
}
}
static void VID_Mode_f( void )
{
int w, h;
@@ -167,26 +209,25 @@ static void VID_Mode_f( void )
return;
}
R_ChangeDisplaySettings( w, h, Cvar_VariableInteger( "fullscreen" ) );
R_ChangeDisplaySettings( w, h, bound( 0, vid_fullscreen.value, WINDOW_MODE_COUNT - 1 ));
}
void VID_Init( void )
{
// system screen width and height (don't suppose for change from console at all)
Cvar_Get( "width", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "screen width" );
Cvar_Get( "height", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "screen height" );
Cvar_RegisterVariable( &window_width );
Cvar_RegisterVariable( &window_height );
window_xpos = Cvar_Get( "_window_xpos", "130", FCVAR_RENDERINFO, "window position by horizontal" );
window_ypos = Cvar_Get( "_window_ypos", "48", FCVAR_RENDERINFO, "window position by vertical" );
vid_gamma = Cvar_Get( "gamma", "2.5", FCVAR_ARCHIVE, "gamma amount" );
vid_brightness = Cvar_Get( "brightness", "0.0", FCVAR_ARCHIVE, "brightness factor" );
vid_displayfrequency = Cvar_Get ( "vid_displayfrequency", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "fullscreen refresh rate" );
vid_fullscreen = Cvar_Get( "fullscreen", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "enable fullscreen mode" );
vid_mode = Cvar_Get( "vid_mode", "0", FCVAR_RENDERINFO, "current video mode index (used just for storage)" );
vid_highdpi = Cvar_Get( "vid_highdpi", "1", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "enable High-DPI mode" );
vid_rotate = Cvar_Get( "vid_rotate", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "screen rotation (0-3)" );
vid_scale = Cvar_Get( "vid_scale", "1.0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "pixel scale" );
Cvar_RegisterVariable( &vid_mode );
Cvar_RegisterVariable( &vid_highdpi );
Cvar_RegisterVariable( &vid_rotate );
Cvar_RegisterVariable( &vid_scale );
Cvar_RegisterVariable( &vid_fullscreen );
Cvar_RegisterVariable( &vid_maximized );
Cvar_RegisterVariable( &vid_brightness );
Cvar_RegisterVariable( &vid_gamma );
Cvar_RegisterVariable( &window_xpos );
Cvar_RegisterVariable( &window_ypos );
// a1ba: planned to be named vid_mode for compability
// but supported mode list is filled by backends, so numbers are not portable any more

View File

@@ -9,6 +9,13 @@ typedef struct vidmode_s
int height;
} vidmode_t;
typedef enum window_mode_e
{
WINDOW_MODE_WINDOWED = 0,
WINDOW_MODE_FULLSCREEN,
WINDOW_MODE_BORDERLESS,
WINDOW_MODE_COUNT,
} window_mode_t;
typedef struct
{
@@ -21,8 +28,6 @@ typedef struct
qboolean initialized; // OpenGL subsystem started
qboolean extended; // extended context allows to GL_Debug
qboolean software;
} glwstate_t;
extern glwstate_t glw_state;
@@ -30,14 +35,15 @@ extern glwstate_t glw_state;
#define VID_MIN_HEIGHT 200
#define VID_MIN_WIDTH 320
extern convar_t *vid_fullscreen;
extern convar_t *vid_displayfrequency;
extern convar_t *vid_highdpi;
extern convar_t *vid_rotate;
extern convar_t *vid_scale;
extern convar_t vid_fullscreen;
extern convar_t vid_maximized;
extern convar_t vid_highdpi;
extern convar_t window_xpos;
extern convar_t window_ypos;
extern convar_t gl_msaa_samples;
extern convar_t *gl_msaa_samples;
void R_SaveVideoMode( int w, int h, int render_w, int render_h );
void R_SaveVideoMode( int w, int h, int render_w, int render_h, qboolean maximized );
void VID_SetDisplayTransform( int *render_w, int *render_h );
void VID_CheckChanges( void );
const char *VID_GetModeString( int vid_mode );
void VID_StartupGamma( void );

View File

@@ -159,9 +159,11 @@ static uint Voice_GetOpusCompressedData( byte *out, uint maxsize, uint *frames )
if( voice.input_file )
{
uint numbytes;
double updateInterval;
double updateInterval, curtime = Sys_DoubleTime();
updateInterval = curtime - voice.start_time;
voice.start_time = curtime;
updateInterval = cl.mtime[0] - cl.mtime[1];
numbytes = updateInterval * voice.samplerate * voice.width * VOICE_PCM_CHANNELS;
numbytes = Q_min( numbytes, voice.input_file->size - voice.input_file_pos );
numbytes = Q_min( numbytes, sizeof( voice.input_buffer ) - voice.input_buffer_pos );
@@ -380,7 +382,7 @@ void Voice_RecordStart( void )
{
Sound_Process( &voice.input_file, voice.samplerate, voice.width, SOUND_RESAMPLE );
voice.input_file_pos = 0;
voice.start_time = Sys_DoubleTime();
voice.is_recording = true;
}
@@ -497,7 +499,7 @@ void CL_AddVoiceToDatagram( void )
if( cls.state != ca_active || !Voice_IsRecording() || !voice.encoder )
return;
size = Voice_GetOpusCompressedData( voice.output_buffer, sizeof( voice.output_buffer ), &frames );
if( size > 0 && MSG_GetNumBytesLeft( &cls.datagram ) >= size + 32 )
@@ -598,8 +600,10 @@ qboolean Voice_Init( const char *pszCodecName, int quality )
}
// reinitialize only if codec parameters are different
if( Q_strcmp( voice.codec, pszCodecName ) && voice.quality != quality )
Voice_Shutdown();
if( !Q_strcmp( voice.codec, pszCodecName ) && voice.quality == quality )
return true;
Voice_Shutdown();
voice.autogain.block_size = 128;

View File

@@ -17,10 +17,20 @@ GNU General Public License for more details.
#include "base_cmd.h"
#include "cdll_int.h"
// TODO: use another hash function, as COM_HashKey depends on string length
#define HASH_SIZE 128 // 128 * 4 * 4 == 2048 bytes
typedef struct base_command_hashmap_s
{
base_command_t *basecmd; // base command: cvar, alias or command
const char *name; // key for searching
base_command_type_e type; // type for faster searching
struct base_command_hashmap_s *next;
} base_command_hashmap_t;
static base_command_hashmap_t *hashed_cmds[HASH_SIZE];
#define BaseCmd_HashKey( x ) COM_HashKey( name, HASH_SIZE )
/*
============
BaseCmd_FindInBucket
@@ -28,7 +38,7 @@ BaseCmd_FindInBucket
Find base command in bucket
============
*/
base_command_hashmap_t *BaseCmd_FindInBucket( base_command_hashmap_t *bucket, base_command_type_e type, const char *name )
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
@@ -44,9 +54,9 @@ BaseCmd_GetBucket
Get bucket which contain basecmd by given name
============
*/
base_command_hashmap_t *BaseCmd_GetBucket( const char *name )
static base_command_hashmap_t *BaseCmd_GetBucket( const char *name )
{
return hashed_cmds[ COM_HashKey( name, HASH_SIZE ) ];
return hashed_cmds[ BaseCmd_HashKey( name ) ];
}
/*
@@ -73,7 +83,7 @@ BaseCmd_Find
Find every type of base command and write into arguments
============
*/
void BaseCmd_FindAll(const char *name, base_command_t **cmd, base_command_t **alias, base_command_t **cvar)
void BaseCmd_FindAll( const char *name, base_command_t **cmd, base_command_t **alias, base_command_t **cvar )
{
base_command_hashmap_t *base = BaseCmd_GetBucket( name );
base_command_hashmap_t *i = base;
@@ -101,7 +111,6 @@ void BaseCmd_FindAll(const char *name, base_command_t **cmd, base_command_t **al
}
}
}
}
/*
@@ -113,41 +122,23 @@ Add new typed base command to hashmap
*/
void BaseCmd_Insert( base_command_type_e type, base_command_t *basecmd, const char *name )
{
uint hash = COM_HashKey( name, HASH_SIZE );
base_command_hashmap_t *elem;
base_command_hashmap_t *elem, *cur, *find;
uint hash = BaseCmd_HashKey( name );
elem = Z_Malloc( sizeof( base_command_hashmap_t ) );
elem->basecmd = basecmd;
elem->type = type;
elem->name = name;
elem->next = hashed_cmds[hash];
hashed_cmds[hash] = elem;
}
/*
============
BaseCmd_Replace
// link the variable in alphanumerical order
for( cur = NULL, find = hashed_cmds[hash];
find && Q_strcmp( find->name, elem->name ) < 0;
cur = find, find = find->next );
Used in case, when basecmd has been registered, but gamedll wants to register it's own
============
*/
qboolean BaseCmd_Replace( base_command_type_e type, base_command_t *basecmd, const char *name )
{
base_command_hashmap_t *i = BaseCmd_GetBucket( name );
if( cur ) cur->next = elem;
else hashed_cmds[hash] = elem;
for( ; i && ( i->type != type || Q_stricmp( name, i->name ) ) ; // filter out
i = i->next );
if( !i )
{
Con_Reportf( S_ERROR "BaseCmd_Replace: couldn't find %s\n", name);
return false;
}
i->basecmd = basecmd;
i->name = name; // may be freed after
return true;
elem->next = find;
}
/*
@@ -159,7 +150,7 @@ Remove base command from hashmap
*/
void BaseCmd_Remove( base_command_type_e type, const char *name )
{
uint hash = COM_HashKey( name, HASH_SIZE );
uint hash = BaseCmd_HashKey( name );
base_command_hashmap_t *i, *prev;
for( prev = NULL, i = hashed_cmds[hash]; i &&
@@ -221,23 +212,27 @@ void BaseCmd_Stats_f( void )
if( len > maxsize )
maxsize = len;
}
Con_Printf( "Base command stats:\n");
Con_Printf( "Bucket minimal length: %d\n", minsize );
Con_Printf( "Bucket maximum length: %d\n", maxsize );
Con_Printf( "Empty buckets: %d\n", empty );
Con_Printf( "min length: %d, max length: %d, empty: %d\n", minsize, maxsize, empty );
}
typedef struct
{
qboolean valid;
int lookups;
} basecmd_test_stats_t;
static void BaseCmd_CheckCvars( const char *key, const char *value, const void *unused, void *ptr )
{
base_command_t *v = BaseCmd_Find( HM_CVAR, key );
qboolean *invalid = ptr;
basecmd_test_stats_t *stats = ptr;
if( !v )
stats->lookups++;
if( !BaseCmd_Find( HM_CVAR, key ))
{
Con_Printf( "Cvar %s is missing in basecmd\n", key );
*invalid = true;
stats->valid = false;
}
}
@@ -250,38 +245,51 @@ testing order matches cbuf execute
*/
void BaseCmd_Test_f( void )
{
void *cmd;
cmdalias_t *a;
qboolean invalid = false;
basecmd_test_stats_t stats;
double start, end, dt;
int i;
// Cmd_LookupCmds don't allows to check alias, so just iterate
for( a = Cmd_AliasGetList(); a; a = a->next )
stats.valid = true;
stats.lookups = 0;
start = Sys_DoubleTime() * 1000;
for( i = 0; i < 1000; i++ )
{
base_command_t *v = BaseCmd_Find( HM_CMDALIAS, a->name );
cmdalias_t *a;
void *cmd;
if( !v )
// Cmd_LookupCmds don't allows to check alias, so just iterate
for( a = Cmd_AliasGetList(); a; a = a->next, stats.lookups++ )
{
Con_Printf( "Alias %s is missing in basecmd\n", a->name );
invalid = true;
if( !BaseCmd_Find( HM_CMDALIAS, a->name ))
{
Con_Printf( "Alias %s is missing in basecmd\n", a->name );
stats.valid = false;
}
}
for( cmd = Cmd_GetFirstFunctionHandle(); cmd;
cmd = Cmd_GetNextFunctionHandle( cmd ), stats.lookups++ )
{
if( !BaseCmd_Find( HM_CMD, Cmd_GetName( cmd )))
{
Con_Printf( "Command %s is missing in basecmd\n", Cmd_GetName( cmd ));
stats.valid = false;
}
}
Cvar_LookupVars( 0, NULL, &stats.valid, (setpair_t)BaseCmd_CheckCvars );
}
for( cmd = Cmd_GetFirstFunctionHandle(); cmd;
cmd = Cmd_GetNextFunctionHandle( cmd ) )
{
base_command_t *v = BaseCmd_Find( HM_CMD, Cmd_GetName( cmd ) );
end = Sys_DoubleTime() * 1000;
if( !v )
{
Con_Printf( "Command %s is missing in basecmd\n", Cmd_GetName( cmd ) );
invalid = true;
}
}
dt = end - start;
Cvar_LookupVars( 0, NULL, &invalid, (setpair_t)BaseCmd_CheckCvars );
if( !invalid )
{
if( !stats.valid )
Con_Printf( "BaseCmd is valid\n" );
}
Con_Printf( "Test took %.3f ms, %d lookups, %.3f us/lookup\n", dt, stats.lookups, dt / stats.lookups * 1000 );
BaseCmd_Stats_f();
}

View File

@@ -17,8 +17,6 @@ GNU General Public License for more details.
#ifndef BASE_CMD_H
#define BASE_CMD_H
// TODO: Find cases when command hashmap works incorrect
// and maybe disable it
#define XASH_HASHED_VARS
#ifdef XASH_HASHED_VARS
@@ -33,23 +31,13 @@ typedef enum base_command_type
typedef void base_command_t;
typedef struct base_command_hashmap_s
{
base_command_t *basecmd; // base command: cvar, alias or command
const char *name; // key for searching
base_command_type_e type; // type for faster searching
struct base_command_hashmap_s *next;
} base_command_hashmap_t;
void BaseCmd_Init( void );
base_command_hashmap_t *BaseCmd_GetBucket( const char *name );
base_command_hashmap_t *BaseCmd_FindInBucket( base_command_hashmap_t *bucket, base_command_type_e type, const char *name );
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 );
void BaseCmd_Insert ( base_command_type_e type, base_command_t *basecmd, const char *name );
qboolean BaseCmd_Replace( base_command_type_e type, base_command_t *basecmd, const char *name ); // only if same name
void BaseCmd_Remove ( base_command_type_e type, const char *name );
void BaseCmd_Stats_f( void ); // to be registered later
void BaseCmd_Test_f( void ); // to be registered later

View File

@@ -120,6 +120,18 @@ void Cbuf_AddText( const char *text )
Cbuf_AddTextToBuffer( &cmd_text, text );
}
void Cbuf_AddTextf( const char *fmt, ... )
{
va_list va;
char buf[MAX_VA_STRING];
va_start( va, fmt );
Q_vsnprintf( buf, sizeof( buf ), fmt, va );
va_end( va );
Cbuf_AddText( buf );
}
/*
============
Cbuf_AddFilteredText
@@ -535,7 +547,7 @@ int GAME_EXPORT Cmd_Argc( void )
Cmd_Argv
============
*/
const char *Cmd_Argv( int arg )
const char *GAME_EXPORT Cmd_Argv( int arg )
{
if((uint)arg >= cmd_argc )
return "";
@@ -547,7 +559,7 @@ const char *Cmd_Argv( int arg )
Cmd_Args
============
*/
const char *Cmd_Args( void )
const char *GAME_EXPORT Cmd_Args( void )
{
return cmd_args;
}
@@ -984,7 +996,7 @@ static void Cmd_ExecuteStringWithPrivilegeCheck( const char *text, qboolean isPr
cmd_condlevel = 0;
// cvar value substitution
if( CVAR_TO_BOOL( cmd_scripting ))
if( cmd_scripting.value && isPrivileged )
{
while( *text )
{
@@ -1150,13 +1162,13 @@ void Cmd_ForwardToServer( void )
str[0] = 0;
if( Q_stricmp( Cmd_Argv( 0 ), "cmd" ))
{
Q_strcat( str, Cmd_Argv( 0 ));
Q_strcat( str, " " );
Q_strncat( str, Cmd_Argv( 0 ), sizeof( str ));
Q_strncat( str, " ", sizeof( str ));
}
if( Cmd_Argc() > 1 )
Q_strcat( str, Cmd_Args( ));
else Q_strcat( str, "\n" );
Q_strncat( str, Cmd_Args( ), sizeof( str ));
else Q_strncat( str, "\n", sizeof( str ));
MSG_WriteString( &cls.netchan.message, str );
}
@@ -1254,21 +1266,21 @@ static void Cmd_Apropos_f( void )
cmdalias_t *alias;
const char *partial;
int count = 0;
qboolean ispattern;
char buf[MAX_VA_STRING];
if( Cmd_Argc() > 1 )
{
partial = Cmd_Args();
}
else
if( Cmd_Argc() < 2 )
{
Msg( "apropos what?\n" );
return;
}
ispattern = partial && Q_strpbrk( partial, "*?" );
if( !ispattern )
partial = va( "*%s*", partial );
partial = Cmd_Args();
if( !Q_strpbrk( partial, "*?" ))
{
Q_snprintf( buf, sizeof( buf ), "*%s*", partial );
partial = buf;
}
for( var = (convar_t*)Cvar_GetList(); var; var = var->next )
{
@@ -1345,7 +1357,7 @@ inserts escape sequences
void Cmd_Escape( char *newCommand, const char *oldCommand, int len )
{
int c;
int scripting = CVAR_TO_BOOL( cmd_scripting );
int scripting = cmd_scripting.value;
while( (c = *oldCommand++) && len > 1 )
{
@@ -1395,8 +1407,8 @@ void Cmd_Init( void )
#endif // XASH_DEDICATED
Cmd_AddRestrictedCommand( "alias", Cmd_Alias_f, "create a script function. Without arguments show the list of all alias" );
Cmd_AddRestrictedCommand( "unalias", Cmd_UnAlias_f, "remove a script function" );
Cmd_AddCommand( "if", Cmd_If_f, "compare and set condition bits" );
Cmd_AddCommand( "else", Cmd_Else_f, "invert condition bit" );
Cmd_AddRestrictedCommand( "if", Cmd_If_f, "compare and set condition bits" );
Cmd_AddRestrictedCommand( "else", Cmd_Else_f, "invert condition bit" );
#if defined(XASH_HASHED_VARS)
Cmd_AddCommand( "basecmd_stats", BaseCmd_Stats_f, "print info about basecmd usage" );

View File

@@ -21,6 +21,7 @@ GNU General Public License for more details.
#define S_WARN "^3Warning:^7 "
#define S_ERROR "^1Error:^7 "
#define S_USAGE "Usage: "
#define S_USAGE_INDENT " "
#define S_OPENGL_NOTE "^2OpenGL Note:^7 "
#define S_OPENGL_WARN "^3OpenGL Warning:^7 "
@@ -67,8 +68,4 @@ GNU General Public License for more details.
#define XASH_VERSION "0.20" // engine current version
#define XASH_COMPAT_VERSION "0.99" // version we are based on
// renderers order is important, software is always a last chance fallback
#define DEFAULT_RENDERERS { "gl", "gles1", "gles2", "gl4es", "soft" }
#define DEFAULT_RENDERERS_LEN 5
#endif//COM_STRINGS_H

View File

@@ -22,7 +22,6 @@ GNU General Public License for more details.
#include "const.h"
#include "client.h"
#include "library.h"
#include "sequence.h"
static const char *file_exts[] =
{
@@ -104,7 +103,7 @@ static float fran1( void )
return temp;
}
void COM_SetRandomSeed( int lSeed )
void GAME_EXPORT COM_SetRandomSeed( int lSeed )
{
if( lSeed ) idum = lSeed;
else idum = -time( NULL );
@@ -151,6 +150,30 @@ int GAME_EXPORT COM_RandomLong( int lLow, int lHigh )
return lLow + (n % x);
}
/*
============
va
does a varargs printf into a temp buffer,
so I don't need to have varargs versions
of all text functions.
============
*/
char *va( const char *format, ... )
{
va_list argptr;
static char string[16][MAX_VA_STRING], *s;
static int stringindex = 0;
s = string[stringindex];
stringindex = (stringindex + 1) & 15;
va_start( argptr, format );
Q_vsnprintf( s, sizeof( string[0] ), format, argptr );
va_end( argptr );
return s;
}
/*
===============================================================================
@@ -243,7 +266,7 @@ static void LZSS_BuildHash( lzss_state_t *state, const byte *source )
list->start = node;
}
byte *LZSS_CompressNoAlloc( lzss_state_t *state, byte *pInput, int input_length, byte *pOutputBuf, uint *pOutputSize )
static byte *LZSS_CompressNoAlloc( lzss_state_t *state, byte *pInput, int input_length, byte *pOutputBuf, uint *pOutputSize )
{
byte *pStart = pOutputBuf; // allocate the output buffer, compressed buffer is expected to be less, caller will free
byte *pEnd = pStart + input_length - sizeof( lzss_header_t ) - 8; // prevent compression failure
@@ -529,7 +552,6 @@ This doesn't search in the pak file.
*/
int GAME_EXPORT COM_ExpandFilename( const char *fileName, char *nameOutBuffer, int nameOutBufferSize )
{
const char *path;
char result[MAX_SYSPATH];
if( !COM_CheckString( fileName ) || !nameOutBuffer || nameOutBufferSize <= 0 )
@@ -538,10 +560,8 @@ int GAME_EXPORT COM_ExpandFilename( const char *fileName, char *nameOutBuffer, i
// filename examples:
// media\sierra.avi - D:\Xash3D\valve\media\sierra.avi
// models\barney.mdl - D:\Xash3D\bshift\models\barney.mdl
if(( path = FS_GetDiskPath( fileName, false )) != NULL )
if( g_fsapi.GetFullDiskPath( result, sizeof( result ), fileName, false ))
{
Q_sprintf( result, "%s/%s", host.rootdir, path );
// check for enough room
if( Q_strlen( result ) > nameOutBufferSize )
return 0;
@@ -592,7 +612,7 @@ COM_Nibble
Returns the 4 bit nibble for a hex character
==================
*/
byte COM_Nibble( char c )
static byte COM_Nibble( char c )
{
if(( c >= '0' ) && ( c <= '9' ))
{
@@ -640,7 +660,7 @@ COM_MemFgets
=============
*/
char *COM_MemFgets( byte *pMemFile, int fileSize, int *filePos, char *pBuffer, int bufferSize )
char *GAME_EXPORT COM_MemFgets( byte *pMemFile, int fileSize, int *filePos, char *pBuffer, int bufferSize )
{
int i, last, stop;
@@ -694,7 +714,7 @@ Cache_Check
consistency check
====================
*/
void *Cache_Check( poolhandle_t mempool, cache_user_t *c )
void *GAME_EXPORT Cache_Check( poolhandle_t mempool, cache_user_t *c )
{
if( !c->data )
return NULL;
@@ -711,7 +731,7 @@ COM_LoadFileForMe
=============
*/
byte* GAME_EXPORT COM_LoadFileForMe( const char *filename, int *pLength )
byte *GAME_EXPORT COM_LoadFileForMe( const char *filename, int *pLength )
{
string name;
byte *file, *pfile;
@@ -751,7 +771,7 @@ COM_LoadFile
=============
*/
byte *COM_LoadFile( const char *filename, int usehunk, int *pLength )
byte *GAME_EXPORT COM_LoadFile( const char *filename, int usehunk, int *pLength )
{
return COM_LoadFileForMe( filename, pLength );
}
@@ -837,63 +857,6 @@ void GAME_EXPORT pfnGetModelBounds( model_t *mod, float *mins, float *maxs )
}
}
/*
=============
pfnCvar_RegisterServerVariable
standard path to register game variable
=============
*/
void GAME_EXPORT pfnCvar_RegisterServerVariable( cvar_t *variable )
{
if( variable != NULL )
SetBits( variable->flags, FCVAR_EXTDLL );
Cvar_RegisterVariable( (convar_t *)variable );
}
/*
=============
pfnCvar_RegisterEngineVariable
use with precaution: this cvar will NOT unlinked
after game.dll is unloaded
=============
*/
void GAME_EXPORT pfnCvar_RegisterEngineVariable( cvar_t *variable )
{
Cvar_RegisterVariable( (convar_t *)variable );
}
/*
=============
pfnCvar_RegisterVariable
=============
*/
cvar_t *pfnCvar_RegisterClientVariable( const char *szName, const char *szValue, int flags )
{
// a1ba: try to mitigate outdated client.dll vulnerabilities
if( !Q_stricmp( szName, "motdfile" ))
flags |= FCVAR_PRIVILEGED;
if( FBitSet( flags, FCVAR_GLCONFIG ))
return (cvar_t *)Cvar_Get( szName, szValue, flags, va( CVAR_GLCONFIG_DESCRIPTION, szName ));
return (cvar_t *)Cvar_Get( szName, szValue, flags|FCVAR_CLIENTDLL, Cvar_BuildAutoDescription( flags|FCVAR_CLIENTDLL ));
}
/*
=============
pfnCvar_RegisterVariable
=============
*/
cvar_t *pfnCvar_RegisterGameUIVariable( const char *szName, const char *szValue, int flags )
{
if( FBitSet( flags, FCVAR_GLCONFIG ))
return (cvar_t *)Cvar_Get( szName, szValue, flags, va( CVAR_GLCONFIG_DESCRIPTION, szName ));
return (cvar_t *)Cvar_Get( szName, szValue, flags|FCVAR_GAMEUIDLL, Cvar_BuildAutoDescription( flags|FCVAR_GAMEUIDLL ));
}
/*
=============
pfnCVarGetPointer
@@ -901,7 +864,7 @@ pfnCVarGetPointer
can return NULL
=============
*/
cvar_t *pfnCVarGetPointer( const char *szVarName )
cvar_t *GAME_EXPORT pfnCVarGetPointer( const char *szVarName )
{
return (cvar_t *)Cvar_FindVar( szVarName );
}
@@ -986,7 +949,7 @@ pfnGetGameDir
void GAME_EXPORT pfnGetGameDir( char *szGetGameDir )
{
if( !szGetGameDir ) return;
Q_strcpy( szGetGameDir, GI->gamefolder );
Q_strncpy( szGetGameDir, GI->gamefolder, sizeof( GI->gamefolder ));
}
qboolean COM_IsSafeFileToDownload( const char *filename )
@@ -1033,15 +996,32 @@ qboolean COM_IsSafeFileToDownload( const char *filename )
return true;
}
const char *COM_GetResourceTypeName( resourcetype_t restype )
{
switch( restype )
{
case t_decal: return "decal";
case t_eventscript: return "eventscript";
case t_generic: return "generic";
case t_model: return "model";
case t_skin: return "skin";
case t_sound: return "sound";
case t_world: return "world";
default: return "unknown";
}
}
char *_copystring( poolhandle_t mempool, const char *s, const char *filename, int fileline )
{
size_t size;
char *b;
if( !s ) return NULL;
if( !mempool ) mempool = host.mempool;
b = _Mem_Alloc( mempool, Q_strlen( s ) + 1, false, filename, fileline );
Q_strcpy( b, s );
size = Q_strlen( s ) + 1;
b = _Mem_Alloc( mempool, size, false, filename, fileline );
Q_strncpy( b, s, size );
return b;
}
@@ -1066,8 +1046,7 @@ void *GAME_EXPORT pfnSequenceGet( const char *fileName, const char *entryName )
{
Msg( "Sequence_Get: file %s, entry %s\n", fileName, entryName );
return Sequence_Get( fileName, entryName );
return NULL;
}
/*
@@ -1081,7 +1060,7 @@ void *GAME_EXPORT pfnSequencePickSentence( const char *groupName, int pickMethod
{
Msg( "Sequence_PickSentence: group %s, pickMethod %i\n", groupName, pickMethod );
return Sequence_PickSentence( groupName, pickMethod, picked );
return NULL;
}
@@ -1092,30 +1071,7 @@ pfnIsCareerMatch
used by CS:CZ (client stub)
=============
*/
int GAME_EXPORT GAME_EXPORT pfnIsCareerMatch( void )
{
return 0;
}
/*
=============
pfnRegisterTutorMessageShown
only exists in PlayStation version
=============
*/
void GAME_EXPORT pfnRegisterTutorMessageShown( int mid )
{
}
/*
=============
pfnGetTimesTutorMessageShown
only exists in PlayStation version
=============
*/
int GAME_EXPORT pfnGetTimesTutorMessageShown( int mid )
int GAME_EXPORT pfnIsCareerMatch( void )
{
return 0;
}

View File

@@ -144,7 +144,7 @@ typedef enum
#define GameState (&host.game)
#define FORCE_DRAW_VERSION_TIME 5.0f // draw version for 5 seconds
#define FORCE_DRAW_VERSION_TIME 5.0 // draw version for 5 seconds
#ifdef _DEBUG
void DBG_AssertFunction( qboolean fExpr, const char* szExpr, const char* szFile, int szLine, const char* szMessage );
@@ -153,19 +153,17 @@ void DBG_AssertFunction( qboolean fExpr, const char* szExpr, const char* szFile,
#define Assert( f )
#endif
extern convar_t *gl_vsync;
extern convar_t *scr_loading;
extern convar_t *scr_download;
extern convar_t *cmd_scripting;
extern convar_t *sv_maxclients;
extern convar_t *cl_allow_levelshots;
extern convar_t *vid_displayfrequency;
extern convar_t gl_vsync;
extern convar_t scr_loading;
extern convar_t scr_download;
extern convar_t cmd_scripting;
extern convar_t cl_allow_levelshots;
extern convar_t host_developer;
extern convar_t *host_limitlocal;
extern convar_t *host_framerate;
extern convar_t *host_maxfps;
extern convar_t host_limitlocal;
extern convar_t host_maxfps;
extern convar_t sys_timescale;
extern convar_t cl_filterstuffcmd;
extern convar_t rcon_password;
/*
==============================================================
@@ -273,40 +271,6 @@ typedef struct
double forcedEnd;
} soundlist_t;
typedef struct
{
char model[MAX_QPATH]; // curstate.modelindex = SV_ModelIndex
vec3_t tentOffset; // if attached, client origin + tentOffset = tent origin.
short clientIndex;
float fadeSpeed;
float bounceFactor;
byte hitSound;
qboolean high_priority;
float x, y, z;
int flags;
float time;
// base state
vec3_t velocity; // baseline.origin
vec3_t avelocity; // baseline.angles
int fadeamount; // baseline.renderamt
float sparklife; // baseline.framerate
float thinkTime; // baseline.scale
// current state
vec3_t origin; // entity.origin
vec3_t angles; // entity.angles
float renderamt; // curstate.renderamt
color24 rendercolor; // curstate.rendercolor
int rendermode; // curstate.rendermode
int renderfx; // curstate.renderfx
float framerate; // curstate.framerate
float frame; // curstate.frame
byte body; // curstate.body
byte skin; // curstate.skin
float scale; // curstate.scale
} tentlist_t;
typedef enum bugcomp_e
{
// default mode, we assume that user dlls are not relying on engine bugs
@@ -358,14 +322,12 @@ typedef struct host_parm_s
qboolean allow_cheats; // this host will allow cheating
qboolean con_showalways; // show console always (developer and dedicated)
qboolean change_game; // initialize when game is changed
qboolean mouse_visible; // vgui override cursor control
qboolean mouse_visible; // vgui override cursor control (never change outside Platform_SetCursorType!)
qboolean shutdown_issued; // engine is shutting down
qboolean force_draw_version; // used when fraps is loaded
float force_draw_version_time;
double force_draw_version_time;
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
int sv_cvars_restored; // count of restored server cvars
qboolean crashed; // set to true if crashed
qboolean daemonized;
qboolean enabledll;
@@ -394,6 +356,11 @@ typedef struct host_parm_s
// bug compatibility level, for very "special" games
bugcomp_t bugcomp;
// measure time to first frame
double starttime;
// count of sleeps can be inserted between frames
double pureframetime;
} host_parm_t;
extern host_parm_t host;
@@ -421,6 +388,7 @@ void FS_Shutdown( void );
void Cbuf_Init( void );
void Cbuf_Clear( void );
void Cbuf_AddText( const char *text );
void Cbuf_AddTextf( const char *text, ... ) _format( 1 );
void Cbuf_AddFilteredText( const char *text );
void Cbuf_InsertText( const char *text );
void Cbuf_ExecStuffCmds( void );
@@ -561,6 +529,7 @@ int FS_GetStreamPos( stream_t *stream );
void FS_FreeStream( stream_t *stream );
qboolean Sound_Process( wavdata_t **wav, int rate, int width, uint flags );
uint Sound_GetApproxWavePlayLen( const char *filepath );
qboolean Sound_SupportedFileFormat( const char *fileext );
//
// host.c
@@ -623,15 +592,12 @@ qboolean SV_Active( void );
==============================================================
*/
void pfnCvar_RegisterServerVariable( cvar_t *variable );
void pfnCvar_RegisterEngineVariable( cvar_t *variable );
cvar_t *pfnCvar_RegisterClientVariable( const char *szName, const char *szValue, int flags );
cvar_t *pfnCvar_RegisterGameUIVariable( const char *szName, const char *szValue, int flags );
char *COM_MemFgets( byte *pMemFile, int fileSize, int *filePos, char *pBuffer, int bufferSize );
void COM_HexConvert( const char *pszInput, int nInputLength, byte *pOutput );
int COM_SaveFile( const char *filename, const void *data, int len );
byte* COM_LoadFileForMe( const char *filename, int *pLength );
qboolean COM_IsSafeFileToDownload( const char *filename );
const char *COM_GetResourceTypeName( resourcetype_t restype );
cvar_t *pfnCVarGetPointer( const char *szVarName );
int pfnDrawConsoleString( int x, int y, char *string );
void pfnDrawSetTextColor( float r, float g, float b );
@@ -642,7 +608,6 @@ void pfnGetModelBounds( model_t *mod, float *mins, float *maxs );
void pfnCVarDirectSet( cvar_t *var, const char *szValue );
int COM_CheckParm( char *parm, char **ppnext );
void pfnGetGameDir( char *szGetGameDir );
int pfnDecalIndex( const char *m );
int pfnGetModelType( model_t *mod );
int pfnIsMapValid( char *filename );
void Con_Reportf( const char *szFmt, ... ) _format( 1 );
@@ -662,8 +627,6 @@ void *pfnSequencePickSentence( const char *groupName, int pickMethod, int *picke
int pfnIsCareerMatch( void );
// Decay engfuncs (stubs)
int pfnGetTimesTutorMessageShown( int mid );
void pfnRegisterTutorMessageShown( int mid );
void pfnConstructTutorMessageDecayBuffer( int *buffer, int buflen );
void pfnProcessTutorMessageDecayBuffer( int *buffer, int bufferLength );
void pfnResetTutorMessageDecayData( void );
@@ -739,7 +702,6 @@ char *CL_Userinfo( void );
void CL_LegacyUpdateInfo( void );
void CL_CharEvent( int key );
qboolean CL_DisableVisibility( void );
int CL_PointContents( const vec3_t point );
byte *COM_LoadFile( const char *filename, int usehunk, int *pLength );
int CL_GetDemoComment( const char *demoname, char *comment );
void COM_AddAppDirectoryToSearchPath( const char *pszBaseDir, const char *appName );
@@ -748,9 +710,7 @@ struct cmd_s *Cmd_GetFirstFunctionHandle( void );
struct cmd_s *Cmd_GetNextFunctionHandle( struct cmd_s *cmd );
struct cmdalias_s *Cmd_AliasGetList( void );
const char *Cmd_GetName( struct cmd_s *cmd );
struct pmtrace_s *PM_TraceLine( float *start, float *end, int flags, int usehull, int ignore_pe );
void SV_StartSound( edict_t *ent, int chan, const char *sample, float vol, float attn, int flags, int pitch );
void SV_StartMusic( const char *curtrack, const char *looptrack, int position );
void SV_CreateDecal( sizebuf_t *msg, const float *origin, int decalIndex, int entityIndex, int modelIndex, int flags, float scale );
void Log_Printf( const char *fmt, ... ) _format( 1 );
void SV_BroadcastCommand( const char *fmt, ... ) _format( 1 );
@@ -775,8 +735,6 @@ int SV_GetMaxClients( void );
qboolean CL_IsRecordDemo( void );
qboolean CL_IsTimeDemo( void );
qboolean CL_IsPlaybackDemo( void );
qboolean CL_IsBackgroundDemo( void );
qboolean CL_IsBackgroundMap( void );
qboolean SV_Initialized( void );
qboolean CL_LoadProgs( const char *name );
void CL_ProcessFile( qboolean successfully_received, const char *filename );
@@ -789,8 +747,6 @@ void SV_ShutdownGame( void );
void SV_ExecLoadLevel( void );
void SV_ExecLoadGame( void );
void SV_ExecChangeLevel( void );
void SV_InitGameProgs( void );
void SV_FreeGameProgs( void );
void CL_WriteMessageHistory( void );
void CL_SendCmd( void );
void CL_Disconnect( void );
@@ -816,6 +772,7 @@ const char *Info_ValueForKey( const char *s, const char *key );
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 );
qboolean Info_SetValueForKeyf( char *s, const char *key, int maxsize, const char *format, ... ) _format( 4 );
qboolean Info_SetValueForStarKey( char *s, const char *key, const char *value, int maxsize );
qboolean Info_IsValid( const char *s );
void Info_WriteVars( file_t *f );
@@ -841,6 +798,7 @@ void COM_NormalizeAngles( vec3_t angles );
int COM_FileSize( const char *filename );
void COM_FreeFile( void *buffer );
int COM_CompareFileTime( const char *filename1, const char *filename2, int *iCompare );
char *va( const char *format, ... ) _format( 1 );
// soundlib shared exports
qboolean S_Init( void );
@@ -853,7 +811,6 @@ void S_StopAllSounds( qboolean ambient );
// gamma routines
void BuildGammaTable( float gamma, float brightness );
byte LightToTexGamma( byte b );
byte TextureToGamma( byte b );
//
// identification.c
@@ -869,6 +826,10 @@ void NET_InitMasters( void );
void NET_SaveMasters( void );
qboolean NET_SendToMasters( netsrc_t sock, size_t len, const void *data );
qboolean NET_IsMasterAdr( netadr_t adr );
void NET_MasterHeartbeat( void );
void NET_MasterClear( void );
void NET_MasterShutdown( void );
qboolean NET_GetMaster( netadr_t from, uint *challenge, double *last_heartbeat );
#ifdef REF_DLL
#error "common.h in ref_dll"

View File

@@ -18,7 +18,7 @@ GNU General Public License for more details.
#include "const.h"
#include "kbutton.h"
extern convar_t *con_gamemaps;
extern convar_t con_gamemaps;
#define CON_MAXCMDS 4096 // auto-complete intermediate list
@@ -76,12 +76,13 @@ int Cmd_ListMaps( search_t *t, char *lastmapname, size_t len )
compiler[0] = '\0';
generator[0] = '\0';
f = FS_Open( t->filenames[i], "rb", con_gamemaps->value );
f = FS_Open( t->filenames[i], "rb", con_gamemaps.value );
if( f )
{
dheader_t *header;
dheader_t *header;
dextrahdr_t *hdrext;
dlump_t entities;
memset( buf, 0, sizeof( buf ));
FS_Read( f, buf, sizeof( buf ));
@@ -89,10 +90,10 @@ int Cmd_ListMaps( search_t *t, char *lastmapname, size_t len )
ver = header->version;
// check all the lumps and some other errors
if( Mod_TestBmodelLumps( t->filenames[i], buf, true ))
if( Mod_TestBmodelLumps( f, t->filenames[i], buf, true, &entities ))
{
lumpofs = header->lumps[LUMP_ENTITIES].fileofs;
lumplen = header->lumps[LUMP_ENTITIES].filelen;
lumpofs = entities.fileofs;
lumplen = entities.filelen;
ver = header->version;
}
@@ -100,8 +101,7 @@ int Cmd_ListMaps( search_t *t, char *lastmapname, size_t len )
if( hdrext->id == IDEXTRAHEADER ) version = hdrext->version;
Q_strncpy( entfilename, t->filenames[i], sizeof( entfilename ));
COM_StripExtension( entfilename );
COM_DefaultExtension( entfilename, ".ent" );
COM_ReplaceExtension( entfilename, ".ent", sizeof( entfilename ));
ents = (char *)FS_LoadFile( entfilename, NULL, true );
if( !ents && lumplen >= 10 )
@@ -145,7 +145,7 @@ int Cmd_ListMaps( search_t *t, char *lastmapname, size_t len )
}
if( f ) FS_Close(f);
COM_FileBase( t->filenames[i], mapname );
COM_FileBase( t->filenames[i], mapname, sizeof( mapname ));
switch( ver )
{
@@ -190,10 +190,10 @@ qboolean Cmd_GetMapList( const char *s, char *completedname, int length )
string matchbuf;
int i, nummaps;
t = FS_Search( va( "maps/%s*.bsp", s ), true, con_gamemaps->value );
t = FS_Search( va( "maps/%s*.bsp", s ), true, con_gamemaps.value );
if( !t ) return false;
COM_FileBase( t->filenames[0], matchbuf );
COM_FileBase( t->filenames[0], matchbuf, sizeof( matchbuf ));
if( completedname && length )
Q_strncpy( completedname, matchbuf, length );
if( t->numfilenames == 1 ) return true;
@@ -230,7 +230,7 @@ qboolean Cmd_GetDemoList( const char *s, char *completedname, int length )
t = FS_Search( va( "%s*.dem", s ), true, true );
if( !t ) return false;
COM_FileBase( t->filenames[0], matchbuf );
COM_FileBase( t->filenames[0], matchbuf, sizeof( matchbuf ));
if( completedname && length )
Q_strncpy( completedname, matchbuf, length );
if( t->numfilenames == 1 ) return true;
@@ -240,7 +240,7 @@ qboolean Cmd_GetDemoList( const char *s, char *completedname, int length )
if( Q_stricmp( COM_FileExtension( t->filenames[i] ), "dem" ))
continue;
COM_FileBase( t->filenames[i], matchbuf );
COM_FileBase( t->filenames[i], matchbuf, sizeof( matchbuf ));
Con_Printf( "%16s\n", matchbuf );
numdems++;
}
@@ -276,7 +276,7 @@ qboolean Cmd_GetMovieList( const char *s, char *completedname, int length )
t = FS_Search( va( "media/%s*.avi", s ), true, false );
if( !t ) return false;
COM_FileBase( t->filenames[0], matchbuf );
COM_FileBase( t->filenames[0], matchbuf, sizeof( matchbuf ));
if( completedname && length )
Q_strncpy( completedname, matchbuf, length );
if( t->numfilenames == 1 ) return true;
@@ -286,7 +286,7 @@ qboolean Cmd_GetMovieList( const char *s, char *completedname, int length )
if( Q_stricmp( COM_FileExtension( t->filenames[i] ), "avi" ))
continue;
COM_FileBase( t->filenames[i], matchbuf );
COM_FileBase( t->filenames[i], matchbuf, sizeof( matchbuf ));
Con_Printf( "%16s\n", matchbuf );
nummovies++;
}
@@ -323,7 +323,7 @@ qboolean Cmd_GetMusicList( const char *s, char *completedname, int length )
t = FS_Search( va( "media/%s*.*", s ), true, false );
if( !t ) return false;
COM_FileBase( t->filenames[0], matchbuf );
COM_FileBase( t->filenames[0], matchbuf, sizeof( matchbuf ));
if( completedname && length )
Q_strncpy( completedname, matchbuf, length );
if( t->numfilenames == 1 ) return true;
@@ -335,7 +335,7 @@ qboolean Cmd_GetMusicList( const char *s, char *completedname, int length )
if( Q_stricmp( ext, "wav" ) && Q_stricmp( ext, "mp3" ))
continue;
COM_FileBase( t->filenames[i], matchbuf );
COM_FileBase( t->filenames[i], matchbuf, sizeof( matchbuf ));
Con_Printf( "%16s\n", matchbuf );
numtracks++;
}
@@ -368,10 +368,10 @@ qboolean Cmd_GetSavesList( const char *s, char *completedname, int length )
string matchbuf;
int i, numsaves;
t = FS_Search( va( "%s%s*.sav", DEFAULT_SAVE_DIRECTORY, s ), true, true ); // lookup only in gamedir
t = FS_Search( va( DEFAULT_SAVE_DIRECTORY "%s*.sav", s ), true, true ); // lookup only in gamedir
if( !t ) return false;
COM_FileBase( t->filenames[0], matchbuf );
COM_FileBase( t->filenames[0], matchbuf, sizeof( matchbuf ));
if( completedname && length )
Q_strncpy( completedname, matchbuf, length );
if( t->numfilenames == 1 ) return true;
@@ -381,7 +381,7 @@ qboolean Cmd_GetSavesList( const char *s, char *completedname, int length )
if( Q_stricmp( COM_FileExtension( t->filenames[i] ), "sav" ))
continue;
COM_FileBase( t->filenames[i], matchbuf );
COM_FileBase( t->filenames[i], matchbuf, sizeof( matchbuf ));
Con_Printf( "%16s\n", matchbuf );
numsaves++;
}
@@ -418,7 +418,7 @@ qboolean Cmd_GetConfigList( const char *s, char *completedname, int length )
t = FS_Search( va( "%s*.cfg", s ), true, false );
if( !t ) return false;
COM_FileBase( t->filenames[0], matchbuf );
COM_FileBase( t->filenames[0], matchbuf, sizeof( matchbuf ));
if( completedname && length )
Q_strncpy( completedname, matchbuf, length );
if( t->numfilenames == 1 ) return true;
@@ -428,7 +428,7 @@ qboolean Cmd_GetConfigList( const char *s, char *completedname, int length )
if( Q_stricmp( COM_FileExtension( t->filenames[i] ), "cfg" ))
continue;
COM_FileBase( t->filenames[i], matchbuf );
COM_FileBase( t->filenames[i], matchbuf, sizeof( matchbuf ));
Con_Printf( "%16s\n", matchbuf );
numconfigs++;
}
@@ -518,7 +518,7 @@ qboolean Cmd_GetItemsList( const char *s, char *completedname, int length )
t = FS_Search( va( "%s/%s*.txt", clgame.itemspath, s ), true, false );
if( !t ) return false;
COM_FileBase( t->filenames[0], matchbuf );
COM_FileBase( t->filenames[0], matchbuf, sizeof( matchbuf ));
if( completedname && length )
Q_strncpy( completedname, matchbuf, length );
if( t->numfilenames == 1 ) return true;
@@ -528,7 +528,7 @@ qboolean Cmd_GetItemsList( const char *s, char *completedname, int length )
if( Q_stricmp( COM_FileExtension( t->filenames[i] ), "txt" ))
continue;
COM_FileBase( t->filenames[i], matchbuf );
COM_FileBase( t->filenames[i], matchbuf, sizeof( matchbuf ));
Con_Printf( "%16s\n", matchbuf );
numitems++;
}
@@ -570,7 +570,7 @@ qboolean Cmd_GetKeysList( const char *s, char *completedname, int length )
const char *keyname = Key_KeynumToString( i );
if(( *s == '*' ) || !Q_strnicmp( keyname, s, len))
Q_strcpy( keys[numkeys++], keyname );
Q_strncpy( keys[numkeys++], keyname, sizeof( keys[0] ));
}
if( !numkeys ) return false;
@@ -710,7 +710,7 @@ qboolean Cmd_GetCustomList( const char *s, char *completedname, int length )
t = FS_Search( va( "%s*.hpk", s ), true, false );
if( !t ) return false;
COM_FileBase( t->filenames[0], matchbuf );
COM_FileBase( t->filenames[0], matchbuf, sizeof( matchbuf ));
if( completedname && length )
Q_strncpy( completedname, matchbuf, length );
if( t->numfilenames == 1 ) return true;
@@ -720,7 +720,7 @@ qboolean Cmd_GetCustomList( const char *s, char *completedname, int length )
if( Q_stricmp( COM_FileExtension( t->filenames[i] ), "hpk" ))
continue;
COM_FileBase( t->filenames[i], matchbuf );
COM_FileBase( t->filenames[i], matchbuf, sizeof( matchbuf ));
Con_Printf( "%16s\n", matchbuf );
numitems++;
}
@@ -764,7 +764,7 @@ qboolean Cmd_GetGamesList( const char *s, char *completedname, int length )
for( i = 0, numgamedirs = 0; i < FI->numgames; i++ )
{
if(( *s == '*' ) || !Q_strnicmp( FI->games[i]->gamefolder, s, len))
Q_strcpy( gamedirs[numgamedirs++], FI->games[i]->gamefolder );
Q_strncpy( gamedirs[numgamedirs++], FI->games[i]->gamefolder, sizeof( gamedirs[0] ));
}
if( !numgamedirs ) return false;
@@ -825,7 +825,7 @@ qboolean Cmd_GetCDList( const char *s, char *completedname, int length )
for( i = 0, numcdcommands = 0; i < 8; i++ )
{
if(( *s == '*' ) || !Q_strnicmp( cd_command[i], s, len))
Q_strcpy( cdcommands[numcdcommands++], cd_command[i] );
Q_strncpy( cdcommands[numcdcommands++], cd_command[i], sizeof( cdcommands[0] ));
}
if( !numcdcommands ) return false;
@@ -860,6 +860,7 @@ qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir )
byte buf[MAX_SYSPATH];
string mpfilter;
char *buffer;
size_t buffersize;
string result;
int i, size;
search_t *t;
@@ -882,7 +883,8 @@ qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir )
return false;
}
buffer = Mem_Calloc( host.mempool, t->numfilenames * 2 * sizeof( result ));
buffersize = t->numfilenames * 2 * sizeof( result );
buffer = Mem_Calloc( host.mempool, buffersize );
use_filter = COM_CheckStringEmpty( GI->mp_filter ) ? true : false;
for( i = 0; i < t->numfilenames; i++ )
@@ -898,31 +900,31 @@ qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir )
continue;
f = FS_Open( t->filenames[i], "rb", onlyingamedir );
COM_FileBase( t->filenames[i], mapname );
COM_FileBase( t->filenames[i], mapname, sizeof( mapname ));
if( f )
{
int num_spawnpoints = 0;
dheader_t *header;
dlump_t entities;
memset( buf, 0, MAX_SYSPATH );
FS_Read( f, buf, MAX_SYSPATH );
header = (dheader_t *)buf;
// check all the lumps and some other errors
if( !Mod_TestBmodelLumps( t->filenames[i], buf, true ))
if( !Mod_TestBmodelLumps( f, t->filenames[i], buf, true, &entities ))
{
FS_Close( f );
continue;
}
// after call Mod_TestBmodelLumps we gurantee what map is valid
lumpofs = header->lumps[LUMP_ENTITIES].fileofs;
lumplen = header->lumps[LUMP_ENTITIES].filelen;
lumpofs = entities.fileofs;
lumplen = entities.filelen;
Q_strncpy( entfilename, t->filenames[i], sizeof( entfilename ));
COM_StripExtension( entfilename );
COM_DefaultExtension( entfilename, ".ent" );
COM_ReplaceExtension( entfilename, ".ent", sizeof( entfilename ));
ents = (char *)FS_LoadFile( entfilename, NULL, true );
if( !ents && lumplen >= 10 )
@@ -967,8 +969,8 @@ qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir )
if( num_spawnpoints )
{
// format: mapname "maptitle"\n
Q_sprintf( result, "%s \"%s\"\n", mapname, message );
Q_strcat( buffer, result ); // add new string
Q_snprintf( result, sizeof( result ), "%s \"%s\"\n", mapname, message );
Q_strncat( buffer, result, buffersize ); // add new string
}
}
}
@@ -1027,6 +1029,7 @@ autocomplete_list_t cmd_list[] =
{ "play", 1, Cmd_GetSoundList },
{ "map", 1, Cmd_GetMapList },
{ "cd", 1, Cmd_GetCDList },
{ "mp3", 1, Cmd_GetCDList },
{ NULL }, // termiantor
};
@@ -1039,10 +1042,14 @@ compare first argument with string
*/
static qboolean Cmd_CheckName( const char *name )
{
if( !Q_stricmp( Cmd_Argv( 0 ), name ))
const char *p = Cmd_Argv( 0 );
if( !Q_stricmp( p, name ))
return true;
if( !Q_stricmp( Cmd_Argv( 0 ), va( "\\%s", name )))
if( p[0] == '\\' && !Q_stricmp( &p[1], name ))
return true;
return false;
}
@@ -1324,8 +1331,9 @@ static void Cmd_WriteHelp(const char *name, const char *unused, const char *desc
{
int length;
if( !desc || !Q_strcmp( desc, "" ))
if( !COM_CheckString( desc ))
return; // ignore fantom cmds
if( name[0] == '+' || name[0] == '-' )
return; // key bindings
@@ -1354,7 +1362,6 @@ void Host_FinalizeConfig( file_t *f, const char *config )
FS_Close( f );
FS_Delete( backup );
FS_Rename( config, backup );
FS_Delete( config );
FS_Rename( newcfg, config );
}
@@ -1421,8 +1428,6 @@ void GAME_EXPORT Host_WriteServerConfig( const char *name )
Q_snprintf( newconfigfile, MAX_STRING, "%s.new", name );
SV_InitGameProgs(); // collect user variables
// FIXME: move this out until menu parser is done
CSCR_LoadDefaultCVars( "settings.scr" );
@@ -1439,8 +1444,6 @@ void GAME_EXPORT Host_WriteServerConfig( const char *name )
Host_FinalizeConfig( f, name );
}
else Con_DPrintf( S_ERROR "Couldn't write %s.\n", name );
SV_FreeGameProgs(); // release progs with all variables
}
/*

View File

@@ -12,7 +12,9 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include "common.h"
@@ -23,15 +25,16 @@ Sys_Crash
Crash handler, called from system
================
*/
#if XASH_CRASHHANDLER == CRASHHANDLER_DBGHELP || XASH_CRASHHANDLER == CRASHHANDLER_WIN32
#if XASH_WIN32
#if XASH_CRASHHANDLER == CRASHHANDLER_DBGHELP
#if DBGHELP
#pragma comment( lib, "dbghelp" )
#include <winnt.h>
#include <dbghelp.h>
#include <psapi.h>
#include <time.h>
#ifndef XASH_SDL
typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR;
@@ -187,7 +190,65 @@ static void Sys_StackTrace( PEXCEPTION_POINTERS pInfo )
SymCleanup( process );
}
#endif /* XASH_CRASHHANDLER == CRASHHANDLER_DBGHELP */
static void Sys_GetProcessName( char *processName, size_t bufferSize )
{
char fullpath[MAX_PATH];
GetModuleBaseName( GetCurrentProcess(), NULL, fullpath, sizeof( fullpath ) - 1 );
COM_FileBase( fullpath, processName, bufferSize );
}
static void Sys_GetMinidumpFileName( const char *processName, char *mdmpFileName, size_t bufferSize )
{
time_t currentUtcTime = time( NULL );
struct tm *currentLocalTime = localtime( &currentUtcTime );
Q_snprintf( mdmpFileName, bufferSize, "%s_%s_crash_%d%.2d%.2d_%.2d%.2d%.2d.mdmp",
processName,
Q_buildcommit(),
currentLocalTime->tm_year + 1900,
currentLocalTime->tm_mon + 1,
currentLocalTime->tm_mday,
currentLocalTime->tm_hour,
currentLocalTime->tm_min,
currentLocalTime->tm_sec);
}
static qboolean Sys_WriteMinidump(PEXCEPTION_POINTERS exceptionInfo, MINIDUMP_TYPE minidumpType)
{
HRESULT errorCode;
string processName;
string mdmpFileName;
MINIDUMP_EXCEPTION_INFORMATION minidumpInfo;
Sys_GetProcessName( processName, sizeof( processName ));
Sys_GetMinidumpFileName( processName, mdmpFileName, sizeof( mdmpFileName ));
SetLastError( NOERROR );
HANDLE fileHandle = CreateFile(
mdmpFileName, GENERIC_WRITE, FILE_SHARE_WRITE,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
errorCode = HRESULT_FROM_WIN32( GetLastError( ));
if( !SUCCEEDED( errorCode )) {
CloseHandle( fileHandle );
return false;
}
minidumpInfo.ThreadId = GetCurrentThreadId();
minidumpInfo.ExceptionPointers = exceptionInfo;
minidumpInfo.ClientPointers = FALSE;
qboolean status = MiniDumpWriteDump(
GetCurrentProcess(), GetCurrentProcessId(), fileHandle,
minidumpType, &minidumpInfo, NULL, NULL);
CloseHandle( fileHandle );
return status;
}
#endif /* DBGHELP */
LPTOP_LEVEL_EXCEPTION_FILTER oldFilter;
static long _stdcall Sys_Crash( PEXCEPTION_POINTERS pInfo )
@@ -198,7 +259,7 @@ static long _stdcall Sys_Crash( PEXCEPTION_POINTERS pInfo )
// check to avoid recursive call
host.crashed = true;
#if XASH_CRASHHANDLER == CRASHHANDLER_DBGHELP
#if DBGHELP
Sys_StackTrace( pInfo );
#else
Sys_Warn( "Sys_Crash: call %p at address %p", pInfo->ExceptionRecord->ExceptionAddress, pInfo->ExceptionRecord->ExceptionCode );
@@ -208,6 +269,26 @@ static long _stdcall Sys_Crash( PEXCEPTION_POINTERS pInfo )
CL_Crashed(); // tell client about crash
else host.status = HOST_CRASHED;
#if DBGHELP
if( Sys_CheckParm( "-minidumps" ))
{
int minidumpFlags = (
MiniDumpWithDataSegs |
MiniDumpWithCodeSegs |
MiniDumpWithHandleData |
MiniDumpWithFullMemory |
MiniDumpWithFullMemoryInfo |
MiniDumpWithIndirectlyReferencedMemory |
MiniDumpWithThreadInfo |
MiniDumpWithModuleHeaders);
if( !Sys_WriteMinidump( pInfo, (MINIDUMP_TYPE)minidumpFlags )) {
// fallback method, create minidump with minimal info in it
Sys_WriteMinidump( pInfo, MiniDumpWithDataSegs );
}
}
#endif
if( host_developer.value <= 0 )
{
// no reason to call debugger in release build - just exit
@@ -237,39 +318,21 @@ void Sys_RestoreCrashHandler( void )
if( oldFilter ) SetUnhandledExceptionFilter( oldFilter );
}
#elif XASH_CRASHHANDLER == CRASHHANDLER_UCONTEXT
#elif XASH_FREEBSD || XASH_NETBSD || XASH_OPENBSD || XASH_ANDROID || XASH_LINUX
// Posix signal handler
#include "library.h"
#if XASH_FREEBSD || XASH_NETBSD || XASH_OPENBSD || XASH_ANDROID || XASH_LINUX
#define HAVE_UCONTEXT_H 1
#endif
#ifdef HAVE_UCONTEXT_H
#include <ucontext.h>
#endif
#include <signal.h>
#include <sys/mman.h>
#include "library.h"
#ifdef XASH_DYNAMIC_DLADDR
static int d_dladdr( void *sym, Dl_info *info )
{
static int (*dladdr_real) ( void *sym, Dl_info *info );
#define STACK_BACKTRACE_STR "Stack backtrace:\n"
#define STACK_DUMP_STR "Stack dump:\n"
if( !dladdr_real )
dladdr_real = dlsym( (void*)(size_t)(-1), "dladdr" );
#define STACK_BACKTRACE_STR_LEN ( sizeof( STACK_BACKTRACE_STR ) - 1 )
#define STACK_DUMP_STR_LEN ( sizeof( STACK_DUMP_STR ) - 1 )
#define ALIGN( x, y ) (((uintptr_t) ( x ) + (( y ) - 1 )) & ~(( y ) - 1 ))
memset( info, 0, sizeof( *info ) );
if( !dladdr_real )
return -1;
return dladdr_real( sym, info );
}
#define dladdr d_dladdr
#endif
static struct sigaction oldFilter;
static int Sys_PrintFrame( char *buf, int len, int i, void *addr )
{
@@ -282,28 +345,18 @@ static int Sys_PrintFrame( char *buf, int len, int i, void *addr )
if( dlinfo.dli_sname )
return Q_snprintf( buf, len, "%2d: %p <%s+%lu> (%s)\n", i, addr, dlinfo.dli_sname,
(unsigned long)addr - (unsigned long)dlinfo.dli_saddr, dlinfo.dli_fname ); // print symbol, module and address
else
return Q_snprintf( buf, len, "%2d: %p (%s)\n", i, addr, dlinfo.dli_fname ); // print module and address
return Q_snprintf( buf, len, "%2d: %p (%s)\n", i, addr, dlinfo.dli_fname ); // print module and address
}
else
return Q_snprintf( buf, len, "%2d: %p\n", i, addr ); // print only address
return Q_snprintf( buf, len, "%2d: %p\n", i, addr ); // print only address
}
struct sigaction oldFilter;
#define STACK_BACKTRACE_STR "Stack backtrace:\n"
#define STACK_DUMP_STR "Stack dump:\n"
#define STACK_BACKTRACE_STR_LEN (sizeof( STACK_BACKTRACE_STR ) - 1)
#define STACK_DUMP_STR_LEN (sizeof( STACK_DUMP_STR ) - 1)
#define ALIGN( x, y ) (((uintptr_t) (x) + ((y)-1)) & ~((y)-1))
static void Sys_Crash( int signal, siginfo_t *si, void *context)
{
void *pc = NULL, **bp = NULL, **sp = NULL; // this must be set for every OS!
char message[8192];
int len, logfd, i = 0;
size_t pagesize;
#if XASH_OPENBSD
struct sigcontext *ucontext = (struct sigcontext*)context;
@@ -335,9 +388,9 @@ static void Sys_Crash( int signal, siginfo_t *si, void *context)
bp = (void**)ucontext->uc_mcontext.mc_ebp;
sp = (void**)ucontext->uc_mcontext.mc_esp;
#elif XASH_NETBSD
pc = (void*)ucontext->uc_mcontext.__gregs[REG_EIP];
bp = (void**)ucontext->uc_mcontext.__gregs[REG_EBP];
sp = (void**)ucontext->uc_mcontext.__gregs[REG_ESP];
pc = (void*)ucontext->uc_mcontext.__gregs[_REG_EIP];
bp = (void**)ucontext->uc_mcontext.__gregs[_REG_EBP];
sp = (void**)ucontext->uc_mcontext.__gregs[_REG_ESP];
#elif XASH_OPENBSD
pc = (void*)ucontext->sc_eip;
bp = (void**)ucontext->sc_ebp;
@@ -358,10 +411,10 @@ static void Sys_Crash( int signal, siginfo_t *si, void *context)
#endif
// safe actions first, stack and memory may be corrupted
len = Q_snprintf( message, sizeof( message ), "Ver: %s %s (build %i-%s, %s-%s)\n",
XASH_ENGINE_NAME, XASH_VERSION, Q_buildnum(), Q_buildcommit(), Q_buildos(), Q_buildarch() );
len = Q_snprintf( message, sizeof( message ), "Ver: " XASH_ENGINE_NAME " " XASH_VERSION " (build %i-%s, %s-%s)\n",
Q_buildnum(), Q_buildcommit(), Q_buildos(), Q_buildarch() );
#if !XASH_BSD
#if !XASH_FREEBSD && !XASH_NETBSD && !XASH_OPENBSD
len += Q_snprintf( message + len, sizeof( message ) - len, "Crash: signal %d errno %d with code %d at %p %p\n", signal, si->si_errno, si->si_code, si->si_addr, si->si_ptr );
#else
len += Q_snprintf( message + len, sizeof( message ) - len, "Crash: signal %d errno %d with code %d at %p\n", signal, si->si_errno, si->si_code, si->si_addr );
@@ -380,6 +433,7 @@ static void Sys_Crash( int signal, siginfo_t *si, void *context)
if( pc && bp && sp )
{
size_t pagesize = sysconf( _SC_PAGESIZE );
// try to print backtrace
write( STDERR_FILENO, STACK_BACKTRACE_STR, STACK_BACKTRACE_STR_LEN );
write( logfd, STACK_BACKTRACE_STR, STACK_BACKTRACE_STR_LEN );
@@ -447,7 +501,7 @@ static void Sys_Crash( int signal, siginfo_t *si, void *context)
void Sys_SetupCrashHandler( void )
{
struct sigaction act;
struct sigaction act = { 0 };
act.sa_sigaction = Sys_Crash;
act.sa_flags = SA_SIGINFO | SA_ONSTACK;
sigaction( SIGSEGV, &act, &oldFilter );
@@ -464,7 +518,7 @@ void Sys_RestoreCrashHandler( void )
sigaction( SIGILL, &oldFilter, NULL );
}
#elif XASH_CRASHHANDLER == CRASHHANDLER_NULL
#else
void Sys_SetupCrashHandler( void )
{

View File

@@ -17,9 +17,23 @@ GNU General Public License for more details.
#include "custom.h"
#include "ref_common.h"
qboolean CustomDecal_Validate( void *raw, int nFileSize )
static rgbdata_t *CustomDecal_LoadImage( const char *path, void *raw, int size )
{
rgbdata_t *test = FS_LoadImage( "#logo.bmp", raw, nFileSize );
const char *testname;
// this way we limit file types
if( !Q_stricmp( COM_FileExtension( path ), "png" ))
testname = "#logo.png";
else testname = "#logo.bmp";
Image_SetForceFlags( IL_LOAD_PLAYER_DECAL );
return FS_LoadImage( testname, raw, size );
}
static qboolean CustomDecal_Validate( const char *path, void *raw, int nFileSize )
{
rgbdata_t *test = CustomDecal_LoadImage( path, raw, nFileSize );
if( test )
{
@@ -97,21 +111,25 @@ qboolean COM_CreateCustomization( customization_t *pListHead, resource_t *pResou
{
pCust->resource.playernum = playernumber;
if( CustomDecal_Validate( pCust->pBuffer, pResource->nDownloadSize ))
if( CustomDecal_Validate( pResource->szFileName, pCust->pBuffer, pResource->nDownloadSize ))
{
if( !FBitSet( flags, FCUST_IGNOREINIT ))
{
if( pResource->nDownloadSize >= (1 * 1024) && pResource->nDownloadSize <= ( 16 * 1024 ))
if( pResource->nDownloadSize >= (1 * 1024) && pResource->nDownloadSize <= ( 128 * 1024 ))
{
pCust->bTranslated = true;
pCust->nUserData1 = 0;
pCust->nUserData2 = 1;
if( !FBitSet( flags, FCUST_WIPEDATA ))
pCust->pInfo = FS_LoadImage( "#logo.bmp", pCust->pBuffer, pCust->resource.nDownloadSize );
pCust->pInfo = CustomDecal_LoadImage( pResource->szFileName, pCust->pBuffer, pCust->resource.nDownloadSize );
else pCust->pInfo = NULL;
if( nLumps ) *nLumps = 1;
}
else
{
Con_Printf( S_WARN "Ignoring custom decal \"%s\": wrong size (%i bytes)\n", pResource->szFileName, pResource->nDownloadSize );
}
}
}
}

View File

@@ -19,9 +19,36 @@ GNU General Public License for more details.
#include "eiface.h" // ARRAYSIZE
convar_t *cvar_vars = NULL; // head of list
convar_t *cmd_scripting;
CVAR_DEFINE_AUTO( cmd_scripting, "0", FCVAR_ARCHIVE|FCVAR_PRIVILEGED, "enable simple condition checking and variable operations" );
CVAR_DEFINE_AUTO( cl_filterstuffcmd, "0", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "filter commands coming from server" );
#ifdef HACKS_RELATED_HLMODS
typedef struct cvar_filter_quirks_s
{
const char *gamedir; // gamedir to enable for
const char *cvars; // list of cvars should be excluded from filter
} cvar_filter_quirks_t;
static cvar_filter_quirks_t cvar_filter_quirks[] =
{
// EXAMPLE:
//{
// "valve",
// "test;test1;test100"
//},
{
"ricochet",
"r_drawviewmodel",
},
{
"dod",
"cl_dodmusic" // Day of Defeat Beta 1.3 cvar
},
};
static cvar_filter_quirks_t *cvar_active_filter_quirks = NULL;
#endif
CVAR_DEFINE_AUTO( cl_filterstuffcmd, "1", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "filter commands coming from server" );
/*
============
@@ -72,10 +99,16 @@ Cvar_BuildAutoDescription
build cvar auto description that based on the setup flags
============
*/
const char *Cvar_BuildAutoDescription( int flags )
const char *Cvar_BuildAutoDescription( const char *szName, int flags )
{
static char desc[256];
if( FBitSet( flags, FCVAR_GLCONFIG ))
{
Q_snprintf( desc, sizeof( desc ), CVAR_GLCONFIG_DESCRIPTION, szName );
return desc;
}
desc[0] = '\0';
if( FBitSet( flags, FCVAR_EXTDLL ))
@@ -178,7 +211,7 @@ const char *Cvar_ValidateString( convar_t *var, const char *value )
int len = 0;
// step through the string, only copying back in characters that are printable
while( *pszValue && len < MAX_STRING )
while( *pszValue && len < ( MAX_STRING - 1 ))
{
if( ((byte)*pszValue) < 32 )
{
@@ -220,6 +253,24 @@ const char *Cvar_ValidateString( convar_t *var, const char *value )
return pszValue;
}
/*
============
Cvar_ValidateVarName
============
*/
static qboolean Cvar_ValidateVarName( const char *s, qboolean isvalue )
{
if( !s )
return false;
if( Q_strchr( s, '\\' ) && !isvalue )
return false;
if( Q_strchr( s, '\"' ))
return false;
if( Q_strchr( s, ';' ) && !isvalue )
return false;
return true;
}
/*
============
Cvar_UnlinkVar
@@ -368,7 +419,7 @@ convar_t *Cvar_Get( const char *name, const char *value, int flags, const char *
// which executed from the config file. So we don't need to
// change value here: we *already* have actual value from config.
// in other cases we need to rewrite them
if( Q_strcmp( var->desc, "" ))
if( COM_CheckStringEmpty( var->desc ))
{
// directly set value
freestring( var->string );
@@ -428,6 +479,23 @@ convar_t *Cvar_Get( const char *name, const char *value, int flags, const char *
return var;
}
/*
============
Cvar_Getf
============
*/
convar_t *Cvar_Getf( const char *var_name, int flags, const char *description, const char *format, ... )
{
char value[MAX_VA_STRING];
va_list args;
va_start( args, format );
Q_vsnprintf( value, sizeof( value ), format, args );
va_end( args );
return Cvar_Get( var_name, value, flags, description );
}
/*
============
Cvar_RegisterVariable
@@ -495,6 +563,113 @@ void Cvar_RegisterVariable( convar_t *var )
#endif
}
/*
============
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;
if( !Cvar_ValidateVarName( var_name, false ))
{
Con_DPrintf( S_ERROR "Invalid cvar name string: %s\n", var_name );
return NULL;
}
var = Cvar_FindVar( var_name );
if( !var )
{
// if cvar not found, create it
return Cvar_Get( var_name, value, FCVAR_USER_CREATED, NULL );
}
else
{
if( !Cmd_CurrentCommandIsPrivileged( ))
{
if( FBitSet( var->flags, FCVAR_PRIVILEGED ))
{
Con_Printf( "%s is priveleged.\n", var->name );
return var;
}
if( cl_filterstuffcmd.value > 0.0f && FBitSet( var->flags, FCVAR_FILTERABLE ))
{
Con_Printf( "%s is filterable.\n", var->name );
return var;
}
}
}
// use this check to prevent acessing for unexisting fields
// for cvar_t: latched_string, description, etc
dll_variable = FBitSet( var->flags, FCVAR_EXTDLL );
// check value
if( !value )
{
if( !FBitSet( var->flags, FCVAR_EXTENDED|FCVAR_ALLOCATED ))
{
Con_Printf( "%s has no default value and can't be reset.\n", var->name );
return var;
}
if( dll_variable )
value = "0";
else
value = var->def_string; // reset to default value
}
if( !Q_strcmp( value, var->string ))
return var;
// any latched values not allowed for game cvars
if( dll_variable )
force = true;
if( !force )
{
if( FBitSet( var->flags, FCVAR_READ_ONLY ))
{
Con_Printf( "%s is read-only.\n", var->name );
return var;
}
if( FBitSet( var->flags, FCVAR_CHEAT ) && !host.allow_cheats )
{
Con_Printf( "%s is cheat protected.\n", var->name );
return var;
}
// just tell user about deferred changes
if( FBitSet( var->flags, FCVAR_LATCH ) && ( SV_Active() || CL_Active( )))
Con_Printf( "%s will be changed upon restarting.\n", var->name );
}
pszValue = Cvar_ValidateString( var, value );
// nothing to change
if( !Q_strcmp( pszValue, var->string ))
return var;
// fill it cls.userinfo, svs.serverinfo
if( !Cvar_UpdateInfo( var, pszValue, true ))
return var;
// and finally changed the cvar itself
freestring( var->string );
var->string = copystring( pszValue );
var->value = Q_atof( var->string );
// tell engine about changes
Cvar_Changed( var );
return var;
}
/*
============
Cvar_DirectSet
@@ -506,18 +681,18 @@ void Cvar_DirectSet( convar_t *var, const char *value )
{
const char *pszValue;
if( !var ) return; // ???
if( unlikely( !var )) return; // ???
// lookup for registration
if( CVAR_CHECK_SENTINEL( var ) || ( var->next == NULL && !FBitSet( var->flags, FCVAR_EXTENDED|FCVAR_ALLOCATED )))
if( unlikely( CVAR_CHECK_SENTINEL( var ) || ( var->next == NULL && !FBitSet( var->flags, FCVAR_EXTENDED|FCVAR_ALLOCATED ))))
{
// need to registering cvar fisrt
Cvar_RegisterVariable( var ); // ok, register it
}
// lookup for registration again
if( var != Cvar_FindVar( var->name ))
return; // how this possible?
// lookup for registration again
if( var != Cvar_FindVar( var->name ))
return; // how this possible?
}
if( FBitSet( var->flags, FCVAR_READ_ONLY ))
{
@@ -777,6 +952,39 @@ static qboolean Cvar_ShouldSetCvar( convar_t *v, qboolean isPrivileged )
if( cl_filterstuffcmd.value <= 0.0f )
return true;
#ifdef HACKS_RELATED_HLMODS
// check if game-specific filter exceptions should be applied
// TODO: for cmd exceptions, make generic function
if( cvar_active_filter_quirks )
{
const char *cur, *next;
cur = cvar_active_filter_quirks->cvars;
next = Q_strchr( cur, ';' );
// TODO: implement Q_strchrnul
while( cur && *cur )
{
size_t len = next ? next - cur : Q_strlen( cur );
// found, quit
if( !Q_strnicmp( cur, v->name, len ))
return true;
if( next )
{
cur = next + 1;
next = Q_strchr( cur, ';' );
}
else
{
// stop
cur = NULL;
}
}
}
#endif
if( FBitSet( v->flags, FCVAR_FILTERABLE ))
return false;
@@ -840,8 +1048,6 @@ qboolean Cvar_CommandWithPrivilegeCheck( convar_t *v, qboolean isPrivileged )
else
{
Cvar_DirectSet( v, Cmd_Argv( 1 ));
if( host.apply_game_config )
host.sv_cvars_restored++;
return true;
}
}
@@ -884,7 +1090,41 @@ void Cvar_Toggle_f( void )
v = !Cvar_VariableInteger( Cmd_Argv( 1 ));
Cvar_Set( Cmd_Argv( 1 ), va( "%i", v ));
Cvar_Set( Cmd_Argv( 1 ), v ? "1" : "0" );
}
/*
============
Cvar_Set_f
Allows setting and defining of arbitrary cvars from console, even if they
weren't declared in C code.
============
*/
void Cvar_Set_f( void )
{
int i, c, l = 0, len;
char combined[MAX_CMD_TOKENS];
c = Cmd_Argc();
if( c < 3 )
{
Msg( S_USAGE "set <variable> <value>\n" );
return;
}
combined[0] = 0;
for( i = 2; i < c; i++ )
{
len = Q_strlen( Cmd_Argv(i) + 1 );
if( l + len >= MAX_CMD_TOKENS - 2 )
break;
Q_strncat( combined, Cmd_Argv( i ), sizeof( combined ));
if( i != c-1 ) Q_strncat( combined, " ", sizeof( combined ));
l += len;
}
Cvar_Set2( Cmd_Argv( 1 ), combined );
}
/*
@@ -932,7 +1172,6 @@ void Cvar_List_f( void )
{
convar_t *var;
const char *match = NULL;
char *value;
int count = 0;
size_t matchlen = 0;
@@ -944,6 +1183,8 @@ void Cvar_List_f( void )
for( var = cvar_vars; var; var = var->next )
{
char value[MAX_VA_STRING];
if( var->name[0] == '@' )
continue; // never shows system cvars
@@ -951,12 +1192,12 @@ void Cvar_List_f( void )
continue;
if( Q_colorstr( var->string ))
value = va( "\"%s\"", var->string );
else value = va( "\"^2%s^7\"", var->string );
Q_snprintf( value, sizeof( value ), "\"%s\"", var->string );
else Q_snprintf( value, sizeof( value ), "\"^2%s^7\"", var->string );
if( FBitSet( var->flags, FCVAR_EXTENDED|FCVAR_ALLOCATED ))
Con_Printf( " %-*s %s ^3%s^7\n", 32, var->name, value, var->desc );
else Con_Printf( " %-*s %s ^3%s^7\n", 32, var->name, value, Cvar_BuildAutoDescription( var->flags ));
else Con_Printf( " %-*s %s ^3%s^7\n", 32, var->name, value, Cvar_BuildAutoDescription( var->name, var->flags ));
count++;
}
@@ -998,16 +1239,37 @@ Reads in all archived cvars
void Cvar_Init( void )
{
cvar_vars = NULL;
cmd_scripting = Cvar_Get( "cmd_scripting", "0", FCVAR_ARCHIVE|FCVAR_PRIVILEGED, "enable simple condition checking and variable operations" );
Cvar_RegisterVariable (&host_developer); // early registering for dev
cvar_active_filter_quirks = NULL;
Cvar_RegisterVariable( &cmd_scripting );
Cvar_RegisterVariable( &host_developer ); // early registering for dev
Cvar_RegisterVariable( &cl_filterstuffcmd );
Cmd_AddRestrictedCommand( "setgl", Cvar_SetGL_f, "change the value of a opengl variable" ); // OBSOLETE
Cmd_AddRestrictedCommand( "toggle", Cvar_Toggle_f, "toggles a console variable's values (use for more info)" );
Cmd_AddRestrictedCommand( "reset", Cvar_Reset_f, "reset any type variable to initial value" );
Cmd_AddCommand( "set", Cvar_Set_f, "create or change the value of a console variable" );
Cmd_AddCommand( "cvarlist", Cvar_List_f, "display all console variables beginning with the specified prefix" );
}
/*
============
Cvar_PostFSInit
============
*/
void Cvar_PostFSInit( void )
{
int i;
for( i = 0; i < ARRAYSIZE( cvar_filter_quirks ); i++ )
{
if( !Q_stricmp( cvar_filter_quirks[i].gamedir, GI->gamefolder ))
{
cvar_active_filter_quirks = &cvar_filter_quirks[i];
break;
}
}
}
#if XASH_ENGINE_TESTS
#include "tests.h"

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