Compare commits

...

945 Commits

Author SHA1 Message Date
SNMetamorph
ec5e9cb6e3 engine: client: send engine build information to masterserver 2024-06-10 20:53:59 +03:00
Alibek Omarov
f4b4546197 engine: temporarily fix loading studio models with split texture model 2024-06-10 14:57:00 +03:00
Alibek Omarov
f047749e61 engine: move studio model truncation into separate function, disable it by default 2024-06-10 13:34:02 +03:00
Alibek Omarov
87840ce91d engine: fix potential buffer overflow in Mod_StudioTexName
* Model names are 64 bytes wide, adding texture character means we needs 65 byte wide string.
* It never gets stored in memory anyway.
2024-06-10 13:28:01 +03:00
Alibek Omarov
bf31e9f634 engine: fix NO_ASAN macro usage with MSVC 2024-06-09 09:37:16 +03:00
Alibek Omarov
f86d84daed engine: platform: sdl: initialize window name string when building with old SDL 2024-06-09 09:16:45 +03:00
Alibek Omarov
41ed920d35 common: xash3d_types: fix build 2024-06-09 09:16:07 +03:00
Alibek Omarov
df23ddb545 engine: server: fix signed integer overflow in challenge generator 2024-06-09 07:05:24 +03:00
Alibek Omarov
767556ccad engine: temporarily disable ASan in MSG_WriteUBitLong (evil!) 2024-06-09 07:03:59 +03:00
Alibek Omarov
f9dab2ad19 engine: server: rename sv_allow_upload to sv_allowupload for compatibility 2024-06-09 07:02:50 +03:00
Alibek Omarov
66cb3a6120 engine: client: add room_off variable to toggle sound effects processing for GoldSrc compatibility
* Fixes Sven-Coop 4.8 client.
* Declare dsp_off deprecated.
2024-06-09 03:51:43 +03:00
Tuldok
7672a370da engine: Crashhandler support for Windows-on-ARM (arm/arm64) 2024-06-08 21:35:55 +03:00
Alibek Omarov
870e47ed03 engine: ensure character signness when checking for nonprintable characters 2024-06-07 22:22:13 +03:00
Alibek Omarov
32d4bdb80f engine: fix UTF-8 sequence input
Fixes: 2e0fc3e4c1 ("engine: client: do not repeatedly check cl_charset value, use generic Con_UtfProcessChar")
2024-06-07 22:16:32 +03:00
Alibek Omarov
929dfd2c71 mainui: update 2024-06-03 09:04:47 +03:00
Alibek Omarov
f437af6451 mainui: update 2024-06-03 07:57:10 +03:00
Alibek Omarov
413a0fb2e5 engine: client: improve accumulating rounding error, thanks @SNMetamorph for suggestion 2024-06-02 13:09:10 +03:00
Alibek Omarov
793adadb06 mainui: update 2024-06-02 12:51:30 +03:00
Alibek Omarov
999b43b89f engine: implement changing cursor type in gameui 2024-06-02 12:24:14 +03:00
Alibek Omarov
bd60c88c7d ref: soft: fix build with OpenMP under Visual Studio 2024-06-02 11:39:54 +03:00
Alibek Omarov
23b9a2eddf waf.bat: add checks for newer pythons, remove checks for pythons below 2.7 2024-06-02 11:39:54 +03:00
Alibek Omarov
0b57d97c8c vgui_support: update submodule 2024-06-02 11:35:57 +03:00
Alibek Omarov
6255293dd4 engine: fix using OpenMP PHS generation under Visual Studio 2024-06-02 10:34:10 +03:00
Alibek Omarov
04136d95a3 filesystem: fix build warning 2024-06-02 10:33:33 +03:00
Alibek Omarov
40aa29e42a ci: remove freebsd-13-2 task 2024-06-02 10:04:04 +03:00
Alibek Omarov
a709f30da9 engine: soundlib: libmpg: add wrappers on top of libc read & lseek in case they don't match internal mpg123 types
(we better migrate to upstream libmpg at some point)
2024-06-02 09:19:17 +03:00
Alibek Omarov
0796c14e79 engine: client: fix framerate depending player move 2024-06-02 04:15:17 +03:00
Alibek Omarov
a9c0a4be23 engine: server: add cvar to disable bandwidth test on server side 2024-06-01 05:27:35 +03:00
Alibek Omarov
3e1209d3a4 engine: client: do not rely on host.downloadcount when connecting to the server with HTTP enabled
* Replace cl.downloadUrl by cl.http_download
2024-06-01 04:30:21 +03:00
Alibek Omarov
caf14c1b7c engine: soundlib: libmpg: fix the inconsistent use of offset types in lseek() 2024-05-31 03:35:39 +03:00
Alibek Omarov
27f7d2c8d2 engine: common: ban few more executable types for COM_IsSafeFileToDownload 2024-05-31 00:43:28 +03:00
Alibek Omarov
8ee430eda2 engine: common: double check that resource starting with !MD5 doesn't have any extension 2024-05-31 00:42:44 +03:00
Alibek Omarov
484e4cb225 engine: common: net_ws: less verbose HTTP client, fix printing header size in case of an error 2024-05-31 00:07:14 +03:00
Alibek Omarov
b080ad9954 engine: moved link_t helpers to sv_world.c from world.c and made them static 2024-05-30 07:31:03 +03:00
Alibek Omarov
f6625d9188 engine: common: remove unused et_name array 2024-05-30 07:22:21 +03:00
Alibek Omarov
1eb2816bc4 engine: client: manually call FS_Rescan if we downloaded an archive while connecting to server 2024-05-30 06:48:17 +03:00
Alibek Omarov
077be5aaf3 engine: client: only strip DEFAULT_SOUNDPATH from t_sound resources 2024-05-30 06:47:46 +03:00
Alibek Omarov
d59875f114 engine: common: for automatic wad precache to work, we need to count the real wad usage on dedicated 2024-05-30 06:18:15 +03:00
Alibek Omarov
e89191ed39 engine: common: automatically precache wad files required by loaded map
Makes it easier to host server with multiplayer maps and broken .res files.
2024-05-30 05:58:41 +03:00
Alibek Omarov
ea21438637 engine: netchan: append .ztmp extension instead of replacing original extension
* so we don't send wrong file that has same name but different extension

* validate filename size so it won't get truncated in fragbuf_t
2024-05-30 04:50:58 +03:00
Alibek Omarov
0d2e8333e8 common: remove unused boneinfo.h header 2024-05-29 12:25:23 +03:00
Alibek Omarov
338399e622 engine: common: implement PHS calculation like in QuakeWorld/GoldSrc 2024-05-29 05:58:51 +03:00
Alibek Omarov
27cab8aad5 scripts: waifulib: compiler_optimizations: set HAVE_OPENMP=1 define if openmp feature was enabled during the build 2024-05-29 05:41:47 +03:00
Alibek Omarov
1545a49b4c engine: client: only allocate debug hulls polygons when they're requested
* Make the appropriate changes in ref_gl
2024-05-29 05:41:47 +03:00
Alibek Omarov
3ca15250e8 engine: common: use Mod_PointInLeaf in Mod_GetPVSForPoint instead of traversing nodes manually 2024-05-29 05:41:47 +03:00
Alibek Omarov
6cbac51731 engine: common: add function for compressing visdata 2024-05-29 05:41:47 +03:00
Alibek Omarov
e310c666b1 engine: common: add phs flag to Mod_FatPVS, unused currently 2024-05-29 05:41:47 +03:00
Alibek Omarov
677b0170aa engine: server: remove recalculating viewpoint for PVS hack, as it causes issues with inconsistency between real and "restored" view positions 2024-05-29 05:41:47 +03:00
Alibek Omarov
9150b770e4 engine: common: mod_bmodel: add function Mod_DecompressVisTo that will copy fat vis data into the provided buffer 2024-05-29 05:41:47 +03:00
Alibek Omarov
2ad6511c31 public: add Q_memor routine that binary OR's data from src to dst
Supposed to be compiled with optimizations enabled.
2024-05-29 05:41:33 +03:00
Alibek Omarov
0848f28d83 waf: upgrade to latest master 2024-05-26 19:32:14 +03:00
Alibek Omarov
5d9bc950ce wscript: do not load msvc manually, it will be loaded by compiler_{c,cxx} 2024-05-25 22:40:25 +03:00
Alibek Omarov
714da79395 mainui: update 2024-05-25 22:25:33 +03:00
Alibek Omarov
823fe9ebbd waf: upgrade to waf 2.1.1/waifu 1.3.0. Try to fix most optparse->argparse migration issues 2024-05-25 04:58:28 +03:00
Alibek Omarov
4bf72b5383 engine: forbid accessing cvars starting with con_ and scr_ through stufftext
Some stupid servers might mess up with console cvars values.
2024-05-25 02:26:42 +03:00
Alibek Omarov
51945f002b engine: server: check for invoker entity when filtering out host client during entities thinking 2024-05-23 02:06:54 +03:00
Alibek Omarov
bcca9387de engine: server: sv_pmove: always set FEV_NOTHOST for events coming from PMove (like GoldSrc) 2024-05-23 01:51:42 +03:00
Alibek Omarov
b8417fa46d ref: soft: search parent in both entity lists when drawing MOVETYPE_FOLLOW entities
Fixes the issue in Brutal Half-Life beta 2 with invisible scientist skin.

Fixes: 6862b14e59 ("ref: soft: only draw MOVETYPE_FOLLOW studio model if it's parent is visible")
2024-05-19 06:31:46 +03:00
Alibek Omarov
85b0699288 ref: gl: search parent in both entity lists when drawing MOVETYPE_FOLLOW entities
Fixes the issue in Brutal Half-Life beta 2 with invisible scientist skin.

Fixes: dc1d65f621 ("ref: gl: only draw MOVETYPE_FOLLOW studio model if it's parent is visible")
2024-05-19 06:29:22 +03:00
Alibek Omarov
6c03fb0226 engine: client: first attempt to use utflib to replace Con_UtfProcessCharForce calls 2024-05-15 05:25:53 +03:00
Alibek Omarov
a084dea07c public: add functions to convert from Unicode codepoints into CP1251 or CP1252 2024-05-15 05:07:18 +03:00
Alibek Omarov
2e0fc3e4c1 engine: client: do not repeatedly check cl_charset value, use generic Con_UtfProcessChar 2024-05-15 05:06:57 +03:00
Alibek Omarov
24f4d410ce filesystem: take FS_Read improvements from DarkPlaces and proper fix for buffer overflow 2024-05-15 03:43:02 +03:00
Alibek Omarov
052e0445ab engine: client: console: cleanup input buffer from line feed characters before pushing it to the console history 2024-05-15 03:08:22 +03:00
Alibek Omarov
758c908d5a public: add buffer size parameter to COM_RemoveLineFeed 2024-05-15 03:06:57 +03:00
Alibek Omarov
3917c2589d filesystem: fix buffer overflow in FS_Read when we pass single byte buffer to it with one character sitting in ungetc 2024-05-15 02:45:01 +03:00
Alibek Omarov
f4a77308ec engine: soundlib: fix possible buffer overflow in Sound_ConvertUpsample 2024-05-06 15:45:49 +03:00
Alibek Omarov
103b9724f9 scripts: waifulib: compiler_optimizations: fix linking OpenMP 2024-05-06 15:36:26 +03:00
Alibek Omarov
75a315ecf0 engine: client: add optional (compile time for now) setting to reconfigure engine to use 48kHz sounds 2024-05-06 15:10:34 +03:00
Alibek Omarov
63b3b9ef6d engine: client: fix missing upsampling for >32kHz sounds 2024-05-06 15:09:52 +03:00
Alibek Omarov
a6c2cfe89b engine: avoid constants in Q_strncpy third argument, where possible 2024-05-06 14:27:26 +03:00
Alibek Omarov
5120657386 engine: fix possible buffer overflow in S_StreamGetCurrentState 2024-05-06 06:53:22 +03:00
Alibek Omarov
e754de46d1 engine: client: fix buffer overflow in S_FindName 2024-05-06 06:42:47 +03:00
Alibek Omarov
5d718aa0d6 scripts: waifulib: compiler_optimizations: add flag for building with OpenMP (not used anywhere in the engine but let's keep it) 2024-05-06 06:42:15 +03:00
Alibek Omarov
55fcbc8880 engine: soundlib: implement linear interpolation in Sound_ResampleInternal
* split resampling into three functions
* added resampling using SDL_AudioCVT, it's slow, so isn't enabled by default
2024-05-06 06:41:23 +03:00
Alibek Omarov
e19aa001b2 engine: client: ref_common: slight refactoring, reorder ref_state_t 2024-05-06 01:59:50 +03:00
Alibek Omarov
b447ea9c18 engine: client: remove unused fields in client_static_t 2024-05-06 01:59:14 +03:00
Alibek Omarov
13274655d4 engine: client: sound: slight refactoring, removed unused s_listener.velocity 2024-05-06 01:30:06 +03:00
Alibek Omarov
3723ac60ef engine: client: s_mix: _inline -> static 2024-05-06 00:51:32 +03:00
Alibek Omarov
da578f47f1 engine: client: fix sounds being paused in menu and then blasted all at the same time in multiplayer 2024-05-06 00:41:38 +03:00
Alibek Omarov
433e7de686 engine: clean up unused soundlib flags, set SOUND_LOOPED flag on looped sounds 2024-05-05 06:16:57 +03:00
Alibek Omarov
e18e9ae2ea engine: platform: sdl: ignore keyboard events if text mode is active 2024-05-04 11:05:17 +03:00
Alibek Omarov
27d5123a61 mainui: update 2024-05-03 16:55:17 +03:00
Alibek Omarov
89b9f9ffe2 github: update SDL to 2.30.3 2024-05-03 16:04:13 +03:00
Alibek Omarov
a17b8aaa13 public: fix parameter name omitted error for older compilers 2024-05-03 16:01:24 +03:00
Alibek Omarov
e210969612 scripts: gha: build_linux: spew config.log on build failure 2024-05-03 15:57:26 +03:00
Alibek Omarov
1208356b92 ref: gl: gl2_shim: remove unused ALLOCA_H include 2024-05-03 15:53:57 +03:00
Alibek Omarov
d7cd74fe2f wscript: no need to pass PACKAGING into env 2024-05-03 15:45:20 +03:00
Alibek Omarov
31b63e9939 wscript: exclude executing large file test for PSVita 2024-05-03 15:44:35 +03:00
Alibek Omarov
b99c2c2df1 wscript: do not execute test for test for large files 2024-05-03 15:38:35 +03:00
Alibek Omarov
94d3eff9ce engine: host: fix build with Q_strchrnul returning const char * 2024-05-03 15:31:20 +03:00
Alibek Omarov
b78e9961c6 public: fix build on Windows
stristr doesn't exist actually
2024-05-03 15:30:42 +03:00
Alibek Omarov
b0704ca5d6 mainui: update 2024-05-03 06:38:21 +03:00
Alibek Omarov
31c0934108 engine: fix parsing -bugcomp flags, assume bugcomp flags only starts with alphabetic character 2024-05-03 06:28:48 +03:00
Alibek Omarov
37083c8aef ref: soft: mark sw_drawflat and sw_draworder as cheats 2024-05-01 00:52:45 +03:00
Alibek Omarov
af23b0c67b public: crtlib: refactoring with new macros, use system strlcpy/strlcat if possible 2024-04-30 02:20:14 +03:00
Alibek Omarov
a9e83fb9cf wscript: move std defining macros into libpublic's sdk_includes target, so we don't accidentally feed submodules our macros 2024-04-29 05:29:53 +03:00
Alibek Omarov
51126e1691 mainui: update 2024-04-29 05:28:41 +03:00
Alibek Omarov
dd410a2de5 engine: implement small Message Rewrite Facitility that allows to run mods that directly write internal GoldSrc messages 2024-04-28 06:59:18 +03:00
Alibek Omarov
7ccb0b5c02 public: make simple ctype functions inlined 2024-04-28 06:59:18 +03:00
Alibek Omarov
7f3e62e456 public: remove unneeded copy in Q_atov 2024-04-28 06:59:18 +03:00
Alibek Omarov
fcfc29d7ea public: fix variables types in COM_HashKey, they are all supposed to be unsigned integers 2024-04-28 06:59:18 +03:00
Alibek Omarov
2f3429a144 engine: common: base_cmd: use flexible array to store basecmd name 2024-04-28 06:59:18 +03:00
Alibek Omarov
20782693f4 engine: server: rename symbols for svs, sv and SV_DropClient to avoid AMXModX trying to acquire their pointers 2024-04-28 06:59:18 +03:00
Alibek Omarov
0cfb354374 common: add RENAME_SYMBOL macro that renames symbol for compatibility with nasty mods (also reformat this portion, while we're at it) 2024-04-28 06:59:18 +03:00
Alibek Omarov
9be5b7c6c9 engine: physint: empty-define ALLOC_CHECK if not defined by SDK, so this header can be freely moved to another SDK 2024-04-28 06:59:18 +03:00
Alibek Omarov
e7653d2ea6 engine: soundlib: fix searching for a RIFF/WAVE chunks in streams 2024-04-27 10:51:56 +03:00
Alibek Omarov
1494887e29 engine: soundlib: snd_wav: replace strncmp by IsFourCC helper function 2024-04-26 06:29:38 +03:00
Alibek Omarov
42dab2b1a5 engine: soundlib: snd_wav: attempt to fix misleading warning about truncated file 2024-04-26 06:25:18 +03:00
Alibek Omarov
36a0c1fb17 ref: if the entity is opaque, check the renderfx too, it might become translucent 2024-04-26 04:15:21 +03:00
Alibek Omarov
60c6767337 filesystem: copy absolute path to library in FS_FindLibrary for compatibility
Extend fullPath for longer absolute paths.
2024-04-22 04:02:46 +03:00
Alibek Omarov
75451cc7fa engine: client: print correct message names in legacymode 2024-04-22 04:02:46 +03:00
Alibek Omarov
db10035d9d engine: add GoldSrc protocol definitions 2024-04-22 04:02:46 +03:00
Alibek Omarov
de21d845ec engine: don't forget to put newline at the end of overflowed console message 2024-04-21 20:21:17 +03:00
Alibek Omarov
320f8466e6 engine: hpak: don't print error about missing custom.hpak in quiet mode 2024-04-21 20:05:37 +03:00
Alibek Omarov
f3208e95b2 engine: server: remove misleading message about interface version in case when GetEntityAPI2 has failed
Add message when GetEntityAPI was used instead
2024-04-21 20:05:34 +03:00
Alibek Omarov
ea34bc8652 engine: turn bugcomp into flags that can be enabled/disabled separately 2024-04-21 16:52:15 +03:00
Alibek Omarov
3daf014af8 wscript: always enable -Werror=implicit-function-declaration 2024-04-20 20:48:01 +03:00
Alibek Omarov
ca9d3d262a engine: common: net_encode: directly call MSG_ReadSBitLong for DT_TIMEWINDOW_*, don't do the multiplier check for DT_TIMEWINDOW_BIG 2024-04-20 20:48:01 +03:00
Alibek Omarov
a08f5e439d engine: common: net_encode: fix comparing DT_TIMEWINDOW_* fields
Fixes: 35783bcec2 ("engine: common: net_encode: fix inaccuracy in DT_TIMEWINDOW_* encoding")
2024-04-19 01:51:25 +03:00
Alibek Omarov
8f6771dff4 engine: common: zone: check that Mem_FindPool might return NULL (it can if Sys_Error was called inside of a Sys_Error) 2024-04-19 00:14:26 +03:00
Alibek Omarov
cd47c6b5b3 engine: common: zone: disallow migrating allocations from one pool to another, as this isn't practically used anywhere 2024-04-19 00:14:26 +03:00
Alibek Omarov
1f4f3d7fda engine: common: zone: remove mempool sentinels as pools aren't subject to buffer overflow or double free anymore 2024-04-19 00:14:26 +03:00
Alibek Omarov
e81b5144b3 engine: common: zone: use realloc for managing mem pools
rearrange data in memheader_s to avoid unnecessary paddings
2024-04-19 00:14:26 +03:00
Alibek Omarov
9ec1caed53 engine: common: zone: implement dummy Q_realloc for XASH_CUSTOM_SWAP 2024-04-19 00:14:26 +03:00
Alibek Omarov
ca3b4a9d7f engine: host: oops 2024-04-18 16:48:41 +03:00
Alibek Omarov
87ac217887 engine: common: net_encode: add bitmask operation to delta tests 2024-04-18 16:44:15 +03:00
Alibek Omarov
213650db8f engine: exit with non-zero return code if engine tests are failed 2024-04-18 16:36:18 +03:00
Alibek Omarov
ac46164a6e engine: common: net_encode: implement basic delta tests 2024-04-17 20:27:22 +03:00
Alibek Omarov
6d12d84e94 engine: common: net_encode: apply post_multiplier to integer fields, like GoldSrc does 2024-04-17 06:23:22 +03:00
Alibek Omarov
2a18cde60c engine: common: net_encode: fix applying integer clamp before multiplier
Without this fix, data still might overflow after applying multiplier
and potentially send incorrect data.
2024-04-17 06:16:44 +03:00
Alibek Omarov
35783bcec2 engine: common: net_encode: fix inaccuracy in DT_TIMEWINDOW_* encoding
By avoiding double rounding, we get more accurate time on client when timebase
gets rounded down and target time gets rounded up:

```
>>> round(123.1) - round(124.51)
-2
>>> round(123.1 - 124.51)
-1
```
2024-04-17 06:09:52 +03:00
Alibek Omarov
1677835b45 engine: common: simplify bit buffer operations
Yields a small performance boost
2024-04-08 07:24:53 +03:00
Alibek Omarov
2f2780cb1b ref: null: fix crashes 2024-04-08 07:23:56 +03:00
Alibek Omarov
95b134b5a6 ci: fix cirrus CI configuration file 2024-04-06 06:58:15 +03:00
Alibek Omarov
f60e856f35 engine: server: replace useless call to SV_Serverinfo to a direct access 2024-04-06 06:58:15 +03:00
Alibek Omarov
2ec0d25d85 Documentation: add note about environment variables 2024-04-05 20:15:38 +03:00
Alibek Omarov
fcd0982524 engine: server: free 64-bit string pool last when unloading library 2024-04-05 19:45:24 +03:00
Alibek Omarov
6881ee742d engine: server: fix incorrect NULL check in pfnCvar_RegisterServerVariable 2024-04-05 18:45:15 +03:00
Alibek Omarov
f070bbef3c engine: server: make EDICT_NUM inlined 2024-04-04 20:42:25 +03:00
Alibek Omarov
dd8c66d90e engine: common: fix possible NULL dereference in LZSS_Compress 2024-04-04 20:42:25 +03:00
Alibek Omarov
f995d055b5 filesystem: fix possible NULL dereference 2024-04-04 20:42:25 +03:00
Alibek Omarov
fed65dd497 engine: imagelib: fix possible NULL dereference 2024-04-04 20:42:25 +03:00
Alibek Omarov
c896425ad9 engine: server: make changelevel commands compatible with GoldSrc 2024-04-04 00:21:28 +03:00
Alibek Omarov
4107bd4e0f engine: common: quickly assume that map is valid when generating maps.lst if mpfilter is set or game is multiplayer only 2024-04-03 06:13:43 +03:00
Alibek Omarov
156b2b2b10 engine: server: remove MAP_HAS_SPAWNPOINT checks 2024-04-03 05:52:42 +03:00
Alibek Omarov
13a063bf7d mainui: update 2024-04-02 04:05:49 +03:00
Alibek Omarov
ef786b7d79 engine: client: fix sprites transparency in Night at the Office 2024-04-02 02:18:49 +03:00
Alibek Omarov
5c0c1b1226 ref: gl: make g_posenum in alias renderer static 2024-03-30 03:52:50 +03:00
Alibek Omarov
d041b2aa27 engine: fix error_on_exit data type 2024-03-26 17:15:34 +03:00
Alibek Omarov
f6d489e038 engine: server: register str64stats command that prints string pool usage statistics 2024-03-26 17:15:15 +03:00
Alibek Omarov
d34fedea69 engine: server: cleanup unused variables 2024-03-25 05:50:04 +03:00
Alibek Omarov
80b3f90091 engine: server: more accurate SV_ParseEdict
* Add removing trailing spaces, like GoldSrc does
* Pass classname first to allow game to override it
* Remove FL_CUSTOMENTITY flag usage, GoldSrc doesn't set this flag for "custom"
  export entities
* Fix possible memory leak
2024-03-25 05:49:59 +03:00
SNMetamorph
2a4fafc3f9 engine: voice: added voice_transmit_scale cvar to configure outcoming voice audio volume 2024-03-23 23:37:03 +03:00
SNMetamorph
9b3ccf5f04 engine: voice: output_buffer renamed to compress_buffer 2024-03-23 23:37:03 +03:00
SNMetamorph
f59ac2360a engine: voice: made voice_scale to influence incoming voice audio volume 2024-03-23 23:37:03 +03:00
Alibek Omarov
ff21fb42e6 engine: client: create separate Opus decoders for each player
Turns out, we can't re-use same decoder for different streams.
2024-03-20 18:41:52 +03:00
Alibek Omarov
288cac69de public: add small utility library for unicode stuff 2024-03-19 21:34:18 +03:00
Alibek Omarov
2640b6d869 engine: host: remove misleading message about TAB-autocompletion in dedicated mode 2024-03-19 21:24:21 +03:00
Alibek Omarov
d8910b0e38 engine: platform: linux: do not search sd_notify if NOTIFY_SOCKET isn't set 2024-03-19 21:23:53 +03:00
Alibek Omarov
049bed555e engine: host: fit -help into 80 columns terminal 2024-03-19 21:13:28 +03:00
Alibek Omarov
fe5944720b engine: use common strings to name the engine, makes branding easier for custom forks 2024-03-19 21:11:10 +03:00
Alibek Omarov
665c46b281 filesystem: minor logging opened archives change 2024-03-19 20:42:10 +03:00
Alibek Omarov
975ab6785e engine: make log starting and ending messages shorter, so it fits into standard 80 columns term 2024-03-19 20:41:46 +03:00
Alibek Omarov
6fa4dbfba2 public: build: use XASH_BUILD_BRANCH define set by Waf. Expect XASH_BUILD_{BRANCH,COMMIT} to be always set. 2024-03-19 19:34:30 +03:00
SNMetamorph
0506a1dfce engine: sys_con: added VCS branch name printing to log file header 2024-03-19 19:31:54 +03:00
SNMetamorph
908a9930e6 public: added Q_buildbranch function, needed for better logging 2024-03-19 19:31:54 +03:00
SNMetamorph
7d7e72196b engine: host: enabled printing current developer level 2024-03-19 19:31:54 +03:00
SNMetamorph
7cc67157e5 engine: sys_con: fixed incorrect logging init messages order 2024-03-19 19:31:54 +03:00
SNMetamorph
b7ff9c7a24 engine: sys_con: added missing title for log messages 2024-03-19 19:31:54 +03:00
Alibek Omarov
aab1fa1ba2 wscript: move gitversion load to libpublic, define XASH_BUILD_BRANCH, use unknown-{commit,branch} if detecting git version was failed 2024-03-19 19:30:52 +03:00
Alibek Omarov
effeba2f44 waf: upgrade to waifu 1.2.0 2024-03-19 19:24:49 +03:00
Alibek Omarov
e039ef35c0 filesystem: don't check for SDL whether we can load Android assets, because filesystem doesn't know anything about SDL
Replace it with runtime check instead.
2024-03-11 23:25:10 +03:00
Alibek Omarov
599a1f026e engine: client: fix missing comma 2024-03-11 22:56:52 +03:00
Alibek Omarov
39cba17f01 filesystem: android: try to fix compiling-in AAsset mounting code 2024-03-11 21:49:33 +03:00
SNMetamorph
17e106f96d ref: gl: invalidate texture units state cache when texture deletes 2024-03-09 22:12:35 +03:00
Alibek Omarov
081cf9132b engine: client: read console_history.txt as binary, skip empty and repeating lines, reimplement it through FS_Gets for fun 2024-03-08 15:25:36 +03:00
Alibek Omarov
6a7e027248 engine: common: add joy_ prefix to automatically filterable cvars 2024-03-08 15:25:36 +03:00
Alibek Omarov
27100e7751 engine: client: hook sensitivity cvar registration and make it priveleged cvar 2024-03-08 15:25:36 +03:00
Alibek Omarov
75d9ed341a Create FUNDING.yml 2024-03-07 09:41:18 +03:00
Alibek Omarov
1a0867523d engine: system: parent messagebox to main window when dealing with Sys_Error 2024-03-05 17:12:51 +03:00
Alibek Omarov
7584bbe47e engine: client: fix sound mute when losing focus 2024-03-03 19:00:50 +03:00
Andrey Akhmichin
505b6cc264 utils: mdldec: boneweights fix. 2024-03-01 20:26:18 +03:00
Alibek Omarov
24f23908be engine: platform: stub Sys_DebuggerPresent on unsupported platforms 2024-02-27 05:17:01 +03:00
Alibek Omarov
43bd73f37b engine: platform: that's why commit --amend and/or rebase --interactive your fixes in your patches before proposing them 2024-02-27 04:59:54 +03:00
mittorn
bb2753cbfc engine/system: add asm-based raise implementation for arm and aarch64, making Sys_DebugBreak more relevant, use tgkill instead of kill 2024-02-27 04:54:55 +03:00
mittorn
5568eccc8a ref/r_sprite: move dframetype to inner block 2024-02-27 04:17:21 +03:00
mittorn
c3b2cc4423 waifulib/compiler_optimizations: disable no-semantic-interposition for gcc4 in release builds too 2024-02-27 04:16:14 +03:00
mittorn
d84130219f crashhandler: set host.crashed before messagebox to allow platform code handle crashed state in different way 2024-02-27 04:14:37 +03:00
mittorn
d97d4d6c42 filesystem: add XASH_ANDROID_ASSETS macro for aassets switch 2024-02-27 04:04:54 +03:00
mittorn
15798aaf52 ref/r_sprite: move dframetype to inner block 2024-02-27 04:04:54 +03:00
mittorn
e53892e827 ref_gl: fix loop scope in ripple code 2024-02-27 04:04:54 +03:00
mittorn
cb12af69ed gl2shim: add SOFTFP_LINK support for gles3compat 2024-02-27 04:04:54 +03:00
mittorn
e82050a4bc gl2shim: fix gcc 4.9 build 2024-02-27 04:04:54 +03:00
mittorn
e4edd2da45 platform/posix: check for non-zero dladdr ret 2024-02-27 04:04:54 +03:00
mittorn
4f80922358 waf/compiler_optimizations: remove no-semantic-interposition for gcc4 2024-02-27 04:04:54 +03:00
mittorn
ae7ed03376 ref_soft: fix crash when y < -height 2024-02-27 04:04:54 +03:00
mittorn
c082e46662 imagelib: fix for loop scope 2024-02-27 04:04:54 +03:00
mittorn
b0bbcab6b4 ref_soft,ref_gl: fix unaligned read in sprite code 2024-02-27 04:04:54 +03:00
SNMetamorph
0fc83080ec engine: server: allowed bandwidth test on listen servers 2024-02-26 19:41:32 +03:00
SNMetamorph
73883b504f engine: client: improved bandwidth test logic 2024-02-26 19:41:32 +03:00
SNMetamorph
8efc9d74e8 engine: server: fixed test packet buffer was not being created 2024-02-26 19:41:32 +03:00
mittorn
373321ff00 ref/gl: do not set type on 1D textures on GLES (will fallback to 2D) 2024-02-26 16:08:37 +03:00
Alibek Omarov
a508467aac engine: client: silently ignore if server didn't sent local player info in delta at spawn
The bug happens somewhere in server, not sure where or how. Remove Host_Error so mods
can be played again.
2024-02-26 11:48:46 +03:00
Alibek Omarov
abbe993e80 3rdparty: gl4es: update 2024-02-26 11:20:04 +03:00
Alibek Omarov
c644e4d569 3rdparty: nanogl: update, fix link error with missing glTexEnvfv 2024-02-26 11:06:09 +03:00
Alibek Omarov
c200e008f1 wscript: disable gl-wes-v2 renderer from Android builds 2024-02-26 10:55:42 +03:00
Alibek Omarov
e95a2da6d0 engine: platform: sdl: slightly rework previous patch to not call SDL each frame and check for NULL pointers 2024-02-23 20:55:32 +03:00
Alibek Omarov
8afca1a79c engine: server: allow starting game from custom map 2024-02-23 20:54:32 +03:00
Alibek Omarov
827c9ca857 filesystem: restore original Xash behavior with unreferenced keys in gameinfo.txt/liblist.gam 2024-02-23 20:54:32 +03:00
Alibek Omarov
2416635ba3 common: validate extended surfaces size 2024-02-23 20:54:32 +03:00
Alibek Omarov
39eec89580 engine: increase elights limit up to 128 2024-02-23 20:54:32 +03:00
Sheridan Kane Rathbun
98d88266a6 engine: platform: sdl: fix incorrect mouse cursor positioning on high-dpi displays (#1623)
Signed-off-by: SheridanR <sheridan.rathbun@gmail.com>
2024-02-23 20:54:17 +03:00
mittorn
0f3359fc05 ref_gl: do not apply overbright color if lightscale correction used 2024-02-22 21:02:34 +03:00
mittorn
6c77608c34 ref_gl: implement color-modulate overbrigths with gl_vbo using texture GL_COMBINE 2024-02-22 21:02:34 +03:00
Alibek Omarov
abdff6eff6 mainui: update 2024-02-22 15:43:49 +03:00
Alibek Omarov
95a75465c9 common: remove FORCEINLINE and NOINLINE macros, we don't use them in engine 2024-02-22 15:43:37 +03:00
Alibek Omarov
119926805f mainui: update 2024-02-21 03:39:11 +03:00
Alibek Omarov
f749b5cb4b 3rdparty: nanogl: update 2024-02-21 02:57:18 +03:00
Alibek Omarov
c29ad6b598 scripts: waifulib: compiler_optimizations: add option to use profiling 2024-02-21 02:57:07 +03:00
Alibek Omarov
4c5dfb963e engine: zone: few more tunings for realloc 2024-02-21 00:59:02 +03:00
Alibek Omarov
e11f9e05d4 engine: server: add GetNativeObject to server's PhysicsAPI 2024-02-19 17:49:37 +03:00
Alibek Omarov
5c8b5b3511 Documentation: extensions: add doc about native-object 2024-02-19 17:49:37 +03:00
Alibek Omarov
2ea7162287 engine: gameui: add GetNativeObject to extended menu API 2024-02-19 17:49:37 +03:00
Alibek Omarov
e62ab51842 engine: platforms: android: platforms aren't expected to get NULL or zero sized native object names anymore 2024-02-19 17:49:37 +03:00
Bohdan Shulyar
f1bc9b87b1 platform: android: port to SDL 2024-02-19 17:47:40 +03:00
Alibek Omarov
a9bddaac64 engine: platform: win32: do not call filesystem functions if filesystem_stdio was failed to load 2024-02-19 06:27:24 +03:00
Alibek Omarov
6cef6f6a75 engine: zone: refactoring 2024-02-19 06:13:54 +03:00
Alibek Omarov
25ea6ed500 scripts: waifulib: don't use relative path while creating ZIP file (so cwd might not be equal to sources path) 2024-02-19 05:00:12 +03:00
Alibek Omarov
3d5173f257 engine: zone: implement Mem_Realloc through standard realloc 2024-02-19 04:22:16 +03:00
Alibek Omarov
05ff0d6020 engine: cmd: remove unused global variable 2024-02-17 22:17:22 +03:00
Alibek Omarov
3cea12627e engine: client: add cl_trace_stufftext from old engine 2024-02-17 22:16:39 +03:00
Alibek Omarov
b59b7c1a8d engine: server: better error message for missing spawn functions 2024-02-17 22:15:41 +03:00
Alibek Omarov
dd2c369df3 engine: imagelib: fix integer overflow on huge images when calculating reflectivity 2024-02-17 22:14:27 +03:00
Andrey Akhmichin
8b79e49a0f engine: server: execute maps/<mapname>_unload.cfg on server deactivation. 2024-02-16 17:57:26 +03:00
Andrey Akhmichin
4ea6eba8f2 engine: server: execute maps/<mapname>_load.cfg before entities precaching. 2024-02-16 17:57:26 +03:00
Andrey Akhmichin
f649076bc3 engine: server: execute map change config file before entities precaching. 2024-02-16 17:57:26 +03:00
Andrey Akhmichin
8ecffa4663 engine: server: define new "disconcfgfile" cvar. 2024-02-16 17:57:26 +03:00
Andrey Akhmichin
e90b83849a engine: server: execute map change config file in singleplayer. 2024-02-16 17:57:26 +03:00
Andrey Akhmichin
d517b9717a engine: server: define new "_sv_override_scientist_mdl" cvar for Uplink's scientist model. 2024-02-16 17:57:26 +03:00
Alibek Omarov
2c0d6e06be engine: server: return NULL in SV_ClientBy{Id,Name} if client array isn't allocated 2024-02-15 13:56:47 +03:00
Alibek Omarov
dec71850a1 engine: console: allow changing background filtering 2024-02-13 15:34:33 +03:00
Alibek Omarov
b1860972c6 engine: font: fix inverted check, fix potential division by zero 2024-02-13 15:33:51 +03:00
Alibek Omarov
1f4c9b67da engine: server: don't init or send voice chat in singleplayer 2024-02-13 15:09:26 +03:00
Alibek Omarov
c2da125358 engine: client: as an experiment, let users override default font rendermode through hud_fontrender and con_fontrender cvars 2024-02-09 07:25:47 +03:00
Alibek Omarov
31fa990d44 engine: gamma: fix gamma changes not caught if gamma cvar was set during frame 2024-02-09 06:29:30 +03:00
Alibek Omarov
d3e60c7d84 engine: gamma: higher brightness limit for compatibility 2024-02-09 06:28:31 +03:00
Alibek Omarov
e2424b4303 engine: server: clean up userinfo and fullupdate throttle on client connect 2024-02-07 23:27:02 +03:00
Alibek Omarov
240563cd1b engine: client: set r_lighting_modulate to 0.6 and save it to config for old Xash mods that use it internally 2024-02-07 23:22:27 +03:00
Alibek Omarov
d708cd58fb mainui: update 2024-02-07 23:22:27 +03:00
Alibek Omarov
491b503f96 engine: common: optimize COM_LoadFile/COM_LoadFileForMe removing double allocation 2024-02-07 23:22:27 +03:00
Alibek Omarov
636a2228f6 filesystem: add new API function LoadFileMalloc that returns a pointer that can be freed using standard free() 2024-02-07 23:22:27 +03:00
Alibek Omarov
bb03e2597c filesystem: allow to pass custom allocation functions to LoadFile 2024-02-07 23:22:27 +03:00
Alibek Omarov
21c828ee40 engine: sounds: remove extra logging 2024-02-05 15:57:59 +03:00
Alibek Omarov
132c9de142 engine: host: add the most important command line flag help string 2024-02-05 15:28:18 +03:00
Alibek Omarov
9d9507d77f engine: change mobility API license to Unlicense, as with build.h
See GitHub issue: https://github.com/FWGS/hlsdk-portable/issues/259

Signed-off-by: Alibek Omarov <a1ba.omarov@gmail.com>
2024-02-05 15:01:03 +03:00
Alibek Omarov
7daa6c3451 engine: server: use soundlist to acquire random sounds for physics 2024-02-05 12:49:31 +03:00
Alibek Omarov
c8e1ffe0dd engine: client: use soundlist to acquire random sounds for temp entities 2024-02-05 12:49:31 +03:00
Alibek Omarov
b5f02324a6 engine: add basic sounds.lst implementation 2024-02-05 12:49:27 +03:00
Alibek Omarov
47f5dfdcfd common: define macros for color codes for easier access 2024-02-05 12:49:27 +03:00
Alibek Omarov
33da68b013 engine: client: move reseting gamma changed flag to the end of the frame for custom renderers 2024-02-05 03:41:15 +03:00
Alibek Omarov
618ec83c9d engine: client: don't trigger CheckGamma if there is no screenshot action 2024-02-05 03:40:14 +03:00
Alibek Omarov
85de61ebc8 engine: client: fix userid not being written to player info on userinfo change 2024-02-05 02:58:46 +03:00
Alibek Omarov
2feaae59f7 engine: client: bring back r_lighting_modulate, as a compatibility cvar 2024-02-02 13:52:17 +03:00
Alibek Omarov
2550d7fbd3 public: tests: remove linuxunkabi remnants 2024-02-01 02:54:22 +03:00
Alibek Omarov
565f717804 ref: add ref_null renderer that does nothing
This was sitting in my git stash for months. Let's publish it now.
2024-02-01 02:45:19 +03:00
Alibek Omarov
b56c83a2f9 Documentation: add a note about musl 2024-01-31 23:59:28 +03:00
Alibek Omarov
bf17996f72 public: remove linuxunkabi 2024-01-31 23:59:28 +03:00
Alibek Omarov
a3acb1c85b engine: gamma: validate gamma cvars in local games too 2024-01-30 17:55:36 +03:00
Alibek Omarov
d4d63301e0 mainui: update 2024-01-30 17:50:31 +03:00
Alibek Omarov
e9af0c9810 ref: gl: wscript: remove all libs dependencies from gles3compat, added by mistake 2024-01-30 17:40:59 +03:00
Alibek Omarov
131ad9c790 3rdparty: update submodules 2024-01-30 17:28:12 +03:00
Alibek Omarov
bfcaba54dc wscript: move werror flags into uselib 2024-01-30 17:24:17 +03:00
Alibek Omarov
f67736180b engine: client: allow nearest filtering for loading and pause icons 2024-01-29 05:59:29 +03:00
Alibek Omarov
725b7ea7f9 common: render_api: rename TF_ALLOW_NEAREST_TOGGLE to just TF_ALLOW_NEAREST, it's just shorter 2024-01-29 05:59:06 +03:00
Alibek Omarov
600d574376 ref: gl: make use of new TF_ALLOW_NEAREST_TOGGLE flag 2024-01-29 05:50:59 +03:00
Alibek Omarov
04f42df7d5 common: render_api: new flag TF_ALLOW_NEAREST_TOGGLE that allows toggling nearest filtering for TF_NOMIPMAP textures 2024-01-29 05:48:42 +03:00
Alibek Omarov
ab15662d78 ref: gl: fix toggling nearest filter on TF_NOMIPMAP textures 2024-01-29 05:48:08 +03:00
Alibek Omarov
072b0cef27 ref: gl: small refactoring on filter choosing for newly uploaded texture 2024-01-29 05:47:10 +03:00
Alibek Omarov
e274c62cfc ref: gl: use TextureFilteringEnabled to decide whether texture will have nearest filtering or linear 2024-01-29 05:44:14 +03:00
Alibek Omarov
a28d45fdb2 engine: console: fix TF_NEAREST missing from quake fixed font 2024-01-29 05:42:22 +03:00
Alibek Omarov
6ca5f7c6fb engine: client: request if font texture has nearest filtering from the renderer 2024-01-29 05:41:16 +03:00
Alibek Omarov
af316bff14 engine: client: add hud_scale_minimal_width to limit scaling factor and potentially avoid unsupported hud sprites resolutions 2024-01-29 04:58:07 +03:00
Alibek Omarov
c8945caefc engine: net_buffer: remove unused MSG_SeekToByte 2024-01-28 20:01:29 +03:00
Alibek Omarov
8c61a2f021 engine: server: cleanup server.h header from unused functions prototypes 2024-01-28 11:35:53 +03:00
Alibek Omarov
0b24810927 engine: client: clean up client.h from unused function prototypes, or move them to appropriate C file 2024-01-28 11:17:06 +03:00
Alibek Omarov
b3d8fb03bf engine: client: add generic handler for simple types of screenshots commands 2024-01-28 10:43:37 +03:00
Alibek Omarov
02c5890c2f ref: soft: cleanup after RefAPI changes, remove unused functions 2024-01-28 10:00:51 +03:00
Alibek Omarov
0579e40857 engine: server: remove unused DumpHashString function 2024-01-28 10:00:51 +03:00
Alibek Omarov
c77f290bc6 engine: remove Netsplit_SendLong, as we're not planning to support old protocol on server side 2024-01-28 10:00:51 +03:00
Alibek Omarov
7bf9407177 ref: gl: remove R_TextureRandomTiling, it's handled by R_TextureAnimation (random tiling as a feature still broken) 2024-01-28 10:00:51 +03:00
Alibek Omarov
b41fe076ae engine: server: exclude expired IP filters from check 2024-01-28 10:00:51 +03:00
Alibek Omarov
a7c422fde6 engine: platform: make Platform_SetTimer static inline to not fix unused-function 2024-01-28 10:00:51 +03:00
Alibek Omarov
568a394a40 wscript: enable -Wunused-functions 2024-01-28 10:00:51 +03:00
Alibek Omarov
2b6a550405 engine: clean up common.h header from unused function prototypes, or move them to appropriate header or C file 2024-01-28 10:00:17 +03:00
Alibek Omarov
7200f0da7e 3rdparty: gl-wes-v2: update 2024-01-28 09:55:18 +03:00
Alibek Omarov
d3c3c26618 ref: gl: vgl_shim: fix -Wmissing-prototypes 2024-01-28 09:55:18 +03:00
Alibek Omarov
7152393089 ref: soft: fix -Wmissing-prototypes 2024-01-28 09:55:18 +03:00
Alibek Omarov
661e60720d ref: gl: fix -Wmissing-prototypes 2024-01-28 09:55:18 +03:00
Alibek Omarov
bf959da7ff engine: libmpg: fix -Wmissing-prototypes 2024-01-28 09:55:18 +03:00
Alibek Omarov
75d476f9df engine: fix -Wmissing-prototypes 2024-01-28 09:55:18 +03:00
Alibek Omarov
b077822f4d filesystem: fix -Wmissing-prototypes 2024-01-28 09:55:18 +03:00
Alibek Omarov
6d3f188675 public: fix -Wmissing-prototypes 2024-01-28 09:55:18 +03:00
Alibek Omarov
0231f5e8ac wscript: warn about missing-prototypes by default for C 2024-01-28 09:55:18 +03:00
Alibek Omarov
901b35d4b1 ref: soft: rework @SNMetamorph's fix for avoiding crash when no world is set (like Customize menu with enabled 3D view) 2024-01-27 17:31:34 +03:00
Alibek Omarov
eaafd0ff13 ref: gl: rework @SNMetamorph's fix for avoiding crash when no world is set (like Customize menu with enabled 3D view) 2024-01-27 17:31:26 +03:00
Alibek Omarov
963d9b8f2a ref: soft: remove useless R_CountDynamicLights function 2024-01-27 17:16:01 +03:00
Alibek Omarov
5696c9c96a ref: gl: remove useless R_CountDynamicLights function 2024-01-27 17:15:57 +03:00
Alibek Omarov
862b9e68be engine: server: fix possible null pointer dereference 2024-01-25 16:21:55 +03:00
Alibek Omarov
2f2890cd11 engine: client: use PARM_TEX_FILTERING to figure out whether we should apply half-texel trick to HUD textures when scaling 2024-01-25 05:50:11 +03:00
Alibek Omarov
482aa840e7 ref: soft: add PARM_TEX_FILTERING handler (stub) 2024-01-25 05:47:12 +03:00
Alibek Omarov
4599983c8e ref: gl: add PARM_TEX_FILTERING handler 2024-01-25 05:46:54 +03:00
Alibek Omarov
11172838f2 engine: ref_api: add PARM_TEX_FILTERING into RefAPI to query if filtering is enabled for selected texture 2024-01-25 05:43:51 +03:00
Alibek Omarov
47bc50b8c6 engine: client: fix taking console color from colors.lst 2024-01-25 04:22:20 +03:00
Alibek Omarov
7c82766a5c readme: add sourcehut builds badge [skip ci] 2024-01-24 21:10:21 +03:00
Alibek Omarov
5d6cf62405 engine: client: voice: open microphone only after server sends svc_voiceinit to us and shutdown immediately after disconnect 2024-01-24 20:52:21 +03:00
Alibek Omarov
edc08e39ef common: move FORCEINLINE from port.h to xash3d_types.h, alongside other compiler-specific attributes 2024-01-24 20:51:34 +03:00
Alibek Omarov
a9846e765d waf: upgrade to latest waifu 2024-01-23 21:34:49 +03:00
Alibek Omarov
aa54309d5c engine: wscript: fix pthreads check by explicitly checking it in C mode 2024-01-23 21:23:23 +03:00
Alibek Omarov
443317bedf wscript: fix RPATH under OpenBSD 2024-01-23 21:03:10 +03:00
Alibek Omarov
ffd320507f ci: enable builds.sr.ht 2024-01-23 20:42:09 +03:00
Alibek Omarov
60df08c11c engine: crashhandler: fix build for NetBSD AMD64 2024-01-23 20:25:17 +03:00
Alibek Omarov
7d464df107 engine: platform: linux: define portability macro for sigevent (oh, glibc...) 2024-01-23 19:22:56 +03:00
Alibek Omarov
296f89acf9 engine: platform: linux: fix build with musl (and probably other libcs) using portability macro 2024-01-23 18:57:33 +03:00
mittorn
5f31417bae ref_gl: fix missing vboarray split transition on some maps 2024-01-19 21:28:49 +03:00
Alibek Omarov
150d98bd15 ref: gl: fix stuck single lightmap texture object when using VBO after updating lightmap 2024-01-19 09:57:11 +03:00
Alibek Omarov
f162fbd806 ref: gl: fix fog with enabled overbrights and no vbo 2024-01-19 06:19:42 +03:00
Alibek Omarov
7d8ea61ac2 ref: gl: move glBegin/glEnd outside of the loop in CL_DrawTracers 2024-01-17 02:46:38 +03:00
Alibek Omarov
40041e30eb engine: console: add cvar con_oldfont to toggle usage between fonts.wad fonts or gfx.wad legacy font 2024-01-15 18:11:08 +03:00
Alibek Omarov
a247e139bf engine: fix dedicated build 2024-01-15 02:08:30 +03:00
Alibek Omarov
00b2ca7f5a ref: gl: remove duplicates from gl_export.h 2024-01-15 02:08:30 +03:00
Alibek Omarov
e58007aab3 wscript: disable /showIncludes based msvcdeps for now, it causes issues with non-English locales 2024-01-14 13:36:49 +03:00
Alibek Omarov
dca862a838 engine: host: execute valid rc script if game was started from -game parameter using default launcher 2024-01-14 10:58:27 +03:00
Alibek Omarov
7e71e20714 engine: client: add cvar scr_drawversion to hide engine version in screenshots (sorry, Uncle Mike!) 2024-01-14 10:58:04 +03:00
Alibek Omarov
cee6862924 engine: client: try to prepend media/ if audio stream couldn't be opened 2024-01-14 10:58:04 +03:00
Alibek Omarov
a8cc68f6b9 ref: gl: fix ripple water is being blurry with gl_texture_nearest after startup 2024-01-14 10:56:58 +03:00
Alibek Omarov
2af0adb629 mainui: update 2024-01-13 05:51:39 +03:00
Alibek Omarov
628ac376ed engine: client: s_dsp: refactoring from hldsp 2024-01-13 05:29:43 +03:00
Alibek Omarov
251e6ac1dc engine: client: s_dsp: use Cvar_DirectSet 2024-01-13 05:29:12 +03:00
Alibek Omarov
9b6518376c engine: cvar: add Cvar_DirectSetValue function 2024-01-13 05:18:30 +03:00
Alibek Omarov
6c3fee7f27 engine: cvar: move common checks if cvar can be updated into generic function 2024-01-13 05:18:09 +03:00
Alibek Omarov
c111a59639 github: set 32-bit windows builds to vs2019, upgrade SDL2 2024-01-13 05:05:54 +03:00
Alibek Omarov
ba9bb70924 common: remove unused gamma definitions 2024-01-13 05:03:58 +03:00
Alibek Omarov
6acc97b0ef engine: client: restore my copyright on my DSP implementation from old engine branch 2024-01-13 00:56:03 +03:00
Alibek Omarov
cd681d4303 engine: replace anorms.h with compatible header from GPL WinQuake sources 2024-01-12 23:13:22 +03:00
Alibek Omarov
46f30e215c common: replace netadr.h with compatible definition from GPL Quake-2 sources 2024-01-12 23:09:38 +03:00
Alibek Omarov
2ae038c01c common: fix broken STATIC_ASSERT macro again 2024-01-12 23:00:56 +03:00
Alibek Omarov
aaa9fbd50f common: replace kbutton.h with compatible defintion from GPL WinQuake sources 2024-01-12 17:20:30 +03:00
Alibek Omarov
51d4716bcb engine: client: rewrite trimming silence at the beginning and ending of the VOX word from scratch 2024-01-12 03:27:05 +03:00
Alibek Omarov
045caacfee engine: client: drop skipping random 0.1 second of an ambient sound 2024-01-12 03:27:05 +03:00
Andrey Akhmichin
95a5c670a2 utils: mdldec: res: activities.txt: remove completely useless ACT_VM_* activities. 2024-01-10 14:38:01 +03:00
Andrey Akhmichin
30259e1573 Documentation: opensource-mods.md: update. 2024-01-10 14:37:52 +03:00
Bohdan Shulyar
8b884132b7 ci: fix missing libs on nswitch 2024-01-10 14:37:43 +03:00
Alibek Omarov
266f9a6bc6 engine: client: add support for parsing IPv6 server list 2024-01-09 16:59:06 +03:00
Alibek Omarov
58177d9251 mainui: update 2024-01-09 04:58:11 +03:00
Alibek Omarov
69e801d6b8 engine: fix bug where user stucks after loading map/save while being connected to remote server 2024-01-09 04:16:52 +03:00
Alibek Omarov
388cc3061f mainui: update 2024-01-09 03:55:28 +03:00
Alibek Omarov
c9d29b3955 ref: gl: fix overbrights with VBO 2024-01-09 03:55:07 +03:00
Alibek Omarov
371025dc8e engine: dedicated: add TextureToGamma stub for imagelib 2024-01-09 03:55:07 +03:00
Alibek Omarov
cf7a79bff3 ref: gl: particles aren't supposed to care about gamma 2024-01-09 03:55:07 +03:00
Alibek Omarov
55dfa1bf44 ref: soft: reorder applying light gamma 2024-01-09 03:55:07 +03:00
Alibek Omarov
519c8a032a ref: soft: adapt studio renderer to new gamma implementation 2024-01-09 03:55:07 +03:00
Alibek Omarov
c15822f375 ref: soft: don't depend on light gamma in recursive light point 2024-01-09 03:55:07 +03:00
Alibek Omarov
0e91deec19 ref: soft: remove unused scale (remnants of r_lightmap_modulate), use integer values for non-interpolated lightstyles 2024-01-09 03:55:07 +03:00
Alibek Omarov
87b204c661 ref: gl: remove unused scale (remnants of r_lightmap_modulate), use integer values for non-interpolated lightstyles 2024-01-09 03:55:07 +03:00
Alibek Omarov
caefa0b7b9 engine: remove cvar r_lighting_modulate, it's some unindentifiable legacy 2024-01-09 03:55:07 +03:00
Alibek Omarov
a311923d4e engine: imagelib: apply texgamma to palette (ideally should be applied only to BSP/WAD textures) 2024-01-09 03:55:07 +03:00
Alibek Omarov
ee4cb39f3e ref: gl: adapt alias renderer to new gamma implementation (untested) 2024-01-09 03:55:07 +03:00
Alibek Omarov
18436a70eb ref: gl: support overbrights, change the gamma applying order closer to the original renderer 2024-01-09 03:55:00 +03:00
Alibek Omarov
8298053e6a ref: gl: don't depend on lightgamma in recursive light point 2024-01-09 03:33:39 +03:00
Alibek Omarov
9304a0041d ref: gl: support kRenderFxLightMultiplier
* add undocumented kRenderFxLightMultiplier to const.h
2024-01-09 03:33:39 +03:00
Alibek Omarov
64f92003fa ref: gl: adapt studio lightning to new gamma
* more accurate SHADE_LAMBERT value (extracted from v_lambert1 global variable)
2024-01-09 03:33:39 +03:00
Alibek Omarov
be0a241244 engine: client: add tests for new gamma implementation 2024-01-09 03:33:39 +03:00
Alibek Omarov
df6546d5b1 engine: client: add new gamma implementation
* immediately expose it in RefAPI. Bump RefAPI to version 7.
* remove VID_StartupGamma, it's not used anymore
* remove stub lightgamma and direct cvars
* add a temporary check for v_direct and v_lightgamma default values
2024-01-09 03:33:24 +03:00
Alibek Omarov
a0c31120d9 ref: add R_GammaChanged function that engine calls on every gamma change 2024-01-07 03:35:23 +03:00
Alibek Omarov
c0757bd84c ref: gl: remove vid_gamma/vid_brightness changed cvar value check 2024-01-07 03:35:23 +03:00
Alibek Omarov
9fa32a9cf4 ref: soft: remove vid_gamma/vid_brightness changed cvar value check 2024-01-07 03:35:23 +03:00
Ruslan Piasetskyi
15bc09b06b engine: platform: linux: Add gettid definition for old systems
The gettid() library support was added in glibc 2.30. Earlier glibc
versions did not provide a wrapper for this system call, necessitating
the use of syscall(2).

Also, put _GNU_SOURCE definition in the guard to avoid the warning:
  ../engine/platform/linux/sys_linux.c:16: warning: "_GNU_SOURCE" redefined
   #define _GNU_SOURCE

  <command-line>: note: this is the location of the previous definition
2024-01-06 13:43:35 +03:00
Alibek Omarov
315aea1991 filesystem: support mods liblist.gam/gameinfo.txt with relative paths to game libs 2024-01-05 04:34:33 +03:00
Alibek Omarov
380422a6dc engine: client: refactor CL_AddEntityEffects, bring everything to GoldSrc behavior
Some effects are meant only for playeres, others only for normal entities
2024-01-05 04:10:45 +03:00
Alibek Omarov
be26ecf1c9 engine: client: don't spawn model effects for players, like GoldSrc 2024-01-05 04:09:20 +03:00
Alibek Omarov
d2bbe9dfd2 engine: client: don't spawn multiple model effects 2024-01-05 04:08:52 +03:00
Alibek Omarov
9c929c1405 engine: client: don't spawn particles if time is stopped 2024-01-05 02:59:47 +03:00
Alibek Omarov
9551240680 engine: host: fix -Werror=parentheses 2024-01-05 02:35:16 +03:00
Alibek Omarov
6605d0456c engine: host: force ENGINE_STEP_POSHISTORY_LERP for Counter-Strike and Condition Zero 2024-01-05 02:27:37 +03:00
Alibek Omarov
99e8f7b486 engine: host: fix warning about incompatible features bits 2024-01-05 02:26:25 +03:00
Alibek Omarov
5ac8f63741 ref: soft: replace skin texture num bound by a proper check, fixes wrong skin on flags in Adrenaline Gamer 2024-01-05 02:25:18 +03:00
Alibek Omarov
9d3949a948 ref: gl: replace skin texture num bound by a proper check, fixes wrong skin on flags in Adrenaline Gamer 2024-01-05 02:25:10 +03:00
Alibek Omarov
5bd1dd34b3 ci: disable freebsd-12 task 2024-01-04 22:15:08 +03:00
Alibek Omarov
6862b14e59 ref: soft: only draw MOVETYPE_FOLLOW studio model if it's parent is visible 2024-01-04 22:02:14 +03:00
Alibek Omarov
dc1d65f621 ref: gl: only draw MOVETYPE_FOLLOW studio model if it's parent is visible 2024-01-04 22:02:09 +03:00
Alibek Omarov
fba3a2b67f ref: soft: return NULL in GetEntityByIndex and ModelHandle 2024-01-04 21:47:03 +03:00
Alibek Omarov
b946c8455d ref: gl: return NULL in GetEntityByIndex and ModelHandle just in case 2024-01-04 21:46:44 +03:00
Alibek Omarov
c56e876043 engine: client: don't reset runfuncs for demoplayback 2024-01-04 06:11:15 +03:00
Alibek Omarov
9773d11464 engine: client: disable MOVETYPE_TOSS interpolation in old protocol, but keep animtime hack for them 2024-01-04 05:53:04 +03:00
Alibek Omarov
3c28b11754 engine: client: cl_demo: fix usercmd in demo playback
I have no explanation why this works but it kinda does?
2024-01-04 05:48:45 +03:00
Alibek Omarov
f2584dcb9d engine: host: better engine features print 2024-01-04 05:31:01 +03:00
Alibek Omarov
ce73838f1b engine: add a function that validates requested features bits 2024-01-04 05:30:18 +03:00
Alibek Omarov
49f972a7c9 engine: add new engine feature ENGINE_STEP_POSHISTORY_LERP that enables CStrike's MOVETYPE_STEP lerp based on position history 2024-01-04 05:05:03 +03:00
Alibek Omarov
1ae01d89de engine: client: correctly support ENGINE_COMPUTE_STUDIO_LERP feature flag without STUDIO_INTERPOLATION_FIX enabled 2024-01-04 03:35:16 +03:00
Alibek Omarov
8e54e18c8f engine: client: disable STUDIO_INTERPOLATION_FIX 2024-01-04 03:32:59 +03:00
Alibek Omarov
18136e5320 engine: client: implement HL25's cl_fixmodelinterpolationartifacts cvar 2024-01-04 03:32:36 +03:00
Alibek Omarov
a29f1899d3 engine: client: remove unused extrapolate variable in CL_PureOrigin 2024-01-03 19:06:46 +03:00
Alibek Omarov
0f804ffc30 engine: client: use extra precision for interpolation 2024-01-03 19:02:09 +03:00
Alibek Omarov
620a4b4894 engine: client: wrong check order, fix previous commit 2023-12-31 06:35:38 +03:00
Alibek Omarov
4cf87c2c23 engine: client: prevent memory corruption on old protocol when server didn't sent local player info in delta at spawn 2023-12-31 06:24:53 +03:00
Alibek Omarov
f031c31b77 engine: client: try another workaround for backwards animtime 2023-12-31 06:12:00 +03:00
Alibek Omarov
c2447d8634 engine: client: stupid hack to allow monsters interpolation on a very specific old protocol engine mod 2023-12-31 05:03:10 +03:00
Alibek Omarov
ae9c1d9f18 engine: remove single-binary option. Now platforms that don't need external launcher, shall set env.DISABLE_LAUNCHER 2023-12-30 23:45:17 +03:00
Alibek Omarov
0132eb6e44 ref: gl: restore usage of FWORLD_CUSTOM_SKYBOX flag, do direct checks instead of PARM check, remove unused tr.fCustomSkybox 2023-12-30 16:55:31 +03:00
Alibek Omarov
f12df54226 ref: soft: remove unused tr.fCustomSkybox 2023-12-30 16:54:56 +03:00
Alibek Omarov
d971055927 engine: move PARM_SKY_SPHERE handling out of engine to renderer, after all renderers might or might not support sky spheres 2023-12-30 16:54:37 +03:00
Alibek Omarov
6059538d77 ref: gl: use direct host.features instead of PARM_FEATURES 2023-12-30 16:41:51 +03:00
Alibek Omarov
17deba0606 ref: gl: use direct cl.paused instead of PARM_GAMEPAUSED 2023-12-30 16:41:39 +03:00
Alibek Omarov
82a2d272ad ref: gl: use direct host.features instead of PARM_FEATURES 2023-12-30 16:41:22 +03:00
Alibek Omarov
707a9228e1 engine: ref_api: draft RefAPI 6.
Remove timings from ref_globals_t struct

Remove R_UpdateRefState accordingly.

Remove unused PARMs

Remove reduntant functions
2023-12-30 16:36:13 +03:00
Alibek Omarov
59ddfb787f ref: soft: remove GetPredictedOrigin() call 2023-12-30 16:36:13 +03:00
Alibek Omarov
acdf1da995 ref: soft: remove GetMoveVars() call 2023-12-30 16:36:13 +03:00
Alibek Omarov
f1cdab91eb ref: soft: remove usage of PARM_VIEWENT_INDEX and PARM_PLAYER_INDEX 2023-12-30 16:36:13 +03:00
Alibek Omarov
05d5abe4db ref: soft: remove usage of PARM_MAX_CLIENTS 2023-12-30 16:36:13 +03:00
Alibek Omarov
44e017a410 ref: soft: convert to usage of ref_host_t to get real engine time 2023-12-30 16:36:13 +03:00
Alibek Omarov
64f3884f23 ref: soft: convert to usage of ref_client_t to get client time 2023-12-30 16:36:13 +03:00
Alibek Omarov
6386782674 ref: soft: acquire engine pointers 2023-12-30 16:36:13 +03:00
Alibek Omarov
8084687e50 ref: gl: remove GetPredictedOrigin call 2023-12-30 16:36:13 +03:00
Alibek Omarov
6c16de55c0 ref: gl: remove GetMoveVars() call 2023-12-30 16:36:13 +03:00
Alibek Omarov
537237ef62 ref: gl: remove usage of PARM_VIEWENT_INDEX and PARM_PLAYER_INDEX 2023-12-30 16:36:13 +03:00
Alibek Omarov
4dfc3f34cb ref: gl: remove usage of PARM_MAX_CLIENTS 2023-12-30 16:36:13 +03:00
Alibek Omarov
d22bbb4213 ref: gl: remove usage of PARM_WORLD_VERSION 2023-12-30 16:36:13 +03:00
Alibek Omarov
0e3b14e9a5 ref: gl: remove usage of PARM_NUMMODELS 2023-12-30 16:36:13 +03:00
Alibek Omarov
afb0540aa3 ref: gl: convert to usage of ref_host_t to get real engine time 2023-12-30 16:36:13 +03:00
Alibek Omarov
4d802d8901 ref: gl: convert to usage of ref_client_t to get client time 2023-12-30 16:36:13 +03:00
Alibek Omarov
6a4bf4965f ref: gl: acquire engine pointers 2023-12-30 16:36:13 +03:00
Alibek Omarov
a3c9538d12 engine: client: add support for new PARMs
Reorganize internal engine structs, carefully check structs compatibility before casting types
2023-12-30 16:36:13 +03:00
Alibek Omarov
632264809f engine: ref_api: add PARMs to get pointers to engine data like cl, host, world, etc. Partially expose cl and host. 2023-12-30 16:36:13 +03:00
Alibek Omarov
bcfabbe802 engine: do not save configs when we closing because of the errors 2023-12-28 22:42:12 +03:00
Alibek Omarov
c244cfc937 engine: do not save configs when we closing because of the errors 2023-12-28 22:40:10 +03:00
Andrey Akhmichin
520fc33394 utils: mdldec: fix wrong conditions. 2023-12-28 20:36:39 +03:00
Alibek Omarov
f705a7cd26 common: xash3d_types: another attempt to properly check static asserts availability 2023-12-28 17:32:07 +03:00
Alibek Omarov
65bfff69d0 engine: wscript: always require librt on Linux since we need it for Platform_SetTimer implementation 2023-12-27 04:14:19 +03:00
Alibek Omarov
9d8ba03f5e common: xash3d_types: fix static_assert macro 2023-12-27 03:10:41 +03:00
Alibek Omarov
778b8ede58 engine: platform: linux: add forgotten _GNU_SOURCE at the top of the file to enable gettid extension 2023-12-27 03:10:20 +03:00
Alibek Omarov
f8a1a2ed71 engine: platform: linux: add missing math.h include 2023-12-26 18:56:30 +03:00
mittorn
b4a7c266b5 platform/linux: implement debug timers and cl_maxframetime to catch very long frames on debugger 2023-12-25 14:22:20 +03:00
mittorn
a488f79852 ref_gl: workaround freezes on adreno with vbo on dlighted decals 2023-12-25 14:21:21 +03:00
Alibek Omarov
b290046503 ref: gl: remove hidden parm -gl-allow-vbo-dontuse needed to activate VBO renderer 2023-12-19 17:55:10 +03:00
Dmitry Toroshchin
e8409cee8b ref_gl: vbo: do not do zero-length drawcalls (fix glError on vivante) 2023-12-19 17:55:10 +03:00
mittorn
1d4d355b38 ref_gl: vbo: fix binding garbade texture after changelevel, fix wpoly counter 2023-12-19 17:55:10 +03:00
mittorn
dfe12535a5 ref_gl: vbo: disable R_TextureRandomTiling implementation until will be fixed 2023-12-19 17:55:10 +03:00
mittorn
74946100f1 ref_gl: fix not restoring static lightmap after decals 2023-12-19 17:55:10 +03:00
mittorn
9a1717915c ref_gl: vbo: apply a1batross's patch for uint index switch 2023-12-19 17:55:10 +03:00
mittorn
3691eb6e48 ref_gl: vbo: fix incorrect lightmap index, optimize loading maps with very big lightmap count, fix clouds drawing after VBO 2023-12-19 17:55:10 +03:00
mittorn
3bb7471fd3 ref_gl: vbo: fix lightmap0 processing, remove ilightmap 2023-12-19 17:55:10 +03:00
mittorn
74e09ddb12 ref_gl: change state management in vbo renderer 2023-12-19 17:55:10 +03:00
mittorn
6b73d056b2 ref_gl: vbo dlights refactiring 2023-12-19 17:55:10 +03:00
mittorn
3e7847551a ref_gl: add ability to skip uploading unused data (disabled) 2023-12-19 17:55:10 +03:00
mittorn
91d92935fa ref_gl: try avoid gpu locking on dlights in vbo renderer 2023-12-19 17:55:10 +03:00
mittorn
eff033298a ref_gl: disable singlepass detail renderer, use correct fog color multipliers in VBO 2023-12-19 17:55:10 +03:00
mittorn
3a8f4961bc ref_gl: fix rarely broken texturechain on some big maps 2023-12-19 17:55:10 +03:00
mittorn
b81f94518a ref_gl: fix out-by-one when all lightstyles are used. Also fix broken in this case in vbo after previous fix 2023-12-19 17:55:10 +03:00
Alibek Omarov
96f7f5457d engine: print all supported and enabled features 2023-12-17 17:51:15 +03:00
Alibek Omarov
498ec6b4f1 engine: client: print enabled features after server connect if it's not a local game 2023-12-17 17:44:05 +03:00
Alibek Omarov
607e62a1ae engine: client: sanitize legacy protocol supported engine features flags
Do not enable what can't be enabled in current protocol.
2023-12-17 17:44:05 +03:00
Alibek Omarov
d41a80bc2c engine: add mask to sanitize possible engine features bits 2023-12-17 17:43:51 +03:00
Alibek Omarov
643bec4071 engine: client: set max FPS when recording with fps_max 0 2023-12-16 22:02:26 +03:00
Alibek Omarov
a7e84230c3 ref: gl: use world version to enable large lightmaps for BSP2 automatically 2023-12-15 07:38:25 +03:00
Alibek Omarov
c96cf7e22d engine: expose world version through RefAPI 2023-12-15 07:38:07 +03:00
Alibek Omarov
46c61660cf engine: expose world BSP version through world global structure 2023-12-15 07:37:40 +03:00
Alibek Omarov
f6fecce52b wscript: do not recurse into ref_soft when BSP2 is enabled 2023-12-15 07:29:38 +03:00
Alibek Omarov
54a5947a3c engine: remove MSGBOX macro 2023-12-15 06:40:04 +03:00
Andrey Akhmichin
521bc675a2 utils: mdldec: smd.c: simplify proper bone rotation code. 2023-12-14 14:55:40 +03:00
Andrey Akhmichin
845cee2578 utils: mdldec: smd.c: prevent division by zero. 2023-12-14 14:54:49 +03:00
Alibek Omarov
93ceb0e4ed engine: client: split the sprites indices only when loading new sprite. Scan the whole array when searching.
Fixes incorrect sprite loading in XDM
2023-12-14 03:12:47 +03:00
Alibek Omarov
13aab4e59c engine: server: fix off-by-one error in Voice_Set/GetClientListening 2023-12-13 14:56:55 +03:00
Alibek Omarov
36c2f9e9f2 engine: refactor rcon redirect, don't make it depend on global object 2023-12-13 14:56:27 +03:00
Alibek Omarov
514da0ffa9 engine: host: do not depend on Sys_Sleep accuracy, instead allocate a timewindow that decrases with each skipped frame 2023-12-11 07:12:44 +03:00
Alibek Omarov
37b8d5da79 mainui: update 2023-12-11 07:12:30 +03:00
Alibek Omarov
b5d602d953 wscript: enable -Werror=alloc-size and -Walloc-zero 2023-12-11 07:11:40 +03:00
Alibek Omarov
c926fee13c filesystem: report an error when opening file was unsuccessful, with the exception for non-existent files 2023-12-11 07:10:51 +03:00
Alibek Omarov
a675806c91 engine: imagelib: img_ktx2: don't allow to load images with no mip levels 2023-12-11 07:06:12 +03:00
Alibek Omarov
683c4874f8 common: add ALLOC_CHECK macro that enables attribute alloc_size on GCC that allows to prevent suspicious allocation sizes 2023-12-09 19:00:25 +03:00
Alibek Omarov
20ced857b4 engine: client: use physents array when tracing physents =/ 2023-12-09 16:45:35 +03:00
Alibek Omarov
c6c86f9665 public: make hash case-insensitive again 2023-12-07 06:46:49 +03:00
Alibek Omarov
1e0107944f engine: make sys_timescale non-cheat, like host_framerate 2023-12-07 00:50:56 +03:00
Alibek Omarov
21797f9ac8 ref: gl: fix solor to color 2023-12-06 05:22:02 +03:00
mittorn
c800b34cd4 ref_api: add R_Flush method 2023-12-06 04:13:27 +03:00
Alibek Omarov
1612e2d669 engine: client: GetRefAPI now must return REF_API_VERSION to prevent possible issue when ref library wasn't recompiled on version bump 2023-12-06 04:13:27 +03:00
Alibek Omarov
26d229c8ca engine, ref: RefAPI 5. Simplify remap calls 2023-12-06 04:13:03 +03:00
Alibek Omarov
9c66e86be1 engine, ref: RefAPI 5. Remove unused calls 2023-12-06 04:13:03 +03:00
Alibek Omarov
7e9f87de2d engine, ref: eliminate calls to global arrays, instead store array pointers at renderer side 2023-12-06 04:13:03 +03:00
Alibek Omarov
67737446ac mainui: update 2023-12-06 04:12:33 +03:00
Andrey Akhmichin
dabed4f9eb utils: mdldec: add separate directories creation for sequences and textures. 2023-12-05 11:18:47 +03:00
Andrey Akhmichin
f9b6389248 utils: mdldec: create full destination path into "Kratisto's mdldec" maner. 2023-12-05 11:18:47 +03:00
Alibek Omarov
9ec1e259b4 engine: platform: sdl: unused variable cleanup 2023-12-05 10:48:47 +03:00
Alibek Omarov
0c2d480d89 engine: client: unused variables cleanup 2023-12-05 10:47:55 +03:00
Alibek Omarov
350d8ccb7b engine: common: cvar: unused variables cleanup 2023-12-05 10:46:26 +03:00
Alibek Omarov
0c512d0431 engine: server: unused variables cleanup 2023-12-05 10:46:03 +03:00
Alibek Omarov
3bf55c9ea4 filesystem: zip: hide CRC checks under common macro 2023-12-04 03:01:11 +03:00
Alibek Omarov
9994c57796 filesystem: fix updating gameinfo.txt from rodir 2023-12-04 03:00:51 +03:00
Alibek Omarov
3f724b6b17 filesystem: remove some really unused variables 2023-12-04 03:00:29 +03:00
Alibek Omarov
255773b4de ref: gl: remove useless calls to glGetString if we're running under GL4ES 2023-12-04 02:53:51 +03:00
Alibek Omarov
5b73a788da ref: gl: disable unused variable warning for GL functions defintions 2023-12-04 02:53:27 +03:00
Alibek Omarov
748b06a00e wscript: warn about unused variables 2023-12-04 02:53:07 +03:00
Alibek Omarov
273bccdc9a engine: nswitch: fix compiling by removing stdc++ from SDL2 dependencies as we link it later (#1519) 2023-12-02 20:25:51 +03:00
Alibek Omarov
f0a2362da3 engine: wscript: another try, link nswitch port using gcc and not g++ 2023-12-02 19:29:30 +03:00
Alibek Omarov
be8ade23e8 engine: wscript: add -nostdlib++ for nswitch so we avoid implicit linking to standard C++ library (we link it explicitly ourselves) 2023-12-02 19:21:44 +03:00
Alibek Omarov
6814908d80 scripts: gha: enable verbose build for nswitch port 2023-12-02 19:08:34 +03:00
Alibek Omarov
08dbfc45d3 ref: gl: refactor getting edge position, texture and lightmap coords 2023-12-02 18:02:18 +03:00
Alibek Omarov
89f9b3df68 public: make simple bbox functions inline 2023-12-02 18:01:57 +03:00
Alibek Omarov
40c9a2fb82 engine: make Mod_SampleSizeForFace accept const surface 2023-12-02 18:01:57 +03:00
Andrey Akhmichin
a34c22fb10 engine: client: add support for "mp3 playfile/loopfile" commands. 2023-12-02 01:10:38 +03:00
Alibek Omarov
e161ff0f7a mainui: update 2023-11-27 19:25:36 +03:00
Alibek Omarov
fee42eab5a mainui: update 2023-11-27 19:05:48 +03:00
Alibek Omarov
2d2e03f235 engine: server: reset edict in ParseSaveTables like GoldSrc does which fixes messed up entities in mods that have advanced save-restore system (thanks to vasiavasiavasia95 for figuring out this bug) 2023-11-27 18:42:50 +03:00
Alibek Omarov
4c3c3529e9 engine: network: rename length variable to something that makes sense. Add usage line to http_addcustomserver 2023-11-26 23:20:46 +03:00
Alibek Omarov
7051b844ff engine: network: set HTTP buffer to 8kb on all systems, without depending on random constant like BUFSIZ 2023-11-26 23:19:49 +03:00
Alibek Omarov
68377435c8 engine: server: remove legacy light -> light_level entity key rewrite 2023-11-26 02:23:52 +03:00
Henry Ford
652b1804a8 wscript: make libdl optional for systems that include it in libc 2023-11-25 14:29:52 +03:00
Henry Ford
e7e1677786 engine: common: comply with C89 in OpenBSD wai_getExecutablePath 2023-11-25 14:29:52 +03:00
Henry Ford
f330aac113 engine: common: dont inlcude ucontext.h on OpenBSD where it doesnt exist 2023-11-25 14:29:52 +03:00
Henry Ford
dbdd330cf7 wscript: try to find alloca in stdlib.h on platforms without alloca.h or malloc.h 2023-11-25 14:29:52 +03:00
Andrey Akhmichin
c448c7b0b1 utils: mdldec: avoid double ".smd" extension output. 2023-11-22 11:05:34 +03:00
Andrey Akhmichin
8d7b9c2f01 utils: mdldec: always write trailing slash for non-empty destination path. 2023-11-22 11:03:28 +03:00
Alibek Omarov
b6a235445a vgui_support: update submodule 2023-11-22 11:02:25 +03:00
Alibek Omarov
9fcd4baa87 engine: client: gameui: expose animated_title and hd_background flags to main menu API 2023-11-22 11:01:18 +03:00
Alibek Omarov
fb0102eb8e filesystem: add support for two new liblist.gam keys: animated_title and hd_background 2023-11-22 11:01:18 +03:00
Alibek Omarov
9c1afaa372 filesystem: fix noskills being written as nomodels in gameinfo.txt 2023-11-22 11:01:18 +03:00
Alibek Omarov
1d1a6badb5 filesystem: VFileSystem009: HL25 compatibility (one single new method) 2023-11-22 11:01:18 +03:00
Andrey Akhmichin
2d41c9cb15 utils: mdldec: texture.c: add Targa image format output support. 2023-11-22 10:56:57 +03:00
Alibek Omarov
722cbe1f02 filesystem: forgot to add defaults.h include 2023-11-20 18:52:05 +03:00
Alibek Omarov
8ac2c241c4 mainui: update 2023-11-20 17:33:40 +03:00
Alibek Omarov
dd11f73951 filesystem: respect DEFAULT_MAX_EDICTS value 2023-11-20 17:32:35 +03:00
Alibek Omarov
a443547d4d common: defaults: add default macro for default gameinfo max_edicts value 2023-11-20 17:32:19 +03:00
Andrey Akhmichin
7a795edeb5 utils: mdldec: better validation checks. 2023-11-20 00:19:14 +03:00
Andrey Akhmichin
a8cbfb8dda Documentation: opensource-mods.md: update link to cs16-client. 2023-11-20 00:15:26 +03:00
SNMetamorph
5216cccef4 engine: server: added singleplayer check for userinfo update 2023-11-20 00:14:30 +03:00
SNMetamorph
a87f399e68 engine: client: revert export for pfnSPR_Load and pfnSPR_Frames functions
This needed for native support GoldSrc Monitor utility.
2023-11-20 00:14:06 +03:00
Andrey Akhmichin
dd310ab851 ci: upgrade freebsd tasks. 2023-11-20 00:13:42 +03:00
Andrey Akhmichin
16cc0ca0fe ref: gl: gl2_shim: replace "malloc.h" header with ALLOCA_H macro. 2023-11-20 00:13:04 +03:00
Alibek Omarov
83d26ad233 engine: server: add sv_allow_autoaim cvar 2023-11-20 00:11:10 +03:00
Alibek Omarov
d1f9a8f2db mainui: updates for HL25 2023-11-19 23:43:46 +03:00
Alibek Omarov
a2e1071808 game_launch: force link libm on Linux to workaround HL25 bug
HL25 doesn't link libm probably because of toolchain updates, where
--Wl,--as-needed became the default.

hl_linux is linked to libm which is why they probably didn't noticed this bug.

Workaround until Valve fixes it: https://github.com/ValveSoftware/halflife/issues/3492
2023-11-19 23:43:46 +03:00
Alibek Omarov
0aa8a2891c engine: client: add gles3compat to renderers list 2023-11-03 17:03:27 +03:00
Alibek Omarov
c0ceab7513 wscript: enable ref_gles3compat for Android 2023-11-03 17:01:47 +03:00
Velaron
5c90e716cb engine: platform: android: refactoring 2023-11-03 16:40:06 +03:00
Velaron
0073225549 scripts: gha: Android deps and build scripts 2023-11-03 16:36:55 +03:00
Alibek Omarov
d03a64602b wscript: change defaults for Android 2023-11-03 16:34:21 +03:00
Alibek Omarov
d67a4234cc filesystem: android: simplify code, get getAssets method only once, remove unneeded casts and memsets (where Mem_Calloc is used) 2023-11-03 16:29:57 +03:00
Alibek Omarov
0d37244490 filesystem: add missing const to 2nd argument of stringlistappend 2023-11-03 16:23:52 +03:00
Velaron
6426919cb5 filesystem: add Android assets support 2023-11-03 16:23:03 +03:00
Alibek Omarov
0a0d63663a filesystem: link with libandroid 2023-11-03 16:22:59 +03:00
Alibek Omarov
71b06801ef engine: platform: android: remove dead code 2023-11-03 14:48:28 +03:00
Alibek Omarov
cfc7b35927 engine: client: don't leave the user without mouse cursor if they enabled m_ignore 2023-11-03 14:48:28 +03:00
Alibek Omarov
76564958d1 engine: host: hide -nativeegl for Android SDL builds 2023-11-03 14:48:28 +03:00
Alibek Omarov
a464c3dd66 scripts: waifulib: compiler_optimizations: rename release build type to humanrights with kept compatibility 2023-11-02 14:33:00 +03:00
Alibek Omarov
bd969f3594 wscript: fix system opus detection, it didn't compile due to nonnull argument 2023-11-01 01:35:39 +03:00
Alibek Omarov
fb87d7c0b3 readme: wording, add icon, add donate.md link [skip ci] 2023-10-31 21:54:23 +03:00
Alibek Omarov
a69fc87940 Documentation: donate: add sponsorship information 2023-10-31 21:54:23 +03:00
Alibek Omarov
e481e1d73e ref: gl: enable GL waves with r_ripple 2023-10-31 21:52:00 +03:00
Alibek Omarov
6c0eed1b2b ref: gl: allow viewing water textures in their full glory with enabled r_ripple 2 2023-10-31 21:52:00 +03:00
Alibek Omarov
a6c67fdf9f ref: gl: upload only part of texture we're using, i.e. 64x64 for 64x64, 128x128 for 128x128 2023-10-31 21:52:00 +03:00
Alibek Omarov
03f838e37e mainui: update 2023-10-31 21:52:00 +03:00
Alibek Omarov
e21fa4a910 engine: add cvar r_refdll_loaded to indicate currently loaded renderer (for menu options and etc) 2023-10-31 21:52:00 +03:00
Alibek Omarov
46889ed453 ref: gl: libc rand() does better job at randomizing 2023-10-31 21:52:00 +03:00
Alibek Omarov
882fcc152c ref: gl: always scale down texture to 64x64, like sw.dll does 2023-10-31 21:52:00 +03:00
Alibek Omarov
a41902bd46 engine: mod_bmodel: detect water textures by texture name like LoadSurfaces does 2023-10-31 21:52:00 +03:00
Alibek Omarov
a6af32dafd ref: gl: connect ripply water to others parts of renderer (init, reset, animation and rendering) 2023-10-31 21:52:00 +03:00
Alibek Omarov
d6dfb83be7 ref: gl: ripply water implementation (bugfixed version from my Quake-2 patches) 2023-10-31 21:52:00 +03:00
Alibek Omarov
597429cf41 engine, filesystem: unify GetNativeObject between all the APIs. Allow getting filesystem APIs through GetNativeObject 2023-10-31 21:25:11 +03:00
Alibek Omarov
5ea074a1fd engine: fix build issues pointed by @Velaron 2023-10-31 21:01:42 +03:00
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
336 changed files with 20801 additions and 15746 deletions

27
.builds/alpine.yml Normal file
View File

@@ -0,0 +1,27 @@
image: alpine/latest
packages:
- build-base
- sdl2-dev
- freetype-dev
- fontconfig-dev
- opus-dev
sources:
- https://git.sr.ht/~a1batross/xash3d-fwgs
tasks:
- client: |
cd xash3d-fwgs
./waf configure -8 --enable-tests --enable-engine-tests build install --destdir=bin
- server: |
cd xash3d-fwgs
./waf configure --reconfigure --dedicated build install --destdir=bin
- run-tests: |
cd xash3d-fwgs/bin
export SDL_VIDEODRIVER=wayland
./xash3d -runtests
./xash -runtests
rm -rf valve/gameinfo.txt test_*
- package: |
cd xash3d-fwgs/bin
tar -cjvf xash3d-fwgs-alpine-amd64.tar.bz2 *
artifacts:
- xash3d-fwgs/bin/xash3d-fwgs-alpine-amd64.tar.bz2

30
.builds/debian-arm64.yml Normal file
View File

@@ -0,0 +1,30 @@
image: debian/sid
arch: amd64
packages:
- build-essential
- python-is-python3
- libsdl2-dev
- libfreetype-dev
- libfontconfig-dev
- libopus-dev
sources:
- https://git.sr.ht/~a1batross/xash3d-fwgs
tasks:
- client: |
cd xash3d-fwgs
./waf configure -8 --enable-tests --enable-engine-tests build install --destdir=bin
- server: |
cd xash3d-fwgs
./waf configure --reconfigure --dedicated build install --destdir=bin
- run-tests: |
cd xash3d-fwgs/bin
export SDL_VIDEODRIVER=wayland
./xash3d -runtests
./xash -runtests
rm -rf valve/gameinfo.txt test_*
- package: |
cd xash3d-fwgs/bin
tar -cjvf xash3d-fwgs-debian-arm64.tar.bz2 *
artifacts:
- xash3d-fwgs/bin/xash3d-fwgs-debian-arm64.tar.bz2

29
.builds/debian.yml Normal file
View File

@@ -0,0 +1,29 @@
image: debian/sid
packages:
- build-essential
- python-is-python3
- libsdl2-dev
- libfreetype-dev
- libfontconfig-dev
- libopus-dev
sources:
- https://git.sr.ht/~a1batross/xash3d-fwgs
tasks:
- client: |
cd xash3d-fwgs
./waf configure -8 --enable-tests --enable-engine-tests build install --destdir=bin
- server: |
cd xash3d-fwgs
./waf configure --reconfigure --dedicated build install --destdir=bin
- run-tests: |
cd xash3d-fwgs/bin
export SDL_VIDEODRIVER=wayland
./xash3d -runtests
./xash -runtests
rm -rf valve/gameinfo.txt test_*
- package: |
cd xash3d-fwgs/bin
tar -cjvf xash3d-fwgs-debian-amd64.tar.bz2 *
artifacts:
- xash3d-fwgs/bin/xash3d-fwgs-debian-amd64.tar.bz2

29
.builds/freebsd.yml Normal file
View File

@@ -0,0 +1,29 @@
image: freebsd/latest
packages:
- lang/python
- devel/pkgconf
- devel/sdl20
- print/freetype2
- x11-fonts/fontconfig
- audio/opus
sources:
- https://git.sr.ht/~a1batross/xash3d-fwgs
tasks:
- client: |
cd xash3d-fwgs
./waf configure --enable-tests --enable-engine-tests build install --destdir=bin
- server: |
cd xash3d-fwgs
./waf configure --reconfigure --dedicated build install --destdir=bin
- run-tests: |
cd xash3d-fwgs/bin
export SDL_VIDEODRIVER=wayland
./xash3d -runtests
./xash -runtests
rm -rf valve/gameinfo.txt test_*
- package: |
cd xash3d-fwgs/bin
tar -cjvf xash3d-fwgs-freebsd-amd64.tar.bz2 *
artifacts:
- xash3d-fwgs/bin/xash3d-fwgs-freebsd-amd64.tar.bz2

29
.builds/netbsd.yml Normal file
View File

@@ -0,0 +1,29 @@
image: netbsd/latest
packages:
- python311
- SDL2
- freetype2
- fontconfig
- libopus
- pkgconf
sources:
- https://git.sr.ht/~a1batross/xash3d-fwgs
tasks:
- client: |
cd xash3d-fwgs
python3.11 waf configure --enable-tests --enable-engine-tests build install --destdir=bin
- server: |
cd xash3d-fwgs
python3.11 waf configure --reconfigure --dedicated build install --destdir=bin
- run-tests: |
cd xash3d-fwgs/bin
export SDL_VIDEODRIVER=wayland
./xash3d -runtests
./xash -runtests
rm -rf valve/gameinfo.txt test_*
- package: |
cd xash3d-fwgs/bin
tar -cjvf xash3d-fwgs-netbsd-amd64.tar.bz2 *
artifacts:
- xash3d-fwgs/bin/xash3d-fwgs-netbsd-amd64.tar.bz2

26
.builds/openbsd.yml Normal file
View File

@@ -0,0 +1,26 @@
image: openbsd/latest
packages:
- python3
- sdl2
- opus
sources:
- https://git.sr.ht/~a1batross/xash3d-fwgs
tasks:
- client: |
cd xash3d-fwgs
python3 waf configure --enable-tests --enable-engine-tests build install --destdir=bin
- server: |
cd xash3d-fwgs
python3 waf configure --reconfigure --dedicated build install --destdir=bin
- run-tests: |
cd xash3d-fwgs/bin
export SDL_VIDEODRIVER=wayland
./xash3d -runtests
./xash -runtests
rm -rf valve/gameinfo.txt test_*
- package: |
cd xash3d-fwgs/bin
tar -cjvf xash3d-fwgs-openbsd-amd64.tar.bz2 *
artifacts:
- xash3d-fwgs/bin/xash3d-fwgs-openbsd-amd64.tar.bz2

View File

@@ -1,34 +1,22 @@
task:
name: freebsd-12-amd64
freebsd_instance:
image_family: freebsd-12-3
setup_script:
- pkg update
- pkg install -y git sdl2 python fontconfig
- git submodule update --init --recursive
test_script:
- ./scripts/cirrus/build_freebsd.sh dedicated
- ./scripts/cirrus/build_freebsd.sh full
task:
name: freebsd-13-amd64
freebsd_instance:
image_family: freebsd-13-1
setup_script:
- pkg update
- pkg install -y git sdl2 python fontconfig
- git submodule update --init --recursive
test_script:
- ./scripts/cirrus/build_freebsd.sh dedicated
- ./scripts/cirrus/build_freebsd.sh full
task: task:
name: freebsd-14-amd64 name: freebsd-14-amd64
freebsd_instance: freebsd_instance:
image_family: freebsd-14-0-snap image_family: freebsd-14-0
setup_script: setup_script:
- pkg update - pkg update
- pkg install -y git sdl2 python fontconfig - pkg install -y pkgconf git sdl2 python fontconfig opus
- git submodule update --init --recursive
test_script:
- ./scripts/cirrus/build_freebsd.sh dedicated
- ./scripts/cirrus/build_freebsd.sh full
task:
name: freebsd-15-amd64
freebsd_instance:
image_family: freebsd-15-0-snap
setup_script:
- pkg update
- pkg install -y pkgconf git sdl2 python fontconfig opus
- git submodule update --init --recursive - git submodule update --init --recursive
test_script: test_script:
- ./scripts/cirrus/build_freebsd.sh dedicated - ./scripts/cirrus/build_freebsd.sh dedicated

1
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1 @@
custom: https://github.com/FWGS/xash3d-fwgs/blob/master/Documentation/donate.md

View File

@@ -13,6 +13,8 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
include: include:
# Linux build specifically want oldest Ubuntu as possible
# to be crossdistribution compatible, otherwise use ubuntu-latest
- os: ubuntu-20.04 - os: ubuntu-20.04
targetos: linux targetos: linux
targetarch: amd64 targetarch: amd64
@@ -22,34 +24,28 @@ jobs:
# - os: ubuntu-aarch64-20.04 # - os: ubuntu-aarch64-20.04
# targetos: linux # targetos: linux
# targetarch: aarch64 # targetarch: aarch64
- os: ubuntu-20.04
# - os: ubuntu-20.04 targetos: android
# targetos: android targetarch: multiarch
# targetarch: 32
# - os: ubuntu-20.04
# targetos: android
# targetarch: 64
# - os: ubuntu-20.04 # - os: ubuntu-20.04
# targetos: motomagx # targetos: motomagx
# targetarch: armv6 # targetarch: armv6
- os: ubuntu-20.04 - os: ubuntu-latest
targetos: nswitch targetos: nswitch
targetarch: arm64 targetarch: arm64
- os: ubuntu-20.04 - os: ubuntu-latest
targetos: psvita targetos: psvita
targetarch: armv7hf targetarch: armv7hf
- os: windows-latest - os: windows-latest
targetos: win32 targetos: win32
targetarch: amd64 targetarch: amd64
- os: windows-latest - os: windows-2019 # always use the oldest possible for 32-bit because of older compilers, and better support of certain legacy OSes
targetos: win32 targetos: win32
targetarch: i386 targetarch: i386
env: env:
SDL_VERSION: 2.26.2 SDL_VERSION: 2.30.3
GH_CPU_ARCH: ${{ matrix.targetarch }} GH_CPU_ARCH: ${{ matrix.targetarch }}
ANDROID_SDK_TOOLS_VER: 4333796
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v3
@@ -80,7 +76,7 @@ jobs:
with: with:
submodules: recursive submodules: recursive
- name: Build flatpak (Compat.i386) - name: Build flatpak (Compat.i386)
uses: FWGS/flatpak-github-actions/flatpak-builder@v5 uses: FWGS/flatpak-github-actions/flatpak-builder@v6.1
with: with:
bundle: ${{ matrix.app }}.flatpak bundle: ${{ matrix.app }}.flatpak
manifest-path: scripts/flatpak/${{ matrix.app }}.yml manifest-path: scripts/flatpak/${{ matrix.app }}.yml

9
.gitignore vendored
View File

@@ -54,12 +54,18 @@ CMakeFiles
Makefile Makefile
cmake_install.cmake cmake_install.cmake
install_manifest.txt install_manifest.txt
CMakeLists.txt*
CMakeScripts
Testing
compile_commands.json
_deps
# makedepend # makedepend
Makefile.dep Makefile.dep
*.bak *.bak
ALL_BUILD.* ALL_BUILD.*
INSTALL.* INSTALL.*
ZERO_CHECK.* ZERO_CHECK.*
CMakeLists.txt
# Visual Studio # Visual Studio
*.obj *.obj
@@ -333,3 +339,6 @@ __pycache__
.history/* .history/*
.cache/* .cache/*
enc_temp_folder/ enc_temp_folder/
# KDevelop4
*.kdev4

View File

@@ -18,7 +18,7 @@ def build(bld):
target = 'gl4es', target = 'gl4es',
features = 'c', features = 'c',
includes = ['gl4es/src', 'gl4es/src/gl', 'gl4es/src/glx', 'gl4es/include'], includes = ['gl4es/src', 'gl4es/src/gl', 'gl4es/src/glx', 'gl4es/include'],
defines = ['NOX11', 'NO_GBM', 'NO_INIT_CONSTRUCTOR', 'DEFAULT_ES=2', 'NOEGL', 'EXTERNAL_GETPROCADDRESS=GL4ES_GetProcAddress', 'NO_LOADER', 'STATICLIB'], defines = ['NOX11', 'NO_GBM', 'NO_INIT_CONSTRUCTOR', 'DEFAULT_ES=2', 'NOEGL', 'NO_LOADER', 'STATICLIB'],
cflags = ['-w', '-fvisibility=hidden', '-std=gnu99'], cflags = ['-w', '-fvisibility=hidden', '-std=gnu99'],
subsystem = bld.env.MSVC_SUBSYSTEM, subsystem = bld.env.MSVC_SUBSYSTEM,
export_includes = '.') export_includes = '.')

View File

@@ -1,17 +1,16 @@
# Bug-compatibility in Xash3D FWGS # Bug-compatibility in Xash3D FWGS
Xash3D FWGS has special mode for games that rely on original engine bugs. Xash3D FWGS has special mode for games that rely on original engine bugs. In this mode, we emulate the behaviour of selected functions that may help running mods relying on engine bugs, but enabling them by default may break majority of other games.
In this mode, we emulate the behaviour of selected functions that may help running mods relying on engine bugs, but enabling them by default may break majority of other games.
At this time, we only have implemented GoldSrc bug-compatibility. It can be enabled with `-bugcomp` command line switch. At this time, we only have implemented GoldSrc bug-compatibility. It can be enabled with `-bugcomp` command line switch.
When `-bugcomp` is specified without argument, it enables everything. This behavior might be changed or removed in future versions.
When `-bugcomp` is specified with argument, it interpreted as flags separated with `+`. This way it's possible to combine multiple levels of bug-compatibility.
## GoldSrc bug-compatibility ## GoldSrc bug-compatibility
### Emulated bugs | Flag | Description | Games that require this flag |
| ------- | ----------- | ---------------------------- |
* `pfnPEntityOfEntIndex` in GoldSrc returns NULL for last player due to incorrect player index comparison | `peoei` | Reverts `pfnPEntityOfEntIndex` behavior to GoldSrc, where it returns NULL for last player due to incorrect player index comparison | * Counter-Strike: Condition Zero - Deleted Scenes |
| `gsmrf` | Rewrites message at the moment when Game DLL attempts to write an internal engine message, usually specific to GoldSrc protocol. Right now only supports `svc_spawnstaticsound`, more messages added by request. | * MetaMod/AMXModX based mods |
### Games and mods that require this
* Counter-Strike: Condition Zero - Deleted Scenes

24
Documentation/donate.md Normal file
View File

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

View File

@@ -0,0 +1,21 @@
## Environment variables
#### Xash3D FWGS
The engine respects these environment variables:
| Variable | Type | Description |
| --------------------- | ---------- | ----------- |
| `XASH3D_GAME` | _string_ | Overrides default game directory. Ignored if `-game` command line argument is set |
| `XASH3D_BASEDIR` | _string_ | Sets path to base (root) directory, instead of current working directory |
| `XASH3D_RODIR` | _string_ | Sets path to read-only base (root) directory. Ignored if `-rodir` command line argument is set |
| `XASH3D_EXTRAS_PAK1` | _string_ | Archive file from specified path will be added to virtual filesystem search path in the lowest possible priority |
| `XASH3D_EXTRAS_PAK2` | _string_ | Similar to `XASH3D_EXTRAS_PAK1` but next to it in priority list |
Environment variables NOT listed in the table above are used internally, and aren't considered as stable interface.
#### mdldec
| Variable | Type | Description |
| --------------------- | ---------- | ----------- |
| `MDLDEC_ACT_PATH` | _string_ | If set, will read activities list from this path |

View File

@@ -0,0 +1,25 @@
# GetNativeObject API
To be able to use platform-specific features or get optional engine interfaces, we've added a simple call to MobilityAPI on client DLL and PhysicsAPI for server DLL and extended MenuAPI for menu DLL.
It's defined like this:
```
void *pfnGetNativeObject( const char *name );
```
#### Cross-platform objects
Only these objects are guaranteed to be available on all targets.
| Object name | Interface |
|-------------|-----------|
| `VFileSystem009` | Provides C++ interface to filesystem, binary-compatible with Valve's VFileSystem009. |
| `XashFileSystemXXX` | Provides C interface to filesystem. This interface is unstable and not recommended for generic use, outside of engine internals. For more info about current version look into `filesystem.h`. |
#### Android-specific objects
| Object name | Interface |
|-------------|-----------|
| `JNIEnv` | Allows interfacing with Java Native Interface. |
| `ActivityClass` | Returns JNI object for engine Android activity class. |

View File

@@ -0,0 +1,65 @@
# sounds.lst.md
Using sounds.lst located in scripts folder, modder can override some of the hardcoded sounds in temp entities and server physics.
File format:
```
<group name>
{
<path1>
<path2>
<path3>
}
<group2 name> <path with %d> <min number> <max number>
```
* Sounds can use any supported sound format (WAV or MP3).
* The path must be relative to the sounds/ folder in the game or base directory root, addon folder, or archive root.
* Groups can be empty or omitted from the file to load no sound.
* Groups can either list a set of files or specify a format string and a range.
* Anything after // will be considered a comment and ignored.
* Behavior is undefined if the group was listed multiple times.
Currently supported groups are:
|Group name|Usage|
|----------|-----|
|`BouncePlayerShell`|Used for BOUNCE_SHELL tempentity hitsound|
|`BounceWeaponShell`|Used for BOUCNE_SHOTSHELL tempentity hitsound|
|`BounceConcrete`|Used for BOUNCE_CONCRETE tempentity hitsound|
|`BounceGlass`|Used for BOUCNE_GLASS|
|`BounceMetal`|Used for BOUNCE_METAL|
|`BounceFlesh`|Used for BOUNCE_FLESH|
|`BounceWood`|Used for BOUNCE_WOOD|
|`Ricochet`|Used for BOUNCE_SHRAP and ricochet tempentities|
|`Explode`|Used for tempentity explosions|
|`EntityWaterEnter`|Used for entity entering water|
|`EntityWaterExit`|Used for entity exiting water|
|`PlayerWaterEnter`|Used for player entering water|
|`PlayerWaterExit`|Used for player exiting water|
## Example
This example is based on defaults sounds used in Half-Life:
```
BouncePlayerShell "player/pl_shell%d.wav" 1 3
BounceWeaponShell "weapons/sshell%d.wav" 1 3
BounceConcrete "debris/concrete%d.wav" 1 3
BounceGlass "debris/glass%d.wav" 1 4
BounceMetal "debris/metal%d.wav" 1 6
BounceFlesh "debris/flesh%d.wav" 1 7
BounceWood "debris/wood%d.wav" 1 4
Ricochet "weapons/ric%d.wav" 1 5
Explode "weapons/explode%d.wav" 3 5
EntityWaterEnter "player/pl_wade%d.wav" 1 4
EntityWaterExit "player/pl_wade%d.wav" 1 4
PlayerWaterEnter
{
"player/pl_wade1.wav"
}
PlayerWaterExit
{
"player/pl_wade2.wav"
}
```

116
Documentation/gameinfo.md Normal file
View File

@@ -0,0 +1,116 @@
# 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 |
| ----------------------- | ---------- | ------------------------ | ----------- |
| `animated_title` | boolean | 0 | Use animated title in main menu (WON Half-Life logo.avi imitation from Half-Life 25-th anniversary update)
| `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) |
| `hd_background` | boolean | 0 | Use HD background for main menu (Half-Life 25-th anniversary update) |
| `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 |
| ----------------- | ------------------ | ---- |
| `animated_title` | `animated_title` | |
| `edicts` | `max_edicts` | |
| `fallback_dir` | `fallback_dir` | |
| `game` | `title` | |
| `gamedir` | `gamedir` | |
| `gamedll` | `gamedll` | |
| `gamedll_linux` | `gamedll_linux` | |
| `gamedll_osx` | `gamedll_osx` | |
| `hd_background` | `hd_background` | |
| `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` | |

15
Documentation/musl.md Normal file
View File

@@ -0,0 +1,15 @@
# Xash3D FWGS on `musl`
Xash3D FWGS works on `musl` out of the box. However, the engine doesn't try to differentiate glibc and musl anymore. If you see error similar to:
```
Host_InitError: can't initialize cl_dlls/client.so: Error relocating valve/cl_dlls/client.so: __sprintf_chk: symbol not found
```
... or you know that the game you're running is linked against glibc, you can try using `libgcompat`, like this:
```
$ LD_PRELOAD=/lib/libgcompat.so.0 ./xash3d ...
```
It will automatically add the missing symbols that glibc binaries usually need. In the future we might automatically link engine against `libgcompat` for better compatibility with prebuilt or closed-source games, if there will be any use for this.

View File

@@ -17,7 +17,7 @@ Mirrored on github - https://github.com/JoelTroch/am_src_rebirth
Mirrored on github - https://github.com/nekonomicon/BattleGrounds Mirrored on github - https://github.com/nekonomicon/BattleGrounds
## Bubblemod ## 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 Mirrored on github - https://github.com/HLSources/BubbleMod
@@ -85,6 +85,9 @@ Official gitlab repository - https://gitlab.com/Sockman/hltopdown
## Half-Life: Update ## Half-Life: Update
Official github repository - https://github.com/Fograin/hl-subsmod-ex 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 ## 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 Available on ModDB - https://www.moddb.com/mods/half-life-weapon-edition/downloads/half-life-weapon-edition-1508-alpha-open-src
@@ -130,22 +133,8 @@ Available in mod archive on ModDB - https://www.moddb.com/mods/overturn
## Oz Deathmatch ## Oz Deathmatch
Mirrored on github - https://github.com/nekonomicon/OZDM Mirrored on github - https://github.com/nekonomicon/OZDM
## 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
## Paranoia ## 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 ## Paranoia 2: The Savior
Prealpha, mirrored on github - https://github.com/a1batross/Paranoia2_ancient Prealpha, mirrored on github - https://github.com/a1batross/Paranoia2_ancient
@@ -160,12 +149,37 @@ Was found on HLFX - http://hlfx.ru/forum/showthread.php?s=2c892dfc52f72be52a89c3
## Ricochet ## Ricochet
Available in Valve's Half-Life repository - https://github.com/ValveSoftware/halflife/tree/master/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 ## Wizard Wars
Download page on official site - http://www.thothie.com/ww/ Download page on official site - http://www.thothie.com/ww/
## XashXT ## XashXT
Mirrored on github - https://github.com/a1batross/XashXT_original 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 ## 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 Available in mod archive on ModDB - https://www.moddb.com/mods/zombie-x-10-final/downloads/zombie-x-10-dle-beta6-last-version
@@ -187,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 Branch **aom** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/aom
## Afraid of Monsters: Director's cut ## 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 ## Azure Sheep
malortie's recreation - https://github.com/malortie/hl-asheep 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 ## Big Lolly
malortie's recreation - https://github.com/malortie/hl-biglolly malortie's recreation - https://github.com/malortie/hl-biglolly
@@ -214,7 +228,7 @@ Branch **caseclosed** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable
Branch **CAd** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/CAd Branch **CAd** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/CAd
## Counter Strike ## Counter Strike
Reverse-engineered code of client part by a1batross - https://github.com/FWGS/cs16-client/tree/v1.32 Reverse-engineered code of client part by a1batross - https://github.com/Velaron/cs16-client
Reverse-engineered code of server part by nagist - https://github.com/nagist/cs16nd Reverse-engineered code of server part by nagist - https://github.com/nagist/cs16nd
@@ -226,15 +240,22 @@ CSO-like Xash3D-based mod, CSMoE - https://github.com/MoeMod/CSMoE
## Crack-Life: Campaign Mode ## Crack-Life: Campaign Mode
Recreation by lostgamer aka nillerusr - https://github.com/LostGamerHL/crack_life Recreation by lostgamer aka nillerusr - https://github.com/LostGamerHL/crack_life
Reverse-engineered code: branch **clcampaign** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/clcampaign
## Escape from the Darkness ## Escape from the Darkness
malortie's recreation - https://github.com/malortie/hl-eftd 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 ## Half-Life: Blue Shift
Unkle Mike's recreation - https://hlfx.ru/forum/showthread.php?s=&threadid=5253 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 ## Half-Life: Induction
Branch **induction** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/induction Branch **induction** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/induction
@@ -242,12 +263,12 @@ Branch **induction** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/
## Half-Life: Opposing Force ## Half-Life: Opposing Force
Recreation by lostgamer aka nillerusr - https://github.com/LostGamerHL/hlsdk-xash3d 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 Spirit of Half Life: Opposing-Force Edition - https://github.com/Hammermaps-DEV/SOHL-V1.9-Opposing-Force-Edition
## Half-Life: Rebellion ## 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 ## Half-Life: Urbicide
Branch **hl_urbicide** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/hl_urbicide Branch **hl_urbicide** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/hl_urbicide
@@ -255,7 +276,7 @@ Branch **hl_urbicide** in hlsdk-portable - https://github.com/FWGS/hlsdk-portabl
## Half-Life: Visitors ## Half-Life: Visitors
malortie's recreation - https://github.com/malortie/hl-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 ## Half-Secret
Branch **half-secret** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/half-secret Branch **half-secret** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/half-secret
@@ -268,18 +289,18 @@ Branch **noffice** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tr
## Poke 646 ## Poke 646
malortie's recreation - https://github.com/malortie/hl-poke646 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 ## Poke 646: Vendetta
malortie's recreation - https://github.com/malortie/hl-poke646-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 ## 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 ## 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 ## Sewer Beta
Branch **sewer_beta** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/sewer_beta Branch **sewer_beta** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/sewer_beta
@@ -290,12 +311,12 @@ Reverse-engineered code by Velaron - https://github.com/Velaron/tf15-client
## The Gate ## The Gate
malortie's recreation - https://github.com/malortie/hl-thegate 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 ## They Hunger
malortie's recreation - https://github.com/malortie/hl-theyhunger 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 They Hunger: Tactical - https://www.moddb.com/mods/they-hunger-tactical/downloads/tht-source-code-documentation
@@ -338,16 +359,22 @@ Branch **half-screwed** in hlsdk-portable - https://github.com/FWGS/hlsdk-portab
Port to Linux - https://github.com/fmoraw/NS Port to Linux - https://github.com/fmoraw/NS
## Spirit of Half-Life ## 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 ## Swiss Cheese Halloween 2002
Just more playable version by malortie - https://github.com/malortie/hl-shall 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 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 ## Threewave CTF
Branch **dmc** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/dmc 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 ## Zombie-X
Branch **zombie-x** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/zombie-x Branch **zombie-x** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/zombie-x

View File

@@ -2,38 +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. 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: Status:
* **Supported**: active, confirmed to be fully functional. * **Supported**: active, was confirmed to be fully functional.
* **In progress**: active, under development. * **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 * **Old Engine**: port was for old engine fork
* **Not maintained**: lack of human resources * **Not maintained**: lack of human resources
* **Not merged**: was done in third-party fork, real status unknown
* **Deprecated**: not supported anymore * **Deprecated**: not supported anymore
Table is sorted by status. Table is sorted by status and platform.
| Platform | Status | Maintainer | Note | Platform | Status | Maintainer | Note
| -------- | ------ | ---------- | ---- | -------- | ------ | ---------- | ----
| Windows | Supported | @a1batross, @SNMetamorph | | Android | Supported | @Velaron |
| *BSD | Supported | @nekonomicon | | *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 | | DOS4GW | Supported | @mittorn |
| GNU/Linux(mipsel) | Supported | @mittorn | | GNU/Linux | Supported | @a1batross, @mittorn |
| Haiku | Supported | not maintained | Was added by #478 and #483
| macOS | Supported | @sofakng |
| MotoMAGX | Supported | @a1batross |
| PSVita | Supported | @fgsfdsfgs | | PSVita | Supported | @fgsfdsfgs |
| Switch | Supported | @fgsfdsfgs | | Switch | Supported | @fgsfdsfgs |
| Wii | In progress | Collaborative effort | [GitHub Repository](https://github.com/saucesaft/xash3d-wii) | Windows | Supported | @a1batross, @SNMetamorph |
| PSP | In progress | @Crow_bar, @Velaron | [GitHub Repository](https://github.com/Crow-bar/xash3d-fwgs) | 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 | | 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) | 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 | iOS | Deprecated | not maintained | See GitHub issue #61

View File

@@ -1,33 +1,27 @@
# Xash3D FWGS Engine # Xash3D FWGS Engine <img align="right" width="128" height="128" src="https://github.com/FWGS/xash3d-fwgs/raw/master/game_launch/icon-xash-material.png" alt="Xash3D FWGS icon" />
[![GitHub Actions Status](https://github.com/FWGS/xash3d-fwgs/actions/workflows/c-cpp.yml/badge.svg)](https://github.com/FWGS/xash3d-fwgs/actions/workflows/c-cpp.yml) [![FreeBSD Build Status](https://img.shields.io/cirrus/github/FWGS/xash3d-fwgs?label=freebsd%20build)](https://cirrus-ci.com/github/FWGS/xash3d-fwgs) [![Discord Server](https://img.shields.io/discord/355697768582610945.svg)](http://fwgsdiscord.mentality.rip/) \ [![builds.sr.ht status](https://builds.sr.ht/~a1batross/xash3d-fwgs.svg)](https://builds.sr.ht/~a1batross/xash3d-fwgs?) [![GitHub Actions Status](https://github.com/FWGS/xash3d-fwgs/actions/workflows/c-cpp.yml/badge.svg)](https://github.com/FWGS/xash3d-fwgs/actions/workflows/c-cpp.yml) [![FreeBSD Build Status](https://img.shields.io/cirrus/github/FWGS/xash3d-fwgs?label=freebsd%20build)](https://cirrus-ci.com/github/FWGS/xash3d-fwgs) [![Discord Server](https://img.shields.io/discord/355697768582610945.svg)](http://fwgsdiscord.mentality.rip/) \
[![Download Stable](https://img.shields.io/badge/download-stable-yellow)](https://github.com/FWGS/xash3d-fwgs/releases/latest) [![Download Testing](https://img.shields.io/badge/downloads-testing-orange)](https://github.com/FWGS/xash3d-fwgs/releases/tag/continuous) [![Download Stable](https://img.shields.io/badge/download-stable-yellow)](https://github.com/FWGS/xash3d-fwgs/releases/latest) [![Download Testing](https://img.shields.io/badge/downloads-testing-orange)](https://github.com/FWGS/xash3d-fwgs/releases/tag/continuous)
Xash3D FWGS is a fork of Xash3D Engine by Unkle Mike with extended features and crossplatform. Xash3D FWGS is a game engine, aimed to provide compatibility with Half-Life Engine and extend it, as well as to give game developers well known workflow.
``` Xash3D FWGS is a heavily modified fork of an original [Xash3D Engine](https://www.moddb.com/engines/xash3d-engine) by Unkle Mike.
Xash3D is a game engine, aimed to provide compatibility with Half-Life Engine,
as well as to give game developers well known workflow and extend it. ## Donate
Read more about Xash3D on ModDB: https://www.moddb.com/engines/xash3d-engine [![Donate to FWGS button](https://img.shields.io/badge/Donate_to_FWGS-%3C3-magenta)](Documentation/donate.md) \
``` If you like Xash3D FWGS, consider supporting individual engine maintainers. By supporting us, you help to continue developing this game engine further. The sponsorship links are available in [documentation](Documentation/donate.md).
## Fork features ## Fork features
* HLSDK 2.4 support. * Steam Half-Life (HLSDK 2.4) support.
* Crossplatform: supported x86 and ARM on Windows/Linux/BSD/Android. ([see docs for more info](Documentation/ports.md)) * Crossplatform and modern compilers support: supports Windows, Linux, BSD & Android on x86 & ARM and [many more](Documentation/ports.md).
* Modern compilers support: say no more to MSVC6. * Better multiplayer support: multiple master servers, headless dedicated server, voice chat and IPv6 support.
* Better multiplayer support: multiple master servers, headless dedicated server. * Multiple renderers support: OpenGL, GLESv1, GLESv2 and Software.
* Mobility API: allows better game integration on mobile devices(vibration, touch controls) * Advanced virtual filesystem: `.pk3` and `.pk3dir` support, compatibility with GoldSrc FS module, fast case-insensitivity emulation for crossplatform.
* Different input methods: touch, gamepad and classic mouse & keyboard. * Mobility API: better game integration on mobile devices (vibration, touch controls)
* Different input methods: touch and gamepad in addition to mouse & keyboard.
* TrueType font rendering, as a part of mainui_cpp. * TrueType font rendering, as a part of mainui_cpp.
* Multiple renderers support: OpenGL, GLESv1, GLESv2, Software. * External VGUI support module.
* Voice support. * PNG & KTX2 image format support.
* External filesystem module like in GoldSrc engine. * [A set of small improvements](Documentation/), without broken compatibility.
* 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.
* Vulkan renderer.
## Installation & Running ## 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. 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.

View File

@@ -18,21 +18,17 @@ GNU General Public License for more details.
// video backends (XASH_VIDEO) // video backends (XASH_VIDEO)
#define VIDEO_NULL 0 #define VIDEO_NULL 0
#define VIDEO_SDL 1 #define VIDEO_SDL 1
#define VIDEO_ANDROID 2
#define VIDEO_FBDEV 3 #define VIDEO_FBDEV 3
#define VIDEO_DOS 4 #define VIDEO_DOS 4
// audio backends (XASH_SOUND) // audio backends (XASH_SOUND)
#define SOUND_NULL 0 #define SOUND_NULL 0
#define SOUND_SDL 1 #define SOUND_SDL 1
#define SOUND_OPENSLES 2
#define SOUND_ALSA 3 #define SOUND_ALSA 3
// input (XASH_INPUT) // input (XASH_INPUT)
#define INPUT_NULL 0 #define INPUT_NULL 0
#define INPUT_SDL 1 #define INPUT_SDL 1
#define INPUT_ANDROID 2
#define INPUT_EVDEV 3 #define INPUT_EVDEV 3
// timer (XASH_TIMER) // timer (XASH_TIMER)
@@ -45,16 +41,13 @@ GNU General Public License for more details.
// messageboxes (XASH_MESSAGEBOX) // messageboxes (XASH_MESSAGEBOX)
#define MSGBOX_STDERR 0 #define MSGBOX_STDERR 0
#define MSGBOX_SDL 1 #define MSGBOX_SDL 1
#define MSGBOX_ANDROID 2
#define MSGBOX_WIN32 3 #define MSGBOX_WIN32 3
#define MSGBOX_NSWITCH 4 #define MSGBOX_NSWITCH 4
// library loading (XASH_LIB) // library loading (XASH_LIB)
#define LIB_NULL 0 #define LIB_NULL 0
#define LIB_POSIX 1 #define LIB_POSIX 1
#define LIB_WIN32 2 #define LIB_WIN32 2
#define LIB_STATIC 3 #define LIB_STATIC 3
#endif /* BACKENDS_H */ #endif /* BACKENDS_H */

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 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 typedef enum
{ {
@@ -25,9 +38,15 @@ typedef enum
PF_DXT3, // s3tc DXT3/BC2 format PF_DXT3, // s3tc DXT3/BC2 format
PF_DXT5, // s3tc DXT5/BC3 format PF_DXT5, // s3tc DXT5/BC3 format
PF_ATI2, // latc ATI2N/BC5 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_SIGNED, // bptc BC6H signed FP16 format
PF_BC6H_UNSIGNED, // bptc BC6H unsigned 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 PF_TOTALCOUNT, // must be last
} pixformat_t; } pixformat_t;
@@ -50,6 +69,7 @@ typedef enum
IL_LOAD_DECAL = BIT(5), // special mode for load gradient decals IL_LOAD_DECAL = BIT(5), // special mode for load gradient decals
IL_OVERVIEW = BIT(6), // overview required some unque operations IL_OVERVIEW = BIT(6), // overview required some unque operations
IL_LOAD_PLAYER_DECAL = BIT(7), // special mode for player decals 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; } ilFlags_t;
// goes into rgbdata_t->encode // goes into rgbdata_t->encode

View File

@@ -534,5 +534,14 @@ typedef struct
#define MAX_EFRAGS 8192 // Arcane Dimensions required #define MAX_EFRAGS 8192 // Arcane Dimensions required
#define MAX_REQUESTS 64 #define MAX_REQUESTS 64
#if ! XASH_64BIT
STATIC_ASSERT( sizeof( mextrasurf_t ) == 324, "mextrasurf_t unexpected size" );
STATIC_ASSERT( sizeof( decal_t ) == 60, "decal_t unexpected size");
STATIC_ASSERT( sizeof( mfaceinfo_t ) == 176, "mfaceinfo_t unexpected size");
#else
STATIC_ASSERT( sizeof( mextrasurf_t) == 496, "mextrasurf_t unexpected size");
STATIC_ASSERT( sizeof( decal_t ) == 88, "decal_t unexpected size");
STATIC_ASSERT( sizeof( mfaceinfo_t ) == 304, "mfaceinfo_t unexpected size");
#endif
#endif//COM_MODEL_H #endif//COM_MODEL_H

View File

@@ -717,6 +717,7 @@ enum
kRenderFxExplode, // Scale up really big! kRenderFxExplode, // Scale up really big!
kRenderFxGlowShell, // Glowing Shell kRenderFxGlowShell, // Glowing Shell
kRenderFxClampMinScale, // Keep this sprite from getting very small (SPRITES only!) kRenderFxClampMinScale, // Keep this sprite from getting very small (SPRITES only!)
kRenderFxLightMultiplier,
}; };
typedef int func_t; typedef int func_t;

View File

@@ -52,26 +52,6 @@ SETUP BACKENDS DEFINITIONS
#endif #endif
#endif // XASH_MESSAGEBOX #endif // XASH_MESSAGEBOX
#endif #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 1
#define XASH_DYNAMIC_DLADDR
#elif XASH_LINUX #elif XASH_LINUX
// we are building for Linux without SDL2, can draw only to framebuffer yet // we are building for Linux without SDL2, can draw only to framebuffer yet
#ifndef XASH_VIDEO #ifndef XASH_VIDEO
@@ -171,6 +151,8 @@ Default build-depended cvar and constant values
#define DEFAULT_MODE_WIDTH 960 #define DEFAULT_MODE_WIDTH 960
#define DEFAULT_MODE_HEIGHT 544 #define DEFAULT_MODE_HEIGHT 544
#define DEFAULT_ALLOWCONSOLE 1 #define DEFAULT_ALLOWCONSOLE 1
#elif XASH_ANDROID
#define DEFAULT_TOUCH_ENABLE "1"
#elif XASH_MOBILE_PLATFORM #elif XASH_MOBILE_PLATFORM
#define DEFAULT_TOUCH_ENABLE "1" #define DEFAULT_TOUCH_ENABLE "1"
#define DEFAULT_M_IGNORE "1" #define DEFAULT_M_IGNORE "1"
@@ -204,7 +186,11 @@ Default build-depended cvar and constant values
#endif // DEFAULT_ALLOWCONSOLE #endif // DEFAULT_ALLOWCONSOLE
#ifndef DEFAULT_FULLSCREEN #ifndef DEFAULT_FULLSCREEN
#define DEFAULT_FULLSCREEN 1 #define DEFAULT_FULLSCREEN "1" // must be a string
#endif // DEFAULT_FULLSCREEN #endif // DEFAULT_FULLSCREEN
#ifndef DEFAULT_MAX_EDICTS
#define DEFAULT_MAX_EDICTS 1200 // was 900 before HL25
#endif // DEFAULT_MAX_EDICTS
#endif // DEFAULTS_H #endif // DEFAULTS_H

View File

@@ -27,4 +27,19 @@ GNU General Public License for more details.
#define ENGINE_COMPUTE_STUDIO_LERP (1<<7) // enable MOVETYPE_STEP lerping back in engine #define ENGINE_COMPUTE_STUDIO_LERP (1<<7) // enable MOVETYPE_STEP lerping back in engine
#define ENGINE_LINEAR_GAMMA_SPACE (1<<8) // disable influence of gamma/brightness cvars to textures/lightmaps, for mods with custom renderer #define ENGINE_LINEAR_GAMMA_SPACE (1<<8) // disable influence of gamma/brightness cvars to textures/lightmaps, for mods with custom renderer
#define ENGINE_STEP_POSHISTORY_LERP (1U<<31) // enable MOVETYPE_STEP interpolation based on position history. Incompatible with ENGINE_COMPUTE_STUDIO_LERP!
// adjust the mask when features will be added or removed
#define ENGINE_FEATURES_MASK \
( ENGINE_WRITE_LARGE_COORD \
| ENGINE_QUAKE_COMPATIBLE \
| ENGINE_LOAD_DELUXEDATA \
| ENGINE_PHYSICS_PUSHER_EXT \
| ENGINE_LARGE_LIGHTMAPS \
| ENGINE_COMPENSATE_QUAKE_BUG \
| ENGINE_IMPROVED_LINETRACE \
| ENGINE_COMPUTE_STUDIO_LERP \
| ENGINE_LINEAR_GAMMA_SPACE \
| ENGINE_STEP_POSHISTORY_LERP )
#endif//FEATURES_H #endif//FEATURES_H

View File

@@ -19,6 +19,8 @@ GNU General Public License for more details.
#define GFL_NOMODELS (1<<0) #define GFL_NOMODELS (1<<0)
#define GFL_NOSKILLS (1<<1) #define GFL_NOSKILLS (1<<1)
#define GFL_RENDER_PICBUTTON_TEXT (1<<2) #define GFL_RENDER_PICBUTTON_TEXT (1<<2)
#define GFL_HD_BACKGROUND (1<<3)
#define GFL_ANIMATED_TITLE (1<<4)
/* /*
======================================================================== ========================================================================

View File

@@ -1,18 +1,35 @@
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ /*
// Copyright (C) 1996-1997 Id Software, Inc.
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#if !defined( KBUTTONH ) This program is free software; you can redistribute it and/or
#define KBUTTONH modify it under the terms of the GNU General Public License
#pragma once as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
typedef struct kbutton_s 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 KBUTTON_H
#define KBUTTON_H
// a1ba: copied from WinQuake/client.h
//
// cl_input
//
typedef struct
{ {
int down[2]; // key nums holding it down int down[2]; // key nums holding it down
int state; // low bit is down state int state; // low bit is down state
} kbutton_t; } kbutton_t;
#endif // !KBUTTONH STATIC_ASSERT( sizeof( kbutton_t ) == 12, "kbutton_t isn't 12 bytes!" );
#endif // KBUTTON_H

View File

@@ -1,76 +1,74 @@
/*** /*
* Copyright (C) 1997-2001 Id Software, Inc.
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* Use, distribution, and modification of this source code and/or resulting
* object code is restricted to non-commercial enhancements to products from
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
#ifndef NETADR_H This program is free software; you can redistribute it and/or
#define NETADR_H 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 NET_ADR_H
#define NET_ADR_H
#include "build.h"
#include STDINT_H #include STDINT_H
typedef enum // net.h -- quake's interface to the networking layer
{ // a1ba: copied from Quake-2/qcommon/qcommon.h and modified to support IPv6
NA_UNUSED = 0,
NA_LOOPBACK,
NA_BROADCAST,
NA_IP,
NA_IPX,
NA_BROADCAST_IPX,
NA_IP6,
NA_MULTICAST_IP6, // all nodes multicast
} netadrtype_t;
// Original structure: #define PORT_ANY -1
// typedef struct netadr_s
// { typedef enum {NA_LOOPBACK = 1, NA_BROADCAST, NA_IP, NA_IPX, NA_BROADCAST_IPX, NA_IP6, NA_MULTICAST_IP6} netadrtype_t;
// netadrtype_t type;
// unsigned char ip[4]; /*
// unsigned char ipx[10]; Original Quake-2 structure:
// unsigned short port; typedef struct
// } netadr_t; {
netadrtype_t type;
byte ip[4];
byte ipx[10];
unsigned short port;
} netadr_t;
*/
#pragma pack( push, 1 ) #pragma pack( push, 1 )
typedef struct netadr_s typedef struct netadr_s
{ {
union union
{ {
// IPv6 struct
struct struct
{ {
uint32_t type; uint16_t type6;
uint8_t ip6[16];
};
struct
{
uint32_t type; // must be netadrtype_t but will break with short enums
union union
{ {
uint8_t ip[4]; uint8_t ip[4];
uint32_t ip4; uint32_t ip4; // for easier conversions
}; };
uint8_t ipx[10]; 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; uint16_t port;
} netadr_t; } netadr_t;
#pragma pack( pop ) #pragma pack( pop )
STATIC_ASSERT( sizeof( netadr_t ) == 20, "invalid netadr_t size" ); STATIC_ASSERT( sizeof( netadr_t ) == 20, "netadr_t isn't 20 bytes!" );
#endif//NETADR_H #endif // NET_ADR_H

View File

@@ -35,7 +35,6 @@ GNU General Public License for more details.
#define __cdecl #define __cdecl
#define __stdcall #define __stdcall
#define _inline static inline #define _inline static inline
#define FORCEINLINE inline __attribute__((always_inline))
#if XASH_POSIX #if XASH_POSIX
#include <unistd.h> #include <unistd.h>
@@ -63,13 +62,6 @@ GNU General Public License for more details.
int x, y; int x, y;
} POINT; } POINT;
#else // WIN32 #else // WIN32
#ifdef __MINGW32__
#define _inline static inline
#define FORCEINLINE inline __attribute__((always_inline))
#else
#define FORCEINLINE __forceinline
#endif
#define open _open #define open _open
#define read _read #define read _read
#define alloca _alloca #define alloca _alloca

View File

@@ -107,7 +107,8 @@ typedef enum
TF_ARB_FLOAT = (1<<26), // float textures TF_ARB_FLOAT = (1<<26), // float textures
TF_NOCOMPARE = (1<<27), // disable comparing for depth textures TF_NOCOMPARE = (1<<27), // disable comparing for depth textures
TF_ARB_16BIT = (1<<28), // keep image as 16-bit (not 24) TF_ARB_16BIT = (1<<28), // keep image as 16-bit (not 24)
TF_MULTISAMPLE = (1<<29) // multisampling texture TF_MULTISAMPLE = (1<<29), // multisampling texture
TF_ALLOW_NEAREST = (1<<30), // allows toggling nearest filtering for TF_NOMIPMAP textures
} texFlags_t; } texFlags_t;
typedef enum typedef enum
@@ -229,7 +230,7 @@ typedef struct render_api_s
void (*R_Reserved0)( void ); void (*R_Reserved0)( void );
// static allocations // static allocations
void *(*pfnMemAlloc)( size_t cb, const char *filename, const int fileline ); void *(*pfnMemAlloc)( size_t cb, const char *filename, const int fileline ) ALLOC_CHECK( 1 );
void (*pfnMemFree)( void *mem, const char *filename, const int fileline ); void (*pfnMemFree)( void *mem, const char *filename, const int fileline );
// engine utils (not related with render API but placed here) // engine utils (not related with render API but placed here)

View File

@@ -28,11 +28,7 @@ typedef byte rgb_t[3]; // unsigned byte colorpack
typedef vec_t matrix3x4[3][4]; typedef vec_t matrix3x4[3][4];
typedef vec_t matrix4x4[4][4]; typedef vec_t matrix4x4[4][4];
#if XASH_64BIT
typedef uint32_t poolhandle_t; typedef uint32_t poolhandle_t;
#else
typedef void* poolhandle_t;
#endif
#undef true #undef true
#undef false #undef false
@@ -57,9 +53,7 @@ typedef uint64_t longtime_t;
#define MAX_USERMSG_LENGTH 2048 // don't modify it's relies on a client-side definitions #define MAX_USERMSG_LENGTH 2048 // don't modify it's relies on a client-side definitions
#define BIT( n ) ( 1U << ( n )) #define BIT( n ) ( 1U << ( n ))
#define GAMMA ( 2.2f ) // Valve Software gamma #define BIT64( n ) ( 1ULL << ( n ))
#define INVGAMMA ( 1.0f / 2.2f ) // back to 1.0
#define TEXGAMMA ( 0.9f ) // compensate dim textures
#define SetBits( iBitVector, bits ) ((iBitVector) = (iBitVector) | (bits)) #define SetBits( iBitVector, bits ) ((iBitVector) = (iBitVector) | (bits))
#define ClearBits( iBitVector, bits ) ((iBitVector) = (iBitVector) & ~(bits)) #define ClearBits( iBitVector, bits ) ((iBitVector) = (iBitVector) & ~(bits))
#define FBitSet( iBitVector, bit ) ((iBitVector) & (bit)) #define FBitSet( iBitVector, bit ) ((iBitVector) & (bit))
@@ -77,47 +71,71 @@ typedef uint64_t longtime_t;
#define ColorIndex( c ) ((( c ) - '0' ) & 7 ) #define ColorIndex( c ) ((( c ) - '0' ) & 7 )
#if defined( __GNUC__ ) #if defined( __GNUC__ )
#ifdef __i386__ #if defined( __i386__ )
#define EXPORT __attribute__(( visibility( "default" ), force_align_arg_pointer )) #define EXPORT __attribute__(( visibility( "default" ), force_align_arg_pointer ))
#define GAME_EXPORT __attribute(( force_align_arg_pointer )) #define GAME_EXPORT __attribute(( force_align_arg_pointer ))
#else #else
#define EXPORT __attribute__(( visibility ( "default" ))) #define EXPORT __attribute__(( visibility ( "default" )))
#define GAME_EXPORT #define GAME_EXPORT
#endif #endif
#define _format(x) __attribute__((format(printf, x, x+1)))
#define NORETURN __attribute__(( noreturn )) #define NORETURN __attribute__(( noreturn ))
#elif defined(_MSC_VER) #define NONNULL __attribute__(( nonnull ))
#define _format( x ) __attribute__(( format( printf, x, x + 1 )))
#define ALLOC_CHECK( x ) __attribute__(( alloc_size( x )))
#define NO_ASAN __attribute__(( no_sanitize( "address" )))
#define RENAME_SYMBOL( x ) asm( x )
#else
#if defined( _MSC_VER )
#define EXPORT __declspec( dllexport ) #define EXPORT __declspec( dllexport )
#define GAME_EXPORT #define NO_ASAN __declspec( no_sanitize_address )
#define _format(x)
#define NORETURN
#else #else
#define EXPORT #define EXPORT
#define NO_ASAN
#endif
#define GAME_EXPORT #define GAME_EXPORT
#define _format(x)
#define NORETURN #define NORETURN
#define NONNULL
#define _format( x )
#define ALLOC_CHECK( x )
#define RENAME_SYMBOL( x )
#endif #endif
#if ( __GNUC__ >= 3 ) #if __GNUC__ >= 3
#define unlikely( x ) __builtin_expect( x, 0 ) #define unlikely( x ) __builtin_expect( x, 0 )
#define likely( x ) __builtin_expect( x, 1 ) #define likely( x ) __builtin_expect( x, 1 )
#elif defined( __has_builtin ) #elif defined( __has_builtin )
#if __has_builtin( __builtin_expect ) #if __has_builtin( __builtin_expect ) // this must be after defined() check
#define unlikely( x ) __builtin_expect( x, 0 ) #define unlikely( x ) __builtin_expect( x, 0 )
#define likely( x ) __builtin_expect( x, 1 ) #define likely( x ) __builtin_expect( x, 1 )
#else
#define unlikely(x) (x)
#define likely(x) (x)
#endif #endif
#else #endif
#if !defined( unlikely ) || !defined( likely )
#define unlikely( x ) ( x ) #define unlikely( x ) ( x )
#define likely( x ) ( x ) #define likely( x ) ( x )
#endif #endif
#if defined( static_assert ) // C11 static_assert #if __STDC_VERSION__ >= 202311L || __cplusplus >= 201103L // C23 or C++ static_assert is a keyword
#define STATIC_ASSERT_( ignore, x, y ) static_assert( x, y )
#define STATIC_ASSERT static_assert #define STATIC_ASSERT static_assert
#elif __STDC_VERSION__ >= 201112L // in C11 it's _Static_assert
#define STATIC_ASSERT_( ignore, x, y ) _Static_assert( x, y )
#define STATIC_ASSERT _Static_assert
#else #else
#define STATIC_ASSERT( x, y ) extern int _static_assert_##__LINE__[( x ) ? 1 : -1] #define STATIC_ASSERT_( id, x, y ) extern int id[( x ) ? 1 : -1]
// need these to correctly expand the line macro
#define STATIC_ASSERT_3( line, x, y ) STATIC_ASSERT_( static_assert_ ## line, x, y )
#define STATIC_ASSERT_2( line, x, y ) STATIC_ASSERT_3( line, x, y )
#define STATIC_ASSERT( x, y ) STATIC_ASSERT_2( __LINE__, x, y )
#endif
#if !defined( __cplusplus ) && __STDC_VERSION__ >= 199101L // not C++ and C99 or newer
#define XASH_RESTRICT restrict
#elif _MSC_VER || __GNUC__ || __clang__ // compiler-specific extensions
#define XASH_RESTRICT __restrict
#else
#define XASH_RESTRICT // nothing
#endif #endif
#ifdef XASH_BIG_ENDIAN #ifdef XASH_BIG_ENDIAN
@@ -177,6 +195,7 @@ typedef struct dll_info_s
} dll_info_t; } dll_info_t;
typedef void (*setpair_t)( const char *key, const void *value, const void *buffer, void *numpairs ); typedef void (*setpair_t)( const char *key, const void *value, const void *buffer, void *numpairs );
typedef void *(*pfnCreateInterface_t)( const char *, int * );
// config strings are a general means of communication from // config strings are a general means of communication from
// the server to all connected clients. // the server to all connected clients.

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

@@ -1,18 +1,22 @@
/*** /*
* Copyright (C) 1996-1997 Id Software, Inc.
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* Use, distribution, and modification of this source code and/or resulting
* object code is restricted to non-commercial enhancements to products from
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
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.
*/
{-0.525731, 0.000000, 0.850651}, {-0.525731, 0.000000, 0.850651},
{-0.442863, 0.238856, 0.864188}, {-0.442863, 0.238856, 0.864188},
{-0.295242, 0.000000, 0.955423}, {-0.295242, 0.000000, 0.955423},

View File

@@ -85,6 +85,12 @@ void CL_PlayCDTrack_f( void )
paused = false; paused = false;
looped = false; looped = false;
} }
else if( !Q_stricmp( command, "playfile" ))
{
S_StartBackgroundTrack( pszTrack, NULL, 0, true );
paused = false;
looped = false;
}
else if( !Q_stricmp( command, "loop" )) else if( !Q_stricmp( command, "loop" ))
{ {
if( Q_isdigit( pszTrack )) if( Q_isdigit( pszTrack ))
@@ -96,6 +102,12 @@ void CL_PlayCDTrack_f( void )
paused = false; paused = false;
looped = true; looped = true;
} }
else if( !Q_stricmp( command, "loopfile" ))
{
S_StartBackgroundTrack( pszTrack, pszTrack, 0, true );
paused = false;
looped = true;
}
else if( !Q_stricmp( command, "pause" )) else if( !Q_stricmp( command, "pause" ))
{ {
S_StreamSetPause( true ); S_StreamSetPause( true );
@@ -145,32 +157,12 @@ void CL_PlayCDTrack_f( void )
CL_ScreenshotGetName CL_ScreenshotGetName
================== ==================
*/ */
static qboolean CL_ScreenshotGetName( int lastnum, char *filename, size_t size ) static qboolean CL_ScreenshotGetName( const char *fmt, int lastnum, char *filename, size_t size )
{ {
if( lastnum < 0 || lastnum > 9999 ) if( lastnum < 0 || lastnum > 9999 )
{
Con_Printf( S_ERROR "unable to write screenshot\n" );
return false; return false;
}
return Q_snprintf( filename, size, "scrshots/%s_shot%04d.png", clgame.mapname, lastnum ) > 0; return Q_snprintf( filename, size, fmt, clgame.mapname, lastnum ) > 0;
}
/*
==================
CL_SnapshotGetName
==================
*/
static qboolean CL_SnapshotGetName( int lastnum, char *filename, size_t size )
{
if( lastnum < 0 || lastnum > 9999 )
{
Con_Printf( S_ERROR "unable to write snapshot\n" );
FS_AllowDirectPaths( false );
return false;
}
return Q_snprintf( filename, size, "../%s_%04d.png", clgame.mapname, lastnum ) > 0;
} }
/* /*
@@ -180,127 +172,6 @@ static qboolean CL_SnapshotGetName( int lastnum, char *filename, size_t size )
============================================================================== ==============================================================================
*/ */
/*
==================
CL_ScreenShot_f
normal screenshot
==================
*/
void CL_ScreenShot_f( void )
{
int i;
string checkname;
if( CL_IsDevOverviewMode() == 1 )
{
// special case for write overview image and script file
Q_snprintf( cls.shotname, sizeof( cls.shotname ), "overviews/%s.bmp", clgame.mapname );
cls.scrshot_action = scrshot_mapshot; // build new frame for mapshot
}
else
{
// scan for a free filename
for( i = 0; i < 9999; i++ )
{
if( !CL_ScreenshotGetName( i, checkname, sizeof( checkname )))
return; // no namespace
if( !FS_FileExists( checkname, false ))
break;
}
Q_strncpy( cls.shotname, checkname, sizeof( cls.shotname ));
cls.scrshot_action = scrshot_normal; // build new frame for screenshot
}
cls.envshot_vieworg = NULL; // no custom view
cls.envshot_viewsize = 0;
}
/*
==================
CL_SnapShot_f
save screenshots into root dir
==================
*/
void CL_SnapShot_f( void )
{
int i;
string checkname;
if( CL_IsDevOverviewMode() == 1 )
{
// special case for write overview image and script file
Q_snprintf( cls.shotname, sizeof( cls.shotname ), "overviews/%s.bmp", clgame.mapname );
cls.scrshot_action = scrshot_mapshot; // build new frame for mapshot
}
else
{
FS_AllowDirectPaths( true );
// scan for a free filename
for( i = 0; i < 9999; i++ )
{
if( !CL_SnapshotGetName( i, checkname, sizeof( checkname )))
return; // no namespace
if( !FS_FileExists( checkname, false ))
break;
}
FS_AllowDirectPaths( false );
Q_strncpy( cls.shotname, checkname, sizeof( cls.shotname ));
cls.scrshot_action = scrshot_snapshot; // build new frame for screenshot
}
cls.envshot_vieworg = NULL; // no custom view
cls.envshot_viewsize = 0;
}
/*
==================
CL_EnvShot_f
cubemap view
==================
*/
void CL_EnvShot_f( void )
{
if( Cmd_Argc() < 2 )
{
Con_Printf( S_USAGE "envshot <shotname>\n" );
return;
}
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;
}
/*
==================
CL_SkyShot_f
skybox view
==================
*/
void CL_SkyShot_f( void )
{
if( Cmd_Argc() < 2 )
{
Con_Printf( S_USAGE "skyshot <shotname>\n" );
return;
}
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;
}
/* /*
================== ==================
CL_LevelShot_f CL_LevelShot_f
@@ -343,23 +214,100 @@ void CL_LevelShot_f( void )
else cls.scrshot_action = scrshot_inactive; // disable - not needs else cls.scrshot_action = scrshot_inactive; // disable - not needs
} }
/* static scrshot_t CL_GetScreenshotTypeFromString( const char *string )
================== {
CL_SaveShot_f if( !Q_stricmp( string, "snapshot" ))
return scrshot_snapshot;
mini-pic in loadgame menu if( !Q_stricmp( string, "screenshot" ))
================== return scrshot_normal;
*/
void CL_SaveShot_f( void ) if( !Q_stricmp( string, "saveshot" ))
return scrshot_savegame;
if( !Q_stricmp( string, "envshot" ))
return scrshot_envshot;
if( !Q_stricmp( string, "skyshot" ))
return scrshot_skyshot;
return scrshot_inactive;
}
void CL_GenericShot_f( void )
{
const char *argv0 = Cmd_Argv( 0 );
scrshot_t type;
type = CL_GetScreenshotTypeFromString( argv0 );
if( type == scrshot_normal || type == scrshot_snapshot )
{
if( CL_IsDevOverviewMode() == 1 )
type = scrshot_mapshot;
}
else
{ {
if( Cmd_Argc() < 2 ) if( Cmd_Argc() < 2 )
{ {
Con_Printf( S_USAGE "saveshot <savename>\n" ); Con_Printf( S_USAGE "%s <shotname>\n", argv0 );
return;
}
}
switch( type )
{
case scrshot_envshot:
case scrshot_skyshot:
Q_snprintf( cls.shotname, sizeof( cls.shotname ), "gfx/env/%s", Cmd_Argv( 1 ));
break;
case scrshot_savegame:
Q_snprintf( cls.shotname, sizeof( cls.shotname ), DEFAULT_SAVE_DIRECTORY "%s.bmp", Cmd_Argv( 1 ));
break;
case scrshot_mapshot:
Q_snprintf( cls.shotname, sizeof( cls.shotname ), "overviews/%s.bmp", clgame.mapname );
break;
case scrshot_normal:
case scrshot_snapshot:
{
const char *fmt;
string checkname;
int i;
if( type == scrshot_snapshot )
{
fmt = "../%s_%04d.png";
FS_AllowDirectPaths( true );
}
else fmt = "scrshots/%s_shot%04d.png";
for( i = 0; i < 9999; i++ )
{
if( !CL_ScreenshotGetName( fmt, i, checkname, sizeof( checkname )))
{
Con_Printf( S_ERROR "unable to write %s\n", argv0 );
FS_AllowDirectPaths( false );
return; return;
} }
Q_snprintf( cls.shotname, sizeof( cls.shotname ), DEFAULT_SAVE_DIRECTORY "%s.bmp", Cmd_Argv( 1 )); if( !FS_FileExists( checkname, true ))
cls.scrshot_action = scrshot_savegame; // build new frame for saveshot break;
}
FS_AllowDirectPaths( false );
Q_strncpy( cls.shotname, checkname, sizeof( cls.shotname ));
break;
}
case scrshot_inactive:
case scrshot_plaque:
default:
return; // shouldn't happen
}
cls.scrshot_action = type; // build new frame for saveshot
cls.envshot_vieworg = NULL;
cls.envshot_viewsize = 0;
} }
/* /*

View File

@@ -70,16 +70,17 @@ qboolean CL_CheckFile( sizebuf_t *msg, resource_t *pResource )
return true; return true;
} }
if( cl.downloadUrl[0] ) host.downloadcount++;
if( cl.http_download )
{ {
HTTP_AddDownload( filepath, pResource->nDownloadSize, true ); HTTP_AddDownload( filepath, pResource->nDownloadSize, true );
host.downloadcount++;
return false;
} }
else
{
MSG_BeginClientCmd( msg, clc_stringcmd ); MSG_BeginClientCmd( msg, clc_stringcmd );
MSG_WriteStringf( msg, "dlfile %s", filepath ); MSG_WriteStringf( msg, "dlfile %s", filepath );
host.downloadcount++; }
return false; return false;
} }
@@ -127,7 +128,7 @@ void CL_MoveToOnHandList( resource_t *pResource )
CL_AddToResourceList( pResource, &cl.resourcesonhand ); CL_AddToResourceList( pResource, &cl.resourcesonhand );
} }
void CL_ClearResourceList( resource_t *pList ) static void CL_ClearResourceList( resource_t *pList )
{ {
resource_t *p, *n; resource_t *p, *n;

View File

@@ -50,7 +50,15 @@ const char *CL_MsgInfo( int cmd )
if( cmd >= 0 && cmd <= svc_lastmsg ) if( cmd >= 0 && cmd <= svc_lastmsg )
{ {
// get engine message name // get engine message name
Q_strncpy( sz, svc_strings[cmd], sizeof( sz )); const char *svc_string = NULL;
if( cls.legacymode )
svc_string = svc_legacy_strings[cmd];
if( !svc_string )
svc_string = svc_strings[cmd];
Q_strncpy( sz, svc_string, sizeof( sz ));
} }
else if( cmd > svc_lastmsg && cmd <= ( svc_lastmsg + MAX_USER_MESSAGES )) else if( cmd > svc_lastmsg && cmd <= ( svc_lastmsg + MAX_USER_MESSAGES ))
{ {

View File

@@ -107,6 +107,8 @@ struct
int angle_position; int angle_position;
} demo; } demo;
static qboolean CL_NextDemo( void );
/* /*
==================== ====================
CL_StartupDemoHeader CL_StartupDemoHeader
@@ -156,7 +158,7 @@ CL_GetDemoRecordClock
write time while demo is recording write time while demo is recording
==================== ====================
*/ */
float CL_GetDemoRecordClock( void ) static float CL_GetDemoRecordClock( void )
{ {
return cl.mtime[0]; return cl.mtime[0];
} }
@@ -168,7 +170,7 @@ CL_GetDemoPlaybackClock
overwrite host.realtime overwrite host.realtime
==================== ====================
*/ */
float CL_GetDemoPlaybackClock( void ) static float CL_GetDemoPlaybackClock( void )
{ {
return host.realtime + host.frametime; return host.realtime + host.frametime;
} }
@@ -194,7 +196,7 @@ CL_WriteDemoCmdHeader
Writes the demo command header and time-delta Writes the demo command header and time-delta
==================== ====================
*/ */
void CL_WriteDemoCmdHeader( byte cmd, file_t *file ) static void CL_WriteDemoCmdHeader( byte cmd, file_t *file )
{ {
float dt; float dt;
@@ -267,7 +269,7 @@ Save state of cls.netchan sequences
so that we can play the demo correctly. so that we can play the demo correctly.
==================== ====================
*/ */
void CL_WriteDemoSequence( file_t *file ) static void CL_WriteDemoSequence( file_t *file )
{ {
Assert( file != NULL ); Assert( file != NULL );
@@ -348,7 +350,7 @@ CL_WriteDemoHeader
Write demo header Write demo header
==================== ====================
*/ */
void CL_WriteDemoHeader( const char *name ) static void CL_WriteDemoHeader( const char *name )
{ {
int copysize; int copysize;
int savepos; int savepos;
@@ -372,7 +374,7 @@ void CL_WriteDemoHeader( const char *name )
demo.header.id = IDEMOHEADER; demo.header.id = IDEMOHEADER;
demo.header.dem_protocol = DEMO_PROTOCOL; demo.header.dem_protocol = DEMO_PROTOCOL;
demo.header.net_protocol = cls.legacymode ? PROTOCOL_LEGACY_VERSION : PROTOCOL_VERSION; 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 = host_maxfps.value ? bound( MIN_FPS, host_maxfps.value, MAX_FPS ) : MAX_FPS;
Q_strncpy( demo.header.mapname, clgame.mapname, sizeof( demo.header.mapname )); 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.comment, clgame.maptitle, sizeof( demo.header.comment ));
Q_strncpy( demo.header.gamedir, FS_Gamedir(), sizeof( demo.header.gamedir )); Q_strncpy( demo.header.gamedir, FS_Gamedir(), sizeof( demo.header.gamedir ));
@@ -436,7 +438,7 @@ CL_StopRecord
finish recording demo finish recording demo
================= =================
*/ */
void CL_StopRecord( void ) static void CL_StopRecord( void )
{ {
int i, curpos; int i, curpos;
float stoptime; float stoptime;
@@ -518,7 +520,7 @@ CL_ReadDemoCmdHeader
read the demo command read the demo command
================= =================
*/ */
qboolean CL_ReadDemoCmdHeader( byte *cmd, float *dt ) static qboolean CL_ReadDemoCmdHeader( byte *cmd, float *dt )
{ {
// read the command // read the command
// HACKHACK: skip NOPs // HACKHACK: skip NOPs
@@ -548,7 +550,7 @@ read the demo usercmd for predicting
and smooth movement during playback the demo and smooth movement during playback the demo
================= =================
*/ */
void CL_ReadDemoUserCmd( qboolean discard ) static void CL_ReadDemoUserCmd( qboolean discard )
{ {
byte data[1024]; byte data[1024];
int cmdnumber; int cmdnumber;
@@ -570,6 +572,9 @@ void CL_ReadDemoUserCmd( qboolean discard )
memset( &nullcmd, 0, sizeof( nullcmd )); memset( &nullcmd, 0, sizeof( nullcmd ));
MSG_Init( &buf, "UserCmd", data, sizeof( data )); MSG_Init( &buf, "UserCmd", data, sizeof( data ));
// a1ba: I have no proper explanation why
cmdnumber++;
pcmd = &cl.commands[cmdnumber & CL_UPDATE_MASK]; pcmd = &cl.commands[cmdnumber & CL_UPDATE_MASK];
pcmd->processedfuncs = false; pcmd->processedfuncs = false;
pcmd->senttime = 0.0f; pcmd->senttime = 0.0f;
@@ -610,7 +615,7 @@ CL_ReadDemoSequence
read netchan sequences read netchan sequences
================= =================
*/ */
void CL_ReadDemoSequence( qboolean discard ) static void CL_ReadDemoSequence( qboolean discard )
{ {
int incoming_sequence; int incoming_sequence;
int incoming_acknowledged; int incoming_acknowledged;
@@ -644,15 +649,17 @@ void CL_ReadDemoSequence( qboolean discard )
CL_DemoStartPlayback CL_DemoStartPlayback
================= =================
*/ */
void CL_DemoStartPlayback( int mode ) static void CL_DemoStartPlayback( int mode )
{ {
if( cls.changedemo ) if( cls.changedemo )
{ {
int maxclients = cl.maxclients;
S_StopAllSounds( true ); S_StopAllSounds( true );
SCR_BeginLoadingPlaque( false ); SCR_BeginLoadingPlaque( false );
CL_ClearState( ); CL_ClearState( );
CL_InitEdicts (); // re-arrange edicts CL_InitEdicts( maxclients ); // re-arrange edicts
} }
else else
{ {
@@ -687,7 +694,7 @@ void CL_DemoStartPlayback( int mode )
CL_DemoAborted CL_DemoAborted
================= =================
*/ */
void CL_DemoAborted( void ) static void CL_DemoAborted( void )
{ {
if( cls.demofile ) if( cls.demofile )
FS_Close( cls.demofile ); FS_Close( cls.demofile );
@@ -698,7 +705,7 @@ void CL_DemoAborted( void )
cls.demofile = NULL; cls.demofile = NULL;
cls.demonum = -1; cls.demonum = -1;
Cvar_SetValue( "v_dark", 0.0f ); Cvar_DirectSet( &v_dark, "0" );
} }
/* /*
@@ -716,7 +723,7 @@ void CL_DemoCompleted( void )
if( !CL_NextDemo() && !cls.changedemo ) if( !CL_NextDemo() && !cls.changedemo )
UI_SetActiveMenu( true ); UI_SetActiveMenu( true );
Cvar_SetValue( "v_dark", 0.0f ); Cvar_DirectSet( &v_dark, "0" );
} }
/* /*
@@ -727,7 +734,7 @@ returns true on success, false on failure
g-cont. probably captain obvious mode is ON g-cont. probably captain obvious mode is ON
================= =================
*/ */
qboolean CL_DemoMoveToNextSection( void ) static qboolean CL_DemoMoveToNextSection( void )
{ {
if( ++demo.entryIndex >= demo.directory.numentries ) if( ++demo.entryIndex >= demo.directory.numentries )
{ {
@@ -749,7 +756,7 @@ qboolean CL_DemoMoveToNextSection( void )
return true; return true;
} }
qboolean CL_ReadRawNetworkData( byte *buffer, size_t *length ) static qboolean CL_ReadRawNetworkData( byte *buffer, size_t *length )
{ {
int msglen = 0; int msglen = 0;
@@ -800,7 +807,7 @@ CL_DemoReadMessageQuake
reads demo data and write it to client reads demo data and write it to client
================= =================
*/ */
qboolean CL_DemoReadMessageQuake( byte *buffer, size_t *length ) static qboolean CL_DemoReadMessageQuake( byte *buffer, size_t *length )
{ {
vec3_t viewangles; vec3_t viewangles;
int msglen = 0; int msglen = 0;
@@ -1015,7 +1022,7 @@ qboolean CL_DemoReadMessage( byte *buffer, size_t *length )
return CL_ReadRawNetworkData( buffer, length ); return CL_ReadRawNetworkData( buffer, length );
} }
void CL_DemoFindInterpolatedViewAngles( float t, float *frac, demoangle_t **prev, demoangle_t **next ) static void CL_DemoFindInterpolatedViewAngles( float t, float *frac, demoangle_t **prev, demoangle_t **next )
{ {
int i, i0, i1, imod; int i, i0, i1, imod;
float at; float at;
@@ -1110,7 +1117,7 @@ CL_FinishTimeDemo
show stats show stats
============== ==============
*/ */
void CL_FinishTimeDemo( void ) static void CL_FinishTimeDemo( void )
{ {
int frames; int frames;
double time; double time;
@@ -1122,7 +1129,10 @@ void CL_FinishTimeDemo( void )
time = host.realtime - cls.td_starttime; time = host.realtime - cls.td_starttime;
if( !time ) time = 1.0; 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();
} }
/* /*
@@ -1256,7 +1266,7 @@ CL_NextDemo
Called when a demo finishes Called when a demo finishes
================== ==================
*/ */
qboolean CL_NextDemo( void ) static qboolean CL_NextDemo( void )
{ {
char str[MAX_QPATH]; char str[MAX_QPATH];
@@ -1306,7 +1316,7 @@ void CL_CheckStartupDemos( void )
} }
// run demos loop in background mode // run demos loop in background mode
Cvar_SetValue( "v_dark", 1.0f ); Cvar_DirectSet( &v_dark, "1" );
cls.demos_pending = false; cls.demos_pending = false;
cls.demonum = 0; cls.demonum = 0;
CL_NextDemo (); CL_NextDemo ();
@@ -1322,11 +1332,11 @@ static void CL_DemoGetName( int lastnum, char *filename, size_t size )
if( lastnum < 0 || lastnum > 9999 ) if( lastnum < 0 || lastnum > 9999 )
{ {
// bound // bound
Q_strncpy( filename, "demo9999.dem", size ); Q_strncpy( filename, "demo9999", size );
return; return;
} }
Q_snprintf( filename, size, "demo%04d.dem", lastnum ); Q_snprintf( filename, size, "demo%04d", lastnum );
} }
/* /*
@@ -1381,7 +1391,9 @@ void CL_Record_f( void )
for( n = 0; n < 10000; n++ ) for( n = 0; n < 10000; n++ )
{ {
CL_DemoGetName( n, demoname, sizeof( demoname )); CL_DemoGetName( n, demoname, sizeof( demoname ));
if( !FS_FileExists( demoname, true )) Q_snprintf( demopath, sizeof( demopath ), "%s.dem", demoname );
if( !FS_FileExists( demopath, true ))
break; break;
} }
@@ -1468,7 +1480,7 @@ void CL_PlayDemo_f( void )
{ {
int c, neg = false; 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' ) while(( c = FS_Getc( cls.demofile )) != '\n' )
{ {

View File

@@ -6,7 +6,7 @@
#include "r_efx.h" #include "r_efx.h"
#include "cl_tent.h" #include "cl_tent.h"
#include "pm_local.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 ramp3[6] = { 0x6d, 0x6b, 6, 5, 4, 3 };
static int gSparkRamp[9] = { 0xfe, 0xfd, 0xfc, 0x6f, 0x6e, 0x6d, 0x6c, 0x67, 0x60 }; static int gSparkRamp[9] = { 0xfe, 0xfd, 0xfc, 0x6f, 0x6e, 0x6d, 0x6c, 0x67, 0x60 };
convar_t *tracerspeed; static CVAR_DEFINE_AUTO( tracerspeed, "6000", 0, "tracer speed" );
convar_t *tracerlength; static CVAR_DEFINE_AUTO( tracerlength, "0.8", 0, "tracer length factor" );
convar_t *traceroffset; static CVAR_DEFINE_AUTO( traceroffset, "30", 0, "tracer starting offset" );
particle_t *cl_active_particles; particle_t *cl_active_particles;
particle_t *cl_active_tracers; particle_t *cl_active_tracers;
@@ -100,9 +100,9 @@ void CL_InitParticles( void )
cl_avelocities[i][2] = COM_RandomFloat( 0.0f, 2.55f ); cl_avelocities[i][2] = COM_RandomFloat( 0.0f, 2.55f );
} }
tracerspeed = Cvar_Get( "tracerspeed", "6000", 0, "tracer speed" ); Cvar_RegisterVariable( &tracerspeed );
tracerlength = Cvar_Get( "tracerlength", "0.8", 0, "tracer length factor" ); Cvar_RegisterVariable( &tracerlength );
traceroffset = Cvar_Get( "traceroffset", "30", 0, "tracer starting offset" ); Cvar_RegisterVariable( &traceroffset );
} }
/* /*
@@ -171,11 +171,11 @@ particle_t * GAME_EXPORT R_AllocParticle( void (*callback)( particle_t*, float )
{ {
particle_t *p; particle_t *p;
if( !cl_draw_particles->value ) if( !cl_draw_particles.value )
return NULL; return NULL;
// never alloc particles when we not in game // never alloc particles when we not in game
// if( tr.frametime == 0.0 ) return NULL; if( cl_clientframetime() == 0.0 ) return NULL;
if( !cl_free_particles ) if( !cl_free_particles )
{ {
@@ -218,15 +218,15 @@ R_AllocTracer
can return NULL if particles is out can return NULL if particles is out
================ ================
*/ */
particle_t *R_AllocTracer( const vec3_t org, const vec3_t vel, float life ) static particle_t *R_AllocTracer( const vec3_t org, const vec3_t vel, float life )
{ {
particle_t *p; particle_t *p;
if( !cl_draw_tracers->value ) if( !cl_draw_tracers.value )
return NULL; return NULL;
// never alloc particles when we not in game // never alloc particles when we not in game
//if( tr.frametime == 0.0 ) return NULL; if( cl_clientframetime() == 0.0 ) return NULL;
if( !cl_free_particles ) if( !cl_free_particles )
{ {
@@ -249,7 +249,7 @@ particle_t *R_AllocTracer( const vec3_t org, const vec3_t vel, float life )
VectorCopy( org, p->org ); VectorCopy( org, p->org );
VectorCopy( vel, p->vel ); VectorCopy( vel, p->vel );
p->die = cl.time + life; p->die = cl.time + life;
p->ramp = tracerlength->value; p->ramp = tracerlength.value;
p->color = 4; // select custom color p->color = 4; // select custom color
p->packedColor = 255; // alpha p->packedColor = 255; // alpha
@@ -300,7 +300,7 @@ R_BeamAlloc
============== ==============
*/ */
BEAM *R_BeamAlloc( void ) static BEAM *R_BeamAlloc( void )
{ {
BEAM *pBeam; BEAM *pBeam;
@@ -323,7 +323,7 @@ R_BeamFree
============== ==============
*/ */
void R_BeamFree( BEAM *pBeam ) static void R_BeamFree( BEAM *pBeam )
{ {
// free particles that have died off. // free particles that have died off.
R_FreeDeadParticles( &pBeam->particles ); R_FreeDeadParticles( &pBeam->particles );
@@ -605,7 +605,7 @@ CL_BeamAttemptToDie
Check for expired beams Check for expired beams
============== ==============
*/ */
qboolean CL_BeamAttemptToDie( BEAM *pBeam ) static qboolean CL_BeamAttemptToDie( BEAM *pBeam )
{ {
Assert( pBeam != NULL ); Assert( pBeam != NULL );
@@ -1236,12 +1236,15 @@ R_BloodStream
particle spray 2 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; particle_t *p;
int i, j; int i, j;
float arc; float arc;
int accel = speed; // must be integer due to bug in GoldSrc 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++ ) for( arc = 0.05f, i = 0; i < 100; i++ )
{ {
@@ -1804,14 +1807,14 @@ void GAME_EXPORT R_TracerEffect( const vec3_t start, const vec3_t end )
float len, speed; float len, speed;
float offset; float offset;
speed = Q_max( tracerspeed->value, 3.0f ); speed = Q_max( tracerspeed.value, 3.0f );
VectorSubtract( end, start, dir ); VectorSubtract( end, start, dir );
len = VectorLength( dir ); len = VectorLength( dir );
if( len == 0.0f ) return; if( len == 0.0f ) return;
VectorScale( dir, 1.0f / len, dir ); // normalize 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 ); VectorScale( dir, offset, vel );
VectorAdd( start, vel, pos ); VectorAdd( start, vel, pos );
VectorScale( dir, speed, vel ); VectorScale( dir, speed, vel );
@@ -2037,7 +2040,7 @@ void CL_ReadPointFile_f( void )
else Con_Printf( "map %s has no leaks!\n", clgame.mapname ); else Con_Printf( "map %s has no leaks!\n", clgame.mapname );
} }
void CL_FreeDeadBeams( void ) static void CL_FreeDeadBeams( void )
{ {
BEAM *pBeam, *pNext, *pPrev = NULL; BEAM *pBeam, *pNext, *pPrev = NULL;
// draw temporary entity beams // draw temporary entity beams
@@ -2067,16 +2070,16 @@ void CL_FreeDeadBeams( void )
void CL_DrawEFX( float time, qboolean fTrans ) void CL_DrawEFX( float time, qboolean fTrans )
{ {
CL_FreeDeadBeams(); CL_FreeDeadBeams();
if( CVAR_TO_BOOL( cl_draw_beams )) if( cl_draw_beams.value )
ref.dllFuncs.CL_DrawBeams( fTrans, cl_active_beams ); ref.dllFuncs.CL_DrawBeams( fTrans, cl_active_beams );
if( fTrans ) if( fTrans )
{ {
R_FreeDeadParticles( &cl_active_particles ); 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 ); ref.dllFuncs.CL_DrawParticles( time, cl_active_particles, PART_SIZE );
R_FreeDeadParticles( &cl_active_tracers ); 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 ); ref.dllFuncs.CL_DrawTracers( time, cl_active_tracers );
} }
} }

View File

@@ -40,7 +40,7 @@ CL_CalcPlayerVelocity
compute velocity for a given client compute velocity for a given client
============= =============
*/ */
void CL_CalcPlayerVelocity( int idx, vec3_t velocity ) static void CL_CalcPlayerVelocity( int idx, vec3_t velocity )
{ {
clientdata_t *pcd; clientdata_t *pcd;
vec3_t delta; vec3_t delta;
@@ -78,13 +78,13 @@ CL_DescribeEvent
============= =============
*/ */
void CL_DescribeEvent( event_info_t *ei, int slot ) static void CL_DescribeEvent( event_info_t *ei, int slot )
{ {
int idx = (slot & 63) * 2; int idx = (slot & 63) * 2;
con_nprint_t info; con_nprint_t info;
string origin_str = { 0 }; //, angles_str = { 0 }; string origin_str = { 0 }; //, angles_str = { 0 };
if( !cl_showevents->value ) if( !cl_showevents.value )
return; return;
info.time_to_live = 1.0f; info.time_to_live = 1.0f;
@@ -192,7 +192,7 @@ void CL_RegisterEvent( int lastnum, const char *szEvName, pfnEventHook func )
ev = clgame.events[lastnum]; ev = clgame.events[lastnum];
// NOTE: ev->index will be set later // NOTE: ev->index will be set later
Q_strncpy( ev->name, szEvName, MAX_QPATH ); Q_strncpy( ev->name, szEvName, sizeof( ev->name ));
ev->func = func; ev->func = func;
} }
@@ -202,7 +202,7 @@ CL_FireEvent
============= =============
*/ */
qboolean CL_FireEvent( event_info_t *ei, int slot ) static qboolean CL_FireEvent( event_info_t *ei, int slot )
{ {
cl_user_event_t *ev; cl_user_event_t *ev;
const char *name; const char *name;
@@ -225,6 +225,18 @@ qboolean CL_FireEvent( event_info_t *ei, int slot )
if( ev->index == ei->index ) 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 ) if( ev->func )
{ {
CL_DescribeEvent( ei, slot ); CL_DescribeEvent( ei, slot );
@@ -232,7 +244,6 @@ qboolean CL_FireEvent( event_info_t *ei, int slot )
return true; return true;
} }
name = cl.event_precache[ei->index];
Con_Reportf( S_ERROR "CL_FireEvent: %s not hooked\n", name ); Con_Reportf( S_ERROR "CL_FireEvent: %s not hooked\n", name );
break; break;
} }
@@ -281,7 +292,7 @@ CL_FindEvent
find first empty event find first empty event
============= =============
*/ */
event_info_t *CL_FindEmptyEvent( void ) static event_info_t *CL_FindEmptyEvent( void )
{ {
int i; int i;
event_state_t *es; event_state_t *es;
@@ -309,7 +320,7 @@ CL_FindEvent
replace only unreliable events replace only unreliable events
============= =============
*/ */
event_info_t *CL_FindUnreliableEvent( void ) static event_info_t *CL_FindUnreliableEvent( void )
{ {
event_state_t *es; event_state_t *es;
event_info_t *ei; event_info_t *ei;
@@ -339,7 +350,7 @@ CL_QueueEvent
============= =============
*/ */
void CL_QueueEvent( int flags, int index, float delay, event_args_t *args ) static void CL_QueueEvent( int flags, int index, float delay, event_args_t *args )
{ {
event_info_t *ei; event_info_t *ei;

View File

@@ -46,10 +46,35 @@ static int CL_LoadFontTexture( const char *fontname, uint texFlags, int *width )
return tex; return tex;
} }
qboolean Con_LoadFixedWidthFont( const char *fontname, cl_font_t *font, float scale, int rendermode, uint texFlags ) static int CL_FontRenderMode( convar_t *fontrender )
{
switch((int)fontrender->value )
{
case 0:
return kRenderTransAdd;
case 1:
return kRenderTransAlpha;
case 2:
return kRenderTransTexture;
default:
Cvar_DirectSet( fontrender, fontrender->def_string );
}
return kRenderTransTexture;
}
void CL_SetFontRendermode( cl_font_t *font )
{
ref.dllFuncs.GL_SetRenderMode( CL_FontRenderMode( font->rendermode ));
}
qboolean Con_LoadFixedWidthFont( const char *fontname, cl_font_t *font, float scale, convar_t *rendermode, uint texFlags )
{ {
int font_width, i; int font_width, i;
if( !rendermode )
return false;
if( font->valid ) if( font->valid )
return true; // already loaded return true; // already loaded
@@ -60,7 +85,6 @@ qboolean Con_LoadFixedWidthFont( const char *fontname, cl_font_t *font, float sc
font->type = FONT_FIXED; font->type = FONT_FIXED;
font->valid = true; font->valid = true;
font->scale = scale; font->scale = scale;
font->nearest = FBitSet( texFlags, TF_NEAREST );
font->rendermode = rendermode; font->rendermode = rendermode;
font->charHeight = Q_rint( font_width / 16 * scale ); font->charHeight = Q_rint( font_width / 16 * scale );
@@ -77,13 +101,16 @@ qboolean Con_LoadFixedWidthFont( const char *fontname, cl_font_t *font, float sc
return true; return true;
} }
qboolean Con_LoadVariableWidthFont( 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, convar_t *rendermode, uint texFlags )
{ {
fs_offset_t length; fs_offset_t length;
qfont_t src; qfont_t src;
byte *pfile; byte *pfile;
int font_width, i; int font_width, i;
if( !rendermode )
return false;
if( font->valid ) if( font->valid )
return true; return true;
@@ -106,8 +133,7 @@ qboolean Con_LoadVariableWidthFont( const char *fontname, cl_font_t *font, float
font->type = FONT_VARIABLE; font->type = FONT_VARIABLE;
font->valid = true; font->valid = true;
font->scale = scale; font->scale = scale ? scale : 1.0f;
font->nearest = FBitSet( texFlags, TF_NEAREST );
font->rendermode = rendermode; font->rendermode = rendermode;
font->charHeight = Q_rint( src.rowheight * scale ); font->charHeight = Q_rint( src.rowheight * scale );
@@ -179,7 +205,8 @@ int CL_DrawCharacter( float x, float y, int number, rgba_t color, cl_font_t *fon
return font->charWidths[number]; return font->charWidths[number];
rc = &font->fontRc[number]; rc = &font->fontRc[number];
if( font->nearest || font->scale <= 1.0f )
if( font->scale <= 1.f || !REF_GET_PARM( PARM_TEX_FILTERING, font->hFontTexture ))
half = 0; half = 0;
s1 = ((float)rc->left + half ) / texw; s1 = ((float)rc->left + half ) / texw;
@@ -193,7 +220,7 @@ int CL_DrawCharacter( float x, float y, int number, rgba_t color, cl_font_t *fon
SPR_AdjustSize( &x, &y, &w, &h ); SPR_AdjustSize( &x, &y, &w, &h );
if( !FBitSet( flags, FONT_DRAW_NORENDERMODE )) if( !FBitSet( flags, FONT_DRAW_NORENDERMODE ))
ref.dllFuncs.GL_SetRenderMode( font->rendermode ); CL_SetFontRendermode( font );
// don't apply color to fixed fonts it's already colored // 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 if( font->type != FONT_FIXED || REF_GET_PARM( PARM_TEX_GLFORMAT, font->hFontTexture ) == 0x8045 ) // GL_LUMINANCE8_ALPHA8
@@ -216,7 +243,7 @@ int CL_DrawString( float x, float y, const char *s, rgba_t color, cl_font_t *fon
Con_UtfProcessChar( 0 ); // clear utf state Con_UtfProcessChar( 0 ); // clear utf state
if( !FBitSet( flags, FONT_DRAW_NORENDERMODE )) if( !FBitSet( flags, FONT_DRAW_NORENDERMODE ))
ref.dllFuncs.GL_SetRenderMode( font->rendermode ); CL_SetFontRendermode( font );
Vector4Copy( color, current_color ); Vector4Copy( color, current_color );

View File

@@ -24,7 +24,7 @@ GNU General Public License for more details.
#include "sound.h" #include "sound.h"
#include "input.h" #include "input.h"
#define STUDIO_INTERPOLATION_FIX // #define STUDIO_INTERPOLATION_FIX
/* /*
================== ==================
@@ -52,19 +52,30 @@ CL_UpdatePositions
Store another position into interpolation circular buffer Store another position into interpolation circular buffer
================== ==================
*/ */
void CL_UpdatePositions( cl_entity_t *ent ) static void CL_UpdatePositions( cl_entity_t *ent )
{ {
position_history_t *ph; position_history_t *ph, *prev;
prev = &ent->ph[ent->current_position];
ent->current_position = (ent->current_position + 1) & HISTORY_MASK; ent->current_position = (ent->current_position + 1) & HISTORY_MASK;
ph = &ent->ph[ent->current_position]; ph = &ent->ph[ent->current_position];
VectorCopy( ent->curstate.origin, ph->origin ); VectorCopy( ent->curstate.origin, ph->origin );
VectorCopy( ent->curstate.angles, ph->angles ); VectorCopy( ent->curstate.angles, ph->angles );
if( ent->model && ent->model->type == mod_brush )
ph->animtime = ent->curstate.animtime; ph->animtime = ent->curstate.animtime;
else
ph->animtime = cl.time; // a1ba: for some reason, this sometimes still may happen
// at this time, I'm not sure whether this bug happens in delta readwrite code
// or server just decides to go backwards and really sends these values
if( ph->animtime < prev->animtime )
{
// try to deduce real animtime by looking up the difference between
// server messages (cl.mtime is never modified ny the interpolation code)
float diff = Q_max( 0, ent->curstate.msg_time - ent->prevstate.msg_time );
ph->animtime = prev->animtime + diff;
}
} }
/* /*
@@ -74,7 +85,7 @@ CL_ResetPositions
Interpolation init or reset after teleporting Interpolation init or reset after teleporting
================== ==================
*/ */
void CL_ResetPositions( cl_entity_t *ent ) static void CL_ResetPositions( cl_entity_t *ent )
{ {
position_history_t store; position_history_t store;
@@ -96,7 +107,7 @@ check for instant movement in case
we don't want interpolate this we don't want interpolate this
================== ==================
*/ */
qboolean CL_EntityTeleported( cl_entity_t *ent ) static qboolean CL_EntityTeleported( cl_entity_t *ent )
{ {
float len, maxlen; float len, maxlen;
vec3_t delta; vec3_t delta;
@@ -117,7 +128,7 @@ CL_CompareTimestamps
round-off floating errors round-off floating errors
================== ==================
*/ */
qboolean CL_CompareTimestamps( float t1, float t2 ) static qboolean CL_CompareTimestamps( float t1, float t2 )
{ {
int iTime1 = t1 * 1000; int iTime1 = t1 * 1000;
int iTime2 = t2 * 1000; int iTime2 = t2 * 1000;
@@ -132,9 +143,9 @@ CL_EntityIgnoreLerp
some ents will be ignore lerping some ents will be ignore lerping
================== ==================
*/ */
qboolean CL_EntityIgnoreLerp( cl_entity_t *e ) static qboolean CL_EntityIgnoreLerp( cl_entity_t *e )
{ {
if( cl_nointerp->value > 0.f ) if( cl_nointerp.value > 0.f )
return true; return true;
if( e->model && e->model->type == mod_alias ) if( e->model && e->model->type == mod_alias )
@@ -149,7 +160,7 @@ CL_EntityCustomLerp
================== ==================
*/ */
qboolean CL_EntityCustomLerp( cl_entity_t *e ) static qboolean CL_EntityCustomLerp( cl_entity_t *e )
{ {
switch( e->curstate.movetype ) switch( e->curstate.movetype )
{ {
@@ -159,6 +170,13 @@ qboolean CL_EntityCustomLerp( cl_entity_t *e )
case MOVETYPE_FLY: case MOVETYPE_FLY:
case MOVETYPE_COMPOUND: case MOVETYPE_COMPOUND:
return false; return false;
// ABSOLUTELY STUPID HACK TO ALLOW MONSTERS
// INTERPOLATION IN GRAVGUNMOD COOP
// MUST BE REMOVED ONCE WE REMOVE 48 PROTO SUPPORT
case MOVETYPE_TOSS:
if( cls.legacymode && e->model && e->model->type == mod_studio )
return false;
} }
return true; return true;
@@ -171,7 +189,7 @@ CL_ParametricMove
check for parametrical moved entities check for parametrical moved entities
================== ==================
*/ */
qboolean CL_ParametricMove( cl_entity_t *ent ) static qboolean CL_ParametricMove( cl_entity_t *ent )
{ {
float frac, dt, t; float frac, dt, t;
vec3_t delta; vec3_t delta;
@@ -208,7 +226,7 @@ CL_UpdateLatchedVars
==================== ====================
*/ */
void CL_UpdateLatchedVars( cl_entity_t *ent ) static void CL_UpdateLatchedVars( cl_entity_t *ent )
{ {
if( !ent->model || ( ent->model->type != mod_alias && ent->model->type != mod_studio )) if( !ent->model || ( ent->model->type != mod_alias && ent->model->type != mod_studio ))
return; // below fields used only for alias and studio interpolation return; // below fields used only for alias and studio interpolation
@@ -303,7 +321,7 @@ CL_ProcessEntityUpdate
apply changes since new frame received apply changes since new frame received
================== ==================
*/ */
void CL_ProcessEntityUpdate( cl_entity_t *ent ) static void CL_ProcessEntityUpdate( cl_entity_t *ent )
{ {
qboolean parametric; qboolean parametric;
@@ -349,11 +367,10 @@ CL_FindInterpolationUpdates
find two timestamps find two timestamps
================== ==================
*/ */
qboolean CL_FindInterpolationUpdates( cl_entity_t *ent, float targettime, position_history_t **ph0, position_history_t **ph1 ) static qboolean CL_FindInterpolationUpdates( cl_entity_t *ent, double targettime, position_history_t **ph0, position_history_t **ph1 )
{ {
qboolean extrapolate = true; qboolean extrapolate = true;
uint i, i0, i1, imod; uint i, i0, i1, imod;
float at;
imod = ent->current_position; imod = ent->current_position;
i0 = (imod - 0) & HISTORY_MASK; // curpos (lerp end) i0 = (imod - 0) & HISTORY_MASK; // curpos (lerp end)
@@ -361,8 +378,10 @@ qboolean CL_FindInterpolationUpdates( cl_entity_t *ent, float targettime, positi
for( i = 1; i < HISTORY_MAX - 1; i++ ) for( i = 1; i < HISTORY_MAX - 1; i++ )
{ {
at = ent->ph[( imod - i ) & HISTORY_MASK].animtime; double at = ent->ph[( imod - i ) & HISTORY_MASK].animtime;
if( at == 0.0f ) break;
if( at == 0.0f )
break;
if( targettime > at ) if( targettime > at )
{ {
@@ -387,15 +406,14 @@ CL_PureOrigin
non-local players interpolation non-local players interpolation
================== ==================
*/ */
void CL_PureOrigin( cl_entity_t *ent, float t, vec3_t outorigin, vec3_t outangles ) static void CL_PureOrigin( cl_entity_t *ent, double t, vec3_t outorigin, vec3_t outangles )
{ {
qboolean extrapolate; double t1, t0, frac;
float t1, t0, frac;
position_history_t *ph0, *ph1; position_history_t *ph0, *ph1;
vec3_t delta; vec3_t delta;
// NOTE: ph0 is next, ph1 is a prev // NOTE: ph0 is next, ph1 is a prev
extrapolate = CL_FindInterpolationUpdates( ent, t, &ph0, &ph1 ); CL_FindInterpolationUpdates( ent, t, &ph0, &ph1 );
if ( !ph0 || !ph1 ) if ( !ph0 || !ph1 )
return; return;
@@ -403,7 +421,7 @@ void CL_PureOrigin( cl_entity_t *ent, float t, vec3_t outorigin, vec3_t outangle
t0 = ph0->animtime; t0 = ph0->animtime;
t1 = ph1->animtime; t1 = ph1->animtime;
if( t0 != 0.0f ) if( t0 != 0.0 )
{ {
vec4_t q, q1, q2; vec4_t q, q1, q2;
@@ -411,9 +429,9 @@ void CL_PureOrigin( cl_entity_t *ent, float t, vec3_t outorigin, vec3_t outangle
if( !Q_equal( t0, t1 )) if( !Q_equal( t0, t1 ))
frac = ( t - t1 ) / ( t0 - t1 ); frac = ( t - t1 ) / ( t0 - t1 );
else frac = 1.0f; else frac = 1.0;
frac = bound( 0.0f, frac, 1.2f ); frac = bound( 0.0, frac, 1.2 );
VectorMA( ph1->origin, frac, delta, outorigin ); VectorMA( ph1->origin, frac, delta, outorigin );
@@ -437,11 +455,11 @@ CL_InterpolateModel
non-players interpolation non-players interpolation
================== ==================
*/ */
int CL_InterpolateModel( cl_entity_t *e ) static int CL_InterpolateModel( cl_entity_t *e )
{ {
position_history_t *ph0 = NULL, *ph1 = NULL; position_history_t *ph0 = NULL, *ph1 = NULL;
vec3_t origin, angles, delta; vec3_t origin, angles, delta;
float t, t1, t2, frac; double t, t1, t2, frac;
vec4_t q, q1, q2; vec4_t q, q1, q2;
VectorCopy( e->curstate.origin, e->origin ); VectorCopy( e->curstate.origin, e->origin );
@@ -464,13 +482,13 @@ int CL_InterpolateModel( cl_entity_t *e )
if( cl.maxclients <= 1 ) if( cl.maxclients <= 1 )
return 1; return 1;
if( e->model->type == mod_brush && !cl_bmodelinterp->value ) if( e->model->type == mod_brush && !cl_bmodelinterp.value )
return 1; return 1;
if( cl.local.moving && cl.local.onground == e->index ) if( cl.local.moving && cl.local.onground == e->index )
return 1; return 1;
t = cl.time - cl_interp->value; t = cl.time - cl_interp.value;
CL_FindInterpolationUpdates( e, t, &ph0, &ph1 ); CL_FindInterpolationUpdates( e, t, &ph0, &ph1 );
if( ph0 == NULL || ph1 == NULL ) if( ph0 == NULL || ph1 == NULL )
@@ -489,9 +507,7 @@ int CL_InterpolateModel( cl_entity_t *e )
return 0; return 0;
} }
// HACKHACK: workaround buggy position history animtime if( Q_equal( t2, t1 ))
// going backward sometimes
if( Q_equal( t2, t1 ) || t2 < t1 )
{ {
VectorCopy( ph0->origin, e->origin ); VectorCopy( ph0->origin, e->origin );
VectorCopy( ph0->angles, e->angles ); VectorCopy( ph0->angles, e->angles );
@@ -529,7 +545,7 @@ interpolate non-local clients
*/ */
void CL_ComputePlayerOrigin( cl_entity_t *ent ) void CL_ComputePlayerOrigin( cl_entity_t *ent )
{ {
float targettime; double targettime;
vec4_t q, q1, q2; vec4_t q, q1, q2;
vec3_t origin; vec3_t origin;
vec3_t angles; vec3_t angles;
@@ -537,7 +553,7 @@ void CL_ComputePlayerOrigin( cl_entity_t *ent )
if( !ent->player ) if( !ent->player )
return; return;
if( cl_nointerp->value > 0.f ) if( cl_nointerp.value > 0.f )
{ {
VectorCopy( ent->curstate.angles, ent->angles ); VectorCopy( ent->curstate.angles, ent->angles );
VectorCopy( ent->curstate.origin, ent->origin ); VectorCopy( ent->curstate.origin, ent->origin );
@@ -555,7 +571,7 @@ void CL_ComputePlayerOrigin( cl_entity_t *ent )
return; return;
} }
targettime = cl.time - cl_interp->value; targettime = cl.time - cl_interp.value;
CL_PureOrigin( ent, targettime, origin, angles ); CL_PureOrigin( ent, targettime, origin, angles );
VectorCopy( angles, ent->angles ); VectorCopy( angles, ent->angles );
@@ -569,7 +585,7 @@ CL_ProcessPlayerState
process player states after the new packet has received process player states after the new packet has received
================= =================
*/ */
void CL_ProcessPlayerState( int playerindex, entity_state_t *state ) static void CL_ProcessPlayerState( int playerindex, entity_state_t *state )
{ {
entity_state_t *ps; entity_state_t *ps;
@@ -589,7 +605,7 @@ reset latched state if this frame entity was teleported
or just EF_NOINTERP was set or just EF_NOINTERP was set
================= =================
*/ */
void CL_ResetLatchedState( int pnum, frame_t *frame, cl_entity_t *ent ) static void CL_ResetLatchedState( int pnum, frame_t *frame, cl_entity_t *ent )
{ {
if( CHECKVISBIT( frame->flags, pnum )) if( CHECKVISBIT( frame->flags, pnum ))
{ {
@@ -679,7 +695,7 @@ CL_FlushEntityPacket
Read and ignore whole entity packet. Read and ignore whole entity packet.
================= =================
*/ */
void CL_FlushEntityPacket( sizebuf_t *msg ) static void CL_FlushEntityPacket( sizebuf_t *msg )
{ {
int newnum; int newnum;
entity_state_t from, to; entity_state_t from, to;
@@ -709,7 +725,7 @@ CL_DeltaEntity
processing delta update processing delta update
================= =================
*/ */
void CL_DeltaEntity( sizebuf_t *msg, frame_t *frame, int newnum, entity_state_t *old, qboolean has_update ) static void CL_DeltaEntity( sizebuf_t *msg, frame_t *frame, int newnum, entity_state_t *old, qboolean has_update )
{ {
cl_entity_t *ent; cl_entity_t *ent;
entity_state_t *state; entity_state_t *state;
@@ -1041,7 +1057,7 @@ CL_LinkCustomEntity
Add server beam to draw list Add server beam to draw list
============= =============
*/ */
void CL_LinkCustomEntity( cl_entity_t *ent, entity_state_t *state ) static void CL_LinkCustomEntity( cl_entity_t *ent, entity_state_t *state )
{ {
ent->curstate.movetype = state->modelindex; // !!! ent->curstate.movetype = state->modelindex; // !!!
@@ -1064,7 +1080,7 @@ Create visible entities in the correct position
for all current players for all current players
============= =============
*/ */
void CL_LinkPlayers( frame_t *frame ) static void CL_LinkPlayers( frame_t *frame )
{ {
entity_state_t *state; entity_state_t *state;
cl_entity_t *ent; cl_entity_t *ent;
@@ -1147,7 +1163,7 @@ CL_LinkPacketEntities
=============== ===============
*/ */
void CL_LinkPacketEntities( frame_t *frame ) static void CL_LinkPacketEntities( frame_t *frame )
{ {
cl_entity_t *ent; cl_entity_t *ent;
entity_state_t *state; entity_state_t *state;
@@ -1212,18 +1228,34 @@ void CL_LinkPacketEntities( frame_t *frame )
#else #else
if( ent->lastmove >= cl.time ) if( ent->lastmove >= cl.time )
{ {
float at = ent->curstate.animtime;
CL_ResetLatchedVars( ent, true ); CL_ResetLatchedVars( ent, true );
if( cl_fixmodelinterpolationartifacts.value )
ent->latched.prevanimtime = ent->curstate.animtime = at;
VectorCopy( ent->curstate.origin, ent->latched.prevorigin ); VectorCopy( ent->curstate.origin, ent->latched.prevorigin );
VectorCopy( ent->curstate.angles, ent->latched.prevangles ); VectorCopy( ent->curstate.angles, ent->latched.prevangles );
if( !FBitSet( host.features, ENGINE_COMPUTE_STUDIO_LERP ))
{
// disable step interpolation in client.dll // disable step interpolation in client.dll
ent->curstate.movetype = MOVETYPE_NONE; ent->curstate.movetype = MOVETYPE_NONE;
} }
}
else
{
if( FBitSet( host.features, ENGINE_COMPUTE_STUDIO_LERP ))
{
interpolate = true;
}
else else
{ {
// restore step interpolation in client.dll // restore step interpolation in client.dll
ent->curstate.movetype = MOVETYPE_STEP; ent->curstate.movetype = MOVETYPE_STEP;
} }
}
#endif #endif
} }
} }
@@ -1247,11 +1279,24 @@ void CL_LinkPacketEntities( frame_t *frame )
if ( !CL_InterpolateModel( ent )) if ( !CL_InterpolateModel( ent ))
continue; continue;
} }
else if( ent->curstate.movetype == MOVETYPE_STEP && !NET_IsLocalAddress( cls.netchan.remote_address )) // a1ba: in GoldSrc this is done for cstrike and czero
// but let modders use this as an engine feature
else if( FBitSet( host.features, ENGINE_STEP_POSHISTORY_LERP ) &&
ent->curstate.movetype == MOVETYPE_STEP && !NET_IsLocalAddress( cls.netchan.remote_address ))
{ {
if( !CL_InterpolateModel( ent )) if( !CL_InterpolateModel( ent ))
continue; continue;
} }
#if 0
// ABSOLUTELY STUPID HACK TO ALLOW MONSTERS
// INTERPOLATION IN GRAVGUNMOD COOP
// MUST BE REMOVED ONCE WE REMOVE 48 PROTO SUPPORT
else if( cls.legacymode && ent->model->type == mod_studio && ent->curstate.movetype == MOVETYPE_TOSS )
{
if( !CL_InterpolateModel( ent ))
continue;
}
#endif
else else
{ {
// no interpolation right now // no interpolation right now
@@ -1447,9 +1492,3 @@ qboolean CL_GetMovieSpatialization( rawchan_t *ch )
return true; return true;
} }
void CL_ExtraUpdate( void )
{
clgame.dllFuncs.IN_Accumulate();
S_ExtraUpdate();
}

View File

@@ -154,7 +154,7 @@ CL_CreatePlaylist
Create a default valve playlist Create a default valve playlist
==================== ====================
*/ */
void CL_CreatePlaylist( const char *filename ) static void CL_CreatePlaylist( const char *filename )
{ {
file_t *f; file_t *f;
@@ -357,7 +357,9 @@ void SPR_AdjustSize( float *x, float *y, float *w, float *h )
*h *= yscale; *h *= yscale;
} }
void SPR_AdjustTexCoords( float width, float height, float *s1, float *t1, float *s2, float *t2 ) static void SPR_AdjustTexCoords( int texnum, float width, float height, float *s1, float *t1, float *s2, float *t2 )
{
if( REF_GET_PARM( PARM_TEX_FILTERING, texnum ))
{ {
if( refState.width != clgame.scrInfo.iWidth ) if( refState.width != clgame.scrInfo.iWidth )
{ {
@@ -372,6 +374,7 @@ void SPR_AdjustTexCoords( float width, float height, float *s1, float *t1, float
*t1 += 0.5f; *t1 += 0.5f;
*t2 -= 0.5f; *t2 -= 0.5f;
} }
}
*s1 /= width; *s1 /= width;
*t1 /= height; *t1 /= height;
@@ -402,6 +405,8 @@ static void SPR_DrawGeneric( int frame, float x, float y, float width, float hei
height = h; height = h;
} }
texnum = ref.dllFuncs.R_GetSpriteTexture( clgame.ds.pSprite, frame );
if( prc ) if( prc )
{ {
wrect_t rc = *prc; wrect_t rc = *prc;
@@ -418,7 +423,7 @@ static void SPR_DrawGeneric( int frame, float x, float y, float width, float hei
t2 = rc.bottom; t2 = rc.bottom;
// calc user-defined rectangle // calc user-defined rectangle
SPR_AdjustTexCoords( width, height, &s1, &t1, &s2, &t2 ); SPR_AdjustTexCoords( texnum, width, height, &s1, &t1, &s2, &t2 );
width = rc.right - rc.left; width = rc.right - rc.left;
height = rc.bottom - rc.top; height = rc.bottom - rc.top;
} }
@@ -434,7 +439,6 @@ static void SPR_DrawGeneric( int frame, float x, float y, float width, float hei
// scale for screen sizes // scale for screen sizes
SPR_AdjustSize( &x, &y, &width, &height ); SPR_AdjustSize( &x, &y, &width, &height );
texnum = ref.dllFuncs.R_GetSpriteTexture( clgame.ds.pSprite, frame );
ref.dllFuncs.Color4ub( clgame.ds.spriteColor[0], clgame.ds.spriteColor[1], clgame.ds.spriteColor[2], clgame.ds.spriteColor[3] ); ref.dllFuncs.Color4ub( clgame.ds.spriteColor[0], clgame.ds.spriteColor[1], clgame.ds.spriteColor[2], clgame.ds.spriteColor[3] );
ref.dllFuncs.R_DrawStretchPic( x, y, width, height, s1, t1, s2, t2, texnum ); ref.dllFuncs.R_DrawStretchPic( x, y, width, height, s1, t1, s2, t2, texnum );
} }
@@ -458,7 +462,7 @@ void CL_DrawCenterPrint( void )
if( !clgame.centerPrint.time ) if( !clgame.centerPrint.time )
return; return;
if(( cl.time - clgame.centerPrint.time ) >= scr_centertime->value ) if(( cl.time - clgame.centerPrint.time ) >= scr_centertime.value )
{ {
// time expired // time expired
clgame.centerPrint.time = 0.0f; clgame.centerPrint.time = 0.0f;
@@ -470,8 +474,7 @@ void CL_DrawCenterPrint( void )
pText = clgame.centerPrint.message; pText = clgame.centerPrint.message;
CL_DrawCharacterLen( font, 0, NULL, &charHeight ); CL_DrawCharacterLen( font, 0, NULL, &charHeight );
CL_SetFontRendermode( font );
ref.dllFuncs.GL_SetRenderMode( font->rendermode );
for( i = 0; i < clgame.centerPrint.lines; i++ ) for( i = 0; i < clgame.centerPrint.lines; i++ )
{ {
lineLength = 0; lineLength = 0;
@@ -547,7 +550,7 @@ fill screen with specfied color
can be modulated can be modulated
============= =============
*/ */
void CL_DrawScreenFade( void ) static void CL_DrawScreenFade( void )
{ {
screenfade_t *sf = &clgame.fade; screenfade_t *sf = &clgame.fade;
int alpha; int alpha;
@@ -665,12 +668,12 @@ void CL_ParseTextMessage( sizebuf_t *msg )
text->g2 = MSG_ReadByte( msg ); text->g2 = MSG_ReadByte( msg );
text->b2 = MSG_ReadByte( msg ); text->b2 = MSG_ReadByte( msg );
text->a2 = MSG_ReadByte( msg ); text->a2 = MSG_ReadByte( msg );
text->fadein = (float)(MSG_ReadShort( msg ) / 256.0f ); text->fadein = (float)(MSG_ReadWord( msg ) / 256.0f );
text->fadeout = (float)(MSG_ReadShort( msg ) / 256.0f ); text->fadeout = (float)(MSG_ReadWord( msg ) / 256.0f );
text->holdtime = (float)(MSG_ReadShort( msg ) / 256.0f ); text->holdtime = (float)(MSG_ReadWord( msg ) / 256.0f );
if( text->effect == 2 ) if( text->effect == 2 )
text->fxtime = (float)(MSG_ReadShort( msg ) / 256.0f ); text->fxtime = (float)(MSG_ReadWord( msg ) / 256.0f );
else text->fxtime = 0.0f; else text->fxtime = 0.0f;
// to prevent grab too long messages // to prevent grab too long messages
@@ -763,7 +766,7 @@ CL_SoundFromIndex
return soundname from index return soundname from index
==================== ====================
*/ */
const char *CL_SoundFromIndex( int index ) static const char *CL_SoundFromIndex( int index )
{ {
sfx_t *sfx = NULL; sfx_t *sfx = NULL;
int hSound; int hSound;
@@ -909,12 +912,12 @@ CL_DrawCrosshair
Render crosshair Render crosshair
==================== ====================
*/ */
void CL_DrawCrosshair( void ) static void CL_DrawCrosshair( void )
{ {
int x, y, width, height; int x, y, width, height;
float xscale, yscale; float xscale, yscale;
if( !clgame.ds.pCrosshair || !cl_crosshair->value ) if( !clgame.ds.pCrosshair || !cl_crosshair.value )
return; return;
// any camera on or client is died // any camera on or client is died
@@ -1088,13 +1091,13 @@ void CL_ClearWorld( void )
clgame.numStatics = 0; clgame.numStatics = 0;
} }
void CL_InitEdicts( void ) void CL_InitEdicts( int maxclients )
{ {
Assert( clgame.entities == NULL ); Assert( clgame.entities == NULL );
if( !clgame.mempool ) return; // Host_Error without client if( !clgame.mempool ) return; // Host_Error without client
#if XASH_LOW_MEMORY != 2 #if XASH_LOW_MEMORY != 2
CL_UPDATE_BACKUP = ( cl.maxclients <= 1 ) ? SINGLEPLAYER_BACKUP : MULTIPLAYER_BACKUP; CL_UPDATE_BACKUP = ( maxclients <= 1 ) ? SINGLEPLAYER_BACKUP : MULTIPLAYER_BACKUP;
#endif #endif
cls.num_client_entities = CL_UPDATE_BACKUP * NUM_PACKET_ENTITIES; cls.num_client_entities = CL_UPDATE_BACKUP * NUM_PACKET_ENTITIES;
cls.packet_entities = Mem_Realloc( clgame.mempool, cls.packet_entities, sizeof( entity_state_t ) * cls.num_client_entities ); cls.packet_entities = Mem_Realloc( clgame.mempool, cls.packet_entities, sizeof( entity_state_t ) * cls.num_client_entities );
@@ -1109,12 +1112,12 @@ void CL_InitEdicts( void )
clgame.remap_info = (remap_info_t **)Mem_Calloc( clgame.mempool, sizeof( remap_info_t* ) * clgame.maxRemapInfos ); clgame.remap_info = (remap_info_t **)Mem_Calloc( clgame.mempool, sizeof( remap_info_t* ) * clgame.maxRemapInfos );
} }
ref.dllFuncs.R_ProcessEntData( true ); ref.dllFuncs.R_ProcessEntData( true, clgame.entities, clgame.maxEntities );
} }
void CL_FreeEdicts( void ) void CL_FreeEdicts( void )
{ {
ref.dllFuncs.R_ProcessEntData( false ); ref.dllFuncs.R_ProcessEntData( false, NULL, 0 );
if( clgame.entities ) if( clgame.entities )
Mem_Free( clgame.entities ); Mem_Free( clgame.entities );
@@ -1140,7 +1143,7 @@ void CL_ClearEdicts( void )
// in case we stopped with error // in case we stopped with error
clgame.maxEntities = 2; clgame.maxEntities = 2;
CL_InitEdicts(); CL_InitEdicts( cl.maxclients );
} }
/* /*
@@ -1235,11 +1238,7 @@ static model_t *CL_LoadSpriteModel( const char *filename, uint type, uint texFla
{ {
char name[MAX_QPATH]; char name[MAX_QPATH];
model_t *mod; model_t *mod;
int i; int i, start;
// use high indices for client sprites
// for GoldSrc bug-compatibility
const int start = type != SPR_HUDSPRITE ? MAX_CLIENT_SPRITES / 2 : 0;
if( !COM_CheckString( filename )) if( !COM_CheckString( filename ))
{ {
@@ -1250,7 +1249,7 @@ static model_t *CL_LoadSpriteModel( const char *filename, uint type, uint texFla
Q_strncpy( name, filename, sizeof( name )); Q_strncpy( name, filename, sizeof( name ));
COM_FixSlashes( name ); COM_FixSlashes( name );
for( i = 0, mod = clgame.sprites + start; i < MAX_CLIENT_SPRITES / 2; i++, mod++ ) for( i = 0, mod = clgame.sprites; i < MAX_CLIENT_SPRITES; i++, mod++ )
{ {
if( !Q_stricmp( mod->name, name )) if( !Q_stricmp( mod->name, name ))
{ {
@@ -1267,8 +1266,15 @@ static model_t *CL_LoadSpriteModel( const char *filename, uint type, uint texFla
} }
// find a free model slot spot // find a free model slot spot
for( i = 0, mod = clgame.sprites + start; i < MAX_CLIENT_SPRITES / 2; i++, mod++ ) // use low indices only for HUD sprites
if( !mod->name[0] ) break; // this is a valid spot // for GoldSrc bug compatibility
start = type == SPR_HUDSPRITE ? 0 : MAX_CLIENT_SPRITES / 2;
for( i = 0, mod = &clgame.sprites[start]; i < MAX_CLIENT_SPRITES / 2; i++, mod++ )
{
if( !mod->name[0] )
break; // this is a valid spot
}
if( i == MAX_CLIENT_SPRITES / 2 ) if( i == MAX_CLIENT_SPRITES / 2 )
{ {
@@ -1320,8 +1326,10 @@ HSPRITE pfnSPR_LoadExt( const char *szPicName, uint texFlags )
========= =========
pfnSPR_Load pfnSPR_Load
function exported for support GoldSrc Monitor utility
========= =========
*/ */
HSPRITE EXPORT pfnSPR_Load( const char *szPicName );
HSPRITE EXPORT pfnSPR_Load( const char *szPicName ) HSPRITE EXPORT pfnSPR_Load( const char *szPicName )
{ {
model_t *spr; model_t *spr;
@@ -1338,7 +1346,7 @@ CL_GetSpritePointer
============= =============
*/ */
const model_t *CL_GetSpritePointer( HSPRITE hSprite ) static const model_t *CL_GetSpritePointer( HSPRITE hSprite )
{ {
model_t *mod; model_t *mod;
int index = hSprite - 1; int index = hSprite - 1;
@@ -1368,8 +1376,10 @@ const model_t *CL_GetSpritePointer( HSPRITE hSprite )
========= =========
pfnSPR_Frames pfnSPR_Frames
function exported for support GoldSrc Monitor utility
========= =========
*/ */
int EXPORT pfnSPR_Frames( HSPRITE hPic );
int EXPORT pfnSPR_Frames( HSPRITE hPic ) int EXPORT pfnSPR_Frames( HSPRITE hPic )
{ {
int numFrames = 0; int numFrames = 0;
@@ -1438,7 +1448,7 @@ pfnSPR_Draw
*/ */
static void GAME_EXPORT pfnSPR_Draw( int frame, int x, int y, const wrect_t *prc ) static void GAME_EXPORT pfnSPR_Draw( int frame, int x, int y, const wrect_t *prc )
{ {
ref.dllFuncs.GL_SetRenderMode( kRenderNormal ); ref.dllFuncs.GL_SetRenderMode( kRenderTransAlpha );
SPR_DrawGeneric( frame, x, y, -1, -1, prc ); SPR_DrawGeneric( frame, x, y, -1, -1, prc );
} }
@@ -1588,7 +1598,7 @@ CL_FillRGBA
============= =============
*/ */
void GAME_EXPORT CL_FillRGBA( int x, int y, int w, int h, int r, int g, int b, int a ) static void GAME_EXPORT CL_FillRGBA( int x, int y, int w, int h, int r, int g, int b, int a )
{ {
float _x = x, _y = y, _w = w, _h = h; float _x = x, _y = y, _w = w, _h = h;
@@ -1630,14 +1640,15 @@ get actual screen info
*/ */
int GAME_EXPORT CL_GetScreenInfo( SCREENINFO *pscrinfo ) int GAME_EXPORT CL_GetScreenInfo( SCREENINFO *pscrinfo )
{ {
float scale_factor = hud_scale->value; qboolean apply_scale_factor = false;
float scale_factor = hud_scale.value;
if( FBitSet( hud_fontscale->flags, FCVAR_CHANGED )) if( FBitSet( hud_fontscale.flags, FCVAR_CHANGED ))
{ {
CL_FreeFont( &cls.creditsFont ); CL_FreeFont( &cls.creditsFont );
SCR_LoadCreditsFont(); SCR_LoadCreditsFont();
ClearBits( hud_fontscale->flags, FCVAR_CHANGED ); ClearBits( hud_fontscale.flags, FCVAR_CHANGED );
} }
// setup screen info // setup screen info
@@ -1645,16 +1656,23 @@ int GAME_EXPORT CL_GetScreenInfo( SCREENINFO *pscrinfo )
clgame.scrInfo.iFlags = SCRINFO_SCREENFLASH; clgame.scrInfo.iFlags = SCRINFO_SCREENFLASH;
if( scale_factor && scale_factor != 1.0f ) if( scale_factor && scale_factor != 1.0f )
{
float scaled_width = (float)refState.width / scale_factor;
if( scaled_width >= hud_scale_minimal_width.value )
apply_scale_factor = true;
}
if( apply_scale_factor )
{ {
clgame.scrInfo.iWidth = (float)refState.width / scale_factor; clgame.scrInfo.iWidth = (float)refState.width / scale_factor;
clgame.scrInfo.iHeight = (float)refState.height / scale_factor; clgame.scrInfo.iHeight = (float)refState.height / scale_factor;
clgame.scrInfo.iFlags |= SCRINFO_STRETCHED; SetBits( clgame.scrInfo.iFlags, SCRINFO_STRETCHED );
} }
else else
{ {
clgame.scrInfo.iWidth = refState.width; clgame.scrInfo.iWidth = refState.width;
clgame.scrInfo.iHeight = refState.height; clgame.scrInfo.iHeight = refState.height;
clgame.scrInfo.iFlags &= ~SCRINFO_STRETCHED; ClearBits( clgame.scrInfo.iFlags, SCRINFO_STRETCHED );
} }
if( !pscrinfo ) return 0; if( !pscrinfo ) return 0;
@@ -1685,6 +1703,23 @@ static void GAME_EXPORT pfnSetCrosshair( HSPRITE hspr, wrect_t rc, int r, int g,
clgame.ds.rcCrosshair = rc; clgame.ds.rcCrosshair = rc;
} }
/*
=============
pfnCvar_RegisterVariable
=============
*/
static cvar_t *GAME_EXPORT pfnCvar_RegisterClientVariable( const char *szName, const char *szValue, int flags )
{
// a1ba: try to mitigate outdated client.dll vulnerabilities
if( !Q_stricmp( szName, "motdfile" )
|| !Q_stricmp( szName, "sensitivity" ))
flags |= FCVAR_PRIVILEGED;
return (cvar_t *)Cvar_Get( szName, szValue, flags|FCVAR_CLIENTDLL, Cvar_BuildAutoDescription( szName, flags|FCVAR_CLIENTDLL ));
}
/* /*
============= =============
pfnHookUserMsg pfnHookUserMsg
@@ -1889,7 +1924,7 @@ static int GAME_EXPORT pfnDrawCharacter( int x, int y, int number, int r, int g,
rgba_t color = { r, g, b, 255 }; rgba_t color = { r, g, b, 255 };
int flags = FONT_DRAW_HUD; int flags = FONT_DRAW_HUD;
if( hud_utf8->value ) if( hud_utf8.value )
flags |= FONT_DRAW_UTF8; flags |= FONT_DRAW_UTF8;
return CL_DrawCharacter( x, y, number, color, &cls.creditsFont, flags ); return CL_DrawCharacter( x, y, number, color, &cls.creditsFont, flags );
@@ -1904,7 +1939,7 @@ drawing string like a console string
*/ */
int GAME_EXPORT pfnDrawConsoleString( int x, int y, char *string ) int GAME_EXPORT pfnDrawConsoleString( int x, int y, char *string )
{ {
cl_font_t *font = Con_GetFont( con_fontsize->value ); cl_font_t *font = Con_GetFont( con_fontsize.value );
rgba_t color; rgba_t color;
Vector4Copy( clgame.ds.textColor, color ); Vector4Copy( clgame.ds.textColor, color );
Vector4Set( clgame.ds.textColor, 255, 255, 255, 255 ); Vector4Set( clgame.ds.textColor, 255, 255, 255, 255 );
@@ -1937,7 +1972,7 @@ compute string length in screen pixels
*/ */
void GAME_EXPORT pfnDrawConsoleStringLen( const char *pText, int *length, int *height ) void GAME_EXPORT pfnDrawConsoleStringLen( const char *pText, int *length, int *height )
{ {
cl_font_t *font = Con_GetFont( con_fontsize->value ); cl_font_t *font = Con_GetFont( con_fontsize.value );
if( height ) *height = font->charHeight; if( height ) *height = font->charHeight;
CL_DrawStringLen( font, pText, length, NULL, FONT_DRAW_UTF8 | FONT_DRAW_HUD ); CL_DrawStringLen( font, pText, length, NULL, FONT_DRAW_UTF8 | FONT_DRAW_HUD );
@@ -1985,7 +2020,7 @@ static int GAME_EXPORT pfnGetWindowCenterX( void )
{ {
int x = 0; int x = 0;
#if XASH_WIN32 #if XASH_WIN32
if( m_ignore->value ) if( m_ignore.value )
{ {
POINT pos; POINT pos;
GetCursorPos( &pos ); GetCursorPos( &pos );
@@ -2010,7 +2045,7 @@ static int GAME_EXPORT pfnGetWindowCenterY( void )
{ {
int y = 0; int y = 0;
#if XASH_WIN32 #if XASH_WIN32
if( m_ignore->value ) if( m_ignore.value )
{ {
POINT pos; POINT pos;
GetCursorPos( &pos ); GetCursorPos( &pos );
@@ -2100,7 +2135,7 @@ pfnGetViewModel
============= =============
*/ */
cl_entity_t* GAME_EXPORT CL_GetViewModel( void ) static cl_entity_t* GAME_EXPORT CL_GetViewModel( void )
{ {
return &clgame.viewent; return &clgame.viewent;
} }
@@ -2122,7 +2157,7 @@ pfnCalcShake
============= =============
*/ */
void GAME_EXPORT pfnCalcShake( void ) static void GAME_EXPORT pfnCalcShake( void )
{ {
screen_shake_t *const shake = &clgame.shake; screen_shake_t *const shake = &clgame.shake;
float frametime, fraction, freq; float frametime, fraction, freq;
@@ -2178,7 +2213,7 @@ pfnApplyShake
============= =============
*/ */
void GAME_EXPORT pfnApplyShake( float *origin, float *angles, float factor ) static void GAME_EXPORT pfnApplyShake( float *origin, float *angles, float factor )
{ {
if( origin ) if( origin )
VectorMA( origin, factor, clgame.shake.applied_offset, origin ); VectorMA( origin, factor, clgame.shake.applied_offset, origin );
@@ -2306,7 +2341,7 @@ pfnPlaySound
============= =============
*/ */
void GAME_EXPORT pfnPlaySound( int ent, float *org, int chan, const char *samp, float vol, float attn, int flags, int pitch ) static void GAME_EXPORT pfnPlaySound( int ent, float *org, int chan, const char *samp, float vol, float attn, int flags, int pitch )
{ {
S_StartSound( org, ent, chan, S_RegisterSound( samp ), vol, attn, pitch, flags ); S_StartSound( org, ent, chan, S_RegisterSound( samp ), vol, attn, pitch, flags );
} }
@@ -2317,7 +2352,7 @@ CL_FindModelIndex
============= =============
*/ */
int GAME_EXPORT CL_FindModelIndex( const char *m ) static int GAME_EXPORT CL_FindModelIndex( const char *m )
{ {
char filepath[MAX_QPATH]; char filepath[MAX_QPATH];
static float lasttimewarn; static float lasttimewarn;
@@ -2354,7 +2389,7 @@ pfnIsLocal
============= =============
*/ */
int GAME_EXPORT pfnIsLocal( int playernum ) static int GAME_EXPORT pfnIsLocal( int playernum )
{ {
if( playernum == cl.playernum ) if( playernum == cl.playernum )
return true; return true;
@@ -2367,7 +2402,7 @@ pfnLocalPlayerDucking
============= =============
*/ */
int GAME_EXPORT pfnLocalPlayerDucking( void ) static int GAME_EXPORT pfnLocalPlayerDucking( void )
{ {
return (cl.local.usehull == 1) ? true : false; return (cl.local.usehull == 1) ? true : false;
} }
@@ -2378,7 +2413,7 @@ pfnLocalPlayerViewheight
============= =============
*/ */
void GAME_EXPORT pfnLocalPlayerViewheight( float *view_ofs ) static void GAME_EXPORT pfnLocalPlayerViewheight( float *view_ofs )
{ {
if( view_ofs ) VectorCopy( cl.viewheight, view_ofs ); if( view_ofs ) VectorCopy( cl.viewheight, view_ofs );
} }
@@ -2389,7 +2424,7 @@ pfnLocalPlayerBounds
============= =============
*/ */
void GAME_EXPORT pfnLocalPlayerBounds( int hull, float *mins, float *maxs ) static void GAME_EXPORT pfnLocalPlayerBounds( int hull, float *mins, float *maxs )
{ {
if( hull >= 0 && hull < 4 ) if( hull >= 0 && hull < 4 )
{ {
@@ -2404,7 +2439,7 @@ pfnIndexFromTrace
============= =============
*/ */
int GAME_EXPORT pfnIndexFromTrace( struct pmtrace_s *pTrace ) static int GAME_EXPORT pfnIndexFromTrace( struct pmtrace_s *pTrace )
{ {
#if 0 // Velaron: breaks compatibility with mods that call the function after CL_PopPMStates #if 0 // Velaron: breaks compatibility with mods that call the function after CL_PopPMStates
if( pTrace->ent >= 0 && pTrace->ent < clgame.pmove->numphysent ) if( pTrace->ent >= 0 && pTrace->ent < clgame.pmove->numphysent )
@@ -2439,7 +2474,7 @@ pfnGetVisent
============= =============
*/ */
physent_t *pfnGetVisent( int idx ) static physent_t *pfnGetVisent( int idx )
{ {
if( idx >= 0 && idx < clgame.pmove->numvisent ) if( idx >= 0 && idx < clgame.pmove->numvisent )
{ {
@@ -2449,13 +2484,43 @@ physent_t *pfnGetVisent( int idx )
return NULL; return NULL;
} }
static int GAME_EXPORT CL_TestLine( const vec3_t start, const vec3_t end, int flags )
{
return PM_TestLineExt( clgame.pmove, clgame.pmove->physents, clgame.pmove->numphysent, start, end, flags );
}
/*
=============
CL_PushTraceBounds
=============
*/
static void GAME_EXPORT CL_PushTraceBounds( int hullnum, const float *mins, const float *maxs )
{
hullnum = bound( 0, hullnum, 3 );
VectorCopy( mins, clgame.pmove->player_mins[hullnum] );
VectorCopy( maxs, clgame.pmove->player_maxs[hullnum] );
}
/*
=============
CL_PopTraceBounds
=============
*/
static void GAME_EXPORT CL_PopTraceBounds( void )
{
memcpy( clgame.pmove->player_mins, host.player_mins, sizeof( host.player_mins ));
memcpy( clgame.pmove->player_maxs, host.player_maxs, sizeof( host.player_maxs ));
}
/* /*
============= =============
pfnSetTraceHull pfnSetTraceHull
============= =============
*/ */
void GAME_EXPORT CL_SetTraceHull( int hull ) static void GAME_EXPORT CL_SetTraceHull( int hull )
{ {
clgame.pmove->usehull = bound( 0, hull, 3 ); clgame.pmove->usehull = bound( 0, hull, 3 );
} }
@@ -2466,7 +2531,7 @@ pfnPlayerTrace
============= =============
*/ */
void GAME_EXPORT CL_PlayerTrace( float *start, float *end, int traceFlags, int ignore_pe, pmtrace_t *tr ) static void GAME_EXPORT CL_PlayerTrace( float *start, float *end, int traceFlags, int ignore_pe, pmtrace_t *tr )
{ {
if( !tr ) return; if( !tr ) return;
*tr = PM_PlayerTraceExt( clgame.pmove, start, end, traceFlags, clgame.pmove->numphysent, clgame.pmove->physents, ignore_pe, NULL ); *tr = PM_PlayerTraceExt( clgame.pmove, start, end, traceFlags, clgame.pmove->numphysent, clgame.pmove->physents, ignore_pe, NULL );
@@ -2478,7 +2543,7 @@ pfnPlayerTraceExt
============= =============
*/ */
void GAME_EXPORT CL_PlayerTraceExt( float *start, float *end, int traceFlags, int (*pfnIgnore)( physent_t *pe ), pmtrace_t *tr ) static void GAME_EXPORT CL_PlayerTraceExt( float *start, float *end, int traceFlags, int (*pfnIgnore)( physent_t *pe ), pmtrace_t *tr )
{ {
if( !tr ) return; if( !tr ) return;
*tr = PM_PlayerTraceExt( clgame.pmove, start, end, traceFlags, clgame.pmove->numphysent, clgame.pmove->physents, -1, pfnIgnore ); *tr = PM_PlayerTraceExt( clgame.pmove, start, end, traceFlags, clgame.pmove->numphysent, clgame.pmove->physents, -1, pfnIgnore );
@@ -2523,7 +2588,7 @@ pfnStopAllSounds
============= =============
*/ */
void GAME_EXPORT pfnStopAllSounds( int ent, int entchannel ) static void GAME_EXPORT pfnStopAllSounds( int ent, int entchannel )
{ {
S_StopSound( ent, entchannel, NULL ); S_StopSound( ent, entchannel, NULL );
} }
@@ -2548,7 +2613,7 @@ model_t *CL_LoadModel( const char *modelname, int *index )
return CL_ModelHandle( i ); return CL_ModelHandle( i );
} }
int GAME_EXPORT CL_AddEntity( int entityType, cl_entity_t *pEnt ) static int GAME_EXPORT CL_AddEntity( int entityType, cl_entity_t *pEnt )
{ {
if( !pEnt ) return false; if( !pEnt ) return false;
@@ -2565,7 +2630,7 @@ pfnGetGameDirectory
============= =============
*/ */
const char *pfnGetGameDirectory( void ) static const char *pfnGetGameDirectory( void )
{ {
static char szGetGameDir[MAX_SYSPATH]; static char szGetGameDir[MAX_SYSPATH];
@@ -2579,7 +2644,7 @@ Key_LookupBinding
============= =============
*/ */
const char *Key_LookupBinding( const char *pBinding ) static const char *Key_LookupBinding( const char *pBinding )
{ {
return Key_KeynumToString( Key_GetKey( pBinding )); return Key_KeynumToString( Key_GetKey( pBinding ));
} }
@@ -2610,7 +2675,7 @@ pfnGetScreenFade
============= =============
*/ */
void GAME_EXPORT pfnGetScreenFade( struct screenfade_s *fade ) static void GAME_EXPORT pfnGetScreenFade( struct screenfade_s *fade )
{ {
if( fade ) *fade = clgame.fade; if( fade ) *fade = clgame.fade;
} }
@@ -2632,7 +2697,7 @@ pfnLoadMapSprite
============= =============
*/ */
model_t *pfnLoadMapSprite( const char *filename ) static model_t *pfnLoadMapSprite( const char *filename )
{ {
model_t *mod; model_t *mod;
@@ -2644,13 +2709,55 @@ model_t *pfnLoadMapSprite( const char *filename )
return NULL; return NULL;
} }
/*
=============
COM_AddAppDirectoryToSearchPath
=============
*/
static void GAME_EXPORT COM_AddAppDirectoryToSearchPath( const char *pszBaseDir, const char *appName )
{
FS_AddGameHierarchy( pszBaseDir, FS_NOWRITE_PATH );
}
/*
===========
COM_ExpandFilename
Finds the file in the search path, copies over the name with the full path name.
This doesn't search in the pak file.
===========
*/
static int GAME_EXPORT COM_ExpandFilename( const char *fileName, char *nameOutBuffer, int nameOutBufferSize )
{
char result[MAX_SYSPATH];
if( !COM_CheckString( fileName ) || !nameOutBuffer || nameOutBufferSize <= 0 )
return 0;
// filename examples:
// media\sierra.avi - D:\Xash3D\valve\media\sierra.avi
// models\barney.mdl - D:\Xash3D\bshift\models\barney.mdl
if( g_fsapi.GetFullDiskPath( result, sizeof( result ), fileName, false ))
{
// check for enough room
if( Q_strlen( result ) > nameOutBufferSize )
return 0;
Q_strncpy( nameOutBuffer, result, nameOutBufferSize );
return 1;
}
return 0;
}
/* /*
============= =============
PlayerInfo_ValueForKey PlayerInfo_ValueForKey
============= =============
*/ */
const char *PlayerInfo_ValueForKey( int playerNum, const char *key ) static const char *PlayerInfo_ValueForKey( int playerNum, const char *key )
{ {
// find the player // find the player
if(( playerNum > cl.maxclients ) || ( playerNum < 1 )) if(( playerNum > cl.maxclients ) || ( playerNum < 1 ))
@@ -2668,7 +2775,7 @@ PlayerInfo_SetValueForKey
============= =============
*/ */
void GAME_EXPORT PlayerInfo_SetValueForKey( const char *key, const char *value ) static void GAME_EXPORT PlayerInfo_SetValueForKey( const char *key, const char *value )
{ {
convar_t *var; convar_t *var;
@@ -2694,7 +2801,7 @@ pfnGetPlayerUniqueID
============= =============
*/ */
qboolean GAME_EXPORT pfnGetPlayerUniqueID( int iPlayer, char playerID[16] ) static qboolean GAME_EXPORT pfnGetPlayerUniqueID( int iPlayer, char playerID[16] )
{ {
if( iPlayer < 1 || iPlayer > cl.maxclients ) if( iPlayer < 1 || iPlayer > cl.maxclients )
return false; return false;
@@ -2714,7 +2821,7 @@ pfnGetTrackerIDForPlayer
obsolete, unused obsolete, unused
============= =============
*/ */
int GAME_EXPORT pfnGetTrackerIDForPlayer( int playerSlot ) static int GAME_EXPORT pfnGetTrackerIDForPlayer( int playerSlot )
{ {
return 0; return 0;
} }
@@ -2726,7 +2833,7 @@ pfnGetPlayerForTrackerID
obsolete, unused obsolete, unused
============= =============
*/ */
int GAME_EXPORT pfnGetPlayerForTrackerID( int trackerID ) static int GAME_EXPORT pfnGetPlayerForTrackerID( int trackerID )
{ {
return 0; return 0;
} }
@@ -2737,7 +2844,7 @@ pfnServerCmdUnreliable
============= =============
*/ */
int GAME_EXPORT pfnServerCmdUnreliable( char *szCmdString ) static int GAME_EXPORT pfnServerCmdUnreliable( char *szCmdString )
{ {
if( !COM_CheckString( szCmdString )) if( !COM_CheckString( szCmdString ))
return 0; return 0;
@@ -2754,7 +2861,7 @@ pfnGetMousePos
============= =============
*/ */
void GAME_EXPORT pfnGetMousePos( struct tagPOINT *ppt ) static void GAME_EXPORT pfnGetMousePos( struct tagPOINT *ppt )
{ {
if( !ppt ) if( !ppt )
return; return;
@@ -2769,7 +2876,7 @@ pfnSetMouseEnable
legacy of dinput code legacy of dinput code
============= =============
*/ */
void GAME_EXPORT pfnSetMouseEnable( qboolean fEnable ) static void GAME_EXPORT pfnSetMouseEnable( qboolean fEnable )
{ {
} }
@@ -2888,7 +2995,7 @@ static int GAME_EXPORT pfnDrawString( int x, int y, const char *str, int r, int
rgba_t color = { r, g, b, 255 }; rgba_t color = { r, g, b, 255 };
int flags = FONT_DRAW_HUD | FONT_DRAW_NOLF; int flags = FONT_DRAW_HUD | FONT_DRAW_NOLF;
if( hud_utf8->value ) if( hud_utf8.value )
SetBits( flags, FONT_DRAW_UTF8 ); SetBits( flags, FONT_DRAW_UTF8 );
return CL_DrawString( x, y, str, color, &cls.creditsFont, flags ); return CL_DrawString( x, y, str, color, &cls.creditsFont, flags );
@@ -2906,7 +3013,7 @@ static int GAME_EXPORT pfnDrawStringReverse( int x, int y, const char *str, int
int flags = FONT_DRAW_HUD | FONT_DRAW_NOLF; int flags = FONT_DRAW_HUD | FONT_DRAW_NOLF;
int width; int width;
if( hud_utf8->value ) if( hud_utf8.value )
SetBits( flags, FONT_DRAW_UTF8 ); SetBits( flags, FONT_DRAW_UTF8 );
CL_DrawStringLen( &cls.creditsFont, str, &width, NULL, flags ); CL_DrawStringLen( &cls.creditsFont, str, &width, NULL, flags );
@@ -2983,7 +3090,7 @@ pfnFillRGBABlend
============= =============
*/ */
void GAME_EXPORT CL_FillRGBABlend( int x, int y, int w, int h, int r, int g, int b, int a ) static void GAME_EXPORT CL_FillRGBABlend( int x, int y, int w, int h, int r, int g, int b, int a )
{ {
float _x = x, _y = y, _w = w, _h = h; float _x = x, _y = y, _w = w, _h = h;
@@ -3045,7 +3152,7 @@ pfnParseFile
handle colon separately handle colon separately
============= =============
*/ */
char *pfnParseFile( char *data, char *token ) static char *pfnParseFile( char *data, char *token )
{ {
return COM_ParseFileSafe( data, token, PFILE_TOKEN_MAX_LENGTH, PFILE_HANDLECOLON, NULL, NULL ); return COM_ParseFileSafe( data, token, PFILE_TOKEN_MAX_LENGTH, PFILE_HANDLECOLON, NULL, NULL );
} }
@@ -3266,7 +3373,7 @@ NetAPI_InitNetworking
================= =================
*/ */
void GAME_EXPORT NetAPI_InitNetworking( void ) static void GAME_EXPORT NetAPI_InitNetworking( void )
{ {
NET_Config( true, false ); // allow remote NET_Config( true, false ); // allow remote
} }
@@ -3277,7 +3384,7 @@ NetAPI_InitNetworking
================= =================
*/ */
void GAME_EXPORT NetAPI_Status( net_status_t *status ) static void GAME_EXPORT NetAPI_Status( net_status_t *status )
{ {
qboolean connected = false; qboolean connected = false;
int packet_loss = 0; int packet_loss = 0;
@@ -3296,7 +3403,7 @@ void GAME_EXPORT NetAPI_Status( net_status_t *status )
status->remote_address = cls.netchan.remote_address; status->remote_address = cls.netchan.remote_address;
status->packet_loss = packet_loss; status->packet_loss = packet_loss;
status->local_address = net_local; status->local_address = net_local;
status->rate = rate->value; status->rate = rate.value;
} }
/* /*
@@ -3305,7 +3412,7 @@ NetAPI_SendRequest
================= =================
*/ */
void GAME_EXPORT NetAPI_SendRequest( int context, int request, int flags, double timeout, netadr_t *remote_address, net_api_response_func_t response ) static void GAME_EXPORT NetAPI_SendRequest( int context, int request, int flags, double timeout, netadr_t *remote_address, net_api_response_func_t response )
{ {
net_request_t *nr = NULL; net_request_t *nr = NULL;
string req; string req;
@@ -3320,6 +3427,9 @@ void GAME_EXPORT NetAPI_SendRequest( int context, int request, int flags, double
if( remote_address->type != NA_IPX && remote_address->type != NA_BROADCAST_IPX ) if( remote_address->type != NA_IPX && remote_address->type != NA_BROADCAST_IPX )
return; // IPX no longer support return; // IPX no longer support
if( request == NETAPI_REQUEST_SERVERLIST )
return; // no support for server list requests
// find a free request // find a free request
for( i = 0; i < MAX_REQUESTS; i++ ) for( i = 0; i < MAX_REQUESTS; i++ )
{ {
@@ -3356,29 +3466,10 @@ void GAME_EXPORT NetAPI_SendRequest( int context, int request, int flags, double
nr->resp.remote_address = *remote_address; nr->resp.remote_address = *remote_address;
nr->flags = flags; nr->flags = flags;
if( request == NETAPI_REQUEST_SERVERLIST )
{
char fullquery[512];
size_t len;
len = CL_BuildMasterServerScanRequest( fullquery, sizeof( fullquery ), false );
// make sure that port is specified
if( !nr->resp.remote_address.port )
nr->resp.remote_address.port = MSG_BigShort( PORT_MASTER );
// grab the list from the master server
NET_SendPacket( NS_CLIENT, len, fullquery, nr->resp.remote_address );
clgame.request_type = NET_REQUEST_CLIENT;
clgame.master_request = nr; // holds the master request unitl the master acking
}
else
{
// local servers request // local servers request
Q_snprintf( req, sizeof( req ), "netinfo %i %i %i", PROTOCOL_VERSION, context, request ); Q_snprintf( req, sizeof( req ), "netinfo %i %i %i", PROTOCOL_VERSION, context, request );
Netchan_OutOfBandPrint( NS_CLIENT, nr->resp.remote_address, "%s", req ); Netchan_OutOfBandPrint( NS_CLIENT, nr->resp.remote_address, "%s", req );
} }
}
/* /*
================= =================
@@ -3386,7 +3477,7 @@ NetAPI_CancelRequest
================= =================
*/ */
void GAME_EXPORT NetAPI_CancelRequest( int context ) static void GAME_EXPORT NetAPI_CancelRequest( int context )
{ {
net_request_t *nr; net_request_t *nr;
int i; int i;
@@ -3405,13 +3496,6 @@ void GAME_EXPORT NetAPI_CancelRequest( int context )
nr->pfnFunc( &nr->resp ); nr->pfnFunc( &nr->resp );
} }
if( clgame.net_requests[i].resp.type == NETAPI_REQUEST_SERVERLIST && &clgame.net_requests[i] == clgame.master_request )
{
if( clgame.request_type == NET_REQUEST_CLIENT )
clgame.request_type = NET_REQUEST_CANCEL;
clgame.master_request = NULL;
}
memset( &clgame.net_requests[i], 0, sizeof( net_request_t )); memset( &clgame.net_requests[i], 0, sizeof( net_request_t ));
break; break;
} }
@@ -3440,8 +3524,6 @@ void GAME_EXPORT NetAPI_CancelAllRequests( void )
} }
memset( clgame.net_requests, 0, sizeof( clgame.net_requests )); memset( clgame.net_requests, 0, sizeof( clgame.net_requests ));
clgame.request_type = NET_REQUEST_CANCEL;
clgame.master_request = NULL;
} }
/* /*
@@ -3450,7 +3532,7 @@ NetAPI_AdrToString
================= =================
*/ */
const char *NetAPI_AdrToString( netadr_t *a ) static const char *NetAPI_AdrToString( netadr_t *a )
{ {
return NET_AdrToString( *a ); return NET_AdrToString( *a );
} }
@@ -3461,7 +3543,7 @@ NetAPI_CompareAdr
================= =================
*/ */
int GAME_EXPORT NetAPI_CompareAdr( netadr_t *a, netadr_t *b ) static int GAME_EXPORT NetAPI_CompareAdr( netadr_t *a, netadr_t *b )
{ {
return NET_CompareAdr( *a, *b ); return NET_CompareAdr( *a, *b );
} }
@@ -3472,7 +3554,7 @@ NetAPI_StringToAdr
================= =================
*/ */
int GAME_EXPORT NetAPI_StringToAdr( char *s, netadr_t *a ) static int GAME_EXPORT NetAPI_StringToAdr( char *s, netadr_t *a )
{ {
return NET_StringToAdr( s, a ); return NET_StringToAdr( s, a );
} }
@@ -3483,7 +3565,7 @@ NetAPI_ValueForKey
================= =================
*/ */
const char *NetAPI_ValueForKey( const char *s, const char *key ) static const char * GAME_EXPORT NetAPI_ValueForKey( const char *s, const char *key )
{ {
return Info_ValueForKey( s, key ); return Info_ValueForKey( s, key );
} }
@@ -3494,7 +3576,7 @@ NetAPI_RemoveKey
================= =================
*/ */
void GAME_EXPORT NetAPI_RemoveKey( char *s, const char *key ) static void GAME_EXPORT NetAPI_RemoveKey( char *s, const char *key )
{ {
Info_RemoveKey( s, key ); Info_RemoveKey( s, key );
} }
@@ -3505,7 +3587,7 @@ NetAPI_SetValueForKey
================= =================
*/ */
void GAME_EXPORT NetAPI_SetValueForKey( char *s, const char *key, const char *value, int maxsize ) static void GAME_EXPORT NetAPI_SetValueForKey( char *s, const char *key, const char *value, int maxsize )
{ {
if( key[0] == '*' ) return; if( key[0] == '*' ) return;
Info_SetValueForStarKey( s, key, value, maxsize ); Info_SetValueForStarKey( s, key, value, maxsize );
@@ -3525,7 +3607,7 @@ Voice_StartVoiceTweakMode
================= =================
*/ */
int GAME_EXPORT Voice_StartVoiceTweakMode( void ) static int GAME_EXPORT Voice_StartVoiceTweakMode( void )
{ {
return 0; return 0;
} }
@@ -3536,7 +3618,7 @@ Voice_EndVoiceTweakMode
================= =================
*/ */
void GAME_EXPORT Voice_EndVoiceTweakMode( void ) static void GAME_EXPORT Voice_EndVoiceTweakMode( void )
{ {
} }
@@ -3546,7 +3628,7 @@ Voice_SetControlFloat
================= =================
*/ */
void GAME_EXPORT Voice_SetControlFloat( VoiceTweakControl iControl, float value ) static void GAME_EXPORT Voice_SetControlFloat( VoiceTweakControl iControl, float value )
{ {
} }
@@ -3556,7 +3638,7 @@ Voice_GetControlFloat
================= =================
*/ */
float GAME_EXPORT Voice_GetControlFloat( VoiceTweakControl iControl ) static float GAME_EXPORT Voice_GetControlFloat( VoiceTweakControl iControl )
{ {
return 1.0f; return 1.0f;
} }
@@ -3874,13 +3956,13 @@ void CL_UnloadProgs( void )
Cvar_FullSet( "cl_background", "0", FCVAR_READ_ONLY ); Cvar_FullSet( "cl_background", "0", FCVAR_READ_ONLY );
Cvar_FullSet( "host_clientloaded", "0", FCVAR_READ_ONLY ); Cvar_FullSet( "host_clientloaded", "0", FCVAR_READ_ONLY );
Cvar_Unlink( FCVAR_CLIENTDLL );
Cmd_Unlink( CMD_CLIENTDLL );
COM_FreeLibrary( clgame.hInstance ); COM_FreeLibrary( clgame.hInstance );
Mem_FreePool( &cls.mempool ); Mem_FreePool( &cls.mempool );
Mem_FreePool( &clgame.mempool ); Mem_FreePool( &clgame.mempool );
memset( &clgame, 0, sizeof( clgame )); memset( &clgame, 0, sizeof( clgame ));
Cvar_Unlink( FCVAR_CLIENTDLL );
Cmd_Unlink( CMD_CLIENTDLL );
} }
qboolean CL_LoadProgs( const char *name ) qboolean CL_LoadProgs( const char *name )
@@ -4038,7 +4120,7 @@ qboolean CL_LoadProgs( const char *name )
if( !Mobile_Init() ) // Xash3D FWGS extension: mobile interface if( !Mobile_Init() ) // Xash3D FWGS extension: mobile interface
Con_Reportf( S_WARN "CL_LoadProgs: couldn't get mobility API\n" ); Con_Reportf( S_WARN "CL_LoadProgs: couldn't get mobility API\n" );
CL_InitEdicts (); // initailize local player and world CL_InitEdicts( cl.maxclients ); // initailize local player and world
CL_InitClientMove(); // initialize pm_shared CL_InitClientMove(); // initialize pm_shared
// initialize game // initialize game

View File

@@ -414,11 +414,15 @@ static void UI_ConvertGameInfo( GAMEINFO *out, gameinfo_t *in )
out->gamemode = in->gamemode; out->gamemode = in->gamemode;
if( in->nomodels ) if( in->nomodels )
out->flags |= GFL_NOMODELS; SetBits( out->flags, GFL_NOMODELS );
if( in->noskills ) if( in->noskills )
out->flags |= GFL_NOSKILLS; SetBits( out->flags, GFL_NOSKILLS );
if( in->render_picbutton_text ) if( in->render_picbutton_text )
out->flags |= GFL_RENDER_PICBUTTON_TEXT; SetBits( out->flags, GFL_RENDER_PICBUTTON_TEXT );
if( in->hd_background )
SetBits( out->flags, GFL_HD_BACKGROUND );
if( in->animated_title )
SetBits( out->flags, GFL_ANIMATED_TITLE );
} }
/* /*
@@ -538,7 +542,7 @@ pfnPIC_Set
========= =========
*/ */
void GAME_EXPORT pfnPIC_Set( HIMAGE hPic, int r, int g, int b, int a ) static void GAME_EXPORT pfnPIC_Set( HIMAGE hPic, int r, int g, int b, int a )
{ {
gameui.ds.gl_texturenum = hPic; gameui.ds.gl_texturenum = hPic;
r = bound( 0, r, 255 ); r = bound( 0, r, 255 );
@@ -554,7 +558,7 @@ pfnPIC_Draw
========= =========
*/ */
void GAME_EXPORT pfnPIC_Draw( int x, int y, int width, int height, const wrect_t *prc ) static void GAME_EXPORT pfnPIC_Draw( int x, int y, int width, int height, const wrect_t *prc )
{ {
ref.dllFuncs.GL_SetRenderMode( kRenderNormal ); ref.dllFuncs.GL_SetRenderMode( kRenderNormal );
PIC_DrawGeneric( x, y, width, height, prc ); PIC_DrawGeneric( x, y, width, height, prc );
@@ -566,7 +570,7 @@ pfnPIC_DrawTrans
========= =========
*/ */
void GAME_EXPORT pfnPIC_DrawTrans( int x, int y, int width, int height, const wrect_t *prc ) static void GAME_EXPORT pfnPIC_DrawTrans( int x, int y, int width, int height, const wrect_t *prc )
{ {
ref.dllFuncs.GL_SetRenderMode( kRenderTransTexture ); ref.dllFuncs.GL_SetRenderMode( kRenderTransTexture );
PIC_DrawGeneric( x, y, width, height, prc ); PIC_DrawGeneric( x, y, width, height, prc );
@@ -578,7 +582,7 @@ pfnPIC_DrawHoles
========= =========
*/ */
void GAME_EXPORT pfnPIC_DrawHoles( int x, int y, int width, int height, const wrect_t *prc ) static void GAME_EXPORT pfnPIC_DrawHoles( int x, int y, int width, int height, const wrect_t *prc )
{ {
ref.dllFuncs.GL_SetRenderMode( kRenderTransAlpha ); ref.dllFuncs.GL_SetRenderMode( kRenderTransAlpha );
PIC_DrawGeneric( x, y, width, height, prc ); PIC_DrawGeneric( x, y, width, height, prc );
@@ -590,7 +594,7 @@ pfnPIC_DrawAdditive
========= =========
*/ */
void GAME_EXPORT pfnPIC_DrawAdditive( int x, int y, int width, int height, const wrect_t *prc ) static void GAME_EXPORT pfnPIC_DrawAdditive( int x, int y, int width, int height, const wrect_t *prc )
{ {
ref.dllFuncs.GL_SetRenderMode( kRenderTransAdd ); ref.dllFuncs.GL_SetRenderMode( kRenderTransAdd );
PIC_DrawGeneric( x, y, width, height, prc ); PIC_DrawGeneric( x, y, width, height, prc );
@@ -642,6 +646,17 @@ static void GAME_EXPORT pfnFillRGBA( int x, int y, int width, int height, int r,
ref.dllFuncs.Color4ub( 255, 255, 255, 255 ); 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 pfnClientCmd
@@ -969,30 +984,23 @@ pfnCheckGameDll
========= =========
*/ */
int GAME_EXPORT pfnCheckGameDll( void ) static int GAME_EXPORT pfnCheckGameDll( void )
{ {
string dllpath; #ifdef XASH_INTERNAL_GAMELIBS
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
return true; return true;
#endif #else
string dllpath;
if( svgame.hInstance ) if( svgame.hInstance )
return true; return true;
COM_GetCommonLibraryPath( LIBRARY_SERVER, dllpath, sizeof( dllpath )); COM_GetCommonLibraryPath( LIBRARY_SERVER, dllpath, sizeof( dllpath ));
if(( hInst = COM_LoadLibrary( dllpath, true, false )) != NULL ) if( FS_FileExists( dllpath, false ))
{
COM_FreeLibrary( hInst ); // don't increase linker's reference counter
return true; return true;
}
Con_Reportf( S_WARN "Could not load server library: %s\n", COM_GetLibraryError() );
return false; return false;
#endif
} }
/* /*
@@ -1084,6 +1092,25 @@ static int pfnDelete( const char *path )
return FS_Delete( path ); return FS_Delete( path );
} }
static void GAME_EXPORT pfnCon_DefaultColor( int r, int g, int b )
{
Con_DefaultColor( r, g, b, true );
}
static void GAME_EXPORT pfnSetCursor( void *hCursor )
{
uintptr_t cursor;
if( !gameui.use_extended_api )
return; // ignore original Xash menus
cursor = (uintptr_t)hCursor;
if( cursor < dc_user || cursor > dc_last )
return;
Platform_SetCursorType( cursor );
}
// engine callbacks // engine callbacks
static ui_enginefuncs_t gEngfuncs = static ui_enginefuncs_t gEngfuncs =
{ {
@@ -1123,7 +1150,7 @@ static ui_enginefuncs_t gEngfuncs =
UI_DrawConsoleString, UI_DrawConsoleString,
UI_DrawSetTextColor, UI_DrawSetTextColor,
Con_DrawStringLen, Con_DrawStringLen,
Con_DefaultColor, pfnCon_DefaultColor,
pfnGetPlayerModel, pfnGetPlayerModel,
pfnSetPlayerModel, pfnSetPlayerModel,
pfnClearScene, pfnClearScene,
@@ -1163,7 +1190,7 @@ static ui_enginefuncs_t gEngfuncs =
pfnHostEndGame, pfnHostEndGame,
COM_RandomFloat, COM_RandomFloat,
COM_RandomLong, COM_RandomLong,
IN_SetCursor, pfnSetCursor,
pfnIsMapValid, pfnIsMapValid,
GL_ProcessTexture, GL_ProcessTexture,
COM_CompareFileTime, COM_CompareFileTime,
@@ -1207,6 +1234,7 @@ static ui_extendedfuncs_t gExtendedfuncs =
pfnParseFileSafe, pfnParseFileSafe,
NET_AdrToString, NET_AdrToString,
NET_CompareAdrSort, NET_CompareAdrSort,
Sys_GetNativeObject,
}; };
void UI_UnloadProgs( void ) void UI_UnloadProgs( void )
@@ -1218,12 +1246,12 @@ void UI_UnloadProgs( void )
Cvar_FullSet( "host_gameuiloaded", "0", FCVAR_READ_ONLY ); Cvar_FullSet( "host_gameuiloaded", "0", FCVAR_READ_ONLY );
Cvar_Unlink( FCVAR_GAMEUIDLL );
Cmd_Unlink( CMD_GAMEUIDLL );
COM_FreeLibrary( gameui.hInstance ); COM_FreeLibrary( gameui.hInstance );
Mem_FreePool( &gameui.mempool ); Mem_FreePool( &gameui.mempool );
memset( &gameui, 0, sizeof( gameui )); memset( &gameui, 0, sizeof( gameui ));
Cvar_Unlink( FCVAR_GAMEUIDLL );
Cmd_Unlink( CMD_GAMEUIDLL );
} }
qboolean UI_LoadProgs( void ) qboolean UI_LoadProgs( void )
@@ -1272,7 +1300,7 @@ qboolean UI_LoadProgs( void )
} }
gameui.use_text_api = false; gameui.use_extended_api = false;
// make local copy of engfuncs to prevent overwrite it with user dll // make local copy of engfuncs to prevent overwrite it with user dll
memcpy( &gpEngfuncs, &gEngfuncs, sizeof( gpEngfuncs )); memcpy( &gpEngfuncs, &gEngfuncs, sizeof( gpEngfuncs ));
@@ -1299,7 +1327,7 @@ qboolean UI_LoadProgs( void )
if( GetExtAPI( MENU_EXTENDED_API_VERSION, &gameui.dllFuncs2, &gpExtendedfuncs ) ) if( GetExtAPI( MENU_EXTENDED_API_VERSION, &gameui.dllFuncs2, &gpExtendedfuncs ) )
{ {
Con_Reportf( "UI_LoadProgs: extended Menu API initialized\n" ); Con_Reportf( "UI_LoadProgs: extended Menu API initialized\n" );
gameui.use_text_api = true; gameui.use_extended_api = true;
} }
} }
else // otherwise, fallback to old and deprecated extensions else // otherwise, fallback to old and deprecated extensions
@@ -1311,7 +1339,7 @@ qboolean UI_LoadProgs( void )
if( GiveTextApi( &gpExtendedfuncs ) ) // they are binary compatible, so we can just pass extended funcs API to menu if( GiveTextApi( &gpExtendedfuncs ) ) // they are binary compatible, so we can just pass extended funcs API to menu
{ {
Con_Reportf( "UI_LoadProgs: extended text API initialized\n" ); Con_Reportf( "UI_LoadProgs: extended text API initialized\n" );
gameui.use_text_api = true; gameui.use_extended_api = true;
} }
} }

File diff suppressed because it is too large Load Diff

View File

@@ -20,17 +20,17 @@ GNU General Public License for more details.
#include "input.h" #include "input.h"
#include "platform/platform.h" #include "platform/platform.h"
mobile_engfuncs_t *gMobileEngfuncs; static mobile_engfuncs_t *gMobileEngfuncs;
convar_t *vibration_length; static CVAR_DEFINE_AUTO( vibration_length, "1.0", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "vibration length" );
convar_t *vibration_enable; static CVAR_DEFINE_AUTO( vibration_enable, "1", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "enable vibration" );
static cl_font_t g_scaled_font; static cl_font_t g_scaled_font;
static float g_font_scale; static float g_font_scale;
static void pfnVibrate( float life, char flags ) static void pfnVibrate( float life, char flags )
{ {
if( !vibration_enable->value ) if( !vibration_enable.value )
return; return;
if( life < 0.0f ) if( life < 0.0f )
@@ -42,7 +42,7 @@ static void pfnVibrate( float life, char flags )
//Con_Reportf( "Vibrate: %f %d\n", life, flags ); //Con_Reportf( "Vibrate: %f %d\n", life, flags );
// here goes platform-specific backends // here goes platform-specific backends
Platform_Vibrate( life * vibration_length->value, flags ); Platform_Vibrate( life * vibration_length.value, flags );
} }
static void Vibrate_f( void ) static void Vibrate_f( void )
@@ -67,7 +67,7 @@ static int pfnDrawScaledCharacter( int x, int y, int number, int r, int g, int b
rgba_t color = { r, g, b, 255 }; rgba_t color = { r, g, b, 255 };
int flags = FONT_DRAW_HUD; int flags = FONT_DRAW_HUD;
if( hud_utf8->value ) if( hud_utf8.value )
SetBits( flags, FONT_DRAW_UTF8 ); SetBits( flags, FONT_DRAW_UTF8 );
if( fabs( g_font_scale - scale ) > 0.1f || if( fabs( g_font_scale - scale ) > 0.1f ||
@@ -87,15 +87,6 @@ static int pfnDrawScaledCharacter( int x, int y, int number, int r, int g, int b
return CL_DrawCharacter( x, y, number, color, &g_scaled_font, flags ); return CL_DrawCharacter( x, y, number, color, &g_scaled_font, flags );
} }
static void *pfnGetNativeObject( const char *obj )
{
if( !obj )
return NULL;
// Backend should consider that obj is case-sensitive
return Platform_GetNativeObject( obj );
}
static void pfnTouch_HideButtons( const char *name, byte state ) static void pfnTouch_HideButtons( const char *name, byte state )
{ {
Touch_HideButtons( name, state, true ); Touch_HideButtons( name, state, true );
@@ -124,7 +115,7 @@ static mobile_engfuncs_t gpMobileEngfuncs =
Touch_ResetDefaultButtons, Touch_ResetDefaultButtons,
pfnDrawScaledCharacter, pfnDrawScaledCharacter,
Sys_Warn, Sys_Warn,
pfnGetNativeObject, Sys_GetNativeObject,
ID_SetCustomClientID, ID_SetCustomClientID,
pfnParseFileSafe pfnParseFileSafe
}; };
@@ -142,8 +133,8 @@ qboolean Mobile_Init( void )
success = true; success = true;
Cmd_AddCommand( "vibrate", (xcommand_t)Vibrate_f, "Vibrate for specified time"); 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"); Cvar_RegisterVariable( &vibration_length );
vibration_enable = Cvar_Get( "vibration_enable", "1", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "Enable vibration"); Cvar_RegisterVariable( &vibration_enable );
return success; return success;
} }

View File

@@ -33,12 +33,12 @@ GNU General Public License for more details.
#define NETGRAPH_NET_COLORS 5 #define NETGRAPH_NET_COLORS 5
#define NUM_LATENCY_SAMPLES 8 #define NUM_LATENCY_SAMPLES 8
convar_t *net_graph; CVAR_DEFINE_AUTO( net_graph, "0", FCVAR_ARCHIVE, "draw network usage graph" );
static convar_t *net_graphpos; static CVAR_DEFINE_AUTO( net_graphpos, "1", FCVAR_ARCHIVE, "network usage graph position" );
static convar_t *net_graphwidth; static CVAR_DEFINE_AUTO( net_scale, "5", FCVAR_ARCHIVE, "network usage graph scale level" );
static convar_t *net_graphheight; static CVAR_DEFINE_AUTO( net_graphwidth, "192", FCVAR_ARCHIVE, "network usage graph width" );
static convar_t *net_graphsolid; static CVAR_DEFINE_AUTO( net_graphheight, "64", FCVAR_ARCHIVE, "network usage graph height" );
static convar_t *net_scale; static CVAR_DEFINE_AUTO( net_graphsolid, "1", FCVAR_ARCHIVE, "fill segments in network usage graph" );
static struct packet_latency_t static struct packet_latency_t
{ {
@@ -211,7 +211,7 @@ static void NetGraph_GetFrameData( float *latency, int *latency_count )
else else
{ {
int frame_latency = Q_min( 1.0f, f->latency ); 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 ) 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++ ) for( a = 0; a < w; a++ )
{ {
i = ( cls.netchan.outgoing_sequence - a ) & NET_TIMINGS_MASK; 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.left = x + w - a - 1;
fill.right = fill.bottom = 1; fill.right = fill.bottom = 1;
@@ -273,7 +273,7 @@ static void NetGraph_DrawTimes( wrect_t rect, int x, int w )
h -= extrap_point; h -= extrap_point;
fill.top -= extrap_point; fill.top -= extrap_point;
if( !net_graphsolid->value ) if( !net_graphsolid.value )
{ {
fill.top -= (h - 1); fill.top -= (h - 1);
start = (h - 1); start = (h - 1);
@@ -295,7 +295,7 @@ static void NetGraph_DrawTimes( wrect_t rect, int x, int w )
fill.top -= h; fill.top -= h;
h = extrap_point - h; h = extrap_point - h;
if( !net_graphsolid->value ) if( !net_graphsolid.value )
h = 1; h = 1;
for( j = 0; j < h; j++ ) for( j = 0; j < h; j++ )
@@ -334,7 +334,7 @@ NetGraph_DrawHatches
*/ */
static void NetGraph_DrawHatches( int x, int y ) 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 colorminor[4] = { 0, 63, 63, 200 };
byte color[4] = { 0, 200, 0, 255 }; byte color[4] = { 0, 200, 0, 255 };
wrect_t hatch = { x, 4, y, 1 }; wrect_t hatch = { x, 4, y, 1 };
@@ -342,9 +342,9 @@ static void NetGraph_DrawHatches( int x, int y )
ystep = Q_max( ystep, 1 ); 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 ); NetGraph_DrawRect( &hatch, color );
} }
@@ -370,14 +370,14 @@ static void NetGraph_DrawTextFields( int x, int y, int w, wrect_t rect, int coun
int pty = Q_max( rect.top + rect.bottom - NETGRAPH_LERP_HEIGHT - 3, 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 out, i = ( cls.netchan.outgoing_sequence - 1 ) & NET_TIMINGS_MASK;
int j = cls.netchan.incoming_sequence & 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 ) if( count > 0 )
{ {
avg = avg / (float)( count - ( host.frametime * FRAMERATE_AVG_FRAC )); avg = avg / (float)( count - ( host.frametime * FRAMERATE_AVG_FRAC ));
if( cl_updaterate->value > 0.0f ) if( cl_updaterate.value > 0.0f )
avg -= 1000.0f / cl_updaterate->value; avg -= 1000.0f / cl_updaterate.value;
// can't be below zero // can't be below zero
avg = Q_max( 0.0f, avg ); avg = Q_max( 0.0f, avg );
@@ -387,11 +387,11 @@ static void NetGraph_DrawTextFields( int x, int y, int w, wrect_t rect, int coun
// move rolling average // move rolling average
framerate = FRAMERATE_AVG_FRAC * host.frametime + ( 1.0f - FRAMERATE_AVG_FRAC ) * framerate; framerate = FRAMERATE_AVG_FRAC * host.frametime + ( 1.0f - FRAMERATE_AVG_FRAC ) * framerate;
ref.dllFuncs.GL_SetRenderMode( font->rendermode ); CL_SetFontRendermode( font );
if( framerate > 0.0f ) if( framerate > 0.0f )
{ {
y -= net_graphheight->value; y -= net_graphheight.value;
CL_DrawStringf( font, x, y, colors, FONT_DRAW_NORENDERMODE, "%.1f fps" , 1.0f / framerate); CL_DrawStringf( font, x, y, colors, FONT_DRAW_NORENDERMODE, "%.1f fps" , 1.0f / framerate);
@@ -422,9 +422,9 @@ static void NetGraph_DrawTextFields( int x, int y, int w, wrect_t rect, int coun
} }
if( graphtype < 3 ) if( graphtype < 3 )
CL_DrawStringf( font, ptx, pty, colors, FONT_DRAW_NORENDERMODE, "%i/s", (int)cl_cmdrate->value ); CL_DrawStringf( font, ptx, pty, colors, FONT_DRAW_NORENDERMODE, "%i/s", (int)cl_cmdrate.value );
CL_DrawStringf( font, ptx, last_y, colors, FONT_DRAW_NORENDERMODE, "%i/s" , (int)cl_updaterate->value ); CL_DrawStringf( font, ptx, last_y, colors, FONT_DRAW_NORENDERMODE, "%i/s" , (int)cl_updaterate.value );
} }
/* /*
@@ -435,12 +435,12 @@ NetGraph_DrawDataSegment
*/ */
static int NetGraph_DrawDataSegment( wrect_t *fill, int bytes, byte r, byte g, byte b, byte a ) 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 }; byte colors[4] = { r, g, b, a };
fill->top -= (int)h; fill->top -= (int)h;
if( net_graphsolid->value ) if( net_graphsolid.value )
fill->bottom = (int)h; fill->bottom = (int)h;
else fill->bottom = 1; else fill->bottom = 1;
@@ -498,7 +498,7 @@ NetGraph_DrawDataUsage
static void NetGraph_DrawDataUsage( int x, int y, int w, int graphtype ) static void NetGraph_DrawDataUsage( int x, int y, int w, int graphtype )
{ {
int a, i, h, lastvalidh = 0, ping; 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 }; wrect_t fill = { 0 };
byte color[4]; byte color[4];
@@ -554,7 +554,7 @@ static void NetGraph_DrawDataUsage( int x, int y, int w, int graphtype )
continue; continue;
color[0] = color[1] = color[2] = color[3] = 255; 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; fill.bottom = 1;
if( NetGraph_AtEdge( a, w )) if( NetGraph_AtEdge( a, w ))
@@ -589,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 )) if( !NetGraph_DrawDataSegment( &fill, netstat_graph[i].voicebytes, 255, 255, 255, 255 ))
continue; continue;
fill.top = y - net_graphheight->value - 1; fill.top = y - net_graphheight.value - 1;
fill.bottom = 1; fill.bottom = 1;
fill.top -= 2; fill.top -= 2;
@@ -598,7 +598,7 @@ static void NetGraph_DrawDataUsage( int x, int y, int w, int graphtype )
} }
if( graphtype >= 2 ) if( graphtype >= 2 )
NetGraph_DrawHatches( x, y - net_graphheight->value - 1 ); NetGraph_DrawHatches( x, y - net_graphheight.value - 1 );
} }
/* /*
@@ -613,12 +613,12 @@ static void NetGraph_GetScreenPos( wrect_t *rect, int *w, int *x, int *y )
rect->right = refState.width; rect->right = refState.width;
rect->bottom = refState.height; 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 ) if( rect->right < *w + 10 )
*w = rect->right - 10; *w = rect->right - 10;
// detect x and y position // detect x and y position
switch( (int)net_graphpos->value ) switch( (int)net_graphpos.value )
{ {
case 1: // right sided case 1: // right sided
*x = rect->left + rect->right - 5 - *w; *x = rect->left + rect->right - 5 - *w;
@@ -661,16 +661,16 @@ void SCR_DrawNetGraph( void )
{ {
graphtype = 2; 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 else
{ {
return; return;
} }
if( net_scale->value <= 0 ) if( net_scale.value <= 0 )
Cvar_SetValue( "net_scale", 0.1f ); Cvar_SetValue( "net_scale", 0.1f );
NetGraph_GetScreenPos( &rect, &w, &x, &y ); NetGraph_GetScreenPos( &rect, &w, &x, &y );
@@ -697,12 +697,12 @@ void SCR_DrawNetGraph( void )
void CL_InitNetgraph( void ) void CL_InitNetgraph( void )
{ {
net_graph = Cvar_Get( "net_graph", "0", FCVAR_ARCHIVE, "draw network usage graph" ); Cvar_RegisterVariable( &net_graph );
net_graphpos = Cvar_Get( "net_graphpos", "1", FCVAR_ARCHIVE, "network usage graph position" ); Cvar_RegisterVariable( &net_graphpos );
net_scale = Cvar_Get( "net_scale", "5", FCVAR_ARCHIVE, "network usage graph scale level" ); Cvar_RegisterVariable( &net_scale );
net_graphwidth = Cvar_Get( "net_graphwidth", "192", FCVAR_ARCHIVE, "network usage graph width" ); Cvar_RegisterVariable( &net_graphwidth );
net_graphheight = Cvar_Get( "net_graphheight", "64", FCVAR_ARCHIVE, "network usage graph height" ); Cvar_RegisterVariable( &net_graphheight );
net_graphsolid = Cvar_Get( "net_graphsolid", "1", FCVAR_ARCHIVE, "fill segments in network usage graph" ); Cvar_RegisterVariable( &net_graphsolid );
packet_loss = packet_choke = 0.0; packet_loss = packet_choke = 0.0;
NetGraph_InitColors(); NetGraph_InitColors();

File diff suppressed because it is too large Load Diff

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

@@ -0,0 +1,706 @@
/*
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
==================
*/
static 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
}
static 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
================
*/
static 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] );
}
static 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 ), sizeof( model ));
//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 );
}
static 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
==============
*/
static 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 ), sizeof( reslist.resnames[i] ));
}
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 );
if( cl_trace_stufftext.value )
{
size_t len = Q_strlen( s );
Con_Printf( "Stufftext: %s%c", s, len && s[len-1] == '\n' ? '\0' : '\n' );
}
#ifdef HACKS_RELATED_HLMODS
// disable Cry Of Fear antisave protection
if( !Q_strnicmp( s, "disconnect", 10 ) && cls.signon != SIGNONS )
break; // too early
#endif
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;
// 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

@@ -54,31 +54,6 @@ void GAME_EXPORT CL_PopPMStates( void )
clgame.pushed = false; clgame.pushed = false;
} }
/*
=============
CL_PushTraceBounds
=============
*/
void GAME_EXPORT CL_PushTraceBounds( int hullnum, const float *mins, const float *maxs )
{
hullnum = bound( 0, hullnum, 3 );
VectorCopy( mins, clgame.pmove->player_mins[hullnum] );
VectorCopy( maxs, clgame.pmove->player_maxs[hullnum] );
}
/*
=============
CL_PopTraceBounds
=============
*/
void GAME_EXPORT CL_PopTraceBounds( void )
{
memcpy( clgame.pmove->player_mins, host.player_mins, sizeof( host.player_mins ));
memcpy( clgame.pmove->player_maxs, host.player_maxs, sizeof( host.player_maxs ));
}
/* /*
=============== ===============
CL_IsPredicted CL_IsPredicted
@@ -86,7 +61,7 @@ CL_IsPredicted
*/ */
qboolean CL_IsPredicted( void ) qboolean CL_IsPredicted( void )
{ {
if( cl_nopred->value || cl.intermission ) if( cl_nopred.value || cl.intermission )
return false; return false;
// never predict the quake demos // never predict the quake demos
@@ -183,7 +158,7 @@ void CL_SetIdealPitch( void )
} }
if( steps < 2 ) return; if( steps < 2 ) return;
cl.local.idealpitch = -dir * cl_idealpitchscale->value; cl.local.idealpitch = -dir * cl_idealpitchscale.value;
} }
/* /*
@@ -234,7 +209,7 @@ void CL_CheckPredictionError( void )
// save the prediction error for interpolation // save the prediction error for interpolation
if( dist > MAX_PREDICTION_ERROR ) 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 ); Con_NPrintf( 10 + ( ++pos & 3 ), "^3player teleported:^7 %.3f units\n", dist );
// a teleport or something or gamepaused // a teleport or something or gamepaused
@@ -242,7 +217,7 @@ void CL_CheckPredictionError( void )
} }
else 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 ); 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] ); VectorCopy( cl.frames[cmd].playerstate[cl.playernum].origin, cl.local.predicted_origins[frame] );
@@ -253,7 +228,7 @@ void CL_CheckPredictionError( void )
// GoldSrc checks for singleplayer // GoldSrc checks for singleplayer
// we would check for local server // we would check for local server
if( dist > MIN_CORRECTION_DISTANCE && !SV_Active() ) if( dist > MIN_CORRECTION_DISTANCE && !SV_Active() )
cls.correction_time = cl_smoothtime->value; cls.correction_time = cl_smoothtime.value;
} }
} }
@@ -417,7 +392,7 @@ CL_AddLinksToPmove
collect solid entities collect solid entities
==================== ====================
*/ */
void CL_AddLinksToPmove( frame_t *frame ) static void CL_AddLinksToPmove( frame_t *frame )
{ {
entity_state_t *state; entity_state_t *state;
model_t *model; model_t *model;
@@ -533,7 +508,7 @@ void GAME_EXPORT CL_SetSolidPlayers( int playernum )
physent_t *pe; physent_t *pe;
int i; int i;
if( !cl_solid_players->value ) if( !cl_solid_players.value )
return; return;
for( i = 0; i < MAX_CLIENTS; i++ ) for( i = 0; i < MAX_CLIENTS; i++ )
@@ -687,11 +662,6 @@ cl_entity_t *CL_GetWaterEntity( const float *rgflPos )
return CL_GetEntityByIndex( entnum ); return CL_GetEntityByIndex( entnum );
} }
int GAME_EXPORT CL_TestLine( const vec3_t start, const vec3_t end, int flags )
{
return PM_TestLineExt( clgame.pmove, clgame.pmove->physents, clgame.pmove->numphysent, start, end, flags );
}
static int GAME_EXPORT pfnTestPlayerPosition( float *pos, pmtrace_t *ptrace ) static int GAME_EXPORT pfnTestPlayerPosition( float *pos, pmtrace_t *ptrace )
{ {
return PM_TestPlayerPosition( clgame.pmove, pos, ptrace, NULL ); return PM_TestPlayerPosition( clgame.pmove, pos, ptrace, NULL );
@@ -824,6 +794,16 @@ static void CL_SetupPMove( playermove_t *pmove, const local_state_t *from, const
cd = &from->client; cd = &from->client;
pmove->player_index = ps->number - 1; pmove->player_index = ps->number - 1;
// a1ba: workaround bug where the server refuse to send our local player in delta
// cl.playernum, in theory, must be equal to our local player index anyway
//
// this might not be a real solution, since everything else will be bogus
// but we need to properly run prediction and avoid potential memory
// corruption
if( pmove->player_index < 0 )
pmove->player_index = bound( 0, cl.playernum, cl.maxclients - 1 );
pmove->multiplayer = (cl.maxclients > 1); pmove->multiplayer = (cl.maxclients > 1);
pmove->runfuncs = runfuncs; pmove->runfuncs = runfuncs;
pmove->time = time * 1000.0f; pmove->time = time * 1000.0f;
@@ -873,10 +853,10 @@ static void CL_SetupPMove( playermove_t *pmove, const local_state_t *from, const
VectorCopy( cd->vuser4, pmove->vuser4 ); VectorCopy( cd->vuser4, pmove->vuser4 );
pmove->cmd = *ucmd; // copy current cmds pmove->cmd = *ucmd; // copy current cmds
Q_strncpy( pmove->physinfo, cls.physinfo, MAX_INFO_STRING ); Q_strncpy( pmove->physinfo, cls.physinfo, sizeof( pmove->physinfo ));
} }
const void CL_FinishPMove( const playermove_t *pmove, local_state_t *to ) static const void CL_FinishPMove( const playermove_t *pmove, local_state_t *to )
{ {
entity_state_t *ps; entity_state_t *ps;
clientdata_t *cd; clientdata_t *cd;
@@ -929,7 +909,7 @@ CL_RunUsercmd
Runs prediction code for user cmd Runs prediction code for user cmd
================= =================
*/ */
void CL_RunUsercmd( local_state_t *from, local_state_t *to, usercmd_t *u, qboolean runfuncs, double *time, unsigned int random_seed ) static void CL_RunUsercmd( local_state_t *from, local_state_t *to, usercmd_t *u, qboolean runfuncs, double *time, unsigned int random_seed )
{ {
usercmd_t cmd; usercmd_t cmd;
@@ -1105,7 +1085,7 @@ void CL_PredictMovement( qboolean repredicting )
cl.local.onground = frame->playerstate[cl.playernum].onground; cl.local.onground = frame->playerstate[cl.playernum].onground;
else cl.local.onground = -1; 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.viewmodel = to->client.viewmodel;
cl.local.repredicting = false; cl.local.repredicting = false;
cl.local.moving = false; cl.local.moving = false;
@@ -1137,7 +1117,7 @@ void CL_PredictMovement( qboolean repredicting )
cl.local.waterlevel = to->client.waterlevel; cl.local.waterlevel = to->client.waterlevel;
cl.local.usehull = to->playerstate.usehull; cl.local.usehull = to->playerstate.usehull;
if( !repredicting || !CVAR_TO_BOOL( cl_lw )) if( !repredicting || !cl_lw.value )
cl.local.viewmodel = to->client.viewmodel; cl.local.viewmodel = to->client.viewmodel;
if( FBitSet( to->client.flags, FL_ONGROUND )) if( FBitSet( to->client.flags, FL_ONGROUND ))
@@ -1167,7 +1147,7 @@ void CL_PredictMovement( qboolean repredicting )
cl.local.moving = false; 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; vec3_t delta;
float frac; float frac;
@@ -1177,14 +1157,14 @@ void CL_PredictMovement( qboolean repredicting )
cls.correction_time -= host.frametime; cls.correction_time -= host.frametime;
// Make sure smoothtime is postive // Make sure smoothtime is postive
if( cl_smoothtime->value <= 0.0f ) if( cl_smoothtime.value <= 0.0f )
Cvar_DirectSet( cl_smoothtime, "0.1" ); Cvar_DirectSet( &cl_smoothtime, "0.1" );
// Clamp from 0 to cl_smoothtime.value // 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 // 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 // Determine how much error we still have to make up for
VectorSubtract( cl.simorg, cl.local.lastorigin, delta ); VectorSubtract( cl.simorg, cl.local.lastorigin, delta );

View File

@@ -211,7 +211,7 @@ static void CL_ParseQuakeServerInfo( sizebuf_t *msg )
clgame.maxEntities = GI->max_edicts; clgame.maxEntities = GI->max_edicts;
clgame.maxEntities = bound( 600, clgame.maxEntities, MAX_EDICTS ); clgame.maxEntities = bound( 600, clgame.maxEntities, MAX_EDICTS );
clgame.maxModels = MAX_MODELS; clgame.maxModels = MAX_MODELS;
Q_strncpy( clgame.maptitle, MSG_ReadString( msg ), MAX_STRING ); Q_strncpy( clgame.maptitle, MSG_ReadString( msg ), sizeof( clgame.maptitle ));
// Re-init hud video, especially if we changed game directories // Re-init hud video, especially if we changed game directories
clgame.dllFuncs.pfnVidInit(); clgame.dllFuncs.pfnVidInit();
@@ -232,10 +232,10 @@ static void CL_ParseQuakeServerInfo( sizebuf_t *msg )
// loading user settings // loading user settings
CSCR_LoadDefaultCVars( "user.scr" ); CSCR_LoadDefaultCVars( "user.scr" );
if( r_decals->value > mp_decals.value ) if( r_decals.value > mp_decals.value )
Cvar_SetValue( "r_decals", mp_decals.value ); Cvar_DirectSet( &r_decals, mp_decals.string );
} }
else Cvar_Reset( "r_decals" ); else Cvar_DirectSet( &r_decals, NULL );
if( cl.background ) // tell the game parts about background state if( cl.background ) // tell the game parts about background state
Cvar_FullSet( "cl_background", "1", FCVAR_READ_ONLY ); Cvar_FullSet( "cl_background", "1", FCVAR_READ_ONLY );
@@ -258,7 +258,7 @@ static void CL_ParseQuakeServerInfo( sizebuf_t *msg )
Q_strncpy( gameui.globals->maptitle, clgame.maptitle, sizeof( gameui.globals->maptitle )); Q_strncpy( gameui.globals->maptitle, clgame.maptitle, sizeof( gameui.globals->maptitle ));
if( !cls.changelevel && !cls.changedemo ) 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 // Quake just have a large packet of initialization data
for( i = 1; i < MAX_MODELS; i++ ) for( i = 1; i < MAX_MODELS; i++ )
@@ -302,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" )); 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 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 Cvar_Set( "cl_levelshot_name", "*black" ); // render a black screen
cls.scrshot_request = scrshot_plaque; // request levelshot even if exist (check filetime) cls.scrshot_request = scrshot_plaque; // request levelshot even if exist (check filetime)
} }
@@ -414,7 +414,7 @@ If an entities model or origin changes from frame to frame, it must be
relinked. Other attributes can change without relinking. relinked. Other attributes can change without relinking.
================== ==================
*/ */
void CL_ParseQuakeEntityData( sizebuf_t *msg, int bits ) static void CL_ParseQuakeEntityData( sizebuf_t *msg, int bits )
{ {
int i, newnum, pack; int i, newnum, pack;
qboolean forcelink; qboolean forcelink;
@@ -565,7 +565,7 @@ CL_ParseQuakeParticles
================== ==================
*/ */
void CL_ParseQuakeParticle( sizebuf_t *msg ) static void CL_ParseQuakeParticle( sizebuf_t *msg )
{ {
int count, color; int count, color;
vec3_t org, dir; vec3_t org, dir;
@@ -587,7 +587,7 @@ CL_ParseQuakeStaticSound
=================== ===================
*/ */
void CL_ParseQuakeStaticSound( sizebuf_t *msg ) static void CL_ParseQuakeStaticSound( sizebuf_t *msg )
{ {
int sound_num; int sound_num;
float vol, attn; float vol, attn;
@@ -694,17 +694,13 @@ static void CL_ParseQuakeBaseline( sizebuf_t *msg )
cl_entity_t *ent; cl_entity_t *ent;
int newnum; int newnum;
memset( &state, 0, sizeof( state ));
newnum = MSG_ReadWord( msg ); // entnum newnum = MSG_ReadWord( msg ); // entnum
if( newnum >= clgame.maxEntities ) if( newnum >= clgame.maxEntities )
Host_Error( "CL_AllocEdict: no free edicts\n" ); 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 // parse baseline
memset( &state, 0, sizeof( state ));
state.modelindex = MSG_ReadByte( msg ); state.modelindex = MSG_ReadByte( msg );
state.frame = MSG_ReadByte( msg ); state.frame = MSG_ReadByte( msg );
state.colormap = MSG_ReadByte( msg ); state.colormap = MSG_ReadByte( msg );
@@ -715,8 +711,10 @@ static void CL_ParseQuakeBaseline( sizebuf_t *msg )
state.angles[1] = MSG_ReadAngle( msg ); state.angles[1] = MSG_ReadAngle( msg );
state.origin[2] = MSG_ReadCoord( msg ); state.origin[2] = MSG_ReadCoord( msg );
state.angles[2] = MSG_ReadAngle( 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->baseline, &state, sizeof( entity_state_t ));
memcpy( &ent->prevstate, &state, sizeof( entity_state_t )); memcpy( &ent->prevstate, &state, sizeof( entity_state_t ));
} }
@@ -818,7 +816,7 @@ CL_QuakeStuffText
================== ==================
*/ */
void CL_QuakeStuffText( const char *text ) static void CL_QuakeStuffText( const char *text )
{ {
Q_strncat( cmd_buf, text, sizeof( cmd_buf )); Q_strncat( cmd_buf, text, sizeof( cmd_buf ));
@@ -833,7 +831,7 @@ CL_QuakeExecStuff
================== ==================
*/ */
void CL_QuakeExecStuff( void ) static void CL_QuakeExecStuff( void )
{ {
char *text = cmd_buf; char *text = cmd_buf;
char token[256]; char token[256];

View File

@@ -41,11 +41,24 @@ CL_CmpStudioTextures
return true if equal 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; 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++ ) for( i = 0; i < numtexs; i++, p1++, p2++ )
{ {
@@ -65,7 +78,7 @@ CL_CreateRawTextureFromPixels
Convert texture_t struct into mstudiotexture_t prototype Convert texture_t struct into mstudiotexture_t prototype
==================== ====================
*/ */
byte *CL_CreateRawTextureFromPixels( texture_t *tx, size_t *size, int topcolor, int bottomcolor ) static byte *CL_CreateRawTextureFromPixels( texture_t *tx, size_t *size, int topcolor, int bottomcolor )
{ {
static mstudiotexture_t pin; static mstudiotexture_t pin;
byte *pal; byte *pal;
@@ -98,7 +111,7 @@ CL_DuplicateTexture
Dupliacte texture with remap pixels Dupliacte texture with remap pixels
==================== ====================
*/ */
void CL_DuplicateTexture( cl_entity_t *entity, model_t *model, mstudiotexture_t *ptexture, int topcolor, int bottomcolor ) static void CL_DuplicateTexture( cl_entity_t *entity, model_t *model, mstudiotexture_t *ptexture, int topcolor, int bottomcolor )
{ {
const char *name; const char *name;
texture_t *tx = NULL; texture_t *tx = NULL;
@@ -141,7 +154,7 @@ CL_UpdateStudioTexture
Update texture top and bottom colors Update texture top and bottom colors
==================== ====================
*/ */
void CL_UpdateStudioTexture( cl_entity_t *entity, mstudiotexture_t *ptexture, int topcolor, int bottomcolor ) static void CL_UpdateStudioTexture( cl_entity_t *entity, mstudiotexture_t *ptexture, int topcolor, int bottomcolor )
{ {
rgbdata_t *pic; rgbdata_t *pic;
texture_t *tx = NULL; texture_t *tx = NULL;
@@ -202,7 +215,7 @@ CL_UpdateAliasTexture
Update texture top and bottom colors Update texture top and bottom colors
==================== ====================
*/ */
void CL_UpdateAliasTexture( cl_entity_t *entity, unsigned short *texture, int skinnum, int topcolor, int bottomcolor ) static void CL_UpdateAliasTexture( cl_entity_t *entity, unsigned short *texture, int skinnum, int topcolor, int bottomcolor )
{ {
char texname[MAX_QPATH]; char texname[MAX_QPATH];
rgbdata_t skin, *pic; rgbdata_t skin, *pic;
@@ -234,6 +247,68 @@ void CL_UpdateAliasTexture( cl_entity_t *entity, unsigned short *texture, int sk
ref.dllFuncs.GL_ProcessTexture( *texture, -1.0f, topcolor, bottomcolor ); ref.dllFuncs.GL_ProcessTexture( *texture, -1.0f, topcolor, bottomcolor );
} }
/*
====================
CL_FreeRemapInfo
Release remap info per entity
====================
*/
static void CL_FreeRemapInfo( remap_info_t *info )
{
int i;
Assert( info != NULL );
// release all colormap texture copies
for( i = 0; i < info->numtextures; i++ )
{
if( info->ptexture != NULL )
{
if( FBitSet( info->ptexture[i].flags, STUDIO_NF_COLORMAP ))
ref.dllFuncs.GL_FreeTexture( info->ptexture[i].index );
}
if( info->textures[i] != 0 )
ref.dllFuncs.GL_FreeTexture( info->textures[i] );
}
Mem_Free( info ); // release struct
}
/*
====================
CL_UpdateRemapInfo
Update all remaps per entity
====================
*/
static void CL_UpdateRemapInfo( cl_entity_t *entity, int topcolor, int bottomcolor )
{
remap_info_t *info;
int i;
i = ( entity == &clgame.viewent ) ? clgame.maxEntities : entity->curstate.number;
info = clgame.remap_info[i];
if( !info ) return; // no remap info
if( info->topcolor == topcolor && info->bottomcolor == bottomcolor )
return; // values is valid
for( i = 0; i < info->numtextures; i++ )
{
if( info->ptexture != NULL )
{
if( FBitSet( info->ptexture[i].flags, STUDIO_NF_COLORMAP ))
CL_UpdateStudioTexture( entity, &info->ptexture[i], topcolor, bottomcolor );
}
else CL_UpdateAliasTexture( entity, &info->textures[i], i, topcolor, bottomcolor );
}
info->topcolor = topcolor;
info->bottomcolor = bottomcolor;
}
/* /*
==================== ====================
CL_AllocRemapInfo CL_AllocRemapInfo
@@ -242,7 +317,7 @@ Allocate new remap info per entity
and make copy of remap textures and make copy of remap textures
==================== ====================
*/ */
void CL_AllocRemapInfo( cl_entity_t *entity, model_t *model, int topcolor, int bottomcolor ) static void CL_AllocRemapInfo( cl_entity_t *entity, model_t *model, int topcolor, int bottomcolor )
{ {
remap_info_t *info; remap_info_t *info;
studiohdr_t *phdr; studiohdr_t *phdr;
@@ -282,10 +357,9 @@ void CL_AllocRemapInfo( cl_entity_t *entity, model_t *model, int topcolor, int b
if( !phdr ) return; // bad model? if( !phdr ) return; // bad model?
src = (mstudiotexture_t *)(((byte *)phdr) + phdr->textureindex); 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 // 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 // this code catches studiomodel change with another studiomodel with remap textures
// e.g. playermodel 'barney' with playermodel 'gordon' // e.g. playermodel 'barney' with playermodel 'gordon'
@@ -350,68 +424,6 @@ void CL_AllocRemapInfo( cl_entity_t *entity, model_t *model, int topcolor, int b
info->model = model; info->model = model;
} }
/*
====================
CL_UpdateRemapInfo
Update all remaps per entity
====================
*/
void CL_UpdateRemapInfo( cl_entity_t *entity, int topcolor, int bottomcolor )
{
remap_info_t *info;
int i;
i = ( entity == &clgame.viewent ) ? clgame.maxEntities : entity->curstate.number;
info = clgame.remap_info[i];
if( !info ) return; // no remap info
if( info->topcolor == topcolor && info->bottomcolor == bottomcolor )
return; // values is valid
for( i = 0; i < info->numtextures; i++ )
{
if( info->ptexture != NULL )
{
if( FBitSet( info->ptexture[i].flags, STUDIO_NF_COLORMAP ))
CL_UpdateStudioTexture( entity, &info->ptexture[i], topcolor, bottomcolor );
}
else CL_UpdateAliasTexture( entity, &info->textures[i], i, topcolor, bottomcolor );
}
info->topcolor = topcolor;
info->bottomcolor = bottomcolor;
}
/*
====================
CL_FreeRemapInfo
Release remap info per entity
====================
*/
void CL_FreeRemapInfo( remap_info_t *info )
{
int i;
Assert( info != NULL );
// release all colormap texture copies
for( i = 0; i < info->numtextures; i++ )
{
if( info->ptexture != NULL )
{
if( FBitSet( info->ptexture[i].flags, STUDIO_NF_COLORMAP ))
ref.dllFuncs.GL_FreeTexture( info->ptexture[i].index );
}
if( info->textures[i] != 0 )
ref.dllFuncs.GL_FreeTexture( info->textures[i] );
}
Mem_Free( info ); // release struct
}
/* /*
==================== ====================
CL_ClearAllRemaps CL_ClearAllRemaps
@@ -434,3 +446,21 @@ void CL_ClearAllRemaps( void )
} }
clgame.remap_info = NULL; clgame.remap_info = NULL;
} }
/*
=============
CL_EntitySetRemapColors
=============
*/
qboolean CL_EntitySetRemapColors( cl_entity_t *e, model_t *mod, int top, int bottom )
{
CL_AllocRemapInfo( e, mod, top, bottom );
if( CL_GetRemapInfoForEntity( e ))
{
CL_UpdateRemapInfo( e, top, bottom );
return true;
}
return false;
}

View File

@@ -20,7 +20,7 @@ GNU General Public License for more details.
int R_FatPVS( const vec3_t org, float radius, byte *visbuffer, qboolean merge, qboolean fullvis ) int R_FatPVS( const vec3_t org, float radius, byte *visbuffer, qboolean merge, qboolean fullvis )
{ {
return Mod_FatPVS( org, radius, visbuffer, world.visbytes, merge, fullvis ); return Mod_FatPVS( org, radius, visbuffer, world.visbytes, merge, fullvis, false );
} }
lightstyle_t *CL_GetLightStyle( int number ) lightstyle_t *CL_GetLightStyle( int number )
@@ -126,7 +126,7 @@ CL_GenericHandle
============= =============
*/ */
const char *CL_GenericHandle( int fileindex ) static const char *CL_GenericHandle( int fileindex )
{ {
if( fileindex < 0 || fileindex >= MAX_CUSTOM ) if( fileindex < 0 || fileindex >= MAX_CUSTOM )
return 0; return 0;
@@ -142,8 +142,6 @@ intptr_t CL_RenderGetParm( const int parm, const int arg, const qboolean checkRe
return 1; return 1;
#endif #endif
return 0; return 0;
case PARM_SKY_SPHERE:
return FBitSet( world.flags, FWORLD_SKYSPHERE ) && !FBitSet( world.flags, FWORLD_CUSTOM_SKYBOX );
case PARAM_GAMEPAUSED: case PARAM_GAMEPAUSED:
return cl.paused; return cl.paused;
case PARM_CLIENT_INGAME: case PARM_CLIENT_INGAME:
@@ -164,6 +162,14 @@ intptr_t CL_RenderGetParm( const int parm, const int arg, const qboolean checkRe
return (intptr_t)world.deluxedata; return (intptr_t)world.deluxedata;
case PARM_SHADOWDATA: case PARM_SHADOWDATA:
return (intptr_t)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: default:
// indicates call from client.dll // indicates call from client.dll
if( checkRef ) if( checkRef )
@@ -179,26 +185,30 @@ intptr_t CL_RenderGetParm( const int parm, const int arg, const qboolean checkRe
return CL_IsThirdPerson(); return CL_IsThirdPerson();
case PARM_QUAKE_COMPATIBLE: case PARM_QUAKE_COMPATIBLE:
return Host_IsQuakeCompatible(); return Host_IsQuakeCompatible();
case PARM_PLAYER_INDEX:
return cl.playernum + 1;
case PARM_VIEWENT_INDEX:
return cl.viewentity;
case PARM_CONNSTATE: case PARM_CONNSTATE:
return (int)cls.state; return (int)cls.state;
case PARM_PLAYING_DEMO: case PARM_PLAYING_DEMO:
return cls.demoplayback; return cls.demoplayback;
case PARM_WATER_LEVEL: case PARM_WATER_LEVEL:
return cl.local.waterlevel; return cl.local.waterlevel;
case PARM_MAX_CLIENTS:
return cl.maxclients;
case PARM_LOCAL_HEALTH: case PARM_LOCAL_HEALTH:
return cl.local.health; return cl.local.health;
case PARM_LOCAL_GAME: case PARM_LOCAL_GAME:
return Host_IsLocalGame(); return Host_IsLocalGame();
case PARM_NUMENTITIES: case PARM_NUMENTITIES:
return pfnNumberOfEntities(); return pfnNumberOfEntities();
case PARM_NUMMODELS: case PARM_GET_CLIENT_PTR:
return cl.nummodels; return (intptr_t)&cl.time; // with the offset
case PARM_GET_HOST_PTR:
return (intptr_t)&host.realtime; // with the offset
case PARM_GET_WORLD_PTR:
return (intptr_t)&world;
case PARM_GET_MOVEVARS_PTR:
return (intptr_t)&clgame.movevars;
case PARM_GET_PALETTE_PTR:
return (intptr_t)&clgame.palette;
case PARM_GET_VIEWENT_PTR:
return (intptr_t)&clgame.viewent;
} }
} }
return 0; return 0;

View File

@@ -20,18 +20,18 @@ GNU General Public License for more details.
#include "input.h" #include "input.h"
#include "library.h" #include "library.h"
convar_t *scr_centertime; CVAR_DEFINE_AUTO( scr_centertime, "2.5", 0, "centerprint hold time" );
convar_t *scr_loading; CVAR_DEFINE_AUTO( scr_loading, "0", 0, "loading bar progress" );
convar_t *scr_download; CVAR_DEFINE_AUTO( scr_download, "-1", 0, "downloading bar progress" );
convar_t *scr_viewsize; CVAR_DEFINE( scr_viewsize, "viewsize", "120", FCVAR_ARCHIVE, "screen size (quake only)" );
convar_t *cl_testlights; CVAR_DEFINE_AUTO( cl_testlights, "0", 0, "test dynamic lights" );
convar_t *cl_allow_levelshots; CVAR_DEFINE( cl_allow_levelshots, "allow_levelshots", "0", FCVAR_ARCHIVE, "allow engine to use indivdual levelshots instead of 'loading' image" );
convar_t *cl_levelshot_name; CVAR_DEFINE_AUTO( cl_levelshot_name, "*black", 0, "contains path to current levelshot" );
static convar_t *cl_envshot_size; static CVAR_DEFINE_AUTO( cl_envshot_size, "256", FCVAR_ARCHIVE, "envshot size of cube side" );
convar_t *v_dark; CVAR_DEFINE_AUTO( v_dark, "0", 0, "starts level from dark screen" );
static convar_t *net_speeds; static CVAR_DEFINE_AUTO( net_speeds, "0", FCVAR_ARCHIVE, "show network packets" );
static convar_t *cl_showfps; static CVAR_DEFINE_AUTO( cl_showfps, "0", FCVAR_ARCHIVE, "show client fps" );
static convar_t *cl_showpos; static CVAR_DEFINE_AUTO( cl_showpos, "0", FCVAR_ARCHIVE, "show local player position and velocity" );
typedef struct typedef struct
{ {
@@ -59,7 +59,7 @@ void SCR_DrawFPS( int height )
char fpsstring[64]; char fpsstring[64];
int offset; int offset;
if( cls.state != ca_active || !cl_showfps->value || cl.background ) if( cls.state != ca_active || !cl_showfps.value || cl.background )
return; return;
switch( cls.scrshot_action ) switch( cls.scrshot_action )
@@ -95,7 +95,7 @@ void SCR_DrawFPS( int height )
if( curfps < minfps ) minfps = curfps; if( curfps < minfps ) minfps = curfps;
if( curfps > maxfps ) maxfps = 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 ); 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 ); else Q_snprintf( fpsstring, sizeof( fpsstring ), "%4i fps", curfps );
MakeRGBA( color, 255, 255, 255, 255 ); MakeRGBA( color, 255, 255, 255, 255 );
@@ -119,7 +119,7 @@ void SCR_DrawPos( void )
cl_entity_t *ent; cl_entity_t *ent;
rgba_t color; rgba_t color;
if( cls.state != ca_active || !cl_showpos->value || cl.background ) if( cls.state != ca_active || !cl_showpos.value || cl.background )
return; return;
ent = CL_GetLocalPlayer(); ent = CL_GetLocalPlayer();
@@ -164,7 +164,7 @@ void SCR_NetSpeeds( void )
if( !host.allow_console ) if( !host.allow_console )
return; return;
if( !net_speeds->value || cls.state != ca_active ) if( !net_speeds.value || cls.state != ca_active )
return; return;
// prevent to get too big values at max // prevent to get too big values at max
@@ -252,7 +252,7 @@ VID_WriteOverviewScript
Create overview script file Create overview script file
=============== ===============
*/ */
void VID_WriteOverviewScript( void ) static void VID_WriteOverviewScript( void )
{ {
ref_overview_t *ov = &clgame.overView; ref_overview_t *ov = &clgame.overView;
string filename; string filename;
@@ -288,9 +288,14 @@ void SCR_MakeScreenShot( void )
qboolean iRet = false; qboolean iRet = false;
int viewsize; int viewsize;
if( cls.scrshot_action == scrshot_inactive )
return;
if( cls.envshot_viewsize > 0 ) if( cls.envshot_viewsize > 0 )
viewsize = cls.envshot_viewsize; viewsize = cls.envshot_viewsize;
else viewsize = cl_envshot_size->value; else viewsize = cl_envshot_size.value;
V_CheckGamma();
switch( cls.scrshot_action ) switch( cls.scrshot_action )
{ {
@@ -317,8 +322,6 @@ void SCR_MakeScreenShot( void )
if( iRet ) if( iRet )
VID_WriteOverviewScript(); // store overview script too VID_WriteOverviewScript(); // store overview script too
break; break;
case scrshot_inactive:
return;
} }
// report // report
@@ -342,11 +345,11 @@ void SCR_MakeScreenShot( void )
SCR_DrawPlaque SCR_DrawPlaque
================ ================
*/ */
void SCR_DrawPlaque( void ) static 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.GL_SetRenderMode( kRenderNormal );
ref.dllFuncs.R_DrawStretchPic( 0, 0, refState.width, refState.height, 0, 0, 1, 1, levelshot ); ref.dllFuncs.R_DrawStretchPic( 0, 0, refState.width, refState.height, 0, 0, 1, 1, levelshot );
if( !cl.background ) CL_DrawHUD( CL_LOADING ); if( !cl.background ) CL_DrawHUD( CL_LOADING );
@@ -366,7 +369,7 @@ void SCR_BeginLoadingPlaque( qboolean is_background )
cl.video_prepped = false; cl.video_prepped = false;
if( !Host_IsDedicated() ) if( !Host_IsDedicated() )
oldclear = gl_clear->value; oldclear = gl_clear.value;
if( CL_IsInMenu( ) && !cls.changedemo && !is_background ) if( CL_IsInMenu( ) && !cls.changedemo && !is_background )
{ {
@@ -382,7 +385,7 @@ void SCR_BeginLoadingPlaque( qboolean is_background )
return; return;
if( !Host_IsDedicated() ) if( !Host_IsDedicated() )
gl_clear->value = 0.0f; gl_clear.value = 0.0f;
if( is_background ) IN_MouseSavePos( ); if( is_background ) IN_MouseSavePos( );
cls.draw_changelevel = !is_background; cls.draw_changelevel = !is_background;
@@ -391,7 +394,7 @@ void SCR_BeginLoadingPlaque( qboolean is_background )
cl.background = is_background; // set right state before svc_serverdata is came cl.background = is_background; // set right state before svc_serverdata is came
if( !Host_IsDedicated() ) if( !Host_IsDedicated() )
gl_clear->value = oldclear; gl_clear.value = oldclear;
// SNDDMA_LockSound(); // SNDDMA_LockSound();
} }
@@ -413,7 +416,7 @@ void SCR_EndLoadingPlaque( void )
SCR_AddDirtyPoint SCR_AddDirtyPoint
================= =================
*/ */
void SCR_AddDirtyPoint( int x, int y ) static void SCR_AddDirtyPoint( int x, int y )
{ {
if( x < scr_dirty.x1 ) scr_dirty.x1 = x; if( x < scr_dirty.x1 ) scr_dirty.x1 = x;
if( x > scr_dirty.x2 ) scr_dirty.x2 = x; if( x > scr_dirty.x2 ) scr_dirty.x2 = x;
@@ -442,7 +445,7 @@ void SCR_TileClear( void )
int i, top, bottom, left, right; int i, top, bottom, left, right;
dirty_t clear; dirty_t clear;
if( scr_viewsize->value >= 120 ) if( scr_viewsize.value >= 120 )
return; // full screen rendering return; // full screen rendering
// erase rect will be the union of the past three frames // erase rect will be the union of the past three frames
@@ -558,7 +561,7 @@ void SCR_LoadCreditsFont( void )
{ {
cl_font_t *const font = &cls.creditsFont; cl_font_t *const font = &cls.creditsFont;
qboolean success = false; qboolean success = false;
float scale = hud_fontscale->value; float scale = hud_fontscale.value;
dword crc = 0; dword crc = 0;
// replace default gfx.wad textures by current charset's font // replace default gfx.wad textures by current charset's font
@@ -570,15 +573,15 @@ void SCR_LoadCreditsFont( void )
"creditsfont_%s.fnt", Cvar_VariableString( "con_charset" )) > 0 ) "creditsfont_%s.fnt", Cvar_VariableString( "con_charset" )) > 0 )
{ {
if( FS_FileExists( charsetFnt, false )) if( FS_FileExists( charsetFnt, false ))
success = Con_LoadVariableWidthFont( charsetFnt, font, scale, kRenderTransAdd, TF_FONT ); success = Con_LoadVariableWidthFont( charsetFnt, font, scale, &hud_fontrender, TF_FONT );
} }
} }
if( !success ) if( !success )
success = Con_LoadVariableWidthFont( "gfx/creditsfont.fnt", font, scale, kRenderTransAdd, TF_FONT ); success = Con_LoadVariableWidthFont( "gfx/creditsfont.fnt", font, scale, &hud_fontrender, TF_FONT );
if( !success ) if( !success )
success = Con_LoadFixedWidthFont( "gfx/conchars", font, scale, kRenderTransAdd, TF_FONT ); success = Con_LoadFixedWidthFont( "gfx/conchars", font, scale, &hud_fontrender, TF_FONT );
// copy font size for client.dll // copy font size for client.dll
if( success ) if( success )
@@ -600,7 +603,7 @@ SCR_InstallParticlePalette
INTERNAL RESOURCE INTERNAL RESOURCE
================ ================
*/ */
void SCR_InstallParticlePalette( void ) static void SCR_InstallParticlePalette( void )
{ {
rgbdata_t *pic; rgbdata_t *pic;
int i; int i;
@@ -646,21 +649,21 @@ void SCR_RegisterTextures( void )
// register gfx.wad images // register gfx.wad images
if( FS_FileExists( "gfx/paused.lmp", false )) if( FS_FileExists( "gfx/paused.lmp", false ))
cls.pauseIcon = ref.dllFuncs.GL_LoadTexture( "gfx/paused.lmp", NULL, 0, TF_IMAGE ); cls.pauseIcon = ref.dllFuncs.GL_LoadTexture( "gfx/paused.lmp", NULL, 0, TF_IMAGE|TF_ALLOW_NEAREST );
else if( FS_FileExists( "gfx/pause.lmp", false )) else if( FS_FileExists( "gfx/pause.lmp", false ))
cls.pauseIcon = ref.dllFuncs.GL_LoadTexture( "gfx/pause.lmp", NULL, 0, TF_IMAGE ); cls.pauseIcon = ref.dllFuncs.GL_LoadTexture( "gfx/pause.lmp", NULL, 0, TF_IMAGE|TF_ALLOW_NEAREST );
if( FS_FileExists( "gfx/lambda.lmp", false )) 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 ); cls.loadingBar = ref.dllFuncs.GL_LoadTexture( "gfx/lambda.lmp", NULL, 0, TF_IMAGE|TF_LUMINANCE|TF_ALLOW_NEAREST );
else cls.loadingBar = ref.dllFuncs.GL_LoadTexture( "gfx/lambda.lmp", NULL, 0, TF_IMAGE ); else cls.loadingBar = ref.dllFuncs.GL_LoadTexture( "gfx/lambda.lmp", NULL, 0, TF_IMAGE|TF_ALLOW_NEAREST );
} }
else if( FS_FileExists( "gfx/loading.lmp", false )) 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 ); cls.loadingBar = ref.dllFuncs.GL_LoadTexture( "gfx/loading.lmp", NULL, 0, TF_IMAGE|TF_LUMINANCE|TF_ALLOW_NEAREST );
else cls.loadingBar = ref.dllFuncs.GL_LoadTexture( "gfx/loading.lmp", NULL, 0, TF_IMAGE ); else cls.loadingBar = ref.dllFuncs.GL_LoadTexture( "gfx/loading.lmp", NULL, 0, TF_IMAGE|TF_ALLOW_NEAREST );
} }
cls.tileImage = ref.dllFuncs.GL_LoadTexture( "gfx/backtile.lmp", NULL, 0, TF_NOMIPMAP ); cls.tileImage = ref.dllFuncs.GL_LoadTexture( "gfx/backtile.lmp", NULL, 0, TF_NOMIPMAP );
@@ -673,9 +676,9 @@ SCR_SizeUp_f
Keybinding command Keybinding command
================= =================
*/ */
void SCR_SizeUp_f( void ) static 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 ));
} }
@@ -686,9 +689,9 @@ SCR_SizeDown_f
Keybinding command Keybinding command
================= =================
*/ */
void SCR_SizeDown_f( void ) static 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 ));
} }
/* /*
@@ -726,6 +729,7 @@ void SCR_VidInit( void )
// restart console size // restart console size
Con_VidInit (); Con_VidInit ();
Touch_NotifyResize();
} }
/* /*
@@ -737,18 +741,18 @@ void SCR_Init( void )
{ {
if( scr_init ) return; if( scr_init ) return;
scr_centertime = Cvar_Get( "scr_centertime", "2.5", 0, "centerprint hold time" ); Cvar_RegisterVariable( &scr_centertime );
cl_levelshot_name = Cvar_Get( "cl_levelshot_name", "*black", 0, "contains path to current levelshot" ); Cvar_RegisterVariable( &cl_levelshot_name );
cl_allow_levelshots = Cvar_Get( "allow_levelshots", "0", FCVAR_ARCHIVE, "allow engine to use indivdual levelshots instead of 'loading' image" ); Cvar_RegisterVariable( &cl_allow_levelshots );
scr_loading = Cvar_Get( "scr_loading", "0", 0, "loading bar progress" ); Cvar_RegisterVariable( &scr_loading );
scr_download = Cvar_Get( "scr_download", "-1", 0, "downloading bar progress" ); Cvar_RegisterVariable( &scr_download );
cl_testlights = Cvar_Get( "cl_testlights", "0", 0, "test dynamic lights" ); Cvar_RegisterVariable( &cl_testlights );
cl_envshot_size = Cvar_Get( "cl_envshot_size", "256", FCVAR_ARCHIVE, "envshot size of cube side" ); Cvar_RegisterVariable( &cl_envshot_size );
v_dark = Cvar_Get( "v_dark", "0", 0, "starts level from dark screen" ); Cvar_RegisterVariable( &v_dark );
scr_viewsize = Cvar_Get( "viewsize", "120", FCVAR_ARCHIVE, "screen size" ); Cvar_RegisterVariable( &scr_viewsize );
net_speeds = Cvar_Get( "net_speeds", "0", FCVAR_ARCHIVE, "show network packets" ); Cvar_RegisterVariable( &net_speeds );
cl_showfps = Cvar_Get( "cl_showfps", "0", FCVAR_ARCHIVE, "show client fps" ); Cvar_RegisterVariable( &cl_showfps );
cl_showpos = Cvar_Get( "cl_showpos", "0", FCVAR_ARCHIVE, "show local player position and velocity" ); Cvar_RegisterVariable( &cl_showpos );
// register our commands // register our commands
Cmd_AddCommand( "skyname", CL_SetSky_f, "set new skybox by basename" ); Cmd_AddCommand( "skyname", CL_SetSky_f, "set new skybox by basename" );

View File

@@ -57,35 +57,7 @@ const char *cl_default_sprites[] =
"sprites/shellchrome.spr", "sprites/shellchrome.spr",
}; };
const char *cl_player_shell_sounds[] = static void CL_PlayerDecal( int playerIndex, int textureIndex, int entityIndex, float *pos );
{
"player/pl_shell1.wav",
"player/pl_shell2.wav",
"player/pl_shell3.wav",
};
const char *cl_weapon_shell_sounds[] =
{
"weapons/sshell1.wav",
"weapons/sshell2.wav",
"weapons/sshell3.wav",
};
const char *cl_ricochet_sounds[] =
{
"weapons/ric1.wav",
"weapons/ric2.wav",
"weapons/ric3.wav",
"weapons/ric4.wav",
"weapons/ric5.wav",
};
const char *cl_explode_sounds[] =
{
"weapons/explode3.wav",
"weapons/explode4.wav",
"weapons/explode5.wav",
};
/* /*
================ ================
@@ -146,6 +118,7 @@ client resources not precached by server
*/ */
void CL_AddClientResources( void ) void CL_AddClientResources( void )
{ {
const char *snd;
char filepath[MAX_QPATH]; char filepath[MAX_QPATH];
int i; int i;
@@ -161,37 +134,37 @@ void CL_AddClientResources( void )
} }
// then check sounds // then check sounds
for( i = 0; i < ARRAYSIZE( cl_player_shell_sounds ); i++ ) for( i = 0; ( snd = SoundList_Get( BouncePlayerShell, i )); i++ )
{ {
Q_snprintf( filepath, sizeof( filepath ), DEFAULT_SOUNDPATH "%s", cl_player_shell_sounds[i] ); Q_snprintf( filepath, sizeof( filepath ), DEFAULT_SOUNDPATH "%s", snd );
if( !FS_FileExists( filepath, false )) if( !FS_FileExists( filepath, false ))
CL_AddClientResource( cl_player_shell_sounds[i], t_sound ); CL_AddClientResource( snd, t_sound );
} }
for( i = 0; i < ARRAYSIZE( cl_weapon_shell_sounds ); i++ ) for( i = 0; ( snd = SoundList_Get( BounceWeaponShell, i )); i++ )
{ {
Q_snprintf( filepath, sizeof( filepath ), DEFAULT_SOUNDPATH "%s", cl_weapon_shell_sounds[i] ); Q_snprintf( filepath, sizeof( filepath ), DEFAULT_SOUNDPATH "%s", snd );
if( !FS_FileExists( filepath, false )) if( !FS_FileExists( filepath, false ))
CL_AddClientResource( cl_weapon_shell_sounds[i], t_sound ); CL_AddClientResource( snd, t_sound );
} }
for( i = 0; i < ARRAYSIZE( cl_explode_sounds ); i++ ) for( i = 0; ( snd = SoundList_Get( Explode, i )); i++ )
{ {
Q_snprintf( filepath, sizeof( filepath ), DEFAULT_SOUNDPATH "%s", cl_explode_sounds[i] ); Q_snprintf( filepath, sizeof( filepath ), DEFAULT_SOUNDPATH "%s", snd );
if( !FS_FileExists( filepath, false )) if( !FS_FileExists( filepath, false ))
CL_AddClientResource( cl_explode_sounds[i], t_sound ); CL_AddClientResource( snd, t_sound );
} }
#if 0 // ric sounds was precached by server-side #if 0 // ric sounds was precached by server-side
for( i = 0; i < ARRAYSIZE( cl_ricochet_sounds ); i++ ) for( i = 0; ( snd = SoundList_Get( Ricochet, i )); i++ )
{ {
Q_snprintf( filepath, sizeof( filepath ), DEFAULT_SOUNDPATH "%s", cl_ricochet_sounds[i] ); Q_snprintf( filepath, sizeof( filepath ), DEFAULT_SOUNDPATH "%s", snd );
if( !FS_FileExists( filepath, false )) if( !FS_FileExists( filepath, false ))
CL_AddClientResource( cl_ricochet_sounds[i], t_sound ); CL_AddClientResource( snd, t_sound );
} }
#endif #endif
} }
@@ -255,7 +228,7 @@ CL_PrepareTEnt
set default values set default values
============== ==============
*/ */
void CL_PrepareTEnt( TEMPENTITY *pTemp, model_t *pmodel ) static void CL_PrepareTEnt( TEMPENTITY *pTemp, model_t *pmodel )
{ {
int frameCount = 0; int frameCount = 0;
int modelIndex = 0; int modelIndex = 0;
@@ -296,10 +269,10 @@ CL_TempEntPlaySound
play collide sound play collide sound
============== ==============
*/ */
void CL_TempEntPlaySound( TEMPENTITY *pTemp, float damp ) static void CL_TempEntPlaySound( TEMPENTITY *pTemp, float damp )
{ {
float fvol; float fvol;
char soundname[32]; const char *soundname = NULL;
qboolean isshellcasing = false; qboolean isshellcasing = false;
int zvel; int zvel;
@@ -310,36 +283,39 @@ void CL_TempEntPlaySound( TEMPENTITY *pTemp, float damp )
switch( pTemp->hitSound ) switch( pTemp->hitSound )
{ {
case BOUNCE_GLASS: case BOUNCE_GLASS:
Q_snprintf( soundname, sizeof( soundname ), "debris/glass%i.wav", COM_RandomLong( 1, 4 )); soundname = SoundList_GetRandom( BounceGlass );
break; break;
case BOUNCE_METAL: case BOUNCE_METAL:
Q_snprintf( soundname, sizeof( soundname ), "debris/metal%i.wav", COM_RandomLong( 1, 6 )); soundname = SoundList_GetRandom( BounceMetal );
break; break;
case BOUNCE_FLESH: case BOUNCE_FLESH:
Q_snprintf( soundname, sizeof( soundname ), "debris/flesh%i.wav", COM_RandomLong( 1, 7 )); soundname = SoundList_GetRandom( BounceFlesh );
break; break;
case BOUNCE_WOOD: case BOUNCE_WOOD:
Q_snprintf( soundname, sizeof( soundname ), "debris/wood%i.wav", COM_RandomLong( 1, 4 )); soundname = SoundList_GetRandom( BounceWood );
break; break;
case BOUNCE_SHRAP: case BOUNCE_SHRAP:
Q_strncpy( soundname, cl_ricochet_sounds[COM_RandomLong( 0, 4 )], sizeof( soundname ) ); soundname = SoundList_GetRandom( Ricochet );
break; break;
case BOUNCE_SHOTSHELL: case BOUNCE_SHOTSHELL:
Q_strncpy( soundname, cl_weapon_shell_sounds[COM_RandomLong( 0, 2 )], sizeof( soundname ) ); soundname = SoundList_GetRandom( BounceWeaponShell );
isshellcasing = true; // shell casings have different playback parameters isshellcasing = true; // shell casings have different playback parameters
fvol = 0.5f; fvol = 0.5f;
break; break;
case BOUNCE_SHELL: case BOUNCE_SHELL:
Q_strncpy( soundname, cl_player_shell_sounds[COM_RandomLong( 0, 2 )], sizeof( soundname ) ); soundname = SoundList_GetRandom( BouncePlayerShell );
isshellcasing = true; // shell casings have different playback parameters isshellcasing = true; // shell casings have different playback parameters
break; break;
case BOUNCE_CONCRETE: case BOUNCE_CONCRETE:
Q_snprintf( soundname, sizeof( soundname ), "debris/concrete%i.wav", COM_RandomLong( 1, 3 )); soundname = SoundList_GetRandom( BounceConcrete );
break; break;
default: // null sound default: // null sound
return; return;
} }
if( !soundname )
return;
zvel = abs( pTemp->entity.baseline.origin[2] ); zvel = abs( pTemp->entity.baseline.origin[2] );
// only play one out of every n // only play one out of every n
@@ -380,7 +356,7 @@ CL_TEntAddEntity
add entity to renderlist add entity to renderlist
============== ==============
*/ */
int CL_TempEntAddEntity( cl_entity_t *pEntity ) static int CL_TempEntAddEntity( cl_entity_t *pEntity )
{ {
vec3_t mins, maxs; vec3_t mins, maxs;
@@ -432,7 +408,7 @@ CL_TEntAddEntity
free the first low priority tempent it finds. free the first low priority tempent it finds.
============== ==============
*/ */
qboolean CL_FreeLowPriorityTempEnt( void ) static qboolean CL_FreeLowPriorityTempEnt( void )
{ {
TEMPENTITY *pActive = cl_active_tents; TEMPENTITY *pActive = cl_active_tents;
TEMPENTITY *pPrev = NULL; TEMPENTITY *pPrev = NULL;
@@ -1489,7 +1465,7 @@ void GAME_EXPORT R_FunnelSprite( const vec3_t org, int modelIndex, int reverse )
=============== ===============
R_SparkEffect R_SparkEffect
Create a streaks + richochet sprite Create a streaks + ricochet sprite
=============== ===============
*/ */
void GAME_EXPORT R_SparkEffect( const vec3_t pos, int count, int velocityMin, int velocityMax ) void GAME_EXPORT R_SparkEffect( const vec3_t pos, int count, int velocityMin, int velocityMax )
@@ -1505,18 +1481,25 @@ R_RicochetSound
Make a random ricochet sound Make a random ricochet sound
============== ==============
*/ */
static void R_RicochetSound_( const vec3_t pos, int sound ) static void R_RicochetSoundByName( const vec3_t pos, const char *name )
{ {
sound_t handle; sound_t handle;
handle = S_RegisterSound( name );
handle = S_RegisterSound( cl_ricochet_sounds[sound] );
S_StartSound( pos, 0, CHAN_AUTO, handle, VOL_NORM, 1.0, 100, 0 ); S_StartSound( pos, 0, CHAN_AUTO, handle, VOL_NORM, 1.0, 100, 0 );
} }
static void R_RicochetSoundByIndex( const vec3_t pos, int idx )
{
const char *name = SoundList_Get( Ricochet, idx );
if( name )
R_RicochetSoundByName( pos, name );
}
void GAME_EXPORT R_RicochetSound( const vec3_t pos ) void GAME_EXPORT R_RicochetSound( const vec3_t pos )
{ {
R_RicochetSound_( pos, COM_RandomLong( 0, 4 )); const char *name = SoundList_GetRandom( Ricochet );
if( name )
R_RicochetSoundByName( pos, name );
} }
/* /*
@@ -1663,10 +1646,14 @@ void GAME_EXPORT R_Explosion( vec3_t pos, int model, float scale, float framerat
if( !FBitSet( flags, TE_EXPLFLAG_NOSOUND )) if( !FBitSet( flags, TE_EXPLFLAG_NOSOUND ))
{ {
hSound = S_RegisterSound( cl_explode_sounds[COM_RandomLong( 0, 2 )] ); const char *name = SoundList_GetRandom( Explode );
if( name )
{
hSound = S_RegisterSound( name );
S_StartSound( pos, 0, CHAN_STATIC, hSound, VOL_NORM, 0.3f, PITCH_NORM, 0 ); S_StartSound( pos, 0, CHAN_STATIC, hSound, VOL_NORM, 0.3f, PITCH_NORM, 0 );
} }
} }
}
/* /*
============== ==============
@@ -1907,6 +1894,7 @@ void CL_ParseTempEntity( sizebuf_t *msg )
cl_entity_t *pEnt; cl_entity_t *pEnt;
dlight_t *dl; dlight_t *dl;
sound_t hSound; sound_t hSound;
const char *name;
if( cls.legacymode ) if( cls.legacymode )
iSize = MSG_ReadByte( msg ); iSize = MSG_ReadByte( msg );
@@ -1966,8 +1954,11 @@ void CL_ParseTempEntity( sizebuf_t *msg )
pos[2] = MSG_ReadCoord( &buf ); pos[2] = MSG_ReadCoord( &buf );
R_BlobExplosion( pos ); R_BlobExplosion( pos );
hSound = S_RegisterSound( cl_explode_sounds[0] ); if(( name = SoundList_Get( Explode, 0 )))
{
hSound = S_RegisterSound( name );
S_StartSound( pos, -1, CHAN_AUTO, hSound, VOL_NORM, 1.0f, PITCH_NORM, 0 ); S_StartSound( pos, -1, CHAN_AUTO, hSound, VOL_NORM, 1.0f, PITCH_NORM, 0 );
}
break; break;
case TE_SMOKE: case TE_SMOKE:
pos[0] = MSG_ReadCoord( &buf ); pos[0] = MSG_ReadCoord( &buf );
@@ -2020,8 +2011,11 @@ void CL_ParseTempEntity( sizebuf_t *msg )
dl->die = cl.time + 0.5; dl->die = cl.time + 0.5;
dl->decay = 300; dl->decay = 300;
hSound = S_RegisterSound( cl_explode_sounds[0] ); if(( name = SoundList_Get( Explode, 0 )))
S_StartSound( pos, -1, CHAN_AUTO, hSound, VOL_NORM, 0.6f, PITCH_NORM, 0 ); {
hSound = S_RegisterSound( name );
S_StartSound( pos, -1, CHAN_AUTO, hSound, VOL_NORM, 1.0f, PITCH_NORM, 0 );
}
break; break;
case TE_BSPDECAL: case TE_BSPDECAL:
case TE_DECAL: case TE_DECAL:
@@ -2249,8 +2243,8 @@ void CL_ParseTempEntity( sizebuf_t *msg )
CL_DecalShoot( CL_DecalIndex( decalIndex ), entityIndex, 0, pos, 0 ); CL_DecalShoot( CL_DecalIndex( decalIndex ), entityIndex, 0, pos, 0 );
R_BulletImpactParticles( pos ); R_BulletImpactParticles( pos );
flags = COM_RandomLong( 0, 0x7fff ); flags = COM_RandomLong( 0, 0x7fff );
if( flags < 0x3fff ) if( flags < 0x3fff && ( count = SoundList_Count( Ricochet )))
R_RicochetSound_( pos, flags % 5 ); R_RicochetSoundByIndex( pos, flags % count );
break; break;
case TE_SPRAY: case TE_SPRAY:
case TE_SPRITE_SPRAY: case TE_SPRITE_SPRAY:
@@ -2414,7 +2408,7 @@ LIGHT STYLE MANAGEMENT
CL_ClearLightStyles CL_ClearLightStyles
================ ================
*/ */
void CL_ClearLightStyles( void ) static void CL_ClearLightStyles( void )
{ {
memset( cl.lightstyles, 0, sizeof( cl.lightstyles )); memset( cl.lightstyles, 0, sizeof( cl.lightstyles ));
} }
@@ -2472,7 +2466,7 @@ dlight_t cl_elights[MAX_ELIGHTS];
CL_ClearDlights CL_ClearDlights
================ ================
*/ */
void CL_ClearDlights( void ) static void CL_ClearDlights( void )
{ {
memset( cl_dlights, 0, sizeof( cl_dlights )); memset( cl_dlights, 0, sizeof( cl_dlights ));
memset( cl_elights, 0, sizeof( cl_elights )); memset( cl_elights, 0, sizeof( cl_elights ));
@@ -2624,12 +2618,12 @@ CL_UpdateFlashlight
update client flashlight update client flashlight
================ ================
*/ */
void CL_UpdateFlashlight( cl_entity_t *ent ) static void CL_UpdateFlashlight( cl_entity_t *ent )
{ {
vec3_t forward, view_ofs; vec3_t forward, view_ofs;
vec3_t vecSrc, vecEnd; vec3_t vecSrc, vecEnd;
float falloff; float falloff;
pmtrace_t *trace; pmtrace_t trace;
cl_entity_t *hit; cl_entity_t *hit;
dlight_t *dl; dlight_t *dl;
@@ -2660,32 +2654,65 @@ void CL_UpdateFlashlight( cl_entity_t *ent )
VectorAdd( ent->origin, view_ofs, vecSrc ); VectorAdd( ent->origin, view_ofs, vecSrc );
VectorMA( vecSrc, FLASHLIGHT_DISTANCE, forward, vecEnd ); 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 // update flashlight endpos
dl = CL_AllocDlight( ent->index ); dl = CL_AllocDlight( ent->index );
#if 1 #if 1
hit = CL_GetEntityByIndex( clgame.pmove->visents[trace->ent].info ); hit = CL_GetEntityByIndex( clgame.pmove->physents[trace.ent].info );
if( hit && hit->model && ( hit->model->type == mod_alias || hit->model->type == mod_studio )) if( hit && hit->model && ( hit->model->type == mod_alias || hit->model->type == mod_studio ))
VectorCopy( hit->origin, dl->origin ); VectorCopy( hit->origin, dl->origin );
else VectorCopy( trace->endpos, dl->origin ); else VectorCopy( trace.endpos, dl->origin );
#else #else
VectorCopy( trace->endpos, dl->origin ); VectorCopy( trace->endpos, dl->origin );
#endif #endif
// compute falloff // compute falloff
falloff = trace->fraction * FLASHLIGHT_DISTANCE; falloff = trace.fraction * FLASHLIGHT_DISTANCE;
if( falloff < 500.0f ) falloff = 1.0f; if( falloff < 500.0f ) falloff = 1.0f;
else falloff = 500.0f / falloff; else falloff = 500.0f / falloff;
falloff *= falloff; falloff *= falloff;
// apply brigthness to dlight // apply brigthness to dlight
dl->color.r = bound( 0, falloff * 255, 255 ); dl->color.r = dl->color.g = dl->color.b = bound( 0, falloff * 255, 255 );
dl->color.g = bound( 0, falloff * 255, 255 );
dl->color.b = bound( 0, falloff * 255, 255 );
dl->die = cl.time + 0.01f; // die on next frame dl->die = cl.time + 0.01f; // die on next frame
dl->radius = 80; dl->radius = 80;
} }
static void R_EntityDimlight( cl_entity_t *ent, int key )
{
dlight_t *dl = CL_AllocDlight( key );
VectorCopy( ent->origin, dl->origin );
dl->color.r = dl->color.g = dl->color.b = 100;
dl->radius = COM_RandomFloat( 200.0f, 231.0f );
dl->die = cl.time + 0.001;
}
static void R_EntityLight( cl_entity_t *ent, int key )
{
dlight_t *dl = CL_AllocDlight( key );
VectorCopy( ent->origin, dl->origin );
dl->color.r = dl->color.g = dl->color.b = 100;
dl->radius = 200;
dl->die = cl.time + 0.001;
R_RocketFlare( ent->origin );
}
static void R_EntityBrightlight( cl_entity_t *ent, int key, int radius )
{
dlight_t *dl = CL_AllocDlight( key );
VectorCopy( ent->origin, dl->origin );
dl->origin[2] += 16.0f;
dl->color.r = dl->color.g = dl->color.b = 250;
if( !radius )
dl->radius = COM_RandomFloat( 400.0f, 431.0f );
else dl->radius = 400;
dl->die = cl.time + 0.001;
}
/* /*
================ ================
CL_AddEntityEffects CL_AddEntityEffects
@@ -2695,50 +2722,41 @@ apply various effects to entity origin or attachment
*/ */
void CL_AddEntityEffects( cl_entity_t *ent ) void CL_AddEntityEffects( cl_entity_t *ent )
{ {
// yellow flies effect 'monster stuck in the wall' // players have special set of effects, from CL_LinkPlayers
if( FBitSet( ent->curstate.effects, EF_BRIGHTFIELD ) && !RP_LOCALCLIENT( ent )) if( ent->player && ent->index != cl.viewentity )
R_EntityParticles( ent ); {
if( FBitSet( ent->curstate.effects, EF_BRIGHTLIGHT ))
R_EntityBrightlight( ent, ent->index /* 4 in GoldSrc */, 0 );
if( FBitSet( ent->curstate.effects, EF_DIMLIGHT )) if( FBitSet( ent->curstate.effects, EF_DIMLIGHT ))
R_EntityDimlight( ent, ent->index /* 4 in GoldSrc */ );
}
else if( RP_LOCALCLIENT( ent ))
{ {
if( ent->player && !Host_IsQuakeCompatible( )) // from CL_PlayerFlashlight
{ if( FBitSet( ent->curstate.effects, EF_BRIGHTLIGHT ))
R_EntityBrightlight( ent, ent->index /* 1 in GoldSrc */, 400 );
else if( FBitSet( ent->curstate.effects, EF_DIMLIGHT ))
CL_UpdateFlashlight( ent ); CL_UpdateFlashlight( ent );
} }
else else
{ {
dlight_t *dl = CL_AllocDlight( ent->index ); // from CL_LinkPacketEntities
dl->color.r = dl->color.g = dl->color.b = 100; if( FBitSet( ent->curstate.effects, EF_BRIGHTFIELD ))
dl->radius = COM_RandomFloat( 200, 231 ); R_EntityParticles( ent );
VectorCopy( ent->origin, dl->origin );
dl->die = cl.time + 0.001;
}
}
if( FBitSet( ent->curstate.effects, EF_BRIGHTLIGHT )) if( FBitSet( ent->curstate.effects, EF_BRIGHTLIGHT ))
{ R_EntityBrightlight( ent, ent->index, 0 );
dlight_t *dl = CL_AllocDlight( ent->index );
dl->color.r = dl->color.g = dl->color.b = 250; if( FBitSet( ent->curstate.effects, EF_DIMLIGHT ))
if( ent->player ) dl->radius = 400; // don't flickering R_EntityDimlight( ent, ent->index );
else dl->radius = COM_RandomFloat( 400, 431 );
VectorCopy( ent->origin, dl->origin );
dl->die = cl.time + 0.001;
dl->origin[2] += 16.0f;
}
// add light effect
if( FBitSet( ent->curstate.effects, EF_LIGHT )) if( FBitSet( ent->curstate.effects, EF_LIGHT ))
{ R_EntityLight( ent, ent->curstate.number );
dlight_t *dl = CL_AllocDlight( ent->index );
dl->color.r = dl->color.g = dl->color.b = 100;
VectorCopy( ent->origin, dl->origin );
R_RocketFlare( ent->origin );
dl->die = cl.time + 0.001;
dl->radius = 200;
} }
// studio models are handle muzzleflashes difference // studio models are handle muzzleflashes difference
if( FBitSet( ent->curstate.effects, EF_MUZZLEFLASH ) && Mod_AliasExtradata( ent->model )) if( FBitSet( ent->curstate.effects, EF_MUZZLEFLASH ) && ent->model && ent->model->type == mod_alias )
{ {
dlight_t *dl = CL_AllocDlight( ent->index ); dlight_t *dl = CL_AllocDlight( ent->index );
vec3_t fv; vec3_t fv;
@@ -2767,15 +2785,11 @@ void CL_AddModelEffects( cl_entity_t *ent )
vec3_t neworigin; vec3_t neworigin;
vec3_t oldorigin; vec3_t oldorigin;
if( !ent->model ) return; if( !ent->model || ent->player )
return;
switch( ent->model->type ) if( ent->model->type != mod_alias && ent->model->type != mod_studio )
{ return;
case mod_alias:
case mod_studio:
break;
default: return;
}
if( cls.demoplayback == DEMO_QUAKE1 ) if( cls.demoplayback == DEMO_QUAKE1 )
{ {
@@ -2795,19 +2809,15 @@ void CL_AddModelEffects( cl_entity_t *ent )
if( FBitSet( ent->model->flags, STUDIO_GIB )) if( FBitSet( ent->model->flags, STUDIO_GIB ))
R_RocketTrail( oldorigin, neworigin, 2 ); R_RocketTrail( oldorigin, neworigin, 2 );
else if( FBitSet( ent->model->flags, STUDIO_ZOMGIB ))
if( FBitSet( ent->model->flags, STUDIO_ZOMGIB ))
R_RocketTrail( oldorigin, neworigin, 4 ); R_RocketTrail( oldorigin, neworigin, 4 );
else if( FBitSet( ent->model->flags, STUDIO_TRACER ))
if( FBitSet( ent->model->flags, STUDIO_TRACER ))
R_RocketTrail( oldorigin, neworigin, 3 ); R_RocketTrail( oldorigin, neworigin, 3 );
else if( FBitSet( ent->model->flags, STUDIO_TRACER2 ))
if( FBitSet( ent->model->flags, STUDIO_TRACER2 ))
R_RocketTrail( oldorigin, neworigin, 5 ); R_RocketTrail( oldorigin, neworigin, 5 );
else if( FBitSet( ent->model->flags, STUDIO_ROCKET ))
if( FBitSet( ent->model->flags, STUDIO_ROCKET ))
{ {
dlight_t *dl = CL_AllocDlight( ent->index ); dlight_t *dl = CL_AllocDlight( ent->curstate.number );
dl->color.r = dl->color.g = dl->color.b = 200; dl->color.r = dl->color.g = dl->color.b = 200;
VectorCopy( ent->origin, dl->origin ); VectorCopy( ent->origin, dl->origin );
@@ -2821,11 +2831,9 @@ void CL_AddModelEffects( cl_entity_t *ent )
R_RocketTrail( oldorigin, neworigin, 0 ); R_RocketTrail( oldorigin, neworigin, 0 );
} }
else if( FBitSet( ent->model->flags, STUDIO_GRENADE ))
if( FBitSet( ent->model->flags, STUDIO_GRENADE ))
R_RocketTrail( oldorigin, neworigin, 1 ); R_RocketTrail( oldorigin, neworigin, 1 );
else if( FBitSet( ent->model->flags, STUDIO_TRACER3 ))
if( FBitSet( ent->model->flags, STUDIO_TRACER3 ))
R_RocketTrail( oldorigin, neworigin, 6 ); R_RocketTrail( oldorigin, neworigin, 6 );
} }
@@ -2843,10 +2851,10 @@ void CL_TestLights( void )
float f, r; float f, r;
dlight_t *dl; dlight_t *dl;
if( !CVAR_TO_BOOL( cl_testlights )) if( !cl_testlights.value )
return; return;
numLights = bound( 1, cl_testlights->value, MAX_DLIGHTS ); numLights = bound( 1, cl_testlights.value, MAX_DLIGHTS );
AngleVectors( cl.viewangles, forward, right, NULL ); AngleVectors( cl.viewangles, forward, right, NULL );
for( i = 0; i < numLights; i++ ) for( i = 0; i < numLights; i++ )
@@ -2905,7 +2913,7 @@ CL_PlayerDecal
spray custom colored decal (clan logo etc) spray custom colored decal (clan logo etc)
=============== ===============
*/ */
void CL_PlayerDecal( int playernum, int customIndex, int entityIndex, float *pos ) static void CL_PlayerDecal( int playernum, int customIndex, int entityIndex, float *pos )
{ {
int textureIndex = 0; int textureIndex = 0;
customization_t *pCust = NULL; customization_t *pCust = NULL;

View File

@@ -81,7 +81,6 @@ void R_DebugParticle( const vec3_t pos, byte r, byte g, byte b );
void R_RicochetSound( const vec3_t pos ); void R_RicochetSound( const vec3_t pos );
struct dlight_s *CL_AllocDlight( int key ); struct dlight_s *CL_AllocDlight( int key );
struct dlight_s *CL_AllocElight( int key ); struct dlight_s *CL_AllocElight( int key );
void CL_UpdateFlashlight( cl_entity_t *pEnt );
void CL_AddEntityEffects( cl_entity_t *ent ); void CL_AddEntityEffects( cl_entity_t *ent );
void CL_AddModelEffects( cl_entity_t *ent ); void CL_AddModelEffects( cl_entity_t *ent );
void CL_DecalShoot( int textureIndex, int entityIndex, int modelIndex, float *pos, int flags ); void CL_DecalShoot( int textureIndex, int entityIndex, int modelIndex, float *pos, int flags );

View File

@@ -68,7 +68,7 @@ qboolean SCR_NextMovie( void )
return true; return true;
} }
void SCR_CreateStartupVids( void ) static void SCR_CreateStartupVids( void )
{ {
file_t *f; file_t *f;
@@ -202,7 +202,6 @@ SCR_PlayCinematic
*/ */
qboolean SCR_PlayCinematic( const char *arg ) qboolean SCR_PlayCinematic( const char *arg )
{ {
string path;
const char *fullpath; const char *fullpath;
fullpath = FS_GetDiskPath( arg, false ); fullpath = FS_GetDiskPath( arg, false );

View File

@@ -29,7 +29,7 @@ V_CalcViewRect
calc frame rectangle (Quake1 style) calc frame rectangle (Quake1 style)
=============== ===============
*/ */
void V_CalcViewRect( void ) static void V_CalcViewRect( void )
{ {
qboolean full = false; qboolean full = false;
int sb_lines; int sb_lines;
@@ -39,7 +39,7 @@ void V_CalcViewRect( void )
{ {
// intermission is always full screen // intermission is always full screen
if( cl.intermission ) size = 120.0f; if( cl.intermission ) size = 120.0f;
else size = scr_viewsize->value; else size = scr_viewsize.value;
if( size >= 120.0f ) if( size >= 120.0f )
sb_lines = 0; // no status bar at all sb_lines = 0; // no status bar at all
@@ -47,12 +47,12 @@ void V_CalcViewRect( void )
sb_lines = 24; // no inventory sb_lines = 24; // no inventory
else sb_lines = 48; else sb_lines = 48;
if( scr_viewsize->value >= 100.0f ) if( scr_viewsize.value >= 100.0f )
{ {
full = true; full = true;
size = 100.0f; size = 100.0f;
} }
else size = scr_viewsize->value; else size = scr_viewsize.value;
if( cl.intermission ) if( cl.intermission )
{ {
@@ -88,7 +88,7 @@ void V_CalcViewRect( void )
V_SetupViewModel V_SetupViewModel
=============== ===============
*/ */
void V_SetupViewModel( void ) static void V_SetupViewModel( void )
{ {
cl_entity_t *view = &clgame.viewent; cl_entity_t *view = &clgame.viewent;
player_info_t *info = &cl.players[cl.playernum]; player_info_t *info = &cl.players[cl.playernum];
@@ -118,7 +118,7 @@ void V_SetupViewModel( void )
V_SetRefParams V_SetRefParams
=============== ===============
*/ */
void V_SetRefParams( ref_params_t *fd ) static void V_SetRefParams( ref_params_t *fd )
{ {
memset( fd, 0, sizeof( ref_params_t )); memset( fd, 0, sizeof( ref_params_t ));
@@ -144,7 +144,7 @@ void V_SetRefParams( ref_params_t *fd )
VectorCopy( cl.viewangles, fd->cl_viewangles ); VectorCopy( cl.viewangles, fd->cl_viewangles );
fd->health = cl.local.health; fd->health = cl.local.health;
VectorCopy( cl.crosshairangle, fd->crosshairangle ); VectorCopy( cl.crosshairangle, fd->crosshairangle );
fd->viewsize = scr_viewsize->value; fd->viewsize = scr_viewsize.value;
VectorCopy( cl.punchangle, fd->punchangle ); VectorCopy( cl.punchangle, fd->punchangle );
fd->maxclients = cl.maxclients; fd->maxclients = cl.maxclients;
@@ -182,7 +182,7 @@ V_MergeOverviewRefdef
merge refdef with overview settings merge refdef with overview settings
=============== ===============
*/ */
void V_RefApplyOverview( ref_viewpass_t *rvp ) static void V_RefApplyOverview( ref_viewpass_t *rvp )
{ {
ref_overview_t *ov = &clgame.overView; ref_overview_t *ov = &clgame.overView;
float aspect; float aspect;
@@ -281,7 +281,7 @@ static void V_AdjustFov( float *fov_x, float *fov_y, float width, float height,
V_GetRefParams V_GetRefParams
============= =============
*/ */
void V_GetRefParams( ref_params_t *fd, ref_viewpass_t *rvp ) static void V_GetRefParams( ref_params_t *fd, ref_viewpass_t *rvp )
{ {
// part1: deniable updates // part1: deniable updates
VectorCopy( fd->simvel, cl.simvel ); VectorCopy( fd->simvel, cl.simvel );
@@ -311,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] ); rvp->fov_y = V_CalcFov( &rvp->fov_x, clgame.viewport[2], clgame.viewport[3] );
// adjust FOV for widescreen // 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 ); V_AdjustFov( &rvp->fov_x, &rvp->fov_y, clgame.viewport[2], clgame.viewport[3], false );
rvp->flags = 0; rvp->flags = 0;
@@ -339,7 +339,7 @@ qboolean V_PreRender( void )
// if the screen is disabled (loading plaque is up) // if the screen is disabled (loading plaque is up)
if( cls.disable_screen ) 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" ); Con_Reportf( "V_PreRender: loading plaque timed out\n" );
cls.disable_screen = 0.0f; cls.disable_screen = 0.0f;
@@ -347,6 +347,8 @@ qboolean V_PreRender( void )
return false; return false;
} }
V_CheckGamma();
ref.dllFuncs.R_BeginFrame( !cl.paused && ( cls.state == ca_active )); ref.dllFuncs.R_BeginFrame( !cl.paused && ( cls.state == ca_active ));
GL_UpdateSwapInterval( ); GL_UpdateSwapInterval( );
@@ -364,11 +366,13 @@ V_RenderView
*/ */
void V_RenderView( void ) 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; ref_viewpass_t rvp;
int viewnum = 0; 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 return; // still loading
V_CalcViewRect (); // compute viewport rectangle V_CalcViewRect (); // compute viewport rectangle
@@ -404,14 +408,14 @@ void V_RenderView( void )
#define NODE_INTERVAL_X(x) (x * 16.0f) #define NODE_INTERVAL_X(x) (x * 16.0f)
#define NODE_INTERVAL_Y(x) (x * 16.0f) #define NODE_INTERVAL_Y(x) (x * 16.0f)
void R_DrawLeafNode( float x, float y, float scale ) static void R_DrawLeafNode( float x, float y, float scale )
{ {
float downScale = scale * 0.25f;// * POINT_SIZE; float downScale = scale * 0.25f;// * POINT_SIZE;
ref.dllFuncs.R_DrawStretchPic( x - downScale * 0.5f, y - downScale * 0.5f, downScale, downScale, 0, 0, 1, 1, R_GetBuiltinTexture( REF_PARTICLE_TEXTURE ) ); ref.dllFuncs.R_DrawStretchPic( x - downScale * 0.5f, y - downScale * 0.5f, downScale, downScale, 0, 0, 1, 1, R_GetBuiltinTexture( REF_PARTICLE_TEXTURE ) );
} }
void R_DrawNodeConnection( float x, float y, float x2, float y2 ) static void R_DrawNodeConnection( float x, float y, float x2, float y2 )
{ {
ref.dllFuncs.Begin( TRI_LINES ); ref.dllFuncs.Begin( TRI_LINES );
ref.dllFuncs.Vertex3f( x, y, 0 ); ref.dllFuncs.Vertex3f( x, y, 0 );
@@ -419,7 +423,7 @@ void R_DrawNodeConnection( float x, float y, float x2, float y2 )
ref.dllFuncs.End( ); ref.dllFuncs.End( );
} }
void R_ShowTree_r( mnode_t *node, float x, float y, float scale, int shownodes, mleaf_t *viewleaf ) static void R_ShowTree_r( mnode_t *node, float x, float y, float scale, int shownodes, mleaf_t *viewleaf )
{ {
float downScale = scale * 0.8f; float downScale = scale * 0.8f;
@@ -466,13 +470,13 @@ void R_ShowTree_r( mnode_t *node, float x, float y, float scale, int shownodes,
world.recursion_level--; world.recursion_level--;
} }
void R_ShowTree( void ) static void R_ShowTree( void )
{ {
float x = (float)((refState.width - (int)POINT_SIZE) >> 1); float x = (float)((refState.width - (int)POINT_SIZE) >> 1);
float y = NODE_INTERVAL_Y(1.0f); float y = NODE_INTERVAL_Y(1.0f);
mleaf_t *viewleaf; mleaf_t *viewleaf;
if( !cl.worldmodel || !CVAR_TO_BOOL( r_showtree )) if( !cl.worldmodel || !r_showtree.value )
return; return;
world.recursion_level = 0; world.recursion_level = 0;
@@ -547,5 +551,8 @@ void V_PostRender( void )
SCR_MakeScreenShot(); SCR_MakeScreenShot();
ref.dllFuncs.R_AllowFog( true ); ref.dllFuncs.R_AllowFog( true );
Platform_SetTimer( 0.0f );
ref.dllFuncs.R_EndFrame(); ref.dllFuncs.R_EndFrame();
V_CheckGammaEnd();
} }

View File

@@ -174,6 +174,26 @@ typedef struct
// at every server map change // at every server map change
typedef struct typedef struct
{ {
// ==== shared through RefAPI's ref_client_t ====
double time; // this is the time value that the client
// is rendering at. always <= cls.realtime
// a lerp point for other data
double oldtime; // previous cl.time, time-oldtime is used
// to decay light values and smooth step ups
int viewentity;
// server state information
int playernum;
int maxclients;
int nummodels;
model_t *models[MAX_MODELS+1]; // precached models (plus sentinel slot)
qboolean paused;
vec3_t simorg; // predicted origin
// ==== shared through RefAPI's ref_client_t ===
int servercount; // server identification for prespawns int servercount; // server identification for prespawns
int validsequence; // this is the sequence number of the last good int validsequence; // this is the sequence number of the last good
// world snapshot/update we got. If this is 0, we can't // world snapshot/update we got. If this is 0, we can't
@@ -183,7 +203,6 @@ typedef struct
qboolean video_prepped; // false if on new level or new ref dll qboolean video_prepped; // false if on new level or new ref dll
qboolean audio_prepped; // false if on new level or new snd dll qboolean audio_prepped; // false if on new level or new snd dll
qboolean paused;
int delta_sequence; // acknowledged sequence number int delta_sequence; // acknowledged sequence number
@@ -205,17 +224,12 @@ typedef struct
runcmd_t commands[MULTIPLAYER_BACKUP]; // each mesage will send several old cmds runcmd_t commands[MULTIPLAYER_BACKUP]; // each mesage will send several old cmds
local_state_t predicted_frames[MULTIPLAYER_BACKUP]; // local client state local_state_t predicted_frames[MULTIPLAYER_BACKUP]; // local client state
double time; // this is the time value that the client
// is rendering at. always <= cls.realtime
// a lerp point for other data
double oldtime; // previous cl.time, time-oldtime is used
// to decay light values and smooth step ups
double timedelta; // floating delta between two updates double timedelta; // floating delta between two updates
char serverinfo[MAX_SERVERINFO_STRING]; char serverinfo[MAX_SERVERINFO_STRING];
player_info_t players[MAX_CLIENTS]; // collected info about all other players include himself player_info_t players[MAX_CLIENTS]; // collected info about all other players include himself
double lastresourcecheck; double lastresourcecheck;
string downloadUrl; qboolean http_download;
event_state_t events; event_state_t events;
// predicting stuff but not only... // predicting stuff but not only...
@@ -223,7 +237,6 @@ typedef struct
// player final info // player final info
usercmd_t *cmd; // cl.commands[outgoing_sequence].cmd usercmd_t *cmd; // cl.commands[outgoing_sequence].cmd
int viewentity;
vec3_t viewangles; vec3_t viewangles;
vec3_t viewheight; vec3_t viewheight;
vec3_t punchangle; vec3_t punchangle;
@@ -236,14 +249,9 @@ typedef struct
float addangletotal; float addangletotal;
float prevaddangletotal; float prevaddangletotal;
// predicted origin and velocity // predicted velocity
vec3_t simorg;
vec3_t simvel; vec3_t simvel;
// server state information
int playernum;
int maxclients;
entity_state_t instanced_baseline[MAX_CUSTOM_BASELINES]; entity_state_t instanced_baseline[MAX_CUSTOM_BASELINES];
int instanced_baseline_count; int instanced_baseline_count;
@@ -251,8 +259,6 @@ typedef struct
char event_precache[MAX_EVENTS][MAX_QPATH]; char event_precache[MAX_EVENTS][MAX_QPATH];
char files_precache[MAX_CUSTOM][MAX_QPATH]; char files_precache[MAX_CUSTOM][MAX_QPATH];
lightstyle_t lightstyles[MAX_LIGHTSTYLES]; lightstyle_t lightstyles[MAX_LIGHTSTYLES];
model_t *models[MAX_MODELS+1]; // precached models (plus sentinel slot)
int nummodels;
int numfiles; int numfiles;
consistency_t consistency_list[MAX_MODELS]; consistency_t consistency_list[MAX_MODELS];
@@ -270,6 +276,8 @@ typedef struct
model_t *worldmodel; // pointer to world model_t *worldmodel; // pointer to world
int lostpackets; // count lost packets and show dialog in menu int lostpackets; // count lost packets and show dialog in menu
double frametime_remainder;
} client_t; } client_t;
/* /*
@@ -336,8 +344,7 @@ typedef struct
byte charWidths[256]; // scaled widths byte charWidths[256]; // scaled widths
int charHeight; // scaled height int charHeight; // scaled height
int type; // fixed width font or variable int type; // fixed width font or variable
int rendermode; // default rendermode convar_t *rendermode; // user-defined default rendermode
qboolean nearest; // nearest filtering enabled
qboolean valid; // all rectangles are valid qboolean valid; // all rectangles are valid
} cl_font_t; } cl_font_t;
@@ -423,13 +430,6 @@ typedef struct
float applied_angle; float applied_angle;
} screen_shake_t; } 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 typedef struct
{ {
net_response_t resp; net_response_t resp;
@@ -491,9 +491,7 @@ typedef struct
client_textmessage_t *titles; // title messages, not network messages client_textmessage_t *titles; // title messages, not network messages
int numTitles; 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 net_requests[MAX_REQUESTS]; // no reason to keep more
net_request_t *master_request; // queued master request
efrag_t *free_efrags; // linked efrags efrag_t *free_efrags; // linked efrags
cl_entity_t viewent; // viewmodel cl_entity_t viewent; // viewmodel
@@ -522,7 +520,7 @@ typedef struct
int logo_yres; int logo_yres;
float logo_length; float logo_length;
qboolean use_text_api; qboolean use_extended_api;
} gameui_static_t; } gameui_static_t;
typedef struct typedef struct
@@ -543,12 +541,8 @@ typedef struct
poolhandle_t mempool; // client premamnent pool: edicts etc poolhandle_t mempool; // client premamnent pool: edicts etc
netadr_t hltv_listen_address;
int signon; // 0 to SIGNONS, for the signon sequence. int signon; // 0 to SIGNONS, for the signon sequence.
int quakePort; // a 16 bit value that allows quake servers
// to work around address translating routers
// g-cont. this port allow many copies of engine in multiplayer game
// connection information // connection information
char servername[MAX_QPATH]; // name of server from original connect char servername[MAX_QPATH]; // name of server from original connect
double connect_time; // for connection retransmits double connect_time; // for connection retransmits
@@ -627,7 +621,10 @@ typedef struct
file_t *demofile; file_t *demofile;
file_t *demoheader; // contain demo startup info in case we record a demo on this level 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_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 // legacy mode support
qboolean legacymode; // one-way 48 protocol compatibility qboolean legacymode; // one-way 48 protocol compatibility
@@ -635,6 +632,9 @@ typedef struct
int extensions; int extensions;
netadr_t serveradr; netadr_t serveradr;
// do we accept utf8 as input
qboolean accept_utf8;
} client_static_t; } client_static_t;
#ifdef __cplusplus #ifdef __cplusplus
@@ -659,51 +659,55 @@ extern convar_t cl_logocolor;
extern convar_t cl_allow_download; extern convar_t cl_allow_download;
extern convar_t cl_allow_upload; extern convar_t cl_allow_upload;
extern convar_t cl_download_ingame; extern convar_t cl_download_ingame;
extern convar_t *cl_nopred; extern convar_t cl_nopred;
extern convar_t *cl_timeout; extern convar_t cl_timeout;
extern convar_t *cl_nodelta; extern convar_t cl_nodelta;
extern convar_t *cl_interp; extern convar_t cl_interp;
extern convar_t *cl_nointerp; extern convar_t cl_nointerp;
extern convar_t *cl_showerror; extern convar_t cl_showerror;
extern convar_t *cl_nosmooth; extern convar_t cl_nosmooth;
extern convar_t *cl_smoothtime; extern convar_t cl_smoothtime;
extern convar_t *cl_crosshair; extern convar_t cl_crosshair;
extern convar_t *cl_testlights; extern convar_t cl_testlights;
extern convar_t *cl_cmdrate; extern convar_t cl_cmdrate;
extern convar_t *cl_updaterate; extern convar_t cl_updaterate;
extern convar_t *cl_solid_players; extern convar_t cl_solid_players;
extern convar_t *cl_idealpitchscale; extern convar_t cl_idealpitchscale;
extern convar_t *cl_allow_levelshots; extern convar_t cl_allow_levelshots;
extern convar_t *cl_lightstyle_lerping; extern convar_t cl_lightstyle_lerping;
extern convar_t *cl_draw_particles; extern convar_t cl_draw_particles;
extern convar_t *cl_draw_tracers; extern convar_t cl_draw_tracers;
extern convar_t *cl_levelshot_name; extern convar_t cl_levelshot_name;
extern convar_t *cl_draw_beams; extern convar_t cl_draw_beams;
extern convar_t *cl_clockreset; extern convar_t cl_clockreset;
extern convar_t *cl_fixtimerate; extern convar_t cl_fixtimerate;
extern convar_t *hud_fontscale; extern convar_t hud_fontscale;
extern convar_t *hud_scale; extern convar_t hud_fontrender;
extern convar_t *gl_showtextures; extern convar_t hud_scale;
extern convar_t *cl_bmodelinterp; extern convar_t hud_scale_minimal_width;
extern convar_t *cl_lw; // local weapons extern convar_t r_showtextures;
extern convar_t *cl_charset; extern convar_t cl_bmodelinterp;
extern convar_t *cl_trace_messages; extern convar_t cl_lw; // local weapons
extern convar_t *hud_utf8; extern convar_t cl_charset;
extern convar_t *cl_showevents; extern convar_t cl_trace_stufftext;
extern convar_t *scr_centertime; extern convar_t cl_trace_messages;
extern convar_t *scr_viewsize; extern convar_t cl_trace_events;
extern convar_t *scr_loading; extern convar_t hud_utf8;
extern convar_t *v_dark; // start from dark extern convar_t cl_showevents;
extern convar_t *net_graph; extern convar_t scr_centertime;
extern convar_t *rate; extern convar_t scr_viewsize;
extern convar_t *m_ignore; extern convar_t scr_loading;
extern convar_t *r_showtree; extern convar_t v_dark; // start from dark
extern convar_t *ui_renderworld; 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_fixmodelinterpolationartifacts;
//============================================================================= //=============================================================================
void CL_SetLightstyle( int style, const char* s, float f ); void CL_SetLightstyle( int style, const char* s, float f );
void CL_RunLightStyles( void );
void CL_DecayLights( void ); void CL_DecayLights( void );
dlight_t *CL_GetDynamicLight( int number ); dlight_t *CL_GetDynamicLight( int number );
dlight_t *CL_GetEntityLight( int number ); dlight_t *CL_GetEntityLight( int number );
@@ -714,12 +718,8 @@ dlight_t *CL_GetEntityLight( int number );
// cl_cmds.c // cl_cmds.c
// //
void CL_Quit_f( void ); void CL_Quit_f( void );
void CL_ScreenShot_f( void ); void CL_GenericShot_f( void );
void CL_SnapShot_f( void );
void CL_PlayCDTrack_f( void ); void CL_PlayCDTrack_f( void );
void CL_EnvShot_f( void );
void CL_SkyShot_f( void );
void CL_SaveShot_f( void );
void CL_LevelShot_f( void ); void CL_LevelShot_f( void );
void CL_SetSky_f( void ); void CL_SetSky_f( void );
void SCR_Viewpos_f( void ); void SCR_Viewpos_f( void );
@@ -740,8 +740,6 @@ void CL_ClearResourceLists( void );
void CL_Parse_Debug( qboolean enable ); void CL_Parse_Debug( qboolean enable );
void CL_Parse_RecordCommand( int cmd, int startoffset ); void CL_Parse_RecordCommand( int cmd, int startoffset );
void CL_ResetFrame( frame_t *frame ); void CL_ResetFrame( frame_t *frame );
void CL_WriteMessageHistory( void );
const char *CL_MsgInfo( int cmd );
// //
// cl_efx.c // cl_efx.c
@@ -752,7 +750,6 @@ void CL_Particle( const vec3_t org, int color, float life, int zpos, int zvel );
// cl_main.c // cl_main.c
// //
void CL_Init( void ); void CL_Init( void );
void CL_SendCommand( void );
void CL_Disconnect_f( void ); void CL_Disconnect_f( void );
void CL_ProcessFile( qboolean successfully_received, const char *filename ); void CL_ProcessFile( qboolean successfully_received, const char *filename );
void CL_WriteUsercmd( sizebuf_t *msg, int from, int to ); void CL_WriteUsercmd( sizebuf_t *msg, int from, int to );
@@ -761,10 +758,8 @@ qboolean CL_PrecacheResources( void );
void CL_SetupOverviewParams( void ); void CL_SetupOverviewParams( void );
void CL_UpdateFrameLerp( void ); void CL_UpdateFrameLerp( void );
int CL_IsDevOverviewMode( void ); int CL_IsDevOverviewMode( void );
void CL_PingServers_f( void );
void CL_SignonReply( void ); void CL_SignonReply( void );
void CL_ClearState( void ); void CL_ClearState( void );
size_t CL_BuildMasterServerScanRequest( char *buf, size_t size, qboolean nat );
// //
// cl_demo.c // cl_demo.c
@@ -780,8 +775,6 @@ void CL_CheckStartupDemos( void );
void CL_WriteDemoJumpTime( void ); void CL_WriteDemoJumpTime( void );
void CL_CloseDemoHeader( void ); void CL_CloseDemoHeader( void );
void CL_DemoCompleted( void ); void CL_DemoCompleted( void );
void CL_StopPlayback( void );
void CL_StopRecord( void );
void CL_PlayDemo_f( void ); void CL_PlayDemo_f( void );
void CL_TimeDemo_f( void ); void CL_TimeDemo_f( void );
void CL_StartDemos_f( void ); void CL_StartDemos_f( void );
@@ -789,6 +782,7 @@ void CL_Demos_f( void );
void CL_DeleteDemo_f( void ); void CL_DeleteDemo_f( void );
void CL_Record_f( void ); void CL_Record_f( void );
void CL_Stop_f( void ); void CL_Stop_f( void );
int CL_GetDemoComment( const char *demoname, char *comment );
// //
// cl_events.c // cl_events.c
@@ -796,12 +790,9 @@ void CL_Stop_f( void );
void CL_ParseEvent( sizebuf_t *msg ); void CL_ParseEvent( sizebuf_t *msg );
void CL_ParseReliableEvent( sizebuf_t *msg ); void CL_ParseReliableEvent( sizebuf_t *msg );
void CL_SetEventIndex( const char *szEvName, int ev_index ); void CL_SetEventIndex( const char *szEvName, int ev_index );
void CL_QueueEvent( int flags, int index, float delay, event_args_t *args );
void CL_PlaybackEvent( int flags, const edict_t *pInvoker, word eventindex, float delay, float *origin, void CL_PlaybackEvent( int flags, const edict_t *pInvoker, word eventindex, float delay, float *origin,
float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 ); float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 );
void CL_RegisterEvent( int lastnum, const char *szEvName, pfnEventHook func ); void CL_RegisterEvent( int lastnum, const char *szEvName, pfnEventHook func );
void CL_BatchResourceRequest( qboolean initialize );
int CL_EstimateNeededResources( void );
void CL_ResetEvent( event_info_t *ei ); void CL_ResetEvent( event_info_t *ei );
word CL_EventIndex( const char *name ); word CL_EventIndex( const char *name );
void CL_FireEvents( void ); void CL_FireEvents( void );
@@ -810,9 +801,10 @@ void CL_FireEvents( void );
// cl_font.c // cl_font.c
// //
qboolean CL_FixedFont( cl_font_t *font ); 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_LoadFixedWidthFont( const char *fontname, cl_font_t *font, float scale, convar_t *rendermode, uint texFlags );
qboolean Con_LoadVariableWidthFont( 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, convar_t *rendermode, uint texFlags );
void CL_FreeFont( cl_font_t *font ); void CL_FreeFont( cl_font_t *font );
void CL_SetFontRendermode( cl_font_t *font );
int CL_DrawCharacter( float x, float y, int number, rgba_t color, cl_font_t *font, int flags ); int CL_DrawCharacter( float x, float y, int number, rgba_t color, cl_font_t *font, int flags );
int CL_DrawString( float x, float y, const char *s, rgba_t color, cl_font_t *font, int flags ); int CL_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_DrawCharacterLen( cl_font_t *font, int number, int *width, int *height );
@@ -825,12 +817,9 @@ int CL_DrawStringf( cl_font_t *font, float x, float y, rgba_t color, int flags,
// //
void CL_UnloadProgs( void ); void CL_UnloadProgs( void );
qboolean CL_LoadProgs( const char *name ); qboolean CL_LoadProgs( const char *name );
void CL_ParseUserMessage( sizebuf_t *msg, int svc_num );
void CL_LinkUserMessage( char *pszName, const int svc_num, int iSize ); 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_DrawHUD( int state );
void CL_InitEdicts( void ); void CL_InitEdicts( int maxclients );
void CL_FreeEdicts( void ); void CL_FreeEdicts( void );
void CL_ClearWorld( void ); void CL_ClearWorld( void );
void CL_DrawCenterPrint( void ); void CL_DrawCenterPrint( void );
@@ -838,35 +827,24 @@ void CL_ClearSpriteTextures( void );
void CL_CenterPrint( const char *text, float y ); void CL_CenterPrint( const char *text, float y );
void CL_TextMessageParse( byte *pMemFile, int fileSize ); void CL_TextMessageParse( byte *pMemFile, int fileSize );
client_textmessage_t *CL_TextMessageGet( const char *pName ); 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 ); model_t *CL_ModelHandle( int modelindex );
void NetAPI_CancelAllRequests( void ); void NetAPI_CancelAllRequests( void );
int CL_FindModelIndex( const char *m );
cl_entity_t *CL_GetLocalPlayer( void ); cl_entity_t *CL_GetLocalPlayer( void );
model_t *CL_LoadClientSprite( const char *filename ); model_t *CL_LoadClientSprite( const char *filename );
model_t *CL_LoadModel( const char *modelname, int *index ); model_t *CL_LoadModel( const char *modelname, int *index );
HSPRITE EXPORT pfnSPR_Load( const char *szPicName );
HSPRITE pfnSPR_LoadExt( const char *szPicName, uint texFlags ); HSPRITE pfnSPR_LoadExt( const char *szPicName, uint texFlags );
void SPR_AdjustSize( 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 ); 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 );
pmtrace_t *PM_CL_TraceLine( float *start, float *end, int flags, int usehull, int ignore_pe ); 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 ); const char *PM_CL_TraceTexture( int ground, float *vstart, float *vend );
int PM_CL_PointContents( const float *p, int *truecontents ); int PM_CL_PointContents( const float *p, int *truecontents );
void CL_SetTraceHull( int hull );
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 ); physent_t *pfnGetPhysent( int idx );
struct msurface_s *pfnTraceSurface( int ground, float *vstart, float *vend ); struct msurface_s *pfnTraceSurface( int ground, float *vstart, float *vend );
movevars_t *pfnGetMoveVars( void ); movevars_t *pfnGetMoveVars( void );
void CL_EnableScissor( scissor_state_t *scissor, int x, int y, int width, int height ); void CL_EnableScissor( scissor_state_t *scissor, int x, int y, int width, int height );
void CL_DisableScissor( scissor_state_t *scissor ); 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 ); qboolean CL_Scissor( const scissor_state_t *scissor, float *x, float *y, float *width, float *height, float *u0, float *v0, float *u1, float *v1 );
struct cl_entity_s *CL_GetEntityByIndex( int index );
_inline cl_entity_t *CL_EDICT_NUM( int n ) _inline cl_entity_t *CL_EDICT_NUM( int n )
{ {
@@ -886,16 +864,49 @@ _inline cl_entity_t *CL_EDICT_NUM( int n )
// //
// cl_parse.c // 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_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_ParseTempEntity( sizebuf_t *msg );
qboolean CL_DispatchUserMessage( const char *pszName, int iSize, void *pbuf ); qboolean CL_DispatchUserMessage( const char *pszName, int iSize, void *pbuf );
qboolean CL_RequestMissingResources( void ); qboolean CL_RequestMissingResources( void );
void CL_RegisterResources ( sizebuf_t *msg ); void CL_RegisterResources ( sizebuf_t *msg );
void CL_ParseViewEntity( sizebuf_t *msg ); void CL_ParseViewEntity( sizebuf_t *msg );
void CL_ParseServerTime( sizebuf_t *msg ); void CL_ParseServerTime( sizebuf_t *msg );
void CL_ParseUserMessage( sizebuf_t *msg, int svc_num );
void CL_ParseFinaleCutscene( sizebuf_t *msg, int level );
void CL_ParseTextMessage( sizebuf_t *msg );
void CL_BatchResourceRequest( qboolean initialize );
int CL_EstimateNeededResources( void );
//
// cl_parse_48.c
//
void CL_ParseLegacyServerMessage( sizebuf_t *msg, qboolean normal_message );
void CL_LegacyPrecache_f( void );
// //
// cl_scrn.c // cl_scrn.c
@@ -903,8 +914,6 @@ void CL_ParseServerTime( sizebuf_t *msg );
void SCR_VidInit( void ); void SCR_VidInit( void );
void SCR_TileClear( void ); void SCR_TileClear( void );
void SCR_DirtyScreen( void ); void SCR_DirtyScreen( void );
void SCR_AddDirtyPoint( int x, int y );
void SCR_InstallParticlePalette( void );
void SCR_EndLoadingPlaque( void ); void SCR_EndLoadingPlaque( void );
void SCR_RegisterTextures( void ); void SCR_RegisterTextures( void );
void SCR_LoadCreditsFont( void ); void SCR_LoadCreditsFont( void );
@@ -940,20 +949,17 @@ void CL_InitClientMove( void );
void CL_PredictMovement( qboolean repredicting ); void CL_PredictMovement( qboolean repredicting );
void CL_CheckPredictionError( void ); void CL_CheckPredictionError( void );
qboolean CL_IsPredicted( void ); qboolean CL_IsPredicted( void );
int CL_TruePointContents( const vec3_t p );
int CL_WaterEntity( const float *rgflPos ); int CL_WaterEntity( const float *rgflPos );
cl_entity_t *CL_GetWaterEntity( const float *rgflPos ); cl_entity_t *CL_GetWaterEntity( const float *rgflPos );
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_VisTraceLine( vec3_t start, vec3_t end, int flags );
pmtrace_t CL_TraceLine( vec3_t start, vec3_t end, int flags ); pmtrace_t CL_TraceLine( vec3_t start, vec3_t end, int flags );
void CL_PushTraceBounds( int hullnum, const float *mins, const float *maxs );
void CL_PopTraceBounds( void );
void CL_MoveSpectatorCamera( void ); void CL_MoveSpectatorCamera( void );
void CL_SetLastUpdate( void ); void CL_SetLastUpdate( void );
void CL_RedoPrediction( void ); void CL_RedoPrediction( void );
void CL_PushPMStates( void ); void CL_PushPMStates( void );
void CL_PopPMStates( void ); void CL_PopPMStates( void );
void CL_SetUpPlayerPrediction( int dopred, int bIncludeLocalClient ); void CL_SetUpPlayerPrediction( int dopred, int bIncludeLocalClient );
void CL_SetIdealPitch( void );
// //
// cl_qparse.c // cl_qparse.c
@@ -970,21 +976,17 @@ qboolean CL_AddVisibleEntity( cl_entity_t *ent, int entityType );
void CL_ResetLatchedVars( cl_entity_t *ent, qboolean full_reset ); void CL_ResetLatchedVars( cl_entity_t *ent, qboolean full_reset );
qboolean CL_GetEntitySpatialization( struct channel_s *ch ); qboolean CL_GetEntitySpatialization( struct channel_s *ch );
qboolean CL_GetMovieSpatialization( struct rawchan_s *ch ); qboolean CL_GetMovieSpatialization( struct rawchan_s *ch );
void CL_ProcessPlayerState( int playerindex, entity_state_t *state );
void CL_ComputePlayerOrigin( cl_entity_t *clent ); void CL_ComputePlayerOrigin( cl_entity_t *clent );
void CL_ProcessPacket( frame_t *frame ); void CL_ProcessPacket( frame_t *frame );
void CL_MoveThirdpersonCamera( void ); void CL_MoveThirdpersonCamera( void );
qboolean CL_IsPlayerIndex( int idx ); qboolean CL_IsPlayerIndex( int idx );
void CL_SetIdealPitch( void );
void CL_EmitEntities( void ); void CL_EmitEntities( void );
// //
// cl_remap.c // cl_remap.c
// //
remap_info_t *CL_GetRemapInfoForEntity( cl_entity_t *e ); remap_info_t *CL_GetRemapInfoForEntity( cl_entity_t *e );
void CL_AllocRemapInfo( cl_entity_t *entity, model_t *model, int topcolor, int bottomcolor ); qboolean CL_EntitySetRemapColors( cl_entity_t *e, model_t *mod, int top, int bottom );
void CL_FreeRemapInfo( remap_info_t *info );
void CL_UpdateRemapInfo( cl_entity_t *ent, int topcolor, int bottomcolor );
void CL_ClearAllRemaps( void ); void CL_ClearAllRemaps( void );
// //
@@ -1001,18 +1003,17 @@ const ref_overview_t *GL_GetOverviewParms( void );
// //
void R_StoreEfrags( efrag_t **ppefrag, int framecount ); void R_StoreEfrags( efrag_t **ppefrag, int framecount );
void R_AddEfrags( cl_entity_t *ent ); void R_AddEfrags( cl_entity_t *ent );
// //
// cl_tent.c // cl_tent.c
// //
struct particle_s; struct particle_s;
int CL_AddEntity( int entityType, cl_entity_t *pEnt );
void CL_WeaponAnim( int iAnim, int body ); void CL_WeaponAnim( int iAnim, int body );
void CL_ClearEffects( void ); void CL_ClearEffects( void );
void CL_ClearEfrags( void ); void CL_ClearEfrags( void );
void CL_TestLights( void ); void CL_TestLights( void );
void CL_FireCustomDecal( int textureIndex, int entityIndex, int modelIndex, float *pos, int flags, float scale ); void CL_FireCustomDecal( int textureIndex, int entityIndex, int modelIndex, float *pos, int flags, float scale );
void CL_DecalShoot( int textureIndex, int entityIndex, int modelIndex, float *pos, int flags ); void CL_DecalShoot( int textureIndex, int entityIndex, int modelIndex, float *pos, int flags );
void CL_PlayerDecal( int playerIndex, int textureIndex, int entityIndex, float *pos );
void R_FreeDeadParticles( struct particle_s **ppparticles ); void R_FreeDeadParticles( struct particle_s **ppparticles );
void CL_AddClientResource( const char *filename, int type ); void CL_AddClientResource( const char *filename, int type );
void CL_AddClientResources( void ); void CL_AddClientResources( void );
@@ -1034,12 +1035,11 @@ void CL_ReadPointFile_f( void );
void CL_DrawEFX( float time, qboolean fTrans ); void CL_DrawEFX( float time, qboolean fTrans );
void CL_ThinkParticle( double frametime, particle_t *p ); void CL_ThinkParticle( double frametime, particle_t *p );
void CL_ReadLineFile_f( void ); void CL_ReadLineFile_f( void );
void CL_RunLightStyles( void );
// //
// console.c // console.c
// //
extern convar_t *con_fontsize; extern convar_t con_fontsize;
int Con_Visible( void ); int Con_Visible( void );
qboolean Con_FixedFont( void ); qboolean Con_FixedFont( void );
void Con_VidInit( void ); void Con_VidInit( void );
@@ -1054,27 +1054,23 @@ int Con_UtfProcessChar( int in );
int Con_UtfProcessCharForce( int in ); int Con_UtfProcessCharForce( int in );
int Con_UtfMoveLeft( char *str, int pos ); int Con_UtfMoveLeft( char *str, int pos );
int Con_UtfMoveRight( char *str, int pos, int length ); int Con_UtfMoveRight( char *str, int pos, int length );
void Con_DefaultColor( int r, int g, int b ); void Con_DefaultColor( int r, int g, int b, qboolean gameui );
void Con_InvalidateFonts( void );
cl_font_t *Con_GetCurFont( void ); cl_font_t *Con_GetCurFont( void );
cl_font_t *Con_GetFont( int num ); cl_font_t *Con_GetFont( int num );
void Con_DrawCharacterLen( int number, int *width, int *height ); 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 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 GAME_EXPORT Con_DrawStringLen( const char *pText, int *length, int *height ); // legacy, use cl_font.c
void Con_CharEvent( int key ); void Con_CharEvent( int key );
void Con_RestoreFont( void );
void Key_Console( int key ); void Key_Console( int key );
void Key_Message( int key ); void Key_Message( int key );
void Con_FastClose( void ); void Con_FastClose( void );
void Con_Bottom( void ); void Con_Bottom( void );
void Con_Top( void );
void Con_PageDown( int lines ); void Con_PageDown( int lines );
void Con_PageUp( int lines ); void Con_PageUp( int lines );
// //
// s_main.c // s_main.c
// //
void S_StreamRawSamples( int samples, int rate, int width, int channels, const byte *data );
void S_StreamAviSamples( void *Avi, int entnum, float fvol, float attn, float synctime ); void S_StreamAviSamples( void *Avi, int entnum, float fvol, float attn, float synctime );
void S_StartBackgroundTrack( const char *intro, const char *loop, int position, qboolean fullpath ); void S_StartBackgroundTrack( const char *intro, const char *loop, int position, qboolean fullpath );
void S_StopBackgroundTrack( void ); void S_StopBackgroundTrack( void );
@@ -1121,11 +1117,6 @@ void UI_ConnectionProgress_Precache( void );
void UI_ConnectionProgress_Connect( const char *server ); void UI_ConnectionProgress_Connect( const char *server );
void UI_ConnectionProgress_ChangeLevel( void ); void UI_ConnectionProgress_ChangeLevel( void );
void UI_ConnectionProgress_ParseServerInfo( const char *server ); void UI_ConnectionProgress_ParseServerInfo( const char *server );
void pfnPIC_Set( HIMAGE hPic, int r, int g, int b, int a );
void pfnPIC_Draw( int x, int y, int width, int height, const wrect_t *prc );
void pfnPIC_DrawTrans( int x, int y, int width, int height, const wrect_t *prc );
void pfnPIC_DrawHoles( int x, int y, int width, int height, const wrect_t *prc );
void pfnPIC_DrawAdditive( int x, int y, int width, int height, const wrect_t *prc );
// //
// cl_mobile.c // cl_mobile.c

View File

@@ -21,17 +21,20 @@ GNU General Public License for more details.
#include "qfont.h" #include "qfont.h"
#include "wadfile.h" #include "wadfile.h"
#include "input.h" #include "input.h"
#include "utflib.h"
convar_t *con_notifytime; static CVAR_DEFINE_AUTO( scr_conspeed, "600", FCVAR_ARCHIVE, "console moving speed" );
convar_t *scr_conspeed; static CVAR_DEFINE_AUTO( con_notifytime, "3", FCVAR_ARCHIVE, "notify time to live" );
convar_t *con_fontsize; CVAR_DEFINE_AUTO( con_fontsize, "1", FCVAR_ARCHIVE, "console font number (0, 1 or 2)" );
convar_t *con_charset; static CVAR_DEFINE_AUTO( con_fontrender, "2", FCVAR_ARCHIVE, "console font render mode (0: additive, 1: holes, 2: trans)" );
convar_t *con_fontscale; static CVAR_DEFINE_AUTO( con_charset, "cp1251", FCVAR_ARCHIVE, "console font charset (only cp1251 supported now)" );
convar_t *con_fontnum; static CVAR_DEFINE_AUTO( con_fontscale, "1.0", FCVAR_ARCHIVE, "scale font texture" );
convar_t *con_color; 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 CVAR_DEFINE_AUTO( scr_drawversion, "1", FCVAR_ARCHIVE, "draw version in menu or screenshots, doesn't affect console" );
static CVAR_DEFINE_AUTO( con_oldfont, "0", 0, "use legacy font from gfx.wad, might be missing or broken" );
static int g_codepage = 0; static int g_codepage = 0;
static qboolean g_utf8 = false;
static qboolean g_messagemode_privileged = true; static qboolean g_messagemode_privileged = true;
@@ -138,8 +141,9 @@ typedef struct
static console_t con; static console_t con;
void Con_ClearField( field_t *edit ); static void Con_ClearField( field_t *edit );
void Field_CharEvent( field_t *edit, int ch ); static void Field_CharEvent( field_t *edit, int ch );
static void Con_InvalidateFonts( void );
static void Con_LoadHistory( con_history_t *self ); static void Con_LoadHistory( con_history_t *self );
static void Con_SaveHistory( con_history_t *self ); static void Con_SaveHistory( con_history_t *self );
@@ -149,7 +153,7 @@ static void Con_SaveHistory( con_history_t *self );
Con_Clear_f Con_Clear_f
================ ================
*/ */
void Con_Clear_f( void ) static void Con_Clear_f( void )
{ {
con.lines_count = 0; con.lines_count = 0;
con.backscroll = 0; // go to end con.backscroll = 0; // go to end
@@ -162,29 +166,28 @@ Con_SetColor
*/ */
static void Con_SetColor( void ) static void Con_SetColor( void )
{ {
vec3_t color;
int r, g, b; int r, g, b;
int num; int num;
if( !FBitSet( con_color->flags, FCVAR_CHANGED )) if( !FBitSet( con_color.flags, FCVAR_CHANGED ))
return; 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 ) switch( num )
{ {
case 1: case 1:
Con_DefaultColor( r, r, r ); Con_DefaultColor( r, r, r, false );
break; break;
case 3: case 3:
Con_DefaultColor( r, g, b ); Con_DefaultColor( r, g, b, false );
break; break;
default: default:
Cvar_DirectSet( con_color, con_color->def_string ); Cvar_DirectSet( &con_color, con_color.def_string );
break; break;
} }
ClearBits( con_color->flags, FCVAR_CHANGED ); ClearBits( con_color.flags, FCVAR_CHANGED );
} }
/* /*
@@ -205,7 +208,7 @@ void Con_ClearNotify( void )
Con_ClearTyping Con_ClearTyping
================ ================
*/ */
void Con_ClearTyping( void ) static void Con_ClearTyping( void )
{ {
Con_ClearField( &con.input ); Con_ClearField( &con.input );
con.input.widthInChars = con.linewidth; con.input.widthInChars = con.linewidth;
@@ -218,7 +221,7 @@ void Con_ClearTyping( void )
Con_MessageMode_f Con_MessageMode_f
================ ================
*/ */
void Con_MessageMode_f( void ) static void Con_MessageMode_f( void )
{ {
g_messagemode_privileged = Cmd_CurrentCommandIsPrivileged(); g_messagemode_privileged = Cmd_CurrentCommandIsPrivileged();
@@ -234,7 +237,7 @@ void Con_MessageMode_f( void )
Con_MessageMode2_f Con_MessageMode2_f
================ ================
*/ */
void Con_MessageMode2_f( void ) static void Con_MessageMode2_f( void )
{ {
g_messagemode_privileged = Cmd_CurrentCommandIsPrivileged(); g_messagemode_privileged = Cmd_CurrentCommandIsPrivileged();
@@ -279,7 +282,7 @@ void Con_ToggleConsole_f( void )
Con_SetTimes_f Con_SetTimes_f
================ ================
*/ */
void Con_SetTimes_f( void ) static void Con_SetTimes_f( void )
{ {
int newtimes; int newtimes;
@@ -302,7 +305,7 @@ Notifies the console code about the current time
went backwards) went backwards)
================ ================
*/ */
void Con_FixTimes( void ) static void Con_FixTimes( void )
{ {
double diff; double diff;
int i; int i;
@@ -323,7 +326,7 @@ Con_DeleteLine
Deletes the first line from the console history. Deletes the first line from the console history.
================ ================
*/ */
void Con_DeleteLine( void ) static void Con_DeleteLine( void )
{ {
if( con.lines_count == 0 ) if( con.lines_count == 0 )
return; return;
@@ -338,7 +341,7 @@ Con_DeleteLastLine
Deletes the last line from the console history. Deletes the last line from the console history.
================ ================
*/ */
void Con_DeleteLastLine( void ) static void Con_DeleteLastLine( void )
{ {
if( con.lines_count == 0 ) if( con.lines_count == 0 )
return; return;
@@ -397,7 +400,7 @@ Con_AddLine
Appends a given string as a new line to the console. Appends a given string as a new line to the console.
================ ================
*/ */
void Con_AddLine( const char *line, int length, qboolean newline ) static void Con_AddLine( const char *line, int length, qboolean newline )
{ {
char *putpos; char *putpos;
con_lineinfo_t *p; con_lineinfo_t *p;
@@ -443,7 +446,7 @@ Con_CheckResize
If the line width has changed, reformat the buffer. If the line width has changed, reformat the buffer.
================ ================
*/ */
void Con_CheckResize( void ) static void Con_CheckResize( void )
{ {
int charWidth = 8; int charWidth = 8;
int i, width; int i, width;
@@ -492,7 +495,7 @@ void Con_PageDown( int lines )
Con_Top Con_Top
================ ================
*/ */
void Con_Top( void ) static void Con_Top( void )
{ {
con.backscroll = CON_MAXLINES; con.backscroll = CON_MAXLINES;
} }
@@ -538,15 +541,14 @@ INTERNAL RESOURCE
static void Con_LoadConsoleFont( int fontNumber, cl_font_t *font ) static void Con_LoadConsoleFont( int fontNumber, cl_font_t *font )
{ {
qboolean success = false; qboolean success = false;
float scale = con_fontscale->value; float scale = con_fontscale.value;
if( font->valid ) if( font->valid )
return; // already loaded return; // already loaded
// loading conchars if( con_oldfont.value )
if( Sys_CheckParm( "-oldfont" ))
{ {
success = Con_LoadVariableWidthFont( "gfx/conchars.fnt", font, scale, kRenderTransTexture, TF_FONT|TF_NEAREST ); success = Con_LoadVariableWidthFont( "gfx/conchars.fnt", font, scale, &con_fontrender, TF_FONT|TF_NEAREST );
} }
else else
{ {
@@ -559,14 +561,14 @@ static void Con_LoadConsoleFont( int fontNumber, cl_font_t *font )
if( Q_snprintf( path, sizeof( path ), if( Q_snprintf( path, sizeof( path ),
"font%i_%s.fnt", fontNumber, Cvar_VariableString( "con_charset" )) > 0 ) "font%i_%s.fnt", fontNumber, Cvar_VariableString( "con_charset" )) > 0 )
{ {
success = Con_LoadVariableWidthFont( path, font, scale, kRenderTransTexture, TF_FONT|TF_NEAREST ); success = Con_LoadVariableWidthFont( path, font, scale, &con_fontrender, TF_FONT|TF_NEAREST );
} }
} }
if( !success ) if( !success )
{ {
Q_snprintf( path, sizeof( path ), "fonts/font%i", fontNumber ); Q_snprintf( path, sizeof( path ), "fonts/font%i", fontNumber );
success = Con_LoadVariableWidthFont( path, font, scale, kRenderTransTexture, TF_FONT|TF_NEAREST ); success = Con_LoadVariableWidthFont( path, font, scale, &con_fontrender, TF_FONT|TF_NEAREST );
} }
} }
@@ -574,7 +576,7 @@ static void Con_LoadConsoleFont( int fontNumber, cl_font_t *font )
{ {
// quake fixed font as fallback // quake fixed font as fallback
// keep source to print directly into conback image // keep source to print directly into conback image
if( !Con_LoadFixedWidthFont( "gfx/conchars", font, scale, kRenderTransTexture, TF_FONT|TF_KEEP_SOURCE )) if( !Con_LoadFixedWidthFont( "gfx/conchars", font, scale, &con_fontrender, TF_FONT|TF_NEAREST|TF_KEEP_SOURCE ))
Con_DPrintf( S_ERROR "failed to load console font\n" ); Con_DPrintf( S_ERROR "failed to load console font\n" );
} }
} }
@@ -593,8 +595,8 @@ static void Con_LoadConchars( void )
Con_LoadConsoleFont( i, con.chars + i ); Con_LoadConsoleFont( i, con.chars + i );
// select properly fontsize // select properly fontsize
if( con_fontnum->value >= 0 && con_fontnum->value <= CON_NUMFONTS - 1 ) if( con_fontnum.value >= 0 && con_fontnum.value <= CON_NUMFONTS - 1 )
fontSize = con_fontnum->value; fontSize = con_fontnum.value;
else if( refState.width <= 640 ) else if( refState.width <= 640 )
fontSize = 0; fontSize = 0;
else if( refState.width >= 1280 ) else if( refState.width >= 1280 )
@@ -608,19 +610,6 @@ static void Con_LoadConchars( void )
con.curFont = &con.chars[fontSize]; con.curFont = &con.chars[fontSize];
} }
// CP1251 table
int table_cp1251[64] = {
0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021,
0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F,
0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x007F, 0x2122, 0x0459, 0x203A, 0x045A, 0x045C, 0x045B, 0x045F,
0x00A0, 0x040E, 0x045E, 0x0408, 0x00A4, 0x0490, 0x00A6, 0x00A7,
0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x0407,
0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5, 0x00B6, 0x00B7,
0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455, 0x0457
};
/* /*
============================ ============================
Con_UtfProcessChar Con_UtfProcessChar
@@ -630,84 +619,28 @@ Convert utf char to current font's single-byte encoding
*/ */
int Con_UtfProcessCharForce( int in ) int Con_UtfProcessCharForce( int in )
{ {
static int m = -1, k = 0; //multibyte state // TODO: get rid of global state where possible
static int uc = 0; //unicode char static utfstate_t state = { 0 };
if( !in ) int ch = Q_DecodeUTF8( &state, in );
{
m = -1;
k = 0;
uc = 0;
return 0;
}
// Get character length
if(m == -1)
{
uc = 0;
if( in >= 0xF8 )
return 0;
else if( in >= 0xF0 )
uc = in & 0x07, m = 3;
else if( in >= 0xE0 )
uc = in & 0x0F, m = 2;
else if( in >= 0xC0 )
uc = in & 0x1F, m = 1;
else if( in <= 0x7F)
return in; //ascii
// return 0 if we need more chars to decode one
k=0;
return 0;
}
// get more chars
else if( k <= m )
{
uc <<= 6;
uc += in & 0x3F;
k++;
}
if( in > 0xBF || m < 0 )
{
m = -1;
return 0;
}
if( k == m )
{
k = m = -1;
if( g_codepage == 1251 ) if( g_codepage == 1251 )
{ return Q_UnicodeToCP1251( ch );
// cp1251 now if( g_codepage == 1252 )
if( uc >= 0x0410 && uc <= 0x042F ) return Q_UnicodeToCP1252( ch );
return uc - 0x410 + 0xC0;
if( uc >= 0x0430 && uc <= 0x044F )
return uc - 0x430 + 0xE0;
else
{
int i;
for( i = 0; i < 64; i++ )
if( table_cp1251[i] == uc )
return i + 0x80;
}
}
else if( g_codepage == 1252 )
{
if( uc < 255 )
return uc;
}
// not implemented yet return '?'; // not implemented yet
return '?';
}
return 0;
} }
int GAME_EXPORT Con_UtfProcessChar( int in ) int GAME_EXPORT Con_UtfProcessChar( int in )
{ {
if( !g_utf8 ) if( !cls.accept_utf8 ) // incoming character is not a UTF-8 sequence
return in; return in;
else
// otherwise, decode it and convert to selected codepage
return Con_UtfProcessCharForce( in ); return Con_UtfProcessCharForce( in );
} }
/* /*
================= =================
Con_UtfMoveLeft Con_UtfMoveLeft
@@ -717,16 +650,22 @@ get position of previous printful char
*/ */
int Con_UtfMoveLeft( char *str, int pos ) int Con_UtfMoveLeft( char *str, int pos )
{ {
int i, k = 0; utfstate_t state = { 0 };
// int j; int k = 0;
if( !g_utf8 ) int i;
if( !cls.accept_utf8 ) // incoming character is not a UTF-8 sequence
return pos - 1; return pos - 1;
Con_UtfProcessChar( 0 );
if(pos == 1) return 0; if( pos == 1 )
return 0;
for( i = 0; i < pos - 1; i++ ) for( i = 0; i < pos - 1; i++ )
if( Con_UtfProcessChar( (unsigned char)str[i] ) ) {
if( Q_DecodeUTF8( &state, (byte)str[i] ))
k = i + 1; k = i + 1;
Con_UtfProcessChar( 0 ); }
return k; return k;
} }
@@ -739,16 +678,18 @@ get next of previous printful char
*/ */
int Con_UtfMoveRight( char *str, int pos, int length ) int Con_UtfMoveRight( char *str, int pos, int length )
{ {
utfstate_t state = { 0 };
int i; int i;
if( !g_utf8 )
if( !cls.accept_utf8 ) // incoming character is not a UTF-8 sequence
return pos + 1; return pos + 1;
Con_UtfProcessChar( 0 );
for( i = pos; i <= length; i++ ) for( i = pos; i <= length; i++ )
{ {
if( Con_UtfProcessChar( (unsigned char)str[i] ) ) if( Q_DecodeUTF8( &state, (byte)str[i] ))
return i + 1; return i + 1;
} }
Con_UtfProcessChar( 0 );
return pos + 1; return pos + 1;
} }
@@ -808,7 +749,7 @@ compute string width and height in screen pixels
*/ */
void GAME_EXPORT Con_DrawStringLen( const char *pText, int *length, int *height ) void GAME_EXPORT Con_DrawStringLen( const char *pText, int *length, int *height )
{ {
return CL_DrawStringLen( con.curFont, pText, length, height, FONT_DRAW_UTF8 ); CL_DrawStringLen( con.curFont, pText, length, height, FONT_DRAW_UTF8 );
} }
/* /*
@@ -830,19 +771,20 @@ Con_Init
*/ */
void Con_Init( void ) void Con_Init( void )
{ {
int i;
if( host.type == HOST_DEDICATED ) if( host.type == HOST_DEDICATED )
return; // dedicated server already have console return; // dedicated server already have console
// must be init before startup video subsystem // must be init before startup video subsystem
scr_conspeed = Cvar_Get( "scr_conspeed", "600", FCVAR_ARCHIVE, "console moving speed" ); Cvar_RegisterVariable( &scr_conspeed );
con_notifytime = Cvar_Get( "con_notifytime", "3", FCVAR_ARCHIVE, "notify time to live" ); Cvar_RegisterVariable( &con_notifytime );
con_fontsize = Cvar_Get( "con_fontsize", "1", FCVAR_ARCHIVE, "console font number (0, 1 or 2)" ); Cvar_RegisterVariable( &con_fontsize );
con_charset = Cvar_Get( "con_charset", "cp1251", FCVAR_ARCHIVE, "console font charset (only cp1251 supported now)" ); Cvar_RegisterVariable( &con_charset );
con_fontscale = Cvar_Get( "con_fontscale", "1.0", FCVAR_ARCHIVE, "scale font texture" ); Cvar_RegisterVariable( &con_fontscale );
con_fontnum = Cvar_Get( "con_fontnum", "-1", FCVAR_ARCHIVE, "console font number (0, 1 or 2), -1 for autoselect" ); Cvar_RegisterVariable( &con_fontrender );
con_color = Cvar_Get( "con_color", "240 180 24", FCVAR_ARCHIVE, "set a custom console color" ); Cvar_RegisterVariable( &con_fontnum );
Cvar_RegisterVariable( &con_color );
Cvar_RegisterVariable( &scr_drawversion );
Cvar_RegisterVariable( &con_oldfont );
// init the console buffer // init the console buffer
con.bufsize = CON_TEXTSIZE; con.bufsize = CON_TEXTSIZE;
@@ -1120,9 +1062,9 @@ EDIT FIELDS
Con_ClearField Con_ClearField
================ ================
*/ */
void Con_ClearField( field_t *edit ) static void Con_ClearField( field_t *edit )
{ {
memset( edit->buffer, 0, MAX_STRING ); memset( edit->buffer, 0, sizeof( edit->buffer ));
edit->cursor = 0; edit->cursor = 0;
edit->scroll = 0; edit->scroll = 0;
} }
@@ -1135,7 +1077,7 @@ Field_Set
static void Field_Set( field_t *f, const char *string ) static void Field_Set( field_t *f, const char *string )
{ {
f->scroll = 0; f->scroll = 0;
f->cursor = Q_strncpy( f->buffer, string, MAX_STRING ); f->cursor = Q_strncpy( f->buffer, string, sizeof( f->buffer ));
} }
/* /*
@@ -1143,7 +1085,7 @@ static void Field_Set( field_t *f, const char *string )
Field_Paste Field_Paste
================ ================
*/ */
void Field_Paste( field_t *edit ) static void Field_Paste( field_t *edit )
{ {
char *cbd; char *cbd;
int i, pasteLen; int i, pasteLen;
@@ -1179,7 +1121,7 @@ in-game talk, and menu fields
Key events are used for non-printable characters, others are gotten from char events. Key events are used for non-printable characters, others are gotten from char events.
================= =================
*/ */
void Field_KeyDownEvent( field_t *edit, int key ) static void Field_KeyDownEvent( field_t *edit, int key )
{ {
int len; int len;
@@ -1250,7 +1192,7 @@ void Field_KeyDownEvent( field_t *edit, int key )
Field_CharEvent Field_CharEvent
================== ==================
*/ */
void Field_CharEvent( field_t *edit, int ch ) static void Field_CharEvent( field_t *edit, int ch )
{ {
int len; int len;
@@ -1311,7 +1253,7 @@ void Field_CharEvent( field_t *edit, int ch )
Field_DrawInputLine Field_DrawInputLine
================== ==================
*/ */
void Field_DrawInputLine( int x, int y, field_t *edit ) static void Field_DrawInputLine( int x, int y, field_t *edit )
{ {
int len, cursorChar; int len, cursorChar;
int drawLen; int drawLen;
@@ -1441,36 +1383,49 @@ static void Con_HistoryAppend( con_history_t *self, field_t *from )
static void Con_LoadHistory( con_history_t *self ) static void Con_LoadHistory( con_history_t *self )
{ {
const byte *aFile = FS_LoadFile( "console_history.txt", NULL, true );
const char *pLine, *pFile;
int i, len;
field_t *f; field_t *f;
file_t *fd;
int i;
if( !aFile ) fd = FS_Open( "console_history.txt", "rb", true );
if( !fd )
return; return;
for( pFile = pLine = (char *)aFile; *pFile; pFile++ ) while( !FS_Eof( fd ))
{ {
if( *pFile != '\n' ) f = &self->lines[self->next % CON_HISTORY];
Con_ClearField( f );
f->widthInChars = con.linewidth;
FS_Gets( fd, f->buffer, sizeof( f->buffer ));
f->cursor = Q_strlen( f->buffer );
// skip empty lines
if( f->cursor == 0 )
continue; continue;
Con_ClearField( &self->lines[self->next] ); // skip repeating lines
if( self->next > 0 )
len = Q_min( pFile - pLine + 1, sizeof( f->buffer )); {
f = &self->lines[self->next % CON_HISTORY]; field_t *prev;
f->widthInChars = con.linewidth; prev = &self->lines[(self->next - 1) % CON_HISTORY];
f->cursor = len - 1; if( !Q_stricmp( prev->buffer, f->buffer ))
Q_strncpy( f->buffer, pLine, len); continue;
}
self->next++; self->next++;
pLine = pFile + 1;
} }
FS_Close( fd );
for( i = self->next; i < CON_HISTORY; i++ ) for( i = self->next; i < CON_HISTORY; i++ )
{ {
Con_ClearField( &self->lines[i] ); f = &self->lines[i];
self->lines[i].widthInChars = con.linewidth;
Con_ClearField( f );
f->widthInChars = con.linewidth;
} }
self->line = self->next; self->line = self->next;
@@ -1488,7 +1443,7 @@ static void Con_SaveHistory( con_history_t *self )
if( historyStart < 0 ) if( historyStart < 0 )
historyStart = 0; historyStart = 0;
f = FS_Open( "console_history.txt", "w", true ); f = FS_Open( "console_history.txt", "wb", true );
for( i = historyStart; i < self->next; i++ ) for( i = historyStart; i < self->next; i++ )
FS_Printf( f, "%s\n", self->lines[i % CON_HISTORY].buffer ); FS_Printf( f, "%s\n", self->lines[i % CON_HISTORY].buffer );
@@ -1533,6 +1488,9 @@ void Key_Console( int key )
Con_Printf( ">%s\n", con.input.buffer ); Con_Printf( ">%s\n", con.input.buffer );
// copy line to history buffer // copy line to history buffer
// just in case, remove all CR and LF characters pushing it to the history
// not sure how they get even added in the first place
COM_RemoveLineFeed( con.input.buffer, sizeof( con.input.buffer ));
Con_HistoryAppend( &con.history, &con.input ); Con_HistoryAppend( &con.history, &con.input );
Con_ClearField( &con.input ); Con_ClearField( &con.input );
@@ -1683,7 +1641,7 @@ Con_DrawInput
The input line scrolls horizontally if typing goes beyond the right edge The input line scrolls horizontally if typing goes beyond the right edge
================ ================
*/ */
void Con_DrawInput( int lines ) static void Con_DrawInput( int lines )
{ {
int y; int y;
@@ -1703,7 +1661,7 @@ Con_DrawDebugLines
Custom debug messages Custom debug messages
================ ================
*/ */
int Con_DrawDebugLines( void ) static int Con_DrawDebugLines( void )
{ {
notify_t *notify = con.notify; notify_t *notify = con.notify;
int i, count = 0; int i, count = 0;
@@ -1754,11 +1712,15 @@ void Con_DrawDebug( void )
string dlstring; string dlstring;
int x, y; 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", 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 ); host.downloadcount, host.downloadfile, scr_download.value, Sys_DoubleTime() - timeStart );
x = refState.width - 500;
Con_DrawStringLen( dlstring, &length, NULL );
length = Q_max( length, 500 );
x = refState.width - length * 1.05f;
y = con.curFont->charHeight * 1.05f; y = con.curFont->charHeight * 1.05f;
Con_DrawString( x, y, dlstring, g_color_table[7] ); Con_DrawString( x, y, dlstring, g_color_table[7] );
} }
@@ -1784,7 +1746,7 @@ Con_DrawNotify
Draws the last few lines of output transparently over the game top Draws the last few lines of output transparently over the game top
================ ================
*/ */
void Con_DrawNotify( void ) static void Con_DrawNotify( void )
{ {
double time = cl.time; double time = cl.time;
int i, x, y = 0; int i, x, y = 0;
@@ -1799,7 +1761,7 @@ void Con_DrawNotify( void )
{ {
con_lineinfo_t *l = &CON_LINES( i ); con_lineinfo_t *l = &CON_LINES( i );
if( l->addtime < ( time - con_notifytime->value )) if( l->addtime < ( time - con_notifytime.value ))
continue; continue;
Con_DrawString( x, y, l->start, g_color_table[7] ); Con_DrawString( x, y, l->start, g_color_table[7] );
@@ -1836,7 +1798,7 @@ If alpha is 0, the line is not drawn, but still wrapped and its height
returned. returned.
================ ================
*/ */
int Con_DrawConsoleLine( int y, int lineno ) static int Con_DrawConsoleLine( int y, int lineno )
{ {
con_lineinfo_t *li = &CON_LINES( lineno ); con_lineinfo_t *li = &CON_LINES( lineno );
@@ -1891,7 +1853,7 @@ Con_DrawConsole
Draws the console with the solid background Draws the console with the solid background
================ ================
*/ */
void Con_DrawSolidConsole( int lines ) static void Con_DrawSolidConsole( int lines )
{ {
int i, x, y; int i, x, y;
float fraction; float fraction;
@@ -1981,7 +1943,7 @@ void Con_DrawConsole( void )
if( cls.state == ca_connecting || cls.state == ca_connected ) 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 ) if(( Cvar_VariableInteger( "cl_background" ) || Cvar_VariableInteger( "sv_background" )) && cls.key_dest != key_console )
con.vislines = con.showlines = 0; con.vislines = con.showlines = 0;
@@ -1991,7 +1953,7 @@ void Con_DrawConsole( void )
{ {
con.showlines = 0; con.showlines = 0;
if( host_developer.value >= DEV_EXTENDED ) if( host_developer.value >= DEV_EXTENDED && !cls.timedemo )
Con_DrawNotify(); // draw notify lines Con_DrawNotify(); // draw notify lines
} }
} }
@@ -2023,7 +1985,7 @@ void Con_DrawConsole( void )
{ {
if( con.vislines ) if( con.vislines )
Con_DrawSolidConsole( 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 Con_DrawNotify(); // draw notify lines
} }
break; break;
@@ -2045,29 +2007,30 @@ void Con_DrawVersion( void )
byte *color = g_color_table[7]; byte *color = g_color_table[7];
int stringLen, charH = 0; int stringLen, charH = 0;
int start, height = refState.height; int start, height = refState.height;
qboolean draw_version = false;
string curbuild; string curbuild;
switch( cls.scrshot_action ) if( !scr_drawversion.value || CL_IsDevOverviewMode() == 2 || net_graph.value )
{
case scrshot_normal:
case scrshot_snapshot:
draw_version = true;
break;
}
if( !host.force_draw_version )
{
if(( cls.key_dest != key_menu && !draw_version ) || CL_IsDevOverviewMode() == 2 || net_graph->value )
return; return;
if( cls.key_dest == key_menu )
{
Q_snprintf( curbuild, sizeof( curbuild ),
"v%i/" XASH_VERSION " (%s-%s build %i)", PROTOCOL_VERSION, Q_buildos(), Q_buildarch(), Q_buildnum( ));
} }
else
{
qboolean draw_version;
if( host.force_draw_version_time > host.realtime ) draw_version = cls.scrshot_action == scrshot_normal
host.force_draw_version = false; || cls.scrshot_action == scrshot_snapshot
|| host.force_draw_version_time > host.realtime;
if( host.force_draw_version || draw_version ) 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( )); return;
else Q_snprintf( curbuild, MAX_STRING, "v%i/" XASH_VERSION " (%s-%s build %i)", PROTOCOL_VERSION, Q_buildos(), Q_buildarch(), Q_buildnum( ));
Q_snprintf( curbuild, sizeof( curbuild ),
XASH_ENGINE_NAME " v%i/" XASH_VERSION " (%s-%s build %i)", PROTOCOL_VERSION, Q_buildos(), Q_buildarch(), Q_buildnum( ));
}
Con_DrawStringLen( curbuild, &stringLen, &charH ); Con_DrawStringLen( curbuild, &stringLen, &charH );
start = refState.width - stringLen * 1.05f; start = refState.width - stringLen * 1.05f;
@@ -2092,13 +2055,17 @@ void Con_RunConsole( void )
// decide on the destination height of the console // decide on the destination height of the console
if( host.allow_console && cls.key_dest == key_console ) if( host.allow_console && cls.key_dest == key_console )
{ {
#if XASH_MOBILE_PLATFORM
con.showlines = refState.height; // always full screen on mobile devices
#else
if( cls.state < ca_active || cl.first_frame ) if( cls.state < ca_active || cl.first_frame )
con.showlines = refState.height; // full screen con.showlines = refState.height; // full screen
else con.showlines = (refState.height >> 1); // half screen else con.showlines = (refState.height >> 1); // half screen
#endif
} }
else con.showlines = 0; // none visible 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 ) if( con.showlines < con.vislines )
{ {
@@ -2113,35 +2080,33 @@ void Con_RunConsole( void )
con.vislines = con.showlines; con.vislines = con.showlines;
} }
if( FBitSet( con_charset->flags, FCVAR_CHANGED ) || if( FBitSet( con_charset.flags|con_fontscale.flags|con_fontnum.flags|cl_charset.flags|con_oldfont.flags, FCVAR_CHANGED ))
FBitSet( con_fontscale->flags, FCVAR_CHANGED ) ||
FBitSet( con_fontnum->flags, FCVAR_CHANGED ) ||
FBitSet( cl_charset->flags, FCVAR_CHANGED ))
{ {
// update codepage parameters // update codepage parameters
if( !Q_stricmp( con_charset->string, "cp1251" )) if( !Q_stricmp( con_charset.string, "cp1251" ))
{ {
g_codepage = 1251; g_codepage = 1251;
} }
else if( !Q_stricmp( con_charset->string, "cp1252" )) else if( !Q_stricmp( con_charset.string, "cp1252" ))
{ {
g_codepage = 1252; g_codepage = 1252;
} }
else 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_codepage = 1252;
} }
g_utf8 = !Q_stricmp( cl_charset->string, "utf-8" ); cls.accept_utf8 = !Q_stricmp( cl_charset.string, "utf-8" );
Con_InvalidateFonts(); Con_InvalidateFonts();
Con_LoadConchars(); Con_LoadConchars();
ClearBits( con_charset->flags, FCVAR_CHANGED ); ClearBits( con_charset.flags, FCVAR_CHANGED );
ClearBits( con_fontnum->flags, FCVAR_CHANGED ); ClearBits( con_fontnum.flags, FCVAR_CHANGED );
ClearBits( con_fontscale->flags, FCVAR_CHANGED ); ClearBits( con_fontscale.flags, FCVAR_CHANGED );
ClearBits( cl_charset->flags, FCVAR_CHANGED ); ClearBits( cl_charset.flags, FCVAR_CHANGED );
ClearBits( con_oldfont.flags, FCVAR_CHANGED );
} }
} }
@@ -2181,12 +2146,17 @@ INTERNAL RESOURCE
*/ */
void Con_VidInit( void ) void Con_VidInit( void )
{ {
const uint flags = TF_IMAGE|TF_ALLOW_NEAREST;
if( !con.historyLoaded ) if( !con.historyLoaded )
{ {
Con_LoadHistory( &con.history ); Con_LoadHistory( &con.history );
con.historyLoaded = true; con.historyLoaded = true;
} }
if( Sys_CheckParm( "-oldfont" ))
Cvar_DirectSet( &con_oldfont, "1" );
Con_LoadConchars(); Con_LoadConchars();
Con_CheckResize(); Con_CheckResize();
#if XASH_LOW_MEMORY #if XASH_LOW_MEMORY
@@ -2197,28 +2167,28 @@ void Con_VidInit( void )
{ {
// trying to load truecolor image first // trying to load truecolor image first
if( FS_FileExists( "gfx/shell/conback.bmp", false ) || FS_FileExists( "gfx/shell/conback.tga", false )) if( FS_FileExists( "gfx/shell/conback.bmp", false ) || FS_FileExists( "gfx/shell/conback.tga", false ))
con.background = ref.dllFuncs.GL_LoadTexture( "gfx/shell/conback", NULL, 0, TF_IMAGE ); con.background = ref.dllFuncs.GL_LoadTexture( "gfx/shell/conback", NULL, 0, flags );
if( !con.background ) if( !con.background )
{ {
if( FS_FileExists( "cached/conback640", false )) if( FS_FileExists( "cached/conback640", false ))
con.background = ref.dllFuncs.GL_LoadTexture( "cached/conback640", NULL, 0, TF_IMAGE ); con.background = ref.dllFuncs.GL_LoadTexture( "cached/conback640", NULL, 0, flags );
else if( FS_FileExists( "cached/conback", false )) else if( FS_FileExists( "cached/conback", false ))
con.background = ref.dllFuncs.GL_LoadTexture( "cached/conback", NULL, 0, TF_IMAGE ); con.background = ref.dllFuncs.GL_LoadTexture( "cached/conback", NULL, 0, flags );
} }
} }
else else
{ {
// trying to load truecolor image first // trying to load truecolor image first
if( FS_FileExists( "gfx/shell/loading.bmp", false ) || FS_FileExists( "gfx/shell/loading.tga", false )) if( FS_FileExists( "gfx/shell/loading.bmp", false ) || FS_FileExists( "gfx/shell/loading.tga", false ))
con.background = ref.dllFuncs.GL_LoadTexture( "gfx/shell/loading", NULL, 0, TF_IMAGE ); con.background = ref.dllFuncs.GL_LoadTexture( "gfx/shell/loading", NULL, 0, flags );
if( !con.background ) if( !con.background )
{ {
if( FS_FileExists( "cached/loading640", false )) if( FS_FileExists( "cached/loading640", false ))
con.background = ref.dllFuncs.GL_LoadTexture( "cached/loading640", NULL, 0, TF_IMAGE ); con.background = ref.dllFuncs.GL_LoadTexture( "cached/loading640", NULL, 0, flags );
else if( FS_FileExists( "cached/loading", false )) else if( FS_FileExists( "cached/loading", false ))
con.background = ref.dllFuncs.GL_LoadTexture( "cached/loading", NULL, 0, TF_IMAGE ); con.background = ref.dllFuncs.GL_LoadTexture( "cached/loading", NULL, 0, flags );
} }
} }
@@ -2304,11 +2274,20 @@ Con_DefaultColor
called from MainUI called from MainUI
========= =========
*/ */
void GAME_EXPORT Con_DefaultColor( int r, int g, int b ) void Con_DefaultColor( int r, int g, int b, qboolean gameui )
{ {
r = bound( 0, r, 255 ); r = bound( 0, r, 255 );
g = bound( 0, g, 255 ); g = bound( 0, g, 255 );
b = bound( 0, b, 255 ); b = bound( 0, b, 255 );
// gameui wants to override console color... check if it's not default
if( gameui && ( g_color_table[7][0] != r || g_color_table[7][1] != g || g_color_table[7][2] != b ))
{
// yes, different from default orange, disable con_color
SetBits( con_color.flags, FCVAR_READ_ONLY );
ClearBits( con_color.flags, FCVAR_CHANGED );
}
MakeRGBA( g_color_table[7], r, g, b, 255 ); MakeRGBA( g_color_table[7], r, g, b, 255 );
} }

438
engine/client/gamma.c Normal file
View File

@@ -0,0 +1,438 @@
/*
gamma.c - gamma routines
Copyright (C) 2011 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 "xash3d_mathlib.h"
#include "enginefeatures.h"
//-----------------------------------------------------------------------------
// Gamma conversion support
//-----------------------------------------------------------------------------
static qboolean gamma_rebuilt;
static byte texgammatable[256];
static uint lightgammatable[1024];
static uint lineargammatable[1024];
static uint screengammatable[1024];
static CVAR_DEFINE( v_direct, "direct", "0.9", 0, "direct studio lighting" );
static CVAR_DEFINE( v_texgamma, "texgamma", "2.0", 0, "texgamma amount" );
static CVAR_DEFINE( v_lightgamma, "lightgamma", "2.5", 0, "lightgamma amount" );
static CVAR_DEFINE( v_brightness, "brightness", "0.0", FCVAR_ARCHIVE, "brightness factor" );
static CVAR_DEFINE( v_gamma, "gamma", "2.5", FCVAR_ARCHIVE, "gamma amount" );
static void BuildGammaTable( const float gamma, const float brightness, const float texgamma, const float lightgamma )
{
float g1, g2, g3;
int i;
if( gamma != 0.0 )
g1 = 1.0 / gamma;
else g1 = 0.4;
g2 = g1 * texgamma;
if( brightness <= 0.0 )
g3 = 0.125;
else if( brightness <= 1.0 )
g3 = 0.125 - brightness * brightness * 0.075;
else
g3 = 0.05;
for( i = 0; i < 256; i++ )
{
double d = pow( i / 255.0, (double)g2 );
int inf = d * 255.0;
texgammatable[i] = bound( 0, inf, 255 );
}
for( i = 0; i < 1024; i++ )
{
double d;
float f = pow( i / 1023.0, (double)lightgamma );
int inf;
if( brightness > 1.0 )
f *= brightness;
if( f <= g3 )
f = ( f / g3 ) * 0.125;
else
f = (( f - g3 ) / ( 1.0 - g3 )) * 0.875 + 0.125;
d = pow( (double)f, (double)g1 ); // do not remove the cast, or tests fail
inf = d * 1023.0;
lightgammatable[i] = bound( 0, inf, 1023 );
// do these calculations in the same loop...
lineargammatable[i] = pow( i / 1023.0, (double)gamma ) * 1023.0;
screengammatable[i] = pow( i / 1023.0, 1.0 / gamma ) * 1023.0;
}
}
static void V_ValidateGammaCvars( void )
{
if( v_gamma.value < 1.8f )
Cvar_DirectSet( &v_gamma, "1.8" );
else if( v_gamma.value > 3.0f )
Cvar_DirectSet( &v_gamma, "3" );
if( v_texgamma.value < 1.8f )
Cvar_DirectSet( &v_texgamma, "1.8" );
else if( v_texgamma.value > 3.0f )
Cvar_DirectSet( &v_texgamma, "3" );
if( v_lightgamma.value < 1.8f )
Cvar_DirectSet( &v_lightgamma, "1.8" );
else if( v_lightgamma.value > 3.0f )
Cvar_DirectSet( &v_lightgamma, "3" );
if( v_brightness.value < 0.0f )
Cvar_DirectSet( &v_brightness, "0" );
else if( v_brightness.value > 3.0f )
Cvar_DirectSet( &v_brightness, "3" );
}
void V_CheckGamma( void )
{
static qboolean dirty = false;
// because these cvars were defined as archive
// but wasn't doing anything useful
// reset them into default values
// this might be removed after a while
if( v_direct.value == 1.0f || v_lightgamma.value == 1.0f )
{
Cvar_DirectSet( &v_direct, "0.9" );
Cvar_DirectSet( &v_lightgamma, "2.5" );
}
if( cls.scrshot_action == scrshot_envshot || cls.scrshot_action == scrshot_skyshot )
{
dirty = true; // force recalculate next normal frame
BuildGammaTable( 1.8f, 0.0f, 2.0f, 2.5f );
if( ref.initialized )
ref.dllFuncs.R_GammaChanged( true );
return;
}
if( dirty || FBitSet( v_texgamma.flags|v_lightgamma.flags|v_brightness.flags|v_gamma.flags, FCVAR_CHANGED ))
{
V_ValidateGammaCvars();
dirty = false;
gamma_rebuilt = true;
BuildGammaTable( v_gamma.value, v_brightness.value, v_texgamma.value, v_lightgamma.value );
// force refdll to recalculate lightmaps
if( ref.initialized )
ref.dllFuncs.R_GammaChanged( false );
}
}
void V_CheckGammaEnd( void )
{
// don't reset changed flag if it was set during frame
// keep it for next frame
if( !gamma_rebuilt )
return;
gamma_rebuilt = false;
// keep the flags until the end of frame so client.dll will catch these changes
if( FBitSet( v_texgamma.flags|v_lightgamma.flags|v_brightness.flags|v_gamma.flags, FCVAR_CHANGED ))
{
ClearBits( v_texgamma.flags, FCVAR_CHANGED );
ClearBits( v_lightgamma.flags, FCVAR_CHANGED );
ClearBits( v_brightness.flags, FCVAR_CHANGED );
ClearBits( v_gamma.flags, FCVAR_CHANGED );
}
}
void V_Init( void )
{
Cvar_RegisterVariable( &v_texgamma );
Cvar_RegisterVariable( &v_lightgamma );
Cvar_RegisterVariable( &v_brightness );
Cvar_RegisterVariable( &v_gamma );
Cvar_RegisterVariable( &v_direct );
// force gamma init
SetBits( v_gamma.flags, FCVAR_CHANGED );
V_CheckGamma();
}
byte TextureToGamma( byte b )
{
if( FBitSet( host.features, ENGINE_LINEAR_GAMMA_SPACE ))
return b;
return texgammatable[b];
}
byte LightToTexGamma( byte b )
{
if( FBitSet( host.features, ENGINE_LINEAR_GAMMA_SPACE ))
return b;
// 255 << 2 is 1020, impossible to overflow
return lightgammatable[b << 2] >> 2;
}
uint LightToTexGammaEx( uint b )
{
if( FBitSet( host.features, ENGINE_LINEAR_GAMMA_SPACE ))
return b;
if( unlikely( b > ARRAYSIZE( lightgammatable )))
return 0;
return lightgammatable[b];
}
uint ScreenGammaTable( uint b )
{
if( FBitSet( host.features, ENGINE_LINEAR_GAMMA_SPACE ))
return b;
if( unlikely( b > ARRAYSIZE( screengammatable )))
return 0;
return screengammatable[b];
}
uint LinearGammaTable( uint b )
{
if( FBitSet( host.features, ENGINE_LINEAR_GAMMA_SPACE ))
return b;
if( unlikely( b > ARRAYSIZE( lineargammatable )))
return 0;
return lineargammatable[b];
}
#if XASH_ENGINE_TESTS
#include "tests.h"
typedef struct precomputed_gamma_tables_s
{
float gamma;
float brightness;
float texgamma;
float lightgamma;
byte texgammatable[256];
int lightgammatable[1024];
int lineargammatable[1024];
int screengammatable[1024];
} precomputed_gamma_tables_t;
// put at the end of the file, to not confuse Qt Creator's parser
precomputed_gamma_tables_t *Test_GetGammaTables( int i );
static void Test_PrecomputedGammaTables( void )
{
precomputed_gamma_tables_t *data;
int i = 0;
while(( data = Test_GetGammaTables( i )))
{
int j;
BuildGammaTable( data->gamma, data->brightness, data->texgamma, data->lightgamma );
for( j = 0; j < 1024; j++ )
{
if( j < 256 )
{
TASSERT_EQi( texgammatable[j], data->texgammatable[j] );
}
TASSERT_EQi( lightgammatable[j], data->lightgammatable[j] );
TASSERT_EQi( lineargammatable[j], data->lineargammatable[j] );
TASSERT_EQi( screengammatable[j], data->screengammatable[j] );
}
i++;
}
}
void Test_RunGamma( void )
{
TRUN( Test_PrecomputedGammaTables() );
}
precomputed_gamma_tables_t *Test_GetGammaTables( int i )
{
static precomputed_gamma_tables_t precomputed_data[] = {
{
.gamma = 2.5,
.brightness = 0.0,
.texgamma = 2.0,
.lightgamma = 2.5,
.texgammatable = {
0, 3, 5, 7, 9, 10, 12, 14, 15, 17, 19, 20, 22, 23, 25, 26, 27, 29, 30, 31, 33, 34, 35, 37, 38, 39, 41, 42, 43, 44, 46, 47, 48, 49, 50, 52, 53, 54, 55, 56, 57, 59, 60, 61, 62, 63, 64, 65, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 79, 80, 81, 82, 83, 84,
85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 132, 133, 134, 135, 136, 137, 138,
139, 140, 141, 142, 143, 144, 145, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 165, 166, 167, 168, 169, 170, 171, 172, 172, 173, 174, 175, 176, 177, 178, 179, 180, 180, 181, 182, 183, 184, 185,
186, 186, 187, 188, 189, 190, 191, 192, 192, 193, 194, 195, 196, 197, 198, 198, 199, 200, 201, 202, 203, 204, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 214, 214, 215, 216, 217, 218, 219, 219, 220, 221, 222, 223, 224, 224, 225, 226, 227, 228, 229,
229, 230, 231, 232, 233, 233, 234, 235, 236, 237, 238, 238, 239, 240, 241, 242, 242, 243, 244, 245, 246, 246, 247, 248, 249, 250, 250, 251, 252, 253, 254, 255
},
.lightgammatable = {
0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123,
124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227,
228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279,
280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331,
332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 343, 343, 344, 345, 346, 347, 348, 349, 350, 351, 353, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 376, 376, 377, 379, 379, 380, 381, 382, 383,
384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435,
436, 437, 438, 439, 440, 441, 442, 443, 444, 446, 446, 447, 449, 449, 450, 451, 452, 453, 455, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 468, 469, 470, 470, 472, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487,
488, 489, 490, 491, 493, 493, 494, 495, 496, 498, 498, 499, 500, 502, 502, 503, 504, 505, 507, 508, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 520, 521, 521, 522, 523, 524, 525, 526, 527, 528, 530, 530, 531, 532, 533, 534, 536, 536, 537, 538, 539,
540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 552, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 564, 564, 565, 566, 567, 568, 570, 571, 571, 572, 573, 574, 576, 576, 577, 578, 579, 580, 581, 583, 583, 584, 585, 586, 587, 588, 590, 591, 591,
593, 593, 594, 596, 596, 597, 598, 600, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 611, 611, 612, 613, 615, 615, 616, 618, 618, 620, 621, 621, 622, 624, 625, 626, 627, 627, 628, 629, 630, 632, 633, 633, 634, 635, 636, 638, 638, 639, 641, 642, 643, 643,
644, 645, 646, 648, 648, 650, 651, 651, 652, 654, 655, 656, 656, 658, 658, 660, 660, 662, 662, 664, 664, 665, 666, 668, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 682, 682, 683, 684, 685, 686, 687, 688, 690, 690, 691, 692, 693, 695, 696,
696, 697, 698, 699, 700, 701, 702, 703, 705, 706, 706, 707, 708, 709, 710, 711, 712, 713, 715, 716, 716, 717, 718, 719, 721, 721, 722, 724, 724, 725, 727, 727, 728, 729, 730, 731, 733, 733, 734, 735, 736, 737, 738, 740, 740, 741, 743, 744, 744, 745, 747, 747,
748, 749, 750, 752, 753, 753, 755, 755, 757, 757, 758, 759, 760, 761, 762, 764, 764, 766, 766, 767, 769, 770, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 782, 783, 784, 784, 785, 786, 788, 789, 790, 791, 792, 792, 794, 794, 796, 796, 797, 799, 800,
801, 801, 802, 803, 804, 805, 806, 807, 809, 810, 810, 811, 813, 813, 815, 815, 816, 817, 819, 819, 820, 822, 823, 823, 824, 825, 826, 827, 829, 829, 830, 832, 832, 833, 835, 835, 837, 837, 839, 840, 840, 841, 842, 843, 844, 845, 847, 847, 849, 849, 850, 851,
852, 854, 854, 856, 856, 857, 859, 859, 860, 861, 862, 864, 864, 865, 867, 867, 868, 870, 870, 872, 872, 874, 875, 875, 876, 877, 879, 880, 881, 881, 882, 883, 885, 885, 886, 887, 888, 890, 891, 891, 893, 893, 894, 895, 897, 898, 899, 900, 901, 902, 902, 903,
904, 905, 907, 907, 908, 910, 910, 911, 912, 914, 914, 915, 917, 918, 919, 920, 921, 922, 922, 923, 925, 925, 926, 927, 928, 930, 931, 932, 932, 933, 935, 936, 936, 937, 939, 940, 940, 942, 942, 944, 944, 946, 947, 948, 949, 949, 950, 952, 952, 953, 955, 956,
957, 958, 959, 959, 960, 962, 962, 964, 965, 965, 967, 967, 969, 970, 971, 972, 973, 973, 975, 975, 976, 977, 978, 979, 980, 982, 982, 984, 984, 986, 986, 988, 988, 990, 991, 992, 993, 993, 994, 995, 996, 998, 999, 999, 1000, 1002, 1002, 1004, 1005, 1005,
1006, 1007, 1008, 1010, 1011, 1011, 1013, 1014, 1015, 1016, 1017, 1018, 1018, 1019, 1020, 1021, 1023
},
.lineargammatable = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 11, 11,
11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, 24, 24, 24, 25, 25,
25, 25, 26, 26, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 31, 31, 31, 32, 32, 32, 32, 33, 33, 33, 34, 34, 34, 35, 35, 35, 36, 36, 36, 37, 37, 37, 38, 38, 39, 39, 39, 40, 40, 40, 41, 41, 41, 42, 42, 43, 43, 43, 44, 44, 44, 45, 45, 46, 46, 46,
47, 47, 48, 48, 48, 49, 49, 50, 50, 50, 51, 51, 52, 52, 52, 53, 53, 54, 54, 55, 55, 55, 56, 56, 57, 57, 58, 58, 59, 59, 60, 60, 60, 61, 61, 62, 62, 63, 63, 64, 64, 65, 65, 66, 66, 67, 67, 68, 68, 69, 69, 70, 70, 71, 71, 72, 72, 73, 73, 74, 74, 75, 75, 76, 76,
77, 77, 78, 78, 79, 79, 80, 81, 81, 82, 82, 83, 83, 84, 84, 85, 86, 86, 87, 87, 88, 88, 89, 90, 90, 91, 91, 92, 92, 93, 94, 94, 95, 95, 96, 97, 97, 98, 99, 99, 100, 100, 101, 102, 102, 103, 104, 104, 105, 105, 106, 107, 107, 108, 109, 109, 110, 111, 111, 112,
113, 113, 114, 115, 115, 116, 117, 117, 118, 119, 119, 120, 121, 122, 122, 123, 124, 124, 125, 126, 126, 127, 128, 129, 129, 130, 131, 132, 132, 133, 134, 134, 135, 136, 137, 137, 138, 139, 140, 140, 141, 142, 143, 144, 144, 145, 146, 147, 147, 148, 149, 150,
151, 151, 152, 153, 154, 155, 155, 156, 157, 158, 159, 159, 160, 161, 162, 163, 164, 164, 165, 166, 167, 168, 169, 169, 170, 171, 172, 173, 174, 175, 176, 176, 177, 178, 179, 180, 181, 182, 183, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 193, 194,
195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246,
247, 248, 249, 250, 251, 252, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 265, 266, 267, 268, 269, 270, 271, 272, 274, 275, 276, 277, 278, 279, 280, 282, 283, 284, 285, 286, 287, 289, 290, 291, 292, 293, 294, 296, 297, 298, 299, 300, 302, 303, 304, 305,
306, 308, 309, 310, 311, 312, 314, 315, 316, 317, 319, 320, 321, 322, 324, 325, 326, 327, 329, 330, 331, 333, 334, 335, 336, 338, 339, 340, 342, 343, 344, 345, 347, 348, 349, 351, 352, 353, 355, 356, 357, 359, 360, 361, 363, 364, 365, 367, 368, 369, 371, 372,
373, 375, 376, 378, 379, 380, 382, 383, 384, 386, 387, 389, 390, 391, 393, 394, 396, 397, 399, 400, 401, 403, 404, 406, 407, 409, 410, 411, 413, 414, 416, 417, 419, 420, 422, 423, 425, 426, 428, 429, 431, 432, 434, 435, 437, 438, 440, 441, 443, 444, 446, 447,
449, 450, 452, 453, 455, 456, 458, 459, 461, 462, 464, 466, 467, 469, 470, 472, 473, 475, 477, 478, 480, 481, 483, 485, 486, 488, 489, 491, 493, 494, 496, 497, 499, 501, 502, 504, 506, 507, 509, 511, 512, 514, 515, 517, 519, 520, 522, 524, 525, 527, 529, 531,
532, 534, 536, 537, 539, 541, 542, 544, 546, 548, 549, 551, 553, 554, 556, 558, 560, 561, 563, 565, 567, 568, 570, 572, 574, 575, 577, 579, 581, 583, 584, 586, 588, 590, 592, 593, 595, 597, 599, 601, 602, 604, 606, 608, 610, 612, 613, 615, 617, 619, 621, 623,
625, 626, 628, 630, 632, 634, 636, 638, 639, 641, 643, 645, 647, 649, 651, 653, 655, 657, 659, 660, 662, 664, 666, 668, 670, 672, 674, 676, 678, 680, 682, 684, 686, 688, 690, 692, 694, 696, 698, 700, 702, 704, 706, 708, 710, 712, 714, 716, 718, 720, 722, 724,
726, 728, 730, 732, 734, 736, 738, 740, 742, 744, 746, 748, 750, 753, 755, 757, 759, 761, 763, 765, 767, 769, 771, 773, 776, 778, 780, 782, 784, 786, 788, 791, 793, 795, 797, 799, 801, 803, 806, 808, 810, 812, 814, 816, 819, 821, 823, 825, 827, 830, 832, 834,
836, 839, 841, 843, 845, 847, 850, 852, 854, 856, 859, 861, 863, 865, 868, 870, 872, 874, 877, 879, 881, 884, 886, 888, 890, 893, 895, 897, 900, 902, 904, 907, 909, 911, 914, 916, 918, 921, 923, 925, 928, 930, 932, 935, 937, 940, 942, 944, 947, 949, 952, 954,
956, 959, 961, 964, 966, 968, 971, 973, 976, 978, 981, 983, 985, 988, 990, 993, 995, 998, 1000, 1003, 1005, 1008, 1010, 1013, 1015, 1018, 1020, 1023
},
.screengammatable = {
0, 63, 84, 99, 111, 121, 130, 139, 146, 154, 160, 166, 172, 178, 183, 188, 193, 198, 203, 207, 212, 216, 220, 224, 228, 231, 235, 239, 242, 245, 249, 252, 255, 259, 262, 265, 268, 271, 274, 276, 279, 282, 285, 287, 290, 293, 295, 298, 300, 303, 305, 308,
310, 313, 315, 317, 320, 322, 324, 326, 328, 331, 333, 335, 337, 339, 341, 343, 345, 347, 349, 351, 353, 355, 357, 359, 361, 363, 365, 367, 369, 370, 372, 374, 376, 378, 379, 381, 383, 385, 386, 388, 390, 392, 393, 395, 397, 398, 400, 401, 403, 405, 406, 408,
409, 411, 413, 414, 416, 417, 419, 420, 422, 423, 425, 426, 428, 429, 431, 432, 434, 435, 436, 438, 439, 441, 442, 444, 445, 446, 448, 449, 450, 452, 453, 455, 456, 457, 459, 460, 461, 463, 464, 465, 466, 468, 469, 470, 472, 473, 474, 475, 477, 478, 479, 480,
482, 483, 484, 485, 487, 488, 489, 490, 491, 493, 494, 495, 496, 497, 499, 500, 501, 502, 503, 504, 505, 507, 508, 509, 510, 511, 512, 513, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539,
540, 541, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 585, 586, 587, 588, 589, 590,
591, 592, 593, 594, 595, 595, 596, 597, 598, 599, 600, 601, 602, 603, 603, 604, 605, 606, 607, 608, 609, 610, 610, 611, 612, 613, 614, 615, 616, 616, 617, 618, 619, 620, 621, 622, 622, 623, 624, 625, 626, 627, 627, 628, 629, 630, 631, 632, 632, 633, 634, 635,
636, 637, 637, 638, 639, 640, 641, 641, 642, 643, 644, 645, 645, 646, 647, 648, 649, 649, 650, 651, 652, 652, 653, 654, 655, 656, 656, 657, 658, 659, 659, 660, 661, 662, 663, 663, 664, 665, 666, 666, 667, 668, 669, 669, 670, 671, 672, 672, 673, 674, 675, 675,
676, 677, 678, 678, 679, 680, 681, 681, 682, 683, 684, 684, 685, 686, 686, 687, 688, 689, 689, 690, 691, 692, 692, 693, 694, 694, 695, 696, 697, 697, 698, 699, 699, 700, 701, 701, 702, 703, 704, 704, 705, 706, 706, 707, 708, 708, 709, 710, 711, 711, 712, 713,
713, 714, 715, 715, 716, 717, 717, 718, 719, 719, 720, 721, 721, 722, 723, 723, 724, 725, 725, 726, 727, 727, 728, 729, 729, 730, 731, 731, 732, 733, 733, 734, 735, 735, 736, 737, 737, 738, 739, 739, 740, 741, 741, 742, 743, 743, 744, 745, 745, 746, 746, 747,
748, 748, 749, 750, 750, 751, 752, 752, 753, 753, 754, 755, 755, 756, 757, 757, 758, 758, 759, 760, 760, 761, 762, 762, 763, 763, 764, 765, 765, 766, 767, 767, 768, 768, 769, 770, 770, 771, 771, 772, 773, 773, 774, 774, 775, 776, 776, 777, 778, 778, 779, 779,
780, 781, 781, 782, 782, 783, 784, 784, 785, 785, 786, 786, 787, 788, 788, 789, 789, 790, 791, 791, 792, 792, 793, 794, 794, 795, 795, 796, 796, 797, 798, 798, 799, 799, 800, 801, 801, 802, 802, 803, 803, 804, 805, 805, 806, 806, 807, 807, 808, 809, 809, 810,
810, 811, 811, 812, 813, 813, 814, 814, 815, 815, 816, 816, 817, 818, 818, 819, 819, 820, 820, 821, 821, 822, 823, 823, 824, 824, 825, 825, 826, 826, 827, 828, 828, 829, 829, 830, 830, 831, 831, 832, 832, 833, 834, 834, 835, 835, 836, 836, 837, 837, 838, 838,
839, 839, 840, 841, 841, 842, 842, 843, 843, 844, 844, 845, 845, 846, 846, 847, 848, 848, 849, 849, 850, 850, 851, 851, 852, 852, 853, 853, 854, 854, 855, 855, 856, 856, 857, 857, 858, 859, 859, 860, 860, 861, 861, 862, 862, 863, 863, 864, 864, 865, 865, 866,
866, 867, 867, 868, 868, 869, 869, 870, 870, 871, 871, 872, 872, 873, 873, 874, 874, 875, 875, 876, 876, 877, 877, 878, 878, 879, 879, 880, 880, 881, 881, 882, 882, 883, 883, 884, 884, 885, 885, 886, 886, 887, 887, 888, 888, 889, 889, 890, 890, 891, 891, 892,
892, 893, 893, 894, 894, 895, 895, 896, 896, 897, 897, 898, 898, 899, 899, 900, 900, 901, 901, 902, 902, 903, 903, 904, 904, 904, 905, 905, 906, 906, 907, 907, 908, 908, 909, 909, 910, 910, 911, 911, 912, 912, 913, 913, 914, 914, 915, 915, 915, 916, 916, 917,
917, 918, 918, 919, 919, 920, 920, 921, 921, 922, 922, 922, 923, 923, 924, 924, 925, 925, 926, 926, 927, 927, 928, 928, 929, 929, 929, 930, 930, 931, 931, 932, 932, 933, 933, 934, 934, 935, 935, 935, 936, 936, 937, 937, 938, 938, 939, 939, 940, 940, 940, 941,
941, 942, 942, 943, 943, 944, 944, 944, 945, 945, 946, 946, 947, 947, 948, 948, 949, 949, 949, 950, 950, 951, 951, 952, 952, 953, 953, 953, 954, 954, 955, 955, 956, 956, 957, 957, 957, 958, 958, 959, 959, 960, 960, 961, 961, 961, 962, 962, 963, 963, 964, 964,
964, 965, 965, 966, 966, 967, 967, 968, 968, 968, 969, 969, 970, 970, 971, 971, 971, 972, 972, 973, 973, 974, 974, 974, 975, 975, 976, 976, 977, 977, 977, 978, 978, 979, 979, 980, 980, 980, 981, 981, 982, 982, 983, 983, 983, 984, 984, 985, 985, 986, 986, 986,
987, 987, 988, 988, 988, 989, 989, 990, 990, 991, 991, 991, 992, 992, 993, 993, 993, 994, 994, 995, 995, 996, 996, 996, 997, 997, 998, 998, 998, 999, 999, 1000, 1000, 1001, 1001, 1001, 1002, 1002, 1003, 1003, 1003, 1004, 1004, 1005, 1005, 1005, 1006, 1006,
1007, 1007, 1008, 1008, 1008, 1009, 1009, 1010, 1010, 1010, 1011, 1011, 1012, 1012, 1012, 1013, 1013, 1014, 1014, 1014, 1015, 1015, 1016, 1016, 1016, 1017, 1017, 1018, 1018, 1018, 1019, 1019, 1020, 1020, 1020, 1021, 1021, 1022, 1022, 1023
},
}, {
.gamma = 2.2,
.brightness = 1.0,
.texgamma = 2.2,
.lightgamma = 2.4,
.texgammatable = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123,
124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227,
228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
},
.lightgammatable = {
0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31, 33, 34, 35, 36, 37, 39, 40, 41, 42, 43, 45, 46, 47, 48, 50, 51, 52, 53, 55, 56, 57, 58, 60, 61, 62, 63, 65, 66, 67, 69, 70, 71, 72, 74, 75, 76,
78, 79, 80, 81, 83, 84, 85, 87, 88, 89, 91, 92, 93, 94, 96, 97, 98, 100, 101, 102, 104, 105, 106, 108, 109, 110, 112, 113, 114, 116, 117, 118, 120, 121, 122, 124, 125, 126, 128, 129, 130, 132, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 147, 148, 149,
151, 152, 153, 155, 156, 157, 159, 160, 162, 163, 164, 166, 167, 168, 170, 171, 173, 174, 175, 177, 178, 179, 181, 182, 184, 185, 186, 188, 189, 191, 192, 193, 195, 196, 198, 199, 200, 202, 203, 204, 206, 207, 209, 210, 211, 213, 214, 216, 217, 219, 220, 221,
223, 224, 226, 227, 228, 230, 231, 233, 234, 235, 237, 238, 240, 241, 243, 244, 245, 247, 248, 250, 251, 252, 254, 255, 257, 258, 260, 261, 262, 264, 265, 267, 268, 270, 271, 272, 274, 275, 277, 278, 280, 281, 282, 284, 285, 287, 288, 290, 291, 293, 294, 295,
297, 298, 300, 301, 303, 304, 306, 307, 308, 310, 311, 313, 314, 316, 317, 319, 320, 321, 323, 324, 326, 327, 329, 330, 332, 333, 335, 336, 337, 339, 340, 342, 343, 345, 346, 348, 349, 351, 352, 354, 355, 356, 358, 359, 361, 362, 364, 365, 367, 368, 370, 371,
373, 374, 376, 377, 378, 380, 381, 383, 384, 386, 387, 389, 390, 392, 393, 395, 396, 397, 398, 398, 399, 399, 400, 401, 401, 402, 402, 403, 403, 404, 404, 405, 406, 406, 407, 407, 408, 408, 409, 410, 410, 411, 411, 412, 413, 413, 414, 414, 415, 416, 416, 417,
417, 418, 419, 419, 420, 420, 421, 422, 422, 423, 423, 424, 425, 425, 426, 427, 427, 428, 428, 429, 430, 430, 431, 432, 432, 433, 433, 434, 435, 435, 436, 437, 437, 438, 439, 439, 440, 441, 441, 442, 443, 443, 444, 445, 445, 446, 447, 447, 448, 449, 449, 450,
451, 451, 452, 453, 453, 454, 455, 455, 456, 457, 457, 458, 459, 459, 460, 461, 461, 462, 463, 464, 464, 465, 466, 466, 467, 468, 468, 469, 470, 471, 471, 472, 473, 473, 474, 475, 476, 476, 477, 478, 478, 479, 480, 481, 481, 482, 483, 483, 484, 485, 486, 486,
487, 488, 489, 489, 490, 491, 492, 492, 493, 494, 495, 495, 496, 497, 498, 498, 499, 500, 501, 501, 502, 503, 504, 504, 505, 506, 507, 507, 508, 509, 510, 510, 511, 512, 513, 513, 514, 515, 516, 517, 517, 518, 519, 520, 520, 521, 522, 523, 524, 524, 525, 526,
527, 527, 528, 529, 530, 531, 531, 532, 533, 534, 535, 535, 536, 537, 538, 538, 539, 540, 541, 542, 542, 543, 544, 545, 546, 546, 547, 548, 549, 550, 550, 551, 552, 553, 554, 555, 555, 556, 557, 558, 559, 559, 560, 561, 562, 563, 564, 564, 565, 566, 567, 568,
568, 569, 570, 571, 572, 573, 573, 574, 575, 576, 577, 578, 578, 579, 580, 581, 582, 583, 583, 584, 585, 586, 587, 588, 588, 589, 590, 591, 592, 593, 593, 594, 595, 596, 597, 598, 599, 599, 600, 601, 602, 603, 604, 605, 605, 606, 607, 608, 609, 610, 611, 611,
612, 613, 614, 615, 616, 617, 617, 618, 619, 620, 621, 622, 623, 623, 624, 625, 626, 627, 628, 629, 629, 630, 631, 632, 633, 634, 635, 636, 636, 637, 638, 639, 640, 641, 642, 643, 643, 644, 645, 646, 647, 648, 649, 650, 651, 651, 652, 653, 654, 655, 656, 657,
658, 658, 659, 660, 661, 662, 663, 664, 665, 666, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 703,
704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 749, 750, 751,
752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 795, 796, 797, 798, 799, 800,
801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850,
851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 900,
901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952,
953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002,
1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1023
},
.lineargammatable = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4,
4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17,
17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 24, 24, 24, 24, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 30, 30, 30, 31, 31, 31, 32, 32, 32, 33, 33, 33, 34, 34, 34, 35, 35, 35, 36,
36, 36, 37, 37, 38, 38, 38, 39, 39, 39, 40, 40, 40, 41, 41, 42, 42, 42, 43, 43, 44, 44, 44, 45, 45, 46, 46, 46, 47, 47, 48, 48, 48, 49, 49, 50, 50, 51, 51, 51, 52, 52, 53, 53, 54, 54, 55, 55, 55, 56, 56, 57, 57, 58, 58, 59, 59, 60, 60, 61, 61, 61, 62, 62, 63,
63, 64, 64, 65, 65, 66, 66, 67, 67, 68, 68, 69, 69, 70, 70, 71, 71, 72, 72, 73, 73, 74, 75, 75, 76, 76, 77, 77, 78, 78, 79, 79, 80, 80, 81, 82, 82, 83, 83, 84, 84, 85, 86, 86, 87, 87, 88, 88, 89, 90, 90, 91, 91, 92, 93, 93, 94, 94, 95, 96, 96, 97, 97, 98, 99,
99, 100, 100, 101, 102, 102, 103, 104, 104, 105, 105, 106, 107, 107, 108, 109, 109, 110, 111, 111, 112, 113, 113, 114, 115, 115, 116, 117, 117, 118, 119, 119, 120, 121, 121, 122, 123, 123, 124, 125, 126, 126, 127, 128, 128, 129, 130, 131, 131, 132, 133, 133,
134, 135, 136, 136, 137, 138, 139, 139, 140, 141, 142, 142, 143, 144, 145, 145, 146, 147, 148, 148, 149, 150, 151, 151, 152, 153, 154, 155, 155, 156, 157, 158, 159, 159, 160, 161, 162, 163, 163, 164, 165, 166, 167, 167, 168, 169, 170, 171, 172, 172, 173, 174,
175, 176, 177, 177, 178, 179, 180, 181, 182, 183, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 193, 194, 195, 196, 197, 198, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221,
222, 223, 224, 225, 226, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273,
274, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 288, 289, 290, 291, 292, 293, 294, 295, 296, 298, 299, 300, 301, 302, 303, 304, 305, 307, 308, 309, 310, 311, 312, 313, 315, 316, 317, 318, 319, 320, 322, 323, 324, 325, 326, 328, 329, 330, 331, 332,
333, 335, 336, 337, 338, 339, 341, 342, 343, 344, 346, 347, 348, 349, 350, 352, 353, 354, 355, 357, 358, 359, 360, 362, 363, 364, 365, 367, 368, 369, 370, 372, 373, 374, 375, 377, 378, 379, 381, 382, 383, 384, 386, 387, 388, 390, 391, 392, 393, 395, 396, 397,
399, 400, 401, 403, 404, 405, 407, 408, 409, 411, 412, 413, 415, 416, 417, 419, 420, 421, 423, 424, 426, 427, 428, 430, 431, 432, 434, 435, 437, 438, 439, 441, 442, 443, 445, 446, 448, 449, 450, 452, 453, 455, 456, 458, 459, 460, 462, 463, 465, 466, 468, 469,
470, 472, 473, 475, 476, 478, 479, 481, 482, 483, 485, 486, 488, 489, 491, 492, 494, 495, 497, 498, 500, 501, 503, 504, 506, 507, 509, 510, 512, 513, 515, 516, 518, 519, 521, 522, 524, 525, 527, 528, 530, 532, 533, 535, 536, 538, 539, 541, 542, 544, 545, 547,
549, 550, 552, 553, 555, 556, 558, 560, 561, 563, 564, 566, 568, 569, 571, 572, 574, 576, 577, 579, 580, 582, 584, 585, 587, 589, 590, 592, 593, 595, 597, 598, 600, 602, 603, 605, 607, 608, 610, 612, 613, 615, 617, 618, 620, 622, 623, 625, 627, 628, 630, 632,
633, 635, 637, 639, 640, 642, 644, 645, 647, 649, 650, 652, 654, 656, 657, 659, 661, 663, 664, 666, 668, 670, 671, 673, 675, 677, 678, 680, 682, 684, 685, 687, 689, 691, 692, 694, 696, 698, 700, 701, 703, 705, 707, 709, 710, 712, 714, 716, 718, 719, 721, 723,
725, 727, 729, 730, 732, 734, 736, 738, 740, 741, 743, 745, 747, 749, 751, 753, 754, 756, 758, 760, 762, 764, 766, 767, 769, 771, 773, 775, 777, 779, 781, 783, 785, 786, 788, 790, 792, 794, 796, 798, 800, 802, 804, 806, 808, 809, 811, 813, 815, 817, 819, 821,
823, 825, 827, 829, 831, 833, 835, 837, 839, 841, 843, 845, 847, 849, 851, 853, 855, 857, 859, 861, 863, 865, 867, 869, 871, 873, 875, 877, 879, 881, 883, 885, 887, 889, 891, 893, 895, 897, 899, 901, 903, 905, 907, 910, 912, 914, 916, 918, 920, 922, 924, 926,
928, 930, 932, 934, 937, 939, 941, 943, 945, 947, 949, 951, 953, 956, 958, 960, 962, 964, 966, 968, 970, 973, 975, 977, 979, 981, 983, 985, 988, 990, 992, 994, 996, 998, 1001, 1003, 1005, 1007, 1009, 1012, 1014, 1016, 1018, 1020, 1023
},
.screengammatable = {
0, 43, 60, 72, 82, 91, 98, 106, 112, 118, 124, 130, 135, 140, 145, 150, 154, 158, 163, 167, 171, 174, 178, 182, 185, 189, 192, 196, 199, 202, 205, 208, 211, 214, 217, 220, 223, 226, 228, 231, 234, 237, 239, 242, 244, 247, 249, 252, 254, 257, 259, 261,
264, 266, 268, 270, 273, 275, 277, 279, 281, 283, 286, 288, 290, 292, 294, 296, 298, 300, 302, 304, 306, 308, 310, 311, 313, 315, 317, 319, 321, 323, 324, 326, 328, 330, 331, 333, 335, 337, 338, 340, 342, 343, 345, 347, 348, 350, 352, 353, 355, 357, 358, 360,
361, 363, 365, 366, 368, 369, 371, 372, 374, 375, 377, 378, 380, 381, 383, 384, 386, 387, 389, 390, 392, 393, 394, 396, 397, 399, 400, 401, 403, 404, 406, 407, 408, 410, 411, 412, 414, 415, 416, 418, 419, 420, 422, 423, 424, 426, 427, 428, 430, 431, 432, 433,
435, 436, 437, 438, 440, 441, 442, 443, 445, 446, 447, 448, 450, 451, 452, 453, 454, 456, 457, 458, 459, 460, 462, 463, 464, 465, 466, 467, 469, 470, 471, 472, 473, 474, 475, 477, 478, 479, 480, 481, 482, 483, 484, 486, 487, 488, 489, 490, 491, 492, 493, 494,
495, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 545, 546, 547,
548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 583, 584, 585, 586, 587, 588, 589, 590, 591, 591, 592, 593, 594, 595,
596, 597, 598, 598, 599, 600, 601, 602, 603, 604, 604, 605, 606, 607, 608, 609, 609, 610, 611, 612, 613, 614, 615, 615, 616, 617, 618, 619, 620, 620, 621, 622, 623, 624, 624, 625, 626, 627, 628, 629, 629, 630, 631, 632, 633, 633, 634, 635, 636, 637, 637, 638,
639, 640, 641, 641, 642, 643, 644, 645, 645, 646, 647, 648, 649, 649, 650, 651, 652, 652, 653, 654, 655, 656, 656, 657, 658, 659, 659, 660, 661, 662, 663, 663, 664, 665, 666, 666, 667, 668, 669, 669, 670, 671, 672, 672, 673, 674, 675, 675, 676, 677, 678, 678,
679, 680, 681, 681, 682, 683, 684, 684, 685, 686, 686, 687, 688, 689, 689, 690, 691, 692, 692, 693, 694, 694, 695, 696, 697, 697, 698, 699, 700, 700, 701, 702, 702, 703, 704, 705, 705, 706, 707, 707, 708, 709, 709, 710, 711, 712, 712, 713, 714, 714, 715, 716,
716, 717, 718, 719, 719, 720, 721, 721, 722, 723, 723, 724, 725, 725, 726, 727, 728, 728, 729, 730, 730, 731, 732, 732, 733, 734, 734, 735, 736, 736, 737, 738, 738, 739, 740, 740, 741, 742, 742, 743, 744, 744, 745, 746, 746, 747, 748, 748, 749, 750, 750, 751,
752, 752, 753, 754, 754, 755, 756, 756, 757, 758, 758, 759, 759, 760, 761, 761, 762, 763, 763, 764, 765, 765, 766, 767, 767, 768, 769, 769, 770, 770, 771, 772, 772, 773, 774, 774, 775, 776, 776, 777, 777, 778, 779, 779, 780, 781, 781, 782, 782, 783, 784, 784,
785, 786, 786, 787, 787, 788, 789, 789, 790, 791, 791, 792, 792, 793, 794, 794, 795, 795, 796, 797, 797, 798, 799, 799, 800, 800, 801, 802, 802, 803, 803, 804, 805, 805, 806, 806, 807, 808, 808, 809, 809, 810, 811, 811, 812, 812, 813, 814, 814, 815, 815, 816,
817, 817, 818, 818, 819, 820, 820, 821, 821, 822, 823, 823, 824, 824, 825, 825, 826, 827, 827, 828, 828, 829, 830, 830, 831, 831, 832, 833, 833, 834, 834, 835, 835, 836, 837, 837, 838, 838, 839, 839, 840, 841, 841, 842, 842, 843, 843, 844, 845, 845, 846, 846,
847, 847, 848, 849, 849, 850, 850, 851, 851, 852, 853, 853, 854, 854, 855, 855, 856, 857, 857, 858, 858, 859, 859, 860, 860, 861, 862, 862, 863, 863, 864, 864, 865, 865, 866, 867, 867, 868, 868, 869, 869, 870, 870, 871, 872, 872, 873, 873, 874, 874, 875, 875,
876, 876, 877, 878, 878, 879, 879, 880, 880, 881, 881, 882, 882, 883, 884, 884, 885, 885, 886, 886, 887, 887, 888, 888, 889, 889, 890, 891, 891, 892, 892, 893, 893, 894, 894, 895, 895, 896, 896, 897, 898, 898, 899, 899, 900, 900, 901, 901, 902, 902, 903, 903,
904, 904, 905, 905, 906, 906, 907, 908, 908, 909, 909, 910, 910, 911, 911, 912, 912, 913, 913, 914, 914, 915, 915, 916, 916, 917, 917, 918, 918, 919, 920, 920, 921, 921, 922, 922, 923, 923, 924, 924, 925, 925, 926, 926, 927, 927, 928, 928, 929, 929, 930, 930,
931, 931, 932, 932, 933, 933, 934, 934, 935, 935, 936, 936, 937, 937, 938, 938, 939, 939, 940, 940, 941, 941, 942, 942, 943, 943, 944, 944, 945, 945, 946, 946, 947, 947, 948, 948, 949, 949, 950, 950, 951, 951, 952, 952, 953, 953, 954, 954, 955, 955, 956, 956,
957, 957, 958, 958, 959, 959, 960, 960, 961, 961, 962, 962, 963, 963, 964, 964, 965, 965, 966, 966, 967, 967, 968, 968, 969, 969, 969, 970, 970, 971, 971, 972, 972, 973, 973, 974, 974, 975, 975, 976, 976, 977, 977, 978, 978, 979, 979, 980, 980, 981, 981, 982,
982, 982, 983, 983, 984, 984, 985, 985, 986, 986, 987, 987, 988, 988, 989, 989, 990, 990, 991, 991, 991, 992, 992, 993, 993, 994, 994, 995, 995, 996, 996, 997, 997, 998, 998, 999, 999, 999, 1000, 1000, 1001, 1001, 1002, 1002, 1003, 1003, 1004, 1004, 1005,
1005, 1006, 1006, 1006, 1007, 1007, 1008, 1008, 1009, 1009, 1010, 1010, 1011, 1011, 1012, 1012, 1012, 1013, 1013, 1014, 1014, 1015, 1015, 1016, 1016, 1017, 1017, 1017, 1018, 1018, 1019, 1019, 1020, 1020, 1021, 1021, 1022, 1022, 1023
},
}
};
if( i < 0 || i >= ARRAYSIZE( precomputed_data ))
return NULL;
return &precomputed_data[i];
}
#endif

View File

@@ -45,22 +45,24 @@ static struct joy_axis_s
} joyaxis[MAX_AXES] = { 0 }; } joyaxis[MAX_AXES] = { 0 };
static byte currentbinding; // add posibility to remap keys, to place it in joykeys[] static byte currentbinding; // add posibility to remap keys, to place it in joykeys[]
static qboolean joy_initialized; static qboolean joy_initialized;
convar_t *joy_enable;
static convar_t *joy_pitch; static CVAR_DEFINE_AUTO( joy_pitch, "100.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "joystick pitch sensitivity" );
static convar_t *joy_yaw; static CVAR_DEFINE_AUTO( joy_yaw, "100.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "joystick yaw sensitivity" );
static convar_t *joy_forward; static CVAR_DEFINE_AUTO( joy_side, "1.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "joystick side sensitivity. Values from -1.0 to 1.0" );
static convar_t *joy_side; static CVAR_DEFINE_AUTO( joy_forward, "1.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "joystick forward sensitivity. Values from -1.0 to 1.0" );
static convar_t *joy_found; static CVAR_DEFINE_AUTO( joy_lt_threshold, "16384", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "left trigger threshold. Value from 0 to 32767");
static convar_t *joy_index; static CVAR_DEFINE_AUTO( joy_rt_threshold, "16384", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "right trigger threshold. Value from 0 to 32767" );
static convar_t *joy_lt_threshold; 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 convar_t *joy_rt_threshold; 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 convar_t *joy_side_deadzone; static CVAR_DEFINE_AUTO( joy_side_deadzone, DEFAULT_JOY_DEADZONE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "side axis deadzone. Value from 0 to 32767" );
static convar_t *joy_forward_deadzone; static CVAR_DEFINE_AUTO( joy_forward_deadzone, DEFAULT_JOY_DEADZONE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "forward axis deadzone. Value from 0 to 32767");
static convar_t *joy_side_key_threshold; static CVAR_DEFINE_AUTO( joy_pitch_deadzone, DEFAULT_JOY_DEADZONE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "pitch axis deadzone. Value from 0 to 32767");
static convar_t *joy_forward_key_threshold; static CVAR_DEFINE_AUTO( joy_yaw_deadzone, DEFAULT_JOY_DEADZONE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "yaw axis deadzone. Value from 0 to 32767" );
static convar_t *joy_pitch_deadzone; static CVAR_DEFINE_AUTO( joy_axis_binding, "sfpyrl", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "axis hardware id to engine inner axis binding, "
static convar_t *joy_yaw_deadzone; "s - side, f - forward, y - yaw, p - pitch, r - left trigger, l - right trigger" );
static convar_t *joy_axis_binding; 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" );
/* /*
============ ============
@@ -69,7 +71,7 @@ Joy_IsActive
*/ */
qboolean Joy_IsActive( void ) qboolean Joy_IsActive( void )
{ {
return joy_found->value && joy_enable->value; return joy_found.value && joy_enable.value;
} }
/* /*
@@ -94,7 +96,7 @@ void Joy_HatMotionEvent( byte hat, byte value )
}; };
int i; int i;
if( !joy_found->value ) if( !joy_found.value )
return; return;
for( i = 0; i < ARRAYSIZE( keys ); i++ ) for( i = 0; i < ARRAYSIZE( keys ); i++ )
@@ -125,11 +127,11 @@ static void Joy_ProcessTrigger( const engineAxis_t engineAxis, short value )
{ {
case JOY_AXIS_RT: case JOY_AXIS_RT:
trigButton = K_JOY2; trigButton = K_JOY2;
trigThreshold = joy_rt_threshold->value; trigThreshold = joy_rt_threshold.value;
break; break;
case JOY_AXIS_LT: case JOY_AXIS_LT:
trigButton = K_JOY1; trigButton = K_JOY1;
trigThreshold = joy_lt_threshold->value; trigThreshold = joy_lt_threshold.value;
break; break;
default: default:
Con_Reportf( S_ERROR "Joy_ProcessTrigger: invalid axis = %i", engineAxis ); Con_Reportf( S_ERROR "Joy_ProcessTrigger: invalid axis = %i", engineAxis );
@@ -159,12 +161,12 @@ static int Joy_GetHatValueForAxis( const engineAxis_t engineAxis )
switch( engineAxis ) switch( engineAxis )
{ {
case JOY_AXIS_SIDE: case JOY_AXIS_SIDE:
threshold = joy_side_key_threshold->value; threshold = joy_side_key_threshold.value;
negative = JOY_HAT_LEFT; negative = JOY_HAT_LEFT;
positive = JOY_HAT_RIGHT; positive = JOY_HAT_RIGHT;
break; break;
case JOY_AXIS_FWD: case JOY_AXIS_FWD:
threshold = joy_side_key_threshold->value; threshold = joy_side_key_threshold.value;
negative = JOY_HAT_UP; negative = JOY_HAT_UP;
positive = JOY_HAT_DOWN; positive = JOY_HAT_DOWN;
break; break;
@@ -198,10 +200,10 @@ static void Joy_ProcessStick( const engineAxis_t engineAxis, short value )
switch( engineAxis ) switch( engineAxis )
{ {
case JOY_AXIS_FWD: deadzone = joy_forward_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_SIDE: deadzone = joy_side_deadzone.value; break;
case JOY_AXIS_PITCH: deadzone = joy_pitch_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_YAW: deadzone = joy_yaw_deadzone.value; break;
default: default:
Con_Reportf( S_ERROR "Joy_ProcessStick: invalid axis = %i", engineAxis ); Con_Reportf( S_ERROR "Joy_ProcessStick: invalid axis = %i", engineAxis );
break; break;
@@ -236,7 +238,7 @@ Axis events
*/ */
void Joy_AxisMotionEvent( byte axis, short value ) void Joy_AxisMotionEvent( byte axis, short value )
{ {
if( !joy_found->value ) if( !joy_found.value )
return; return;
if( axis >= MAX_AXES ) if( axis >= MAX_AXES )
@@ -271,7 +273,7 @@ Trackball events. UNDONE
*/ */
void Joy_BallMotionEvent( byte ball, short xrel, short yrel ) void Joy_BallMotionEvent( byte ball, short xrel, short yrel )
{ {
//if( !joy_found->value ) //if( !joy_found.value )
// return; // return;
} }
@@ -284,7 +286,7 @@ Button events
*/ */
void Joy_ButtonEvent( byte button, byte down ) void Joy_ButtonEvent( byte button, byte down )
{ {
if( !joy_found->value ) if( !joy_found.value )
return; return;
// generic game button code. // generic game button code.
@@ -309,7 +311,7 @@ Called when joystick is removed. For future expansion
*/ */
void Joy_RemoveEvent( void ) void Joy_RemoveEvent( void )
{ {
if( joy_found->value ) if( joy_found.value )
Cvar_FullSet( "joy_found", "0", FCVAR_READ_ONLY ); Cvar_FullSet( "joy_found", "0", FCVAR_READ_ONLY );
} }
@@ -322,7 +324,7 @@ Called when joystick is removed. For future expansion
*/ */
void Joy_AddEvent( void ) 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 ); Cvar_FullSet( "joy_found", "1", FCVAR_READ_ONLY );
} }
@@ -338,9 +340,9 @@ void Joy_FinalizeMove( float *fw, float *side, float *dpitch, float *dyaw )
if( !Joy_IsActive() ) if( !Joy_IsActive() )
return; 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; size_t i;
for( i = 0; bind[i]; i++ ) for( i = 0; bind[i]; i++ )
@@ -357,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 *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; *side += joy_side.value * (float)joyaxis[JOY_AXIS_SIDE].val/(float)SHRT_MAX;
#if !defined(XASH_SDL) #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 *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; *dyaw -= joy_yaw.value * (float)joyaxis[JOY_AXIS_YAW ].val/(float)SHRT_MAX * host.realframetime;
#else #else
// HACKHACK: SDL have inverted look axis. // HACKHACK: SDL have inverted look axis.
*dpitch -= joy_pitch->value * (float)joyaxis[JOY_AXIS_PITCH].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; *dyaw += joy_yaw.value * (float)joyaxis[JOY_AXIS_YAW ].val/(float)SHRT_MAX * host.realframetime;
#endif #endif
} }
@@ -381,32 +383,31 @@ Main init procedure
*/ */
void Joy_Init( void ) void Joy_Init( void )
{ {
joy_pitch = Cvar_Get( "joy_pitch", "100.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "joystick pitch sensitivity" ); Cvar_RegisterVariable( &joy_pitch );
joy_yaw = Cvar_Get( "joy_yaw", "100.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "joystick yaw sensitivity" ); Cvar_RegisterVariable( &joy_yaw );
joy_side = Cvar_Get( "joy_side", "1.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "joystick side sensitivity. Values from -1.0 to 1.0" ); Cvar_RegisterVariable( &joy_side );
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_forward );
joy_lt_threshold = Cvar_Get( "joy_lt_threshold", "16384", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "left trigger threshold. Value from 0 to 32767"); Cvar_RegisterVariable( &joy_lt_threshold );
joy_rt_threshold = Cvar_Get( "joy_rt_threshold", "16384", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "right trigger threshold. Value from 0 to 32767" ); Cvar_RegisterVariable( &joy_rt_threshold );
// emit a key event at 75% axis move // 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" ); Cvar_RegisterVariable( &joy_side_key_threshold );
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_forward_key_threshold );
// by default, we rely on deadzone detection come from system, but some glitchy devices report false deadzones // 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", DEFAULT_JOY_DEADZONE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "side axis deadzone. Value from 0 to 32767" ); Cvar_RegisterVariable( &joy_side_deadzone );
joy_forward_deadzone = Cvar_Get( "joy_forward_deadzone", DEFAULT_JOY_DEADZONE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "forward axis deadzone. Value from 0 to 32767"); Cvar_RegisterVariable( &joy_forward_deadzone );
joy_pitch_deadzone = Cvar_Get( "joy_pitch_deadzone", DEFAULT_JOY_DEADZONE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "pitch axis deadzone. Value from 0 to 32767"); Cvar_RegisterVariable( &joy_pitch_deadzone );
joy_yaw_deadzone = Cvar_Get( "joy_yaw_deadzone", DEFAULT_JOY_DEADZONE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "yaw axis deadzone. Value from 0 to 32767" ); 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, " Cvar_RegisterVariable( &joy_axis_binding );
"s - side, f - forward, y - yaw, p - pitch, r - left trigger, l - right trigger" ); Cvar_RegisterVariable( &joy_found );
joy_found = Cvar_Get( "joy_found", "0", FCVAR_READ_ONLY, "is joystick is connected" );
// we doesn't loaded config.cfg yet, so this cvar is not archive. // we doesn't loaded config.cfg yet, so this cvar is not archive.
// change by +set joy_index in cmdline // 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 );
// renamed from -nojoy to -noenginejoy to not conflict with // renamed from -nojoy to -noenginejoy to not conflict with
// client.dll's joystick support // client.dll's joystick support
@@ -416,7 +417,7 @@ void Joy_Init( void )
return; 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; joy_initialized = true;
} }

View File

@@ -132,6 +132,8 @@ static struct touch_s
int whitetexture; int whitetexture;
int joytexture; // touch indicator int joytexture; // touch indicator
qboolean configchanged; 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; } touch;
// private to the engine flags // private to the engine flags
@@ -140,28 +142,27 @@ static struct touch_s
touchdefaultbutton_t g_DefaultButtons[256]; touchdefaultbutton_t g_DefaultButtons[256];
int g_LastDefaultButton; int g_LastDefaultButton;
convar_t *touch_pitch; static CVAR_DEFINE_AUTO( touch_in_menu, "0", FCVAR_FILTERABLE, "draw touch in menu (for internal use only)" );
convar_t *touch_yaw; static CVAR_DEFINE_AUTO( touch_forwardzone, "0.06", FCVAR_FILTERABLE, "forward touch zone" );
convar_t *touch_forwardzone; static CVAR_DEFINE_AUTO( touch_sidezone, "0.06", FCVAR_FILTERABLE, "side touch zone" );
convar_t *touch_sidezone; static CVAR_DEFINE_AUTO( touch_pitch, "90", FCVAR_FILTERABLE, "touch pitch sensitivity" );
convar_t *touch_nonlinear_look; static CVAR_DEFINE_AUTO( touch_yaw, "120", FCVAR_FILTERABLE, "touch yaw sensitivity" );
convar_t *touch_pow_mult; static CVAR_DEFINE_AUTO( touch_nonlinear_look, "0", FCVAR_FILTERABLE, "enable nonlinear touch look" );
convar_t *touch_pow_factor; static CVAR_DEFINE_AUTO( touch_pow_factor, "1.3", FCVAR_FILTERABLE, "set > 1 to enable" );
convar_t *touch_exp_mult; static CVAR_DEFINE_AUTO( touch_pow_mult, "400.0", FCVAR_FILTERABLE, "power multiplier, usually 200-1000" );
convar_t *touch_grid_enable; static CVAR_DEFINE_AUTO( touch_exp_mult, "0", FCVAR_FILTERABLE, "exponent multiplier, usually 20-200, 0 to disable" );
convar_t *touch_grid_count; static CVAR_DEFINE_AUTO( touch_grid_count, "50", FCVAR_FILTERABLE, "touch grid count" );
convar_t *touch_config_file; static CVAR_DEFINE_AUTO( touch_grid_enable, "1", FCVAR_FILTERABLE, "enable touch grid" );
convar_t *touch_in_menu; static CVAR_DEFINE_AUTO( touch_config_file, "touch.cfg", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "current touch profile file" );
convar_t *touch_joy_radius; static CVAR_DEFINE_AUTO( touch_precise_amount, "0.5", FCVAR_FILTERABLE, "sensitivity multiplier for precise-look" );
convar_t *touch_dpad_radius; static CVAR_DEFINE_AUTO( touch_highlight_r, "1.0", 0, "highlight r color" );
convar_t *touch_move_indicator; static CVAR_DEFINE_AUTO( touch_highlight_g, "1.0", 0, "highlight g color" );
convar_t *touch_highlight_r; static CVAR_DEFINE_AUTO( touch_highlight_b, "1.0", 0, "highlight b color" );
convar_t *touch_highlight_g; static CVAR_DEFINE_AUTO( touch_highlight_a, "1.0", 0, "highlight alpha" );
convar_t *touch_highlight_b; static CVAR_DEFINE_AUTO( touch_dpad_radius, "1.0", FCVAR_FILTERABLE, "dpad radius multiplier" );
convar_t *touch_highlight_a; static CVAR_DEFINE_AUTO( touch_joy_radius, "1.0", FCVAR_FILTERABLE, "joy radius multiplier" );
convar_t *touch_precise_amount; static CVAR_DEFINE_AUTO( touch_move_indicator, "0.0", FCVAR_FILTERABLE, "indicate move events (0 to disable)" );
convar_t *touch_joy_texture; 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_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" ); CVAR_DEFINE_AUTO( touch_emulate, "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "emulate touch with mouse" );
@@ -169,13 +170,42 @@ CVAR_DEFINE_AUTO( touch_emulate, "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "emulate
#define B(x) (button->x) #define B(x) (button->x)
#define SCR_W ((float)refState.width) #define SCR_W ((float)refState.width)
#define SCR_H ((float)refState.height) #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)) #define TO_SCRN_X(x) (refState.width * (x))
static void IN_TouchCheckCoords( float *x1, float *y1, float *x2, float *y2 ); static void IN_TouchCheckCoords( float *x1, float *y1, float *x2, float *y2 );
static void IN_TouchEditClear( void ); static void IN_TouchEditClear( void );
static void Touch_InitConfig( 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 Touch_ExportButtonToConfig
@@ -207,7 +237,7 @@ static inline int Touch_ExportButtonToConfig( file_t *f, touch_button_t *button,
if( keepAspect ) 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 ); FS_Printf( f, " %f\n", aspect );
} }
else FS_Printf( f, "\n" ); else FS_Printf( f, "\n" );
@@ -222,7 +252,7 @@ Touch_DumpConfig
Dump config to file Dump config to file
================= =================
*/ */
qboolean Touch_DumpConfig( const char *name, const char *profilename ) static qboolean Touch_DumpConfig( const char *name, const char *profilename )
{ {
file_t *f; file_t *f;
touch_button_t *button; touch_button_t *button;
@@ -242,36 +272,38 @@ qboolean Touch_DumpConfig( const char *name, const char *profilename )
FS_Printf( f, "\ntouch_config_file \"%s\"\n", profilename ); FS_Printf( f, "\ntouch_config_file \"%s\"\n", profilename );
FS_Printf( f, "\n// touch cvars\n" ); FS_Printf( f, "\n// touch cvars\n" );
FS_Printf( f, "\n// sensitivity settings\n" ); FS_Printf( f, "\n// sensitivity settings\n" );
FS_Printf( f, "touch_pitch \"%f\"\n", touch_pitch->value ); FS_Printf( f, "touch_pitch \"%f\"\n", touch_pitch.value );
FS_Printf( f, "touch_yaw \"%f\"\n", touch_yaw->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_forwardzone \"%f\"\n", touch_forwardzone.value );
FS_Printf( f, "touch_sidezone \"%f\"\n", touch_sidezone->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_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_factor \"%f\"\n", touch_pow_factor.value );
FS_Printf( f, "touch_pow_mult \"%f\"\n", touch_pow_mult->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, "touch_exp_mult \"%f\"\n", touch_exp_mult.value );
FS_Printf( f, "\n// grid settings\n" ); 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_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, "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, "\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, "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, "\n// highlight when pressed\n" );
FS_Printf( f, "touch_highlight_r \"%f\"\n", touch_highlight_r->value ); 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_g \"%f\"\n", touch_highlight_g.value );
FS_Printf( f, "touch_highlight_b \"%f\"\n", touch_highlight_b->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, "touch_highlight_a \"%f\"\n", touch_highlight_a.value );
FS_Printf( f, "\n// _joy and _dpad options\n" ); 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_dpad_radius \"%f\"\n", touch_dpad_radius.value );
FS_Printf( f, "touch_joy_radius \"%f\"\n", touch_joy_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, "\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, "touch_precise_amount \"%f\"\n", touch_precise_amount.value );
FS_Printf( f, "\n// enable/disable move indicator\n" ); FS_Printf( f, "\n// enable/disable move indicator\n" );
FS_Printf( f, "touch_move_indicator \"%f\"\n", touch_move_indicator->value ); 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, "\n// reset menu state when execing config\n" );
FS_Printf( f, "touch_setclientonly 0\n" ); FS_Printf( f, "touch_setclientonly 0\n" );
FS_Printf( f, "\n// touch buttons\n" ); FS_Printf( f, "\n// touch buttons\n" );
FS_Printf( f, "touch_removeall\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 ) for( button = touch.list_user.first; button; button = button->next )
{ {
@@ -301,18 +333,18 @@ void Touch_WriteConfig( void )
if( Sys_CheckParm( "-nowriteconfig" ) || !touch.configchanged || !touch.config_loaded ) if( Sys_CheckParm( "-nowriteconfig" ) || !touch.configchanged || !touch.config_loaded )
return; 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( newconfigfile, sizeof( newconfigfile ), "%s.new", touch_config_file.string );
Q_snprintf( oldconfigfile, sizeof( oldconfigfile ), "%s.bak", touch_config_file->string ); Q_snprintf( oldconfigfile, sizeof( oldconfigfile ), "%s.bak", touch_config_file.string );
if( Touch_DumpConfig( newconfigfile, touch_config_file->string )) if( Touch_DumpConfig( newconfigfile, touch_config_file.string ))
{ {
FS_Delete( oldconfigfile ); FS_Delete( oldconfigfile );
FS_Rename( touch_config_file->string, oldconfigfile ); FS_Rename( touch_config_file.string, oldconfigfile );
FS_Delete( touch_config_file->string ); FS_Delete( touch_config_file.string );
FS_Rename( newconfigfile, touch_config_file->string ); FS_Rename( newconfigfile, touch_config_file.string );
} }
} }
@@ -377,7 +409,7 @@ static void Touch_GenerateCode_f( void )
if( FBitSet( flags, TOUCH_FL_DEF_HIDE )) if( FBitSet( flags, TOUCH_FL_DEF_HIDE ))
SetBits( flags, TOUCH_FL_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 ) ) ) 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]) ); Con_Printf( "unsigned char color[] = { %d, %d, %d, %d };\n", B(color[0]), B(color[1]), B(color[2]), B(color[3]) );
@@ -393,7 +425,7 @@ static void Touch_RoundAll_f( void )
{ {
touch_button_t *button; touch_button_t *button;
if( !touch_grid_enable->value ) if( !touch_grid_enable.value )
return; return;
for( button = touch.list_user.first; button; button = button->next ) for( button = touch.list_user.first; button; button = button->next )
@@ -550,6 +582,7 @@ static void Touch_RemoveAll_f( void )
{ {
IN_TouchEditClear(); IN_TouchEditClear();
Touch_ClearList( &touch.list_user ); Touch_ClearList( &touch.list_user );
touch.config_aspect_ratio = 0.0f;
} }
static void Touch_SetColor( touchbuttonlist_t *list, const char *name, byte *color ) static void Touch_SetColor( touchbuttonlist_t *list, const char *name, byte *color )
@@ -727,6 +760,8 @@ static void Touch_SetCommand_f( void )
Con_Printf( S_USAGE "touch_setcommand <name> <command>\n" ); Con_Printf( S_USAGE "touch_setcommand <name> <command>\n" );
} }
static void Touch_LoadDefaults_f( void );
static void Touch_ReloadConfig_f( void ) static void Touch_ReloadConfig_f( void )
{ {
touch.state = state_none; touch.state = state_none;
@@ -736,8 +771,15 @@ static void Touch_ReloadConfig_f( void )
touch.selection->finger = -1; touch.selection->finger = -1;
touch.edit = touch.selection = NULL; touch.edit = touch.selection = NULL;
touch.resize_finger = touch.move_finger = touch.look_finger = touch.wheel_finger = -1; touch.resize_finger = touch.move_finger = touch.look_finger = touch.wheel_finger = -1;
if( FS_FileExists( touch_config_file.string, true ) )
Cbuf_AddTextf( "exec %s\n", touch_config_file->string ); {
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, static touch_button_t *Touch_AddButton( touchbuttonlist_t *list,
@@ -785,7 +827,7 @@ void Touch_AddClientButton( const char *name, const char *texture, const char *c
IN_TouchCheckCoords( &x1, &y1, &x2, &y2 ); IN_TouchCheckCoords( &x1, &y1, &x2, &y2 );
if( round == round_aspect ) 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 = Touch_AddButton( &touch.list_user, name, texture, command, x1, y1, x2, y2, color, true );
button->flags |= flags | TOUCH_FL_CLIENT | TOUCH_FL_NOEDIT; button->flags |= flags | TOUCH_FL_CLIENT | TOUCH_FL_NOEDIT;
@@ -810,7 +852,7 @@ static void Touch_LoadDefaults_f( void )
if( g_DefaultButtons[i].texturefile[0] == '#' ) 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; y2 = y1 + ( (float)clgame.scrInfo.iCharHeight / (float)clgame.scrInfo.iHeight ) * g_DefaultButtons[i].aspect + touch.swidth*2/SCR_H;
else 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 ); IN_TouchCheckCoords( &x1, &y1, &x2, &y2 );
@@ -818,6 +860,7 @@ static void Touch_LoadDefaults_f( void )
button->flags |= g_DefaultButtons[i].flags; button->flags |= g_DefaultButtons[i].flags;
button->aspect = g_DefaultButtons[i].aspect; button->aspect = g_DefaultButtons[i].aspect;
} }
touch.configchanged = true;
} }
// Add default button from client // Add default button from client
@@ -910,7 +953,7 @@ static void Touch_AddButton_f( void )
if( aspect ) if( aspect )
{ {
if( B( texturefile )[0] != '#' ) 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; B( aspect ) = aspect;
} }
} }
@@ -918,11 +961,39 @@ static void Touch_AddButton_f( void )
static void Touch_EnableEdit_f( void ) static void Touch_EnableEdit_f( void )
{ {
touch_button_t *button;
float current_ratio = SCR_H/SCR_W;
if( touch.state == state_none ) if( touch.state == state_none )
touch.state = state_edit; touch.state = state_edit;
touch.resize_finger = touch.move_finger = touch.look_finger = touch.wheel_finger = -1; touch.resize_finger = touch.move_finger = touch.look_finger = touch.wheel_finger = -1;
touch.move_button = NULL; touch.move_button = NULL;
touch.configchanged = true; 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 ) static void Touch_DisableEdit_f( void )
@@ -935,7 +1006,7 @@ static void Touch_DisableEdit_f( void )
touch.edit = touch.selection = NULL; touch.edit = touch.selection = NULL;
touch.resize_finger = touch.move_finger = touch.look_finger = touch.wheel_finger = -1; 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" ); Cvar_Set( "touch_in_menu", "0" );
} }
@@ -957,7 +1028,7 @@ static void Touch_DeleteProfile_f( void )
static void Touch_InitEditor( void ) static void Touch_InitEditor( void )
{ {
float x = 0.1f * (SCR_H/SCR_W); float x = 0.1f * (Touch_AspectRatio());
float y = 0.05f; float y = 0.05f;
touch_button_t *temp; touch_button_t *temp;
rgba_t color; rgba_t color;
@@ -1052,33 +1123,34 @@ void Touch_Init( void )
Cmd_AddRestrictedCommand( "touch_generate_code", Touch_GenerateCode_f, "create code sample for mobility API" ); 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_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_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 // 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 // sensitivity configuration
touch_forwardzone = Cvar_Get( "touch_forwardzone", "0.06", FCVAR_FILTERABLE, "forward touch zone" ); Cvar_RegisterVariable( &touch_forwardzone );
touch_sidezone = Cvar_Get( "touch_sidezone", "0.06", FCVAR_FILTERABLE, "side touch zone" ); Cvar_RegisterVariable( &touch_sidezone );
touch_pitch = Cvar_Get( "touch_pitch", "90", FCVAR_FILTERABLE, "touch pitch sensitivity" ); Cvar_RegisterVariable( &touch_pitch );
touch_yaw = Cvar_Get( "touch_yaw", "120", FCVAR_FILTERABLE, "touch yaw sensitivity" ); Cvar_RegisterVariable( &touch_yaw );
touch_nonlinear_look = Cvar_Get( "touch_nonlinear_look", "0", FCVAR_FILTERABLE, "enable nonlinear touch look" ); Cvar_RegisterVariable( &touch_nonlinear_look );
touch_pow_factor = Cvar_Get( "touch_pow_factor", "1.3", FCVAR_FILTERABLE, "set > 1 to enable" ); Cvar_RegisterVariable( &touch_pow_factor );
touch_pow_mult = Cvar_Get( "touch_pow_mult", "400.0", FCVAR_FILTERABLE, "power multiplier, usually 200-1000" ); Cvar_RegisterVariable( &touch_pow_mult );
touch_exp_mult = Cvar_Get( "touch_exp_mult", "0", FCVAR_FILTERABLE, "exponent multiplier, usually 20-200, 0 to disable" ); Cvar_RegisterVariable( &touch_exp_mult );
// touch.cfg // touch.cfg
touch_grid_count = Cvar_Get( "touch_grid_count", "50", FCVAR_FILTERABLE, "touch grid count" ); Cvar_RegisterVariable( &touch_grid_count );
touch_grid_enable = Cvar_Get( "touch_grid_enable", "1", FCVAR_FILTERABLE, "enable touch grid" ); Cvar_RegisterVariable( &touch_grid_enable );
touch_config_file = Cvar_Get( "touch_config_file", "touch.cfg", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "current touch profile file" ); Cvar_RegisterVariable( &touch_config_file );
touch_precise_amount = Cvar_Get( "touch_precise_amount", "0.5", FCVAR_FILTERABLE, "sensitivity multiplier for precise-look" ); Cvar_RegisterVariable( &touch_precise_amount );
touch_highlight_r = Cvar_Get( "touch_highlight_r", "1.0", 0, "highlight r color" ); Cvar_RegisterVariable( &touch_highlight_r );
touch_highlight_g = Cvar_Get( "touch_highlight_g", "1.0", 0, "highlight g color" ); Cvar_RegisterVariable( &touch_highlight_g );
touch_highlight_b = Cvar_Get( "touch_highlight_b", "1.0", 0, "highlight b color" ); Cvar_RegisterVariable( &touch_highlight_b );
touch_highlight_a = Cvar_Get( "touch_highlight_a", "1.0", 0, "highlight alpha" ); Cvar_RegisterVariable( &touch_highlight_a );
touch_dpad_radius = Cvar_Get( "touch_dpad_radius", "1.0", FCVAR_FILTERABLE, "dpad radius multiplier" ); Cvar_RegisterVariable( &touch_dpad_radius );
touch_joy_radius = Cvar_Get( "touch_joy_radius", "1.0", FCVAR_FILTERABLE, "joy radius multiplier" ); Cvar_RegisterVariable( &touch_joy_radius );
touch_move_indicator = Cvar_Get( "touch_move_indicator", "0.0", FCVAR_FILTERABLE, "indicate move events (0 to disable)" ); Cvar_RegisterVariable( &touch_move_indicator );
touch_joy_texture = Cvar_Get( "touch_joy_texture", "touch_default/joy", FCVAR_FILTERABLE, "texture for move indicator"); Cvar_RegisterVariable( &touch_joy_texture );
// input devices cvar // input devices cvar
Cvar_RegisterVariable( &touch_enable ); Cvar_RegisterVariable( &touch_enable );
@@ -1088,7 +1160,7 @@ void Touch_Init( void )
#if SDL_VERSION_ATLEAST( 2, 0, 10 ) #if SDL_VERSION_ATLEAST( 2, 0, 10 )
SDL_SetHint( SDL_HINT_MOUSE_TOUCH_EVENTS, "0" ); SDL_SetHint( SDL_HINT_MOUSE_TOUCH_EVENTS, "0" );
SDL_SetHint( SDL_HINT_TOUCH_MOUSE_EVENTS, "0" ); SDL_SetHint( SDL_HINT_TOUCH_MOUSE_EVENTS, "0" );
#else #elif defined(SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH)
SDL_SetHint( SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH, "1" ); SDL_SetHint( SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH, "1" );
#endif #endif
@@ -1109,9 +1181,9 @@ static void Touch_InitConfig( void )
/// TODO: hud font /// TODO: hud font
//pfnGetScreenInfo( NULL ); //HACK: update hud screen parameters like iHeight //pfnGetScreenInfo( NULL ); //HACK: update hud screen parameters like iHeight
if( FS_FileExists( touch_config_file->string, true ) ) if( FS_FileExists( touch_config_file.string, true ) )
{ {
Cbuf_AddTextf( "exec \"%s\"\n", touch_config_file->string ); Cbuf_AddTextf( "exec \"%s\"\n", touch_config_file.string );
Cbuf_Execute(); Cbuf_Execute();
} }
else else
@@ -1120,7 +1192,7 @@ static void Touch_InitConfig( void )
} }
Touch_InitEditor(); 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.whitetexture = R_GetBuiltinTexture( REF_WHITE_TEXTURE );
touch.configchanged = false; touch.configchanged = false;
touch.config_loaded = true; touch.config_loaded = true;
@@ -1170,10 +1242,10 @@ static void Touch_DrawTexture ( float x1, float y1, float x2, float y2, int text
0, 0, 1, 1, texture ); 0, 0, 1, 1, texture );
} }
#define GRID_COUNT_X ((int)touch_grid_count->value) #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_Y (((int)touch_grid_count.value) * Touch_AspectRatio())
#define GRID_X (1.0f/GRID_COUNT_X) #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_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) #define GRID_ROUND_Y(x) ((float)round( x * GRID_COUNT_Y ) / GRID_COUNT_Y)
@@ -1192,7 +1264,7 @@ static void IN_TouchCheckCoords( float *x1, float *y1, float *x2, float *y2 )
*y1 -= *y2 - 1, *y2 = 1; *y1 -= *y2 - 1, *y2 = 1;
if( *x2 > 1 ) if( *x2 > 1 )
*x1 -= *x2 - 1, *x2 = 1; *x1 -= *x2 - 1, *x2 = 1;
if( CVAR_TO_BOOL( touch_grid_enable )) if( touch_grid_enable.value )
{ {
*x1 = GRID_ROUND_X( *x1 ); *x1 = GRID_ROUND_X( *x1 );
*x2 = GRID_ROUND_X( *x2 ); *x2 = GRID_ROUND_X( *x2 );
@@ -1251,7 +1323,7 @@ static float Touch_DrawText( float x1, float y1, float x2, float y2, const char
{ {
while( *s && ( *s != '\n' ) && ( *s != ';' ) && ( x1 < maxx ) ) while( *s && ( *s != '\n' ) && ( *s != ';' ) && ( x1 < maxx ) )
x1 += Touch_DrawCharacter( x1, y1, *s++, size ); 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 ) if( y1 >= maxy )
break; break;
@@ -1288,10 +1360,10 @@ static void Touch_DrawButtons( touchbuttonlist_t *list )
if( ( B( finger ) != -1 ) && !FBitSet( B( flags ), TOUCH_FL_CLIENT ) ) if( ( B( finger ) != -1 ) && !FBitSet( B( flags ), TOUCH_FL_CLIENT ) )
{ {
color[0] = bound( 0,(float) color[0] * touch_highlight_r->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[1] = bound( 0,(float) color[1] * touch_highlight_g.value, 255 );
color[2] = bound( 0,(float) color[2] * touch_highlight_b->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] = bound( 0,(float) color[3] * touch_highlight_a.value, 255 );
} }
color[3] *= B( fade ); color[3] *= B( fade );
@@ -1358,17 +1430,18 @@ void Touch_Draw( void )
if( !touch.initialized || ( !touch_enable.value && !touch.clientonly )) if( !touch.initialized || ( !touch_enable.value && !touch.clientonly ))
return; return;
if( cls.key_dest != key_game && !touch_in_menu.value )
return;
Touch_InitConfig(); Touch_InitConfig();
if( cls.key_dest != key_game && !CVAR_TO_BOOL(touch_in_menu) )
return;
ref.dllFuncs.GL_SetRenderMode( kRenderTransTexture ); 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; 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 ); Touch_DrawTexture( 0, 0, 1, 1, touch.whitetexture, 32, 32, 32, 255 );
else else
Touch_DrawTexture( 0, 0, 1, 1, touch.whitetexture, 0, 0, 0, 112 ); Touch_DrawTexture( 0, 0, 1, 1, touch.whitetexture, 0, 0, 0, 112 );
@@ -1429,19 +1502,19 @@ void Touch_Draw( void )
ref.dllFuncs.Color4ub( 255, 255, 255, 255 ); 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 width;
float height; 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 ); ClearBits( touch_joy_texture.flags, FCVAR_CHANGED );
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 );
} }
if( touch.move_button->type == touch_move ) if( touch.move_button->type == touch_move )
{ {
width = touch_sidezone->value; width = touch_sidezone.value;
height = touch_forwardzone->value; height = touch_forwardzone.value;
} }
else else
{ {
@@ -1449,13 +1522,13 @@ void Touch_Draw( void )
height = (touch.move_button->y2 - touch.move_button->y1)/2; height = (touch.move_button->y2 - touch.move_button->y1)/2;
} }
ref.dllFuncs.Color4ub( 255, 255, 255, 128 ); ref.dllFuncs.Color4ub( 255, 255, 255, 128 );
ref.dllFuncs.R_DrawStretchPic( TO_SCRN_X( touch.move_start_x - GRID_X * touch_move_indicator->value ), 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_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 ); 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.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 ), 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_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 ); 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 );
} }
@@ -1564,28 +1637,28 @@ static void Touch_Motion( touchEventType type, int fingerID, float x, float y, f
if( fingerID == touch.move_finger ) if( fingerID == touch.move_finger )
{ {
// check bounds // check bounds
if( touch_forwardzone->value <= 0 ) if( touch_forwardzone.value <= 0 )
Cvar_SetValue( "touch_forwardzone", 0.5 ); Cvar_SetValue( "touch_forwardzone", 0.5 );
if( touch_sidezone->value <= 0 ) if( touch_sidezone.value <= 0 )
Cvar_SetValue( "touch_sidezone", 0.3 ); Cvar_SetValue( "touch_sidezone", 0.3 );
if( !touch.move_button || touch.move_button->type == touch_move ) if( !touch.move_button || touch.move_button->type == touch_move )
{ {
// move relative to touch start // move relative to touch start
touch.forward = ( touch.move_start_y - y ) / touch_forwardzone->value; touch.forward = ( touch.move_start_y - y ) / touch_forwardzone.value;
touch.side = ( x - touch.move_start_x ) / touch_sidezone->value; touch.side = ( x - touch.move_start_x ) / touch_sidezone.value;
} }
else if( touch.move_button->type == touch_joy ) else if( touch.move_button->type == touch_joy )
{ {
// move relative to joy center // 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.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.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 ) else if( touch.move_button->type == touch_dpad )
{ {
// like joy, but without acceleration. useful for bhop // 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.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.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 ); touch.forward = bound( -1, touch.forward, 1 );
@@ -1596,9 +1669,9 @@ static void Touch_Motion( touchEventType type, int fingerID, float x, float y, f
if( fingerID == touch.look_finger ) if( fingerID == touch.look_finger )
{ {
if( touch.precision ) 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; float dabs, dcos, dsin;
@@ -1611,11 +1684,11 @@ static void Touch_Motion( touchEventType type, int fingerID, float x, float y, f
dcos = dx / dabs; dcos = dx / dabs;
dsin = dy / dabs; dsin = dy / dabs;
if( touch_exp_mult->value > 1 ) if( touch_exp_mult.value > 1 )
dabs = ( exp( dabs * touch_exp_mult->value ) - 1 ) / touch_exp_mult->value; dabs = ( exp( dabs * touch_exp_mult.value ) - 1 ) / touch_exp_mult.value;
if( touch_pow_mult->value > 1 && touch_pow_factor->value > 1 ) 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; dabs = pow( dabs * touch_pow_mult.value, touch_pow_factor.value ) / touch_pow_mult.value;
dx = dabs * dcos; dx = dabs * dcos;
dy = dabs * dsin; dy = dabs * dsin;
@@ -1626,7 +1699,7 @@ static void Touch_Motion( touchEventType type, int fingerID, float x, float y, f
return; return;
// accumulate // 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;
} }
} }
@@ -1949,15 +2022,25 @@ 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 ) 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 // 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; touch.move_finger = touch.resize_finger = touch.look_finger = -1;
// Hack for keyboard, hope it help // Hack for keyboard, hope it help
// a1ba: this is absolutely horrible
if( cls.key_dest == key_console || cls.key_dest == key_message ) if( cls.key_dest == key_console || cls.key_dest == key_message )
{ {
if ( type == event_down ) // don't pop it again on event_up static float x1 = 0.0f;
x1 += dx;
if( type == event_up ) // don't show keyboard on every tap
{
Key_EnableTextInput( true, true ); Key_EnableTextInput( true, true );
x1 = 0.0f;
}
if( cls.key_dest == key_console ) if( cls.key_dest == key_console )
{ {
static float y1 = 0; static float y1 = 0;
@@ -1979,6 +2062,13 @@ int IN_TouchEvent( touchEventType type, int fingerID, float x, float y, float dx
// exit of console area // exit of console area
if( type == event_down && x < 0.1f && y > 0.9f ) if( type == event_down && x < 0.1f && y > 0.9f )
Cbuf_AddText( "escape\n" ); Cbuf_AddText( "escape\n" );
// swipe from edge to exit console/chat
if(( x > 0.8f && x1 < -0.1f ) || ( x < 0.2f && x1 > 0.1f ))
{
Cbuf_AddText( "escape\n" );
x1 = 0.0f;
}
} }
UI_MouseMove( TO_SCRN_X(x), TO_SCRN_Y(y) ); UI_MouseMove( TO_SCRN_X(x), TO_SCRN_Y(y) );
//MsgDev( D_NOTE, "touch %d %d\n", TO_SCRN_X(x), TO_SCRN_Y(y) ); //MsgDev( D_NOTE, "touch %d %d\n", TO_SCRN_X(x), TO_SCRN_Y(y) );

View File

@@ -17,6 +17,7 @@ GNU General Public License for more details.
#include "input.h" #include "input.h"
#include "client.h" #include "client.h"
#include "vgui_draw.h" #include "vgui_draw.h"
#include "cursor_type.h"
#if XASH_SDL #if XASH_SDL
#include <SDL.h> #include <SDL.h>
@@ -36,16 +37,15 @@ static struct inputstate_s
float lastpitch, lastyaw; float lastpitch, lastyaw;
} inputstate; } inputstate;
extern convar_t *vid_fullscreen; CVAR_DEFINE_AUTO( m_pitch, "0.022", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "mouse pitch value" );
convar_t *m_pitch; CVAR_DEFINE_AUTO( m_yaw, "0.022", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "mouse yaw value" );
convar_t *m_yaw; 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; static CVAR_DEFINE_AUTO( cl_forwardspeed, "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL | FCVAR_FILTERABLE, "Default forward move speed" );
convar_t *cl_forwardspeed; static CVAR_DEFINE_AUTO( cl_backspeed, "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL | FCVAR_FILTERABLE, "Default back move speed" );
convar_t *cl_sidespeed; static CVAR_DEFINE_AUTO( cl_sidespeed, "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL | FCVAR_FILTERABLE, "Default side move speed" );
convar_t *cl_backspeed;
convar_t *look_filter;
convar_t *m_rawinput;
/* /*
================ ================
@@ -58,7 +58,7 @@ uint IN_CollectInputDevices( void )
{ {
uint ret = 0; 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; ret |= INPUT_DEVICE_MOUSE;
if( touch_enable.value ) if( touch_enable.value )
@@ -86,18 +86,18 @@ player is connected to the server
*/ */
void IN_LockInputDevices( qboolean lock ) 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 ) if( lock )
{ {
SetBits( m_ignore->flags, FCVAR_READ_ONLY ); SetBits( m_ignore.flags, FCVAR_READ_ONLY );
SetBits( joy_enable->flags, FCVAR_READ_ONLY ); SetBits( joy_enable.flags, FCVAR_READ_ONLY );
SetBits( touch_enable.flags, FCVAR_READ_ONLY ); SetBits( touch_enable.flags, FCVAR_READ_ONLY );
} }
else else
{ {
ClearBits( m_ignore->flags, FCVAR_READ_ONLY ); ClearBits( m_ignore.flags, FCVAR_READ_ONLY );
ClearBits( joy_enable->flags, FCVAR_READ_ONLY ); ClearBits( joy_enable.flags, FCVAR_READ_ONLY );
ClearBits( touch_enable.flags, FCVAR_READ_ONLY ); ClearBits( touch_enable.flags, FCVAR_READ_ONLY );
} }
} }
@@ -108,14 +108,14 @@ void IN_LockInputDevices( qboolean lock )
IN_StartupMouse IN_StartupMouse
=========== ===========
*/ */
void IN_StartupMouse( void ) static 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" ); Cvar_RegisterVariable( &m_pitch );
m_yaw = Cvar_Get( "m_yaw", "0.022", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "mouse yaw value" ); Cvar_RegisterVariable( &m_yaw );
look_filter = Cvar_Get( "look_filter", "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "filter look events making it smoother" ); Cvar_RegisterVariable( &look_filter );
m_rawinput = Cvar_Get( "m_rawinput", "1", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enable mouse raw input" ); Cvar_RegisterVariable( &m_rawinput );
// You can use -nomouse argument to prevent using mouse from client // You can use -nomouse argument to prevent using mouse from client
// -noenginemouse will disable all mouse input // -noenginemouse will disable all mouse input
@@ -124,11 +124,6 @@ void IN_StartupMouse( void )
in_mouseinitialized = true; in_mouseinitialized = true;
} }
void GAME_EXPORT IN_SetCursor( void *hCursor )
{
// stub
}
/* /*
=========== ===========
IN_MouseSavePos IN_MouseSavePos
@@ -180,9 +175,6 @@ void IN_ToggleClientMouse( int newstate, int oldstate )
{ {
Platform_SetCursorType( dc_arrow ); Platform_SetCursorType( dc_arrow );
#if XASH_ANDROID
Android_ShowMouse( true );
#endif
#if XASH_USE_EVDEV #if XASH_USE_EVDEV
Evdev_SetGrab( false ); Evdev_SetGrab( false );
#endif #endif
@@ -191,14 +183,15 @@ void IN_ToggleClientMouse( int newstate, int oldstate )
{ {
Platform_SetCursorType( dc_none ); Platform_SetCursorType( dc_none );
#if XASH_ANDROID
Android_ShowMouse( false );
#endif
#if XASH_USE_EVDEV #if XASH_USE_EVDEV
Evdev_SetGrab( true ); Evdev_SetGrab( true );
#endif #endif
} }
// don't leave the user without cursor if they enabled m_ignore
if( m_ignore.value )
return;
if( oldstate == key_game ) if( oldstate == key_game )
{ {
IN_DeactivateMouse(); IN_DeactivateMouse();
@@ -209,16 +202,19 @@ void IN_ToggleClientMouse( int newstate, int oldstate )
} }
} }
void IN_CheckMouseState( qboolean active ) static void IN_CheckMouseState( qboolean active )
{ {
static qboolean s_bRawInput, s_bMouseGrab; static qboolean s_bRawInput, s_bMouseGrab;
#if XASH_WIN32 #if XASH_WIN32
qboolean useRawInput = ( CVAR_TO_BOOL( m_rawinput ) && clgame.client_dll_uses_sdl ) || clgame.dllFuncs.pfnLookEvent != NULL; qboolean useRawInput = ( m_rawinput.value && clgame.client_dll_uses_sdl ) || clgame.dllFuncs.pfnLookEvent != NULL;
#else #else
qboolean useRawInput = true; // always use SDL code qboolean useRawInput = true; // always use SDL code
#endif #endif
if( m_ignore.value )
return;
if( active && useRawInput && !host.mouse_visible && cls.state == ca_active ) if( active && useRawInput && !host.mouse_visible && cls.state == ca_active )
{ {
if( !s_bRawInput ) if( !s_bRawInput )
@@ -313,7 +309,7 @@ void IN_DeactivateMouse( void )
IN_MouseMove IN_MouseMove
================ ================
*/ */
void IN_MouseMove( void ) static void IN_MouseMove( void )
{ {
int x, y; int x, y;
@@ -414,9 +410,9 @@ IN_Init
*/ */
void IN_Init( void ) void IN_Init( void )
{ {
cl_forwardspeed = Cvar_Get( "cl_forwardspeed", "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL | FCVAR_FILTERABLE, "Default forward move speed" ); Cvar_RegisterVariable( &cl_forwardspeed );
cl_backspeed = Cvar_Get( "cl_backspeed", "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL | FCVAR_FILTERABLE, "Default back move speed" ); Cvar_RegisterVariable( &cl_backspeed );
cl_sidespeed = Cvar_Get( "cl_sidespeed", "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL | FCVAR_FILTERABLE, "Default side move speed" ); Cvar_RegisterVariable( &cl_sidespeed );
if( !Host_IsDedicated() ) if( !Host_IsDedicated() )
{ {
@@ -453,8 +449,8 @@ static void IN_JoyAppendMove( usercmd_t *cmd, float forwardmove, float sidemove
{ {
static uint moveflags = T | S; static uint moveflags = T | S;
if( forwardmove ) cmd->forwardmove = forwardmove * cl_forwardspeed->value; if( forwardmove ) cmd->forwardmove = forwardmove * cl_forwardspeed.value;
if( sidemove ) cmd->sidemove = sidemove * cl_sidespeed->value; if( sidemove ) cmd->sidemove = sidemove * cl_sidespeed.value;
if( forwardmove ) if( forwardmove )
{ {
@@ -529,8 +525,8 @@ static void IN_CollectInput( float *forward, float *side, float *pitch, float *y
{ {
float x, y; float x, y;
Platform_MouseMove( &x, &y ); Platform_MouseMove( &x, &y );
*pitch += y * m_pitch->value; *pitch += y * m_pitch.value;
*yaw -= x * m_yaw->value; *yaw -= x * m_yaw.value;
#if XASH_USE_EVDEV #if XASH_USE_EVDEV
IN_EvdevMove( yaw, pitch ); IN_EvdevMove( yaw, pitch );
@@ -540,7 +536,7 @@ static void IN_CollectInput( float *forward, float *side, float *pitch, float *y
Joy_FinalizeMove( forward, side, yaw, pitch ); Joy_FinalizeMove( forward, side, yaw, pitch );
Touch_GetMove( forward, side, yaw, pitch ); Touch_GetMove( forward, side, yaw, pitch );
if( look_filter->value ) if( look_filter.value )
{ {
*pitch = ( inputstate.lastpitch + *pitch ) / 2; *pitch = ( inputstate.lastpitch + *pitch ) / 2;
*yaw = ( inputstate.lastyaw + *yaw ) / 2; *yaw = ( inputstate.lastyaw + *yaw ) / 2;
@@ -588,7 +584,7 @@ void IN_EngineAppendMove( float frametime, void *cmd1, qboolean active )
} }
} }
void IN_Commands( void ) static void IN_Commands( void )
{ {
#if XASH_USE_EVDEV #if XASH_USE_EVDEV
IN_EvdevFrame(); IN_EvdevFrame();
@@ -598,7 +594,7 @@ void IN_Commands( void )
{ {
float forward = 0, side = 0, pitch = 0, yaw = 0; 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 ) if( cls.key_dest == key_game )
{ {

View File

@@ -40,14 +40,13 @@ void IN_DeactivateMouse( void );
void IN_MouseSavePos( void ); void IN_MouseSavePos( void );
void IN_MouseRestorePos( void ); void IN_MouseRestorePos( void );
void IN_ToggleClientMouse( int newstate, int oldstate ); void IN_ToggleClientMouse( int newstate, int oldstate );
void IN_SetCursor( void *hCursor );
uint IN_CollectInputDevices( void ); uint IN_CollectInputDevices( void );
void IN_LockInputDevices( qboolean lock ); void IN_LockInputDevices( qboolean lock );
void IN_EngineAppendMove( float frametime, void *cmd, qboolean active ); void IN_EngineAppendMove( float frametime, void *cmd, qboolean active );
extern convar_t *m_yaw; extern convar_t m_yaw;
extern convar_t *m_pitch; extern convar_t m_pitch;
// //
// in_touch.c // in_touch.c
// //
@@ -75,6 +74,7 @@ void Touch_ResetDefaultButtons( void );
int IN_TouchEvent( touchEventType type, int fingerID, float x, float y, float dx, float dy ); int IN_TouchEvent( touchEventType type, int fingerID, float x, float y, float dx, float dy );
void Touch_KeyEvent( int key, int down ); void Touch_KeyEvent( int key, int down );
qboolean Touch_WantVisibleCursor( void ); qboolean Touch_WantVisibleCursor( void );
void Touch_NotifyResize( void );
// //
// in_joy.c // in_joy.c

View File

@@ -144,8 +144,8 @@ keyname_t keynames[] =
static void OSK_EnableTextInput( qboolean enable, qboolean force ); static void OSK_EnableTextInput( qboolean enable, qboolean force );
static qboolean OSK_KeyEvent( int key, int down ); static qboolean OSK_KeyEvent( int key, int down );
static convar_t *osk_enable; static CVAR_DEFINE_AUTO( osk_enable, "0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "enable built-in on-screen keyboard" );
static convar_t *key_rotate; static CVAR_DEFINE_AUTO( key_rotate, "0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "rotate arrow keys (0-3)" );
/* /*
=================== ===================
@@ -332,7 +332,7 @@ int Key_GetKey( const char *pBinding )
Key_Unbind_f Key_Unbind_f
=================== ===================
*/ */
void Key_Unbind_f( void ) static void Key_Unbind_f( void )
{ {
int b; int b;
@@ -358,7 +358,7 @@ void Key_Unbind_f( void )
Key_Unbindall_f Key_Unbindall_f
=================== ===================
*/ */
void Key_Unbindall_f( void ) static void Key_Unbindall_f( void )
{ {
int i; int i;
@@ -378,7 +378,7 @@ void Key_Unbindall_f( void )
Key_Reset_f Key_Reset_f
=================== ===================
*/ */
void Key_Reset_f( void ) static void Key_Reset_f( void )
{ {
keyname_t *kn; keyname_t *kn;
int i; int i;
@@ -400,7 +400,7 @@ void Key_Reset_f( void )
Key_Bind_f Key_Bind_f
=================== ===================
*/ */
void Key_Bind_f( void ) static void Key_Bind_f( void )
{ {
char cmd[1024]; char cmd[1024];
int i, c, b; int i, c, b;
@@ -473,7 +473,7 @@ Key_Bindlist_f
============ ============
*/ */
void Key_Bindlist_f( void ) static void Key_Bindlist_f( void )
{ {
int i; int i;
@@ -513,8 +513,8 @@ void Key_Init( void )
// setup default binding. "unbindall" from config.cfg will be reset it // setup default binding. "unbindall" from config.cfg will be reset it
for( kn = keynames; kn->name; kn++ ) Key_SetBinding( kn->keynum, kn->binding ); 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" ); Cvar_RegisterVariable( &osk_enable );
key_rotate = Cvar_Get( "key_rotate", "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "rotate arrow keys (0-3)" ); Cvar_RegisterVariable( &key_rotate );
} }
@@ -523,7 +523,7 @@ void Key_Init( void )
Key_AddKeyCommands Key_AddKeyCommands
=================== ===================
*/ */
void Key_AddKeyCommands( int key, const char *kb, qboolean down ) static void Key_AddKeyCommands( int key, const char *kb, qboolean down )
{ {
char button[1024]; char button[1024];
char *buttonPtr; char *buttonPtr;
@@ -553,7 +553,7 @@ void Key_AddKeyCommands( int key, const char *kb, qboolean down )
} }
buttonPtr = button; buttonPtr = button;
while(( kb[i] <= ' ' || kb[i] == ';' ) && kb[i] != 0 ) while((((byte)kb[i]) <= ' ' || kb[i] == ';' ) && kb[i] != 0 )
i++; i++;
} }
@@ -590,7 +590,7 @@ static qboolean Key_IsAllowedAutoRepeat( int key )
static int Key_Rotate( 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 ) if( key == K_UPARROW )
key = K_LEFTARROW; key = K_LEFTARROW;
@@ -602,7 +602,7 @@ static int Key_Rotate( int key )
key = K_RIGHTARROW; key = K_RIGHTARROW;
} }
else if( key_rotate->value == 3.0f ) // CCW else if( key_rotate.value == 3.0f ) // CCW
{ {
if( key == K_UPARROW ) if( key == K_UPARROW )
key = K_RIGHTARROW; key = K_RIGHTARROW;
@@ -614,7 +614,7 @@ static int Key_Rotate( int key )
key = K_LEFTARROW; key = K_LEFTARROW;
} }
else if( key_rotate->value == 2.0f ) else if( key_rotate.value == 2.0f )
{ {
if( key == K_UPARROW ) if( key == K_UPARROW )
key = K_DOWNARROW; key = K_DOWNARROW;
@@ -719,10 +719,10 @@ void GAME_EXPORT Key_Event( int key, int down )
switch( cls.key_dest ) switch( cls.key_dest )
{ {
case key_game: case key_game:
if( CVAR_TO_BOOL( gl_showtextures )) if( r_showtextures.value )
{ {
// close texture atlas // close texture atlas
Cvar_SetValue( "r_showtextures", 0.0f ); Cvar_DirectSet( &r_showtextures, "0" );
return; return;
} }
else if( host.mouse_visible && cls.state != ca_cinematic ) else if( host.mouse_visible && cls.state != ca_cinematic )
@@ -749,10 +749,10 @@ void GAME_EXPORT Key_Event( int key, int down )
if( cls.key_dest == key_menu ) if( cls.key_dest == key_menu )
{ {
// only non printable keys passed // only non printable keys passed
if( !gameui.use_text_api ) if( !gameui.use_extended_api )
Key_EnableTextInput( true, false ); Key_EnableTextInput( true, false );
//pass printable chars for old menus //pass printable chars for old menus
if( !gameui.use_text_api && !host.textmode && down && ( key >= 32 ) && ( key <= 'z' ) ) if( !gameui.use_extended_api && !host.textmode && down && ( key >= 32 ) && ( key <= 'z' ) )
{ {
if( Key_IsDown( K_SHIFT ) ) if( Key_IsDown( K_SHIFT ) )
{ {
@@ -797,7 +797,7 @@ Key_EnableTextInput
*/ */
void Key_EnableTextInput( qboolean enable, qboolean force ) void Key_EnableTextInput( qboolean enable, qboolean force )
{ {
if( CVAR_TO_BOOL( osk_enable ) ) if( osk_enable.value )
{ {
OSK_EnableTextInput( enable, force ); OSK_EnableTextInput( enable, force );
return; return;
@@ -995,7 +995,7 @@ struct osk_s
static qboolean OSK_KeyEvent( int key, int down ) static qboolean OSK_KeyEvent( int key, int down )
{ {
if( !osk.enable || !CVAR_TO_BOOL( osk_enable ) ) if( !osk.enable || !osk_enable.value )
return false; return false;
if( osk.sending ) if( osk.sending )
@@ -1055,18 +1055,16 @@ static qboolean OSK_KeyEvent( int key, int down )
break; break;
} }
if( !Q_stricmp( cl_charset->string, "utf-8" ) ) ch = (byte)osk.curbutton.val;
ch = (unsigned char)osk.curbutton.val;
else // do not pass UTF-8 sequence into the engine, convert it here
ch = Con_UtfProcessCharForce( (unsigned char)osk.curbutton.val ); if( !cls.accept_utf8 )
ch = Con_UtfProcessCharForce( ch );
if( !ch ) if( !ch )
break; break;
Con_CharEvent( ch ); CL_CharEvent( ch );
if( cls.key_dest == key_menu )
UI_CharEvent ( ch );
break; break;
} }
} }
@@ -1121,7 +1119,6 @@ static void OSK_EnableTextInput( qboolean enable, qboolean force )
{ {
osk.curlayout = 0; osk.curlayout = 0;
osk.curbutton.val = osk_keylayout[osk.curlayout][osk.curbutton.y][osk.curbutton.x]; osk.curbutton.val = osk_keylayout[osk.curlayout][osk.curbutton.y][osk.curbutton.x];
} }
} }
@@ -1190,7 +1187,7 @@ void OSK_Draw( void )
float x, y; float x, y;
int i, j; int i, j;
if( !osk.enable || !CVAR_TO_BOOL(osk_enable) || !osk.curbutton.val ) if( !osk.enable || !osk_enable.value || !osk.curbutton.val )
return; return;
// draw keyboard // 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 ); Con_Reportf( "%i hull polys\n", model->num_polys );
} }
void Mod_InitDebugHulls( void ) void Mod_InitDebugHulls( model_t *loadmodel )
{ {
int i; int i;
@@ -685,6 +685,9 @@ void Mod_CreatePolygonsForHull( int hullnum )
if( hullnum < 1 || hullnum > 3 ) if( hullnum < 1 || hullnum > 3 )
return; return;
if( !world.num_hull_models )
Mod_InitDebugHulls( mod ); // FIXME: build hulls for separate bmodels (shells, medkits etc)
Con_Printf( "generating polygons for hull %u...\n", hullnum ); Con_Printf( "generating polygons for hull %u...\n", hullnum );
start = Sys_DoubleTime(); start = Sys_DoubleTime();

View File

@@ -8,14 +8,40 @@
struct ref_state_s ref; struct ref_state_s ref;
ref_globals_t refState; ref_globals_t refState;
convar_t *gl_vsync; CVAR_DEFINE_AUTO( gl_vsync, "0", FCVAR_ARCHIVE, "enable vertical syncronization" );
convar_t *gl_showtextures; CVAR_DEFINE_AUTO( r_showtextures, "0", FCVAR_CHEAT, "show all uploaded textures" );
convar_t *r_decals; CVAR_DEFINE_AUTO( r_adjust_fov, "1", FCVAR_ARCHIVE, "making FOV adjustment for wide-screens" );
convar_t *r_adjust_fov; CVAR_DEFINE_AUTO( r_decals, "4096", FCVAR_ARCHIVE, "sets the maximum number of decals" );
convar_t *r_showtree; CVAR_DEFINE_AUTO( gl_msaa_samples, "0", FCVAR_GLCONFIG, "samples number for multisample anti-aliasing" );
convar_t *gl_msaa_samples; CVAR_DEFINE_AUTO( gl_clear, "0", FCVAR_ARCHIVE, "clearing screen after each frame" );
convar_t *gl_clear; CVAR_DEFINE_AUTO( r_showtree, "0", FCVAR_ARCHIVE, "build the graph of visible BSP tree" );
convar_t *r_refdll; static CVAR_DEFINE_AUTO( r_refdll, "", FCVAR_RENDERINFO, "choose renderer implementation, if supported" );
static CVAR_DEFINE_AUTO( r_refdll_loaded, "", FCVAR_READ_ONLY, "currently loaded renderer" );
// there is no need to expose whole host and cl structs into the renderer
// but we still need to update timings accurately as possible
// this looks horrible but the only other option would be passing four
// time pointers and then it's looks even worse with dereferences everywhere
#define STATIC_OFFSET_CHECK( s1, s2, field, base, msg ) \
STATIC_ASSERT( offsetof( s1, field ) == offsetof( s2, field ) - offsetof( s2, base ), msg )
#define REF_CLIENT_CHECK( field ) \
STATIC_OFFSET_CHECK( ref_client_t, client_t, field, time, "broken ref_client_t offset" ); \
STATIC_ASSERT_( szchk_##__LINE__, sizeof(((ref_client_t *)0)->field ) == sizeof( cl.field ), "broken ref_client_t size" )
#define REF_HOST_CHECK( field ) \
STATIC_OFFSET_CHECK( ref_host_t, host_parm_t, field, realtime, "broken ref_client_t offset" ); \
STATIC_ASSERT_( szchk_##__LINE__, sizeof(((ref_host_t *)0)->field ) == sizeof( host.field ), "broken ref_client_t size" )
REF_CLIENT_CHECK( time );
REF_CLIENT_CHECK( oldtime );
REF_CLIENT_CHECK( viewentity );
REF_CLIENT_CHECK( playernum );
REF_CLIENT_CHECK( maxclients );
REF_CLIENT_CHECK( models );
REF_CLIENT_CHECK( paused );
REF_CLIENT_CHECK( simorg );
REF_HOST_CHECK( realtime );
REF_HOST_CHECK( frametime );
REF_HOST_CHECK( features );
void R_GetTextureParms( int *w, int *h, int texnum ) void R_GetTextureParms( int *w, int *h, int texnum )
{ {
@@ -41,18 +67,8 @@ void GAME_EXPORT GL_FreeImage( const char *name )
ref.dllFuncs.GL_FreeTexture( texnum ); ref.dllFuncs.GL_FreeTexture( texnum );
} }
void R_UpdateRefState( void )
{
refState.time = cl.time;
refState.oldtime = cl.oldtime;
refState.realtime = host.realtime;
refState.frametime = host.frametime;
}
void GL_RenderFrame( const ref_viewpass_t *rvp ) void GL_RenderFrame( const ref_viewpass_t *rvp )
{ {
R_UpdateRefState();
VectorCopy( rvp->vieworigin, refState.vieworg ); VectorCopy( rvp->vieworigin, refState.vieworg );
VectorCopy( rvp->viewangles, refState.viewangles ); VectorCopy( rvp->viewangles, refState.viewangles );
@@ -64,11 +80,6 @@ static intptr_t pfnEngineGetParm( int parm, int arg )
return CL_RenderGetParm( parm, arg, false ); // prevent recursion return CL_RenderGetParm( parm, arg, false ); // prevent recursion
} }
static world_static_t *pfnGetWorld( void )
{
return &world;
}
static void pfnStudioEvent( const mstudioevent_t *event, const cl_entity_t *e ) static void pfnStudioEvent( const mstudioevent_t *event, const cl_entity_t *e )
{ {
clgame.dllFuncs.pfnStudioEvent( event, e ); clgame.dllFuncs.pfnStudioEvent( event, e );
@@ -98,24 +109,10 @@ static void *pfnMod_Extradata( int type, model_t *m )
return NULL; return NULL;
} }
static model_t *pfnMod_GetCurrentLoadingModel( void ) static void CL_ExtraUpdate( void )
{ {
return loadmodel; clgame.dllFuncs.IN_Accumulate();
} S_ExtraUpdate();
static void pfnMod_SetCurrentLoadingModel( model_t *m )
{
loadmodel = m;
}
static void pfnGetPredictedOrigin( vec3_t v )
{
VectorCopy( cl.simorg, v );
}
static color24 *pfnCL_GetPaletteColor( int color ) // clgame.palette[color]
{
return &clgame.palette[color];
} }
static void pfnCL_GetScreenInfo( int *width, int *height ) // clgame.scrInfo, ptrs may be NULL static void pfnCL_GetScreenInfo( int *width, int *height ) // clgame.scrInfo, ptrs may be NULL
@@ -167,11 +164,6 @@ static int pfnGetStudioModelInterface( int version, struct r_studio_interface_s
0; 0;
} }
static poolhandle_t pfnImage_GetPool( void )
{
return host.imagepool;
}
static const bpc_desc_t *pfnImage_GetPFDesc( int idx ) static const bpc_desc_t *pfnImage_GetPFDesc( int idx )
{ {
return &PFDesc[idx]; return &PFDesc[idx];
@@ -192,25 +184,6 @@ static screenfade_t *pfnRefGetScreenFade( void )
return &clgame.fade; return &clgame.fade;
} }
/*
===============
R_DoResetGamma
gamma will be reset for
some type of screenshots
===============
*/
static qboolean R_DoResetGamma( void )
{
switch( cls.scrshot_action )
{
case scrshot_envshot:
case scrshot_skyshot:
return true;
default:
return false;
}
}
static qboolean R_Init_Video_( const int type ) static qboolean R_Init_Video_( const int type )
{ {
host.apply_opengl_config = true; host.apply_opengl_config = true;
@@ -231,7 +204,7 @@ static ref_api_t gEngfuncs =
Cvar_VariableString, Cvar_VariableString,
Cvar_SetValue, Cvar_SetValue,
Cvar_Set, Cvar_Set,
(void*)Cvar_RegisterVariable, Cvar_RegisterVariable,
Cvar_FullSet, Cvar_FullSet,
Cmd_AddRefCommand, Cmd_AddRefCommand,
@@ -255,16 +228,12 @@ static ref_api_t gEngfuncs =
Con_DrawString, Con_DrawString,
CL_DrawCenterPrint, CL_DrawCenterPrint,
CL_GetLocalPlayer,
CL_GetViewModel,
CL_GetEntityByIndex,
R_BeamGetEntity, R_BeamGetEntity,
CL_GetWaterEntity, CL_GetWaterEntity,
CL_AddVisibleEntity, CL_AddVisibleEntity,
Mod_SampleSizeForFace, Mod_SampleSizeForFace,
Mod_BoxVisible, Mod_BoxVisible,
pfnGetWorld,
Mod_PointInLeaf, Mod_PointInLeaf,
Mod_CreatePolygonsForHull, Mod_CreatePolygonsForHull,
@@ -281,14 +250,9 @@ static ref_api_t gEngfuncs =
Mod_ForName, Mod_ForName,
pfnMod_Extradata, pfnMod_Extradata,
CL_ModelHandle,
pfnMod_GetCurrentLoadingModel,
pfnMod_SetCurrentLoadingModel,
CL_EntitySetRemapColors,
CL_GetRemapInfoForEntity, CL_GetRemapInfoForEntity,
CL_AllocRemapInfo,
CL_FreeRemapInfo,
CL_UpdateRemapInfo,
CL_ExtraUpdate, CL_ExtraUpdate,
Host_Error, Host_Error,
@@ -296,9 +260,6 @@ static ref_api_t gEngfuncs =
COM_RandomFloat, COM_RandomFloat,
COM_RandomLong, COM_RandomLong,
pfnRefGetScreenFade, pfnRefGetScreenFade,
CL_TextMessageGet,
pfnGetPredictedOrigin,
pfnCL_GetPaletteColor,
pfnCL_GetScreenInfo, pfnCL_GetScreenInfo,
pfnSetLocalLightLevel, pfnSetLocalLightLevel,
Sys_CheckParm, Sys_CheckParm,
@@ -332,9 +293,11 @@ static ref_api_t gEngfuncs =
SW_LockBuffer, SW_LockBuffer,
SW_UnlockBuffer, SW_UnlockBuffer,
BuildGammaTable,
LightToTexGamma, LightToTexGamma,
R_DoResetGamma, LightToTexGammaEx,
TextureToGamma,
ScreenGammaTable,
LinearGammaTable,
CL_GetLightStyle, CL_GetLightStyle,
CL_GetDynamicLight, CL_GetDynamicLight,
@@ -348,7 +311,6 @@ static ref_api_t gEngfuncs =
PM_CL_TraceLine, PM_CL_TraceLine,
CL_VisTraceLine, CL_VisTraceLine,
CL_TraceLine, CL_TraceLine,
pfnGetMoveVars,
Image_AddCmdFlags, Image_AddCmdFlags,
Image_SetForceFlags, Image_SetForceFlags,
@@ -360,7 +322,6 @@ static ref_api_t gEngfuncs =
FS_CopyImage, FS_CopyImage,
FS_FreeImage, FS_FreeImage,
Image_SetMDLPointer, Image_SetMDLPointer,
pfnImage_GetPool,
pfnImage_GetPFDesc, pfnImage_GetPFDesc,
pfnDrawNormalTriangles, pfnDrawNormalTriangles,
@@ -379,14 +340,14 @@ static void R_UnloadProgs( void )
Cvar_FullSet( "host_refloaded", "0", FCVAR_READ_ONLY ); Cvar_FullSet( "host_refloaded", "0", FCVAR_READ_ONLY );
Cvar_Unlink( FCVAR_RENDERINFO | FCVAR_GLCONFIG );
Cmd_Unlink( CMD_REFDLL );
COM_FreeLibrary( ref.hInstance ); COM_FreeLibrary( ref.hInstance );
ref.hInstance = NULL; ref.hInstance = NULL;
memset( &refState, 0, sizeof( refState )); memset( &refState, 0, sizeof( refState ));
memset( &ref.dllFuncs, 0, sizeof( ref.dllFuncs )); 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 ) static void CL_FillTriAPIFromRef( triangleapi_t *dst, const ref_interface_t *src )
@@ -442,7 +403,7 @@ static qboolean R_LoadProgs( const char *name )
// make local copy of engfuncs to prevent overwrite it with user dll // make local copy of engfuncs to prevent overwrite it with user dll
memcpy( &gpEngfuncs, &gEngfuncs, sizeof( gpEngfuncs )); memcpy( &gpEngfuncs, &gEngfuncs, sizeof( gpEngfuncs ));
if( !GetRefAPI( REF_API_VERSION, &ref.dllFuncs, &gpEngfuncs, &refState )) if( GetRefAPI( REF_API_VERSION, &ref.dllFuncs, &gpEngfuncs, &refState ) != REF_API_VERSION )
{ {
COM_FreeLibrary( ref.hInstance ); COM_FreeLibrary( ref.hInstance );
Con_Reportf( "R_LoadProgs: can't init renderer API: wrong version\n" ); Con_Reportf( "R_LoadProgs: can't init renderer API: wrong version\n" );
@@ -531,6 +492,7 @@ static qboolean R_LoadRenderer( const char *refopt )
return false; return false;
} }
Cvar_FullSet( "r_refdll_loaded", refopt, FCVAR_READ_ONLY );
Con_Reportf( "Renderer %s initialized\n", refdll ); Con_Reportf( "Renderer %s initialized\n", refdll );
return true; return true;
@@ -549,21 +511,17 @@ static void SetWidthAndHeightFromCommandLine( void )
return; return;
} }
R_SaveVideoMode( width, height, width, height ); R_SaveVideoMode( width, height, width, height, false );
} }
static void SetFullscreenModeFromCommandLine( void ) static void SetFullscreenModeFromCommandLine( void )
{ {
#if !XASH_MOBILE_PLATFORM if( Sys_CheckParm( "-borderless" ))
if( Sys_CheckParm( "-fullscreen" )) Cvar_DirectSet( &vid_fullscreen, "2" );
{ else if( Sys_CheckParm( "-fullscreen" ))
Cvar_Set( "fullscreen", "1" ); Cvar_DirectSet( &vid_fullscreen, "1" );
}
else if( Sys_CheckParm( "-windowed" )) else if( Sys_CheckParm( "-windowed" ))
{ Cvar_DirectSet( &vid_fullscreen, "0" );
Cvar_Set( "fullscreen", "0" );
}
#endif
} }
static void R_CollectRendererNames( void ) static void R_CollectRendererNames( void )
@@ -583,6 +541,9 @@ static void R_CollectRendererNames( void )
#if XASH_REF_GL4ES_ENABLED #if XASH_REF_GL4ES_ENABLED
"gl4es", "gl4es",
#endif #endif
#if XASH_REF_GLES3COMPAT_ENABLED
"gles3compat",
#endif
#if XASH_REF_SOFT_ENABLED #if XASH_REF_SOFT_ENABLED
"soft", "soft",
#endif #endif
@@ -603,6 +564,9 @@ static void R_CollectRendererNames( void )
#if XASH_REF_GL4ES_ENABLED #if XASH_REF_GL4ES_ENABLED
"GL4ES", "GL4ES",
#endif #endif
#if XASH_REF_GLES3COMPAT_ENABLED
"GLES3 (gl2_shim)",
#endif
#if XASH_REF_SOFT_ENABLED #if XASH_REF_SOFT_ENABLED
"Software", "Software",
#endif #endif
@@ -618,14 +582,15 @@ qboolean R_Init( void )
qboolean success = false; qboolean success = false;
string requested; string requested;
gl_vsync = Cvar_Get( "gl_vsync", "0", FCVAR_ARCHIVE, "enable vertical syncronization" ); Cvar_RegisterVariable( &gl_vsync );
gl_showtextures = Cvar_Get( "r_showtextures", "0", FCVAR_CHEAT, "show all uploaded textures" ); Cvar_RegisterVariable( &r_showtextures );
r_adjust_fov = Cvar_Get( "r_adjust_fov", "1", FCVAR_ARCHIVE, "making FOV adjustment for wide-screens" ); Cvar_RegisterVariable( &r_adjust_fov );
r_decals = Cvar_Get( "r_decals", "4096", FCVAR_ARCHIVE, "sets the maximum number of decals" ); Cvar_RegisterVariable( &r_decals );
gl_msaa_samples = Cvar_Get( "gl_msaa_samples", "0", FCVAR_GLCONFIG, "samples number for multisample anti-aliasing" ); Cvar_RegisterVariable( &gl_msaa_samples );
gl_clear = Cvar_Get( "gl_clear", "0", FCVAR_ARCHIVE, "clearing screen after each frame" ); Cvar_RegisterVariable( &gl_clear );
r_showtree = Cvar_Get( "r_showtree", "0", FCVAR_ARCHIVE, "build the graph of visible BSP tree" ); Cvar_RegisterVariable( &r_showtree );
r_refdll = Cvar_Get( "r_refdll", "", FCVAR_RENDERINFO, "choose renderer implementation, if supported" ); Cvar_RegisterVariable( &r_refdll );
Cvar_RegisterVariable( &r_refdll_loaded );
// cvars that are expected to exist // cvars that are expected to exist
Cvar_Get( "r_speeds", "0", FCVAR_ARCHIVE, "shows renderer speeds" ); Cvar_Get( "r_speeds", "0", FCVAR_ARCHIVE, "shows renderer speeds" );
@@ -646,6 +611,7 @@ qboolean R_Init( void )
// cvars that are expected to exist by client.dll // cvars that are expected to exist by client.dll
// refdll should just get pointer to them // refdll should just get pointer to them
Cvar_Get( "r_lighting_modulate", "0.6", FCVAR_ARCHIVE, "compatibility cvar, does nothing" );
Cvar_Get( "r_drawentities", "1", FCVAR_CHEAT, "render entities" ); Cvar_Get( "r_drawentities", "1", FCVAR_CHEAT, "render entities" );
Cvar_Get( "cl_himodels", "1", FCVAR_ARCHIVE, "draw high-resolution player models in multiplayer" ); Cvar_Get( "cl_himodels", "1", FCVAR_ARCHIVE, "draw high-resolution player models in multiplayer" );
@@ -669,9 +635,9 @@ qboolean R_Init( void )
if( !success && Sys_GetParmFromCmdLine( "-ref", requested )) if( !success && Sys_GetParmFromCmdLine( "-ref", requested ))
success = R_LoadRenderer( requested ); success = R_LoadRenderer( requested );
if( !success && COM_CheckString( r_refdll->string )) if( !success && COM_CheckString( r_refdll.string ))
{ {
Q_strncpy( requested, r_refdll->string, sizeof( requested )); Q_strncpy( requested, r_refdll.string, sizeof( requested ));
success = R_LoadRenderer( requested ); success = R_LoadRenderer( requested );
} }
@@ -691,7 +657,7 @@ qboolean R_Init( void )
if( !success ) 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; return false;
} }

View File

@@ -22,13 +22,12 @@ GNU General Public License for more details.
struct ref_state_s struct ref_state_s
{ {
qboolean initialized;
HINSTANCE hInstance; HINSTANCE hInstance;
qboolean initialized;
int numRenderers;
ref_interface_t dllFuncs; ref_interface_t dllFuncs;
// depends on build configuration // depends on build configuration
int numRenderers;
const char **shortNames; const char **shortNames;
const char **readableNames; const char **readableNames;
}; };
@@ -46,13 +45,12 @@ void R_GetTextureParms( int *w, int *h, int texnum );
void GL_RenderFrame( const struct ref_viewpass_s *rvp ); void GL_RenderFrame( const struct ref_viewpass_s *rvp );
// common engine and renderer cvars // common engine and renderer cvars
extern convar_t *r_decals; extern convar_t r_decals;
extern convar_t *r_adjust_fov; extern convar_t r_adjust_fov;
extern convar_t *gl_clear; extern convar_t gl_clear;
qboolean R_Init( void ); qboolean R_Init( void );
void R_Shutdown( void ); void R_Shutdown( void );
void R_UpdateRefState( void );
extern triangleapi_t gTriApi; extern triangleapi_t gTriApi;

View File

@@ -1,6 +1,7 @@
/* /*
s_dsp.c - digital signal processing algorithms for audio FX s_dsp.c - digital signal processing algorithms for audio FX
Copyright (C) 2009 Uncle Mike Copyright (C) 2009 Uncle Mike
Copyright (C) 2016-2024 Alibek Omarov
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -78,7 +79,7 @@ typedef struct dly_s
int *lpdelayline; int *lpdelayline;
} dly_t; } dly_t;
const sx_preset_t rgsxpre[] = static const sx_preset_t rgsxpre[] =
{ {
// -------reverb-------- -------delay-------- // -------reverb-------- -------delay--------
// lp mod size refl rvblp delay feedback dlylp left // lp mod size refl rvblp delay feedback dlylp left
@@ -115,7 +116,7 @@ const sx_preset_t rgsxpre[] =
// 0x0045dca8 enginegl.exe // 0x0045dca8 enginegl.exe
// SHA256: 42383d32cd712e59ee2c1bd78b7ba48814e680e7026c4223e730111f34a60d66 // SHA256: 42383d32cd712e59ee2c1bd78b7ba48814e680e7026c4223e730111f34a60d66
const sx_preset_t rgsxpre_hlalpha052[] = static const sx_preset_t rgsxpre_hlalpha052[] =
{ {
// -------reverb-------- -------delay-------- // -------reverb-------- -------delay--------
// lp mod size refl rvblp delay feedback dlylp left // lp mod size refl rvblp delay feedback dlylp left
@@ -150,51 +151,51 @@ 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 { 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 // cvars
convar_t *dsp_off; // disable dsp static CVAR_DEFINE_AUTO( dsp_off, "0", FCVAR_ARCHIVE, "disable DSP processing (deprecated)" );
convar_t *roomwater_type; // water room_type static CVAR_DEFINE_AUTO( room_off, "0", FCVAR_ARCHIVE, "disable DSP processing (GoldSrc compatible cvar)" );
convar_t *room_type; // current room type static CVAR_DEFINE_AUTO( dsp_coeff_table, "0", FCVAR_ARCHIVE, "select DSP coefficient table: 0 for release or 1 for alpha 0.52" );
convar_t *hisound; // DSP quality 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 // underwater/special fx modulations
convar_t *sxmod_mod; static CVAR_DEFINE( sxmod_mod, "room_mod", "0", 0, "stereo amptitude modulation for room" );
convar_t *sxmod_lowpass; static CVAR_DEFINE( sxmod_lowpass, "room_lp", "0", 0, "for water fx, lowpass for entire room" );
// stereo delay(no feedback) // 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 // mono reverb
convar_t *sxrvb_lp; // lowpass static CVAR_DEFINE( sxrvb_lp, "room_rvblp", "1", 0, "reverb: low pass filtering level" );
convar_t *sxrvb_feedback; // reverb decay. Higher -- longer static CVAR_DEFINE( sxrvb_feedback, "room_refl", "0", 0, "reverb: decay time" );
convar_t *sxrvb_size; // room size. Higher -- larger static CVAR_DEFINE( sxrvb_size, "room_size", "0", 0, "reverb: initial reflection size" );
// mono delay // mono delay
convar_t *sxdly_lp; // lowpass static CVAR_DEFINE( sxdly_lp, "room_dlylp", "1", 0, "mono delay: low pass filtering level" );
convar_t *sxdly_feedback; // cycles static CVAR_DEFINE( sxdly_feedback, "room_feedback", "0.2", 0, "mono delay: decay time" );
convar_t *sxdly_delay; // current delay in seconds static CVAR_DEFINE( sxdly_delay, "room_delay", "0.8", 0, "mono delay: delay time" );
convar_t *dsp_room; // for compability static int idsp_dma_speed;
convar_t *dsp_coeff_table; // use release or 0.52 style
int idsp_dma_speed;
int idsp_room; int idsp_room;
int room_typeprev; static int room_typeprev;
// routines // routines
int sxamodl, sxamodr; // amplitude modulation values static int sxamodl, sxamodr; // amplitude modulation values
int sxamodlt, sxamodrt; // modulation targets static int sxamodlt, sxamodrt; // modulation targets
int sxmod1cur, sxmod2cur; static int sxmod1cur, sxmod2cur;
int sxmod1, sxmod2; static int sxmod1, sxmod2;
int sxhires; static int sxhires;
portable_samplepair_t *paintto = NULL; static portable_samplepair_t *paintto = NULL;
dly_t rgsxdly[MAXDLY]; // stereo is last static dly_t rgsxdly[MAXDLY]; // stereo is last
int rgsxlp[MAXLP]; static int rgsxlp[MAXLP];
void SX_Profiling_f( void ); static void SX_Profiling_f( void );
/* /*
============ ============
@@ -202,14 +203,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( sxste_delay->flags, FCVAR_CHANGED ); SetBits( sxdly_delay.flags, FCVAR_CHANGED );
SetBits( sxrvb_feedback->flags, FCVAR_CHANGED ); SetBits( room_type.flags, FCVAR_CHANGED );
SetBits( sxdly_delay->flags, FCVAR_CHANGED );
SetBits( room_type->flags, FCVAR_CHANGED );
} }
/* /*
@@ -227,36 +226,34 @@ void SX_Init( void )
sxamodr = sxamodl = sxamodrt = sxamodlt = 255; sxamodr = sxamodl = sxamodrt = sxamodlt = 255;
idsp_dma_speed = SOUND_11k; 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; sxhires = 2;
sxmod1cur = sxmod1 = 350 * ( idsp_dma_speed / SOUND_11k ); sxmod1cur = sxmod1 = 350 * ( idsp_dma_speed / SOUND_11k );
sxmod2cur = sxmod2 = 450 * ( 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" ); Cvar_RegisterVariable( &dsp_off );
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( &room_off );
Cvar_RegisterVariable( &dsp_coeff_table );
roomwater_type = Cvar_Get( "waterroom_type", "14", 0, "water room type" ); Cvar_RegisterVariable( &roomwater_type );
room_type = Cvar_Get( "room_type", "0", 0, "current room type preset" ); Cvar_RegisterVariable( &room_type );
sxmod_lowpass = Cvar_Get( "room_lp", "0", 0, "for water fx, lowpass for entire room" ); Cvar_RegisterVariable( &sxmod_lowpass );
sxmod_mod = Cvar_Get( "room_mod", "0", 0, "stereo amptitude modulation for room" ); Cvar_RegisterVariable( &sxmod_mod );
sxrvb_size = Cvar_Get( "room_size", "0", 0, "reverb: initial reflection size" ); Cvar_RegisterVariable( &sxrvb_size );
sxrvb_feedback = Cvar_Get( "room_refl", "0", 0, "reverb: decay time" ); Cvar_RegisterVariable( &sxrvb_feedback );
sxrvb_lp = Cvar_Get( "room_rvblp", "1", 0, "reverb: low pass filtering level" ); Cvar_RegisterVariable( &sxrvb_lp );
sxdly_delay = Cvar_Get( "room_delay", "0.8", 0, "mono delay: delay time" ); Cvar_RegisterVariable( &sxdly_delay );
sxdly_feedback = Cvar_Get( "room_feedback", "0.2", 0, "mono delay: decay time" ); Cvar_RegisterVariable( &sxdly_feedback );
sxdly_lp = Cvar_Get( "room_dlylp", "1", 0, "mono delay: low pass filtering level" ); 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" ); Cmd_AddCommand( "dsp_profile", SX_Profiling_f, "dsp stress-test, first argument is room_type" );
// for compability
dsp_room = room_type;
SX_ReloadRoomFX(); SX_ReloadRoomFX();
} }
@@ -267,7 +264,7 @@ DLY_Free
Free memory allocated for DSP Free memory allocated for DSP
=========== ===========
*/ */
void DLY_Free( int idelay ) static void DLY_Free( int idelay )
{ {
Assert( idelay >= 0 && idelay < MAXDLY ); Assert( idelay >= 0 && idelay < MAXDLY );
@@ -303,7 +300,7 @@ DLY_Init
Initialize dly Initialize dly
=========== ===========
*/ */
int DLY_Init( int idelay, float delay ) static int DLY_Init( int idelay, float delay )
{ {
dly_t *cur; dly_t *cur;
@@ -339,7 +336,7 @@ DLY_MovePointer
Checks overflow and moves pointer Checks overflow and moves pointer
============ ============
*/ */
_inline void DLY_MovePointer( dly_t *dly ) static void DLY_MovePointer( dly_t *dly )
{ {
if( ++dly->idelayinput >= dly->cdelaysamplesmax ) if( ++dly->idelayinput >= dly->cdelaysamplesmax )
dly->idelayinput = 0; dly->idelayinput = 0;
@@ -355,12 +352,12 @@ DLY_CheckNewStereoDelayVal
Update stereo processor settings if we are in new room 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]; 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; return;
if( delay == 0 ) if( delay == 0 )
@@ -403,7 +400,7 @@ DLY_DoStereoDelay
Do stereo processing Do stereo processing
============= =============
*/ */
void DLY_DoStereoDelay( int count ) static void DLY_DoStereoDelay( int count )
{ {
int delay, samplexf; int delay, samplexf;
dly_t *const dly = &rgsxdly[STEREODLY]; dly_t *const dly = &rgsxdly[STEREODLY];
@@ -468,12 +465,12 @@ DLY_CheckNewDelayVal
Update delay processor settings if we are in new room 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]; dly_t *const dly = &rgsxdly[MONODLY];
if( FBitSet( sxdly_delay->flags, FCVAR_CHANGED )) if( FBitSet( sxdly_delay.flags, FCVAR_CHANGED ))
{ {
if( delay == 0 ) if( delay == 0 )
{ {
@@ -503,8 +500,8 @@ void DLY_CheckNewDelayVal( void )
} }
} }
dly->lp = sxdly_lp->value; dly->lp = sxdly_lp.value;
dly->delayfeedback = 255 * sxdly_feedback->value; dly->delayfeedback = 255 * sxdly_feedback.value;
} }
/* /*
@@ -514,7 +511,7 @@ DLY_DoDelay
Do delay processing Do delay processing
============= =============
*/ */
void DLY_DoDelay( int count ) static void DLY_DoDelay( int count )
{ {
dly_t *const dly = &rgsxdly[MONODLY]; dly_t *const dly = &rgsxdly[MONODLY];
portable_samplepair_t *paint = paintto; portable_samplepair_t *paint = paintto;
@@ -565,7 +562,7 @@ RVB_SetUpDly
Set up dly for reverb 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; int samples;
@@ -601,13 +598,13 @@ RVB_CheckNewReverbVal
Update reverb settings if we are in new room 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 dly1 = &rgsxdly[REVERBPOS];
dly_t *const dly2 = &rgsxdly[REVERBPOS + 1]; 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 ) if( delay == 0.0f )
{ {
@@ -616,13 +613,13 @@ void RVB_CheckNewReverbVal( void )
} }
else else
{ {
RVB_SetUpDly( REVERBPOS, sxrvb_size->value, 500 ); RVB_SetUpDly( REVERBPOS, sxrvb_size.value, 500 );
RVB_SetUpDly( REVERBPOS+1, sxrvb_size->value * 0.71f, 700 ); RVB_SetUpDly( REVERBPOS+1, sxrvb_size.value * 0.71f, 700 );
} }
} }
dly1->lp = dly2->lp = sxrvb_lp->value; dly1->lp = dly2->lp = sxrvb_lp.value;
dly1->delayfeedback = dly2->delayfeedback = (int)(255 * sxrvb_feedback->value); dly1->delayfeedback = dly2->delayfeedback = (int)(255 * sxrvb_feedback.value);
} }
/* /*
@@ -632,7 +629,7 @@ RVB_DoReverbForOneDly
Do reverberation for one dly 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 delay;
int samplexf; int samplexf;
@@ -706,7 +703,7 @@ RVB_DoReverb
Do reverberation processing Do reverberation processing
=========== ===========
*/ */
void RVB_DoReverb( int count ) static void RVB_DoReverb( int count )
{ {
dly_t *const dly1 = &rgsxdly[REVERBPOS]; dly_t *const dly1 = &rgsxdly[REVERBPOS];
dly_t *const dly2 = &rgsxdly[REVERBPOS+1]; dly_t *const dly2 = &rgsxdly[REVERBPOS+1];
@@ -723,7 +720,7 @@ void RVB_DoReverb( int count )
voutm = RVB_DoReverbForOneDly( dly1, vlr, paint ); voutm = RVB_DoReverbForOneDly( dly1, vlr, paint );
voutm += RVB_DoReverbForOneDly( dly2, 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 voutm /= 6; // alpha
else voutm = (11 * voutm) >> 6; else voutm = (11 * voutm) >> 6;
@@ -739,18 +736,18 @@ RVB_DoAMod
Do amplification modulation processing Do amplification modulation processing
=========== ===========
*/ */
void RVB_DoAMod( int count ) static void RVB_DoAMod( int count )
{ {
portable_samplepair_t *paint = paintto; portable_samplepair_t *paint = paintto;
if( !sxmod_lowpass->value && !sxmod_mod->value ) if( !sxmod_lowpass.value && !sxmod_mod.value )
return; return;
for( ; count; count--, paint++ ) for( ; count; count--, paint++ )
{ {
portable_samplepair_t res = *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.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; res.right = rgsxlp[5] + rgsxlp[6] + rgsxlp[7] + rgsxlp[8] + rgsxlp[9] + res.right;
@@ -772,7 +769,7 @@ void RVB_DoAMod( int count )
rgsxlp[8] = rgsxlp[9]; rgsxlp[8] = rgsxlp[9];
} }
if( sxmod_mod->value ) if( sxmod_mod.value )
{ {
if( --sxmod1cur < 0 ) if( --sxmod1cur < 0 )
sxmod1cur = sxmod1; sxmod1cur = sxmod1;
@@ -812,13 +809,9 @@ DSP_Process
(xash dsp interface) (xash dsp interface)
=========== ===========
*/ */
void DSP_Process( int idsp, portable_samplepair_t *pbfront, int sampleCount ) void DSP_Process( portable_samplepair_t *pbfront, int sampleCount )
{ {
if( dsp_off->value ) if( dsp_off.value || room_off.value || !sampleCount )
return;
// don't process DSP while in menu
if( cls.key_dest == key_menu || !sampleCount )
return; return;
// preset is already installed by CheckNewDspPresets // preset is already installed by CheckNewDspPresets
@@ -839,7 +832,7 @@ DSP_ClearState
*/ */
void DSP_ClearState( void ) void DSP_ClearState( void )
{ {
Cvar_SetValue( "room_type", 0.0f ); Cvar_DirectSet( &room_type, "0" );
SX_ReloadRoomFX(); SX_ReloadRoomFX();
} }
@@ -852,12 +845,12 @@ CheckNewDspPresets
*/ */
void CheckNewDspPresets( void ) void CheckNewDspPresets( void )
{ {
if( dsp_off->value != 0.0f ) if( dsp_off.value || room_off.value )
return; 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 case 0: // release
ptable = rgsxpre; ptable = rgsxpre;
@@ -873,20 +866,20 @@ void CheckNewDspPresets( void )
SX_ReloadRoomFX(); SX_ReloadRoomFX();
room_typeprev = -1; room_typeprev = -1;
ClearBits( dsp_coeff_table->flags, FCVAR_CHANGED ); ClearBits( dsp_coeff_table.flags, FCVAR_CHANGED );
} }
if( s_listener.waterlevel > 2 ) if( s_listener.waterlevel > 2 )
idsp_room = roomwater_type->value; idsp_room = roomwater_type.value;
else idsp_room = room_type->value; else idsp_room = room_type.value;
// don't pass invalid presets // don't pass invalid presets
idsp_room = bound( 0, idsp_room, MAX_ROOM_TYPES ); idsp_room = bound( 0, idsp_room, MAX_ROOM_TYPES );
if( FBitSet( hisound->flags, FCVAR_CHANGED )) if( FBitSet( hisound.flags, FCVAR_CHANGED ))
{ {
sxhires = hisound->value; sxhires = hisound.value;
ClearBits( hisound->flags, FCVAR_CHANGED ); ClearBits( hisound.flags, FCVAR_CHANGED );
} }
if( idsp_room == room_typeprev && idsp_room == 0 ) if( idsp_room == room_typeprev && idsp_room == 0 )
@@ -898,15 +891,15 @@ void CheckNewDspPresets( void )
cur = ptable + idsp_room; cur = ptable + idsp_room;
Cvar_SetValue( "room_lp", cur->room_lp ); Cvar_DirectSetValue( &sxmod_lowpass, cur->room_lp );
Cvar_SetValue( "room_mod", cur->room_mod ); Cvar_DirectSetValue( &sxmod_mod, cur->room_mod );
Cvar_SetValue( "room_size", cur->room_size ); Cvar_DirectSetValue( &sxrvb_size, cur->room_size );
Cvar_SetValue( "room_refl", cur->room_refl ); Cvar_DirectSetValue( &sxrvb_feedback, cur->room_refl );
Cvar_SetValue( "room_rvblp", cur->room_rvblp ); Cvar_DirectSetValue( &sxrvb_lp, cur->room_rvblp );
Cvar_SetValue( "room_delay", cur->room_delay ); Cvar_DirectSetValue( &sxdly_delay, cur->room_delay );
Cvar_SetValue( "room_feedback", cur->room_feedback ); Cvar_DirectSetValue( &sxdly_feedback, cur->room_feedback );
Cvar_SetValue( "room_dlylp", cur->room_dlylp ); Cvar_DirectSetValue( &sxdly_lp, cur->room_dlylp );
Cvar_SetValue( "room_left", cur->room_left ); Cvar_DirectSetValue( &sxste_delay, cur->room_left );
} }
room_typeprev = idsp_room; room_typeprev = idsp_room;
@@ -915,15 +908,15 @@ void CheckNewDspPresets( void )
DLY_CheckNewDelayVal( ); DLY_CheckNewDelayVal( );
DLY_CheckNewStereoDelayVal(); DLY_CheckNewStereoDelayVal();
ClearBits( sxrvb_size->flags, FCVAR_CHANGED ); ClearBits( sxrvb_size.flags, FCVAR_CHANGED );
ClearBits( sxdly_delay->flags, FCVAR_CHANGED ); ClearBits( sxdly_delay.flags, FCVAR_CHANGED );
ClearBits( sxste_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]; portable_samplepair_t testbuffer[512];
float oldroom = room_type->value; float oldroom = room_type.value;
double start, end; double start, end;
int i, calls; int i, calls;
@@ -935,7 +928,7 @@ void SX_Profiling_f( void )
if( Cmd_Argc() > 1 ) if( Cmd_Argc() > 1 )
{ {
Cvar_SetValue( "room_type", Q_atof( Cmd_Argv( 1 ))); Cvar_DirectSetValue( &room_type, Q_atof( Cmd_Argv( 1 )));
SX_ReloadRoomFX(); SX_ReloadRoomFX();
CheckNewDspPresets(); // we just need idsp_room immediately, for message below CheckNewDspPresets(); // we just need idsp_room immediately, for message below
} }
@@ -945,7 +938,7 @@ void SX_Profiling_f( void )
start = Sys_DoubleTime(); start = Sys_DoubleTime();
for( calls = 10000; calls; calls-- ) for( calls = 10000; calls; calls-- )
{ {
DSP_Process( idsp_room, testbuffer, 512 ); DSP_Process( testbuffer, 512 );
} }
end = Sys_DoubleTime(); end = Sys_DoubleTime();
@@ -953,7 +946,7 @@ void SX_Profiling_f( void )
if( Cmd_Argc() > 1 ) if( Cmd_Argc() > 1 )
{ {
Cvar_SetValue( "room_type", oldroom ); Cvar_DirectSetValue( &room_type, oldroom );
SX_ReloadRoomFX(); SX_ReloadRoomFX();
CheckNewDspPresets(); CheckNewDspPresets();
} }

View File

@@ -52,8 +52,11 @@ void S_SoundList_f( void )
{ {
totalSize += sc->size; totalSize += sc->size;
if( sc->loopStart >= 0 ) Con_Printf( "L" ); if( FBitSet( sc->flags, SOUND_LOOPED ))
else Con_Printf( " " ); Con_Printf( "L" );
else
Con_Printf( " " );
if( sfx->name[0] == '*' || !Q_strncmp( sfx->name, DEFAULT_SOUNDPATH, sizeof( DEFAULT_SOUNDPATH ) - 1 )) 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 ); 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 ); else Con_Printf( " (%2db) %s : " DEFAULT_SOUNDPATH "%s\n", sc->width * 8, Q_memprint( sc->size ), sfx->name );
@@ -110,7 +113,7 @@ static wavdata_t *S_CreateDefaultSound( void )
sc->width = 2; sc->width = 2;
sc->channels = 1; sc->channels = 1;
sc->loopStart = -1; sc->loopStart = 0;
sc->rate = SOUND_DMA_SPEED; sc->rate = SOUND_DMA_SPEED;
sc->samples = SOUND_DMA_SPEED; sc->samples = SOUND_DMA_SPEED;
sc->size = sc->samples * sc->width * sc->channels; sc->size = sc->samples * sc->width * sc->channels;
@@ -155,7 +158,7 @@ wavdata_t *S_LoadSound( sfx_t *sfx )
Sound_Process( &sc, SOUND_11k, sc->width, SOUND_RESAMPLE ); Sound_Process( &sc, SOUND_11k, sc->width, SOUND_RESAMPLE );
else if( sc->rate > SOUND_11k && sc->rate < SOUND_22k ) // some bad sounds else if( sc->rate > SOUND_11k && sc->rate < SOUND_22k ) // some bad sounds
Sound_Process( &sc, SOUND_22k, sc->width, SOUND_RESAMPLE ); Sound_Process( &sc, SOUND_22k, sc->width, SOUND_RESAMPLE );
else if( sc->rate > SOUND_22k && sc->rate <= SOUND_32k ) // some bad sounds else if( sc->rate > SOUND_22k && sc->rate < SOUND_44k ) // some bad sounds
Sound_Process( &sc, SOUND_44k, sc->width, SOUND_RESAMPLE ); Sound_Process( &sc, SOUND_44k, sc->width, SOUND_RESAMPLE );
sfx->cache = sc; sfx->cache = sc;
@@ -218,7 +221,7 @@ sfx_t *S_FindName( const char *pname, int *pfInCache )
sfx = &s_knownSfx[i]; sfx = &s_knownSfx[i];
memset( sfx, 0, sizeof( *sfx )); memset( sfx, 0, sizeof( *sfx ));
if( pfInCache ) *pfInCache = false; if( pfInCache ) *pfInCache = false;
Q_strncpy( sfx->name, name, MAX_STRING ); Q_strncpy( sfx->name, name, sizeof( sfx->name ));
sfx->servercount = cl.servercount; sfx->servercount = cl.servercount;
sfx->hashValue = COM_HashKey( sfx->name, MAX_SFX_HASH ); sfx->hashValue = COM_HashKey( sfx->name, MAX_SFX_HASH );
@@ -377,7 +380,7 @@ S_InitSounds
void S_InitSounds( void ) void S_InitSounds( void )
{ {
// create unused 0-entry // create unused 0-entry
Q_strncpy( s_knownSfx->name, "*default", MAX_QPATH ); Q_strncpy( s_knownSfx->name, "*default", sizeof( s_knownSfx->name ));
s_knownSfx->hashValue = COM_HashKey( s_knownSfx->name, MAX_SFX_HASH ); s_knownSfx->hashValue = COM_HashKey( s_knownSfx->name, MAX_SFX_HASH );
s_knownSfx->hashNext = s_sfxHashList[s_knownSfx->hashValue]; s_knownSfx->hashNext = s_sfxHashList[s_knownSfx->hashValue];
s_sfxHashList[s_knownSfx->hashValue] = s_knownSfx; s_sfxHashList[s_knownSfx->hashValue] = s_knownSfx;

View File

@@ -43,7 +43,7 @@ CVAR_DEFINE_AUTO( s_lerping, "0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "apply interpo
static CVAR_DEFINE( s_ambient_level, "ambient_level", "0.3", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "volume of environment noises (water and wind)" ); static CVAR_DEFINE( s_ambient_level, "ambient_level", "0.3", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "volume of environment noises (water and wind)" );
static CVAR_DEFINE( s_ambient_fade, "ambient_fade", "1000", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "rate of volume fading when client is moving" ); static CVAR_DEFINE( s_ambient_fade, "ambient_fade", "1000", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "rate of volume fading when client is moving" );
static CVAR_DEFINE_AUTO( s_combine_sounds, "0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "combine channels with same sounds" ); static CVAR_DEFINE_AUTO( s_combine_sounds, "0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "combine channels with same sounds" );
CVAR_DEFINE_AUTO( snd_mute_losefocus, "1", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "silence the audio when game window loses focus" ); static CVAR_DEFINE_AUTO( snd_mute_losefocus, "1", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "silence the audio when game window loses focus" );
CVAR_DEFINE_AUTO( s_test, "0", 0, "engine developer cvar for quick testing new features" ); CVAR_DEFINE_AUTO( s_test, "0", 0, "engine developer cvar for quick testing new features" );
CVAR_DEFINE_AUTO( s_samplecount, "0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "sample count (0 for default value)" ); CVAR_DEFINE_AUTO( s_samplecount, "0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "sample count (0 for default value)" );
CVAR_DEFINE_AUTO( s_warn_late_precache, "0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "warn about late precached sounds on client-side" ); CVAR_DEFINE_AUTO( s_warn_late_precache, "0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "warn about late precached sounds on client-side" );
@@ -64,6 +64,18 @@ float S_GetMasterVolume( void )
{ {
float scale = 1.0f; float scale = 1.0f;
if( host.status == HOST_NOFOCUS && snd_mute_losefocus.value != 0.0f )
{
// we return zero volume to keep sounds running
return 0.0f;
}
if( s_listener.inmenu && !ui_renderworld.value && !Host_IsLocalGame( ))
{
// mute sounds in menu when it's not transparent and we're in multiplayer
return 0.0f;
}
if( !s_listener.inmenu && soundfade.percent != 0 ) if( !s_listener.inmenu && soundfade.percent != 0 )
{ {
scale = bound( 0.0f, soundfade.percent / 100.0f, 1.0f ); scale = bound( 0.0f, soundfade.percent / 100.0f, 1.0f );
@@ -91,7 +103,7 @@ void S_FadeClientVolume( float fadePercent, float fadeOutSeconds, float holdTime
S_IsClient S_IsClient
================= =================
*/ */
qboolean S_IsClient( int entnum ) static qboolean S_IsClient( int entnum )
{ {
return ( entnum == s_listener.entnum ); return ( entnum == s_listener.entnum );
} }
@@ -124,7 +136,7 @@ void S_FreeChannel( channel_t *ch )
S_UpdateSoundFade S_UpdateSoundFade
================= =================
*/ */
void S_UpdateSoundFade( void ) static void S_UpdateSoundFade( void )
{ {
float f, totaltime, elapsed; float f, totaltime, elapsed;
@@ -184,7 +196,7 @@ override any other sound playing on the same channel (see code comments below fo
exceptions). exceptions).
================= =================
*/ */
qboolean SND_FStreamIsPlaying( sfx_t *sfx ) static qboolean SND_FStreamIsPlaying( sfx_t *sfx )
{ {
int ch_idx; int ch_idx;
@@ -322,7 +334,7 @@ channel_t *SND_PickDynamicChannel( int entnum, int channel, sfx_t *sfx, qboolean
// don't restart looping sounds for the same entity // don't restart looping sounds for the same entity
wavdata_t *sc = channels[first_to_die].sfx->cache; wavdata_t *sc = channels[first_to_die].sfx->cache;
if( sc && sc->loopStart != -1 ) if( sc && FBitSet( sc->flags, SOUND_LOOPED ))
{ {
channel_t *ch = &channels[first_to_die]; channel_t *ch = &channels[first_to_die];
@@ -399,7 +411,7 @@ returns TRUE if sound was altered,
returns FALSE if sound was not found (sound is not playing) returns FALSE if sound was not found (sound is not playing)
================= =================
*/ */
int S_AlterChannel( int entnum, int channel, sfx_t *sfx, int vol, int pitch, int flags ) static int S_AlterChannel( int entnum, int channel, sfx_t *sfx, int vol, int pitch, int flags )
{ {
channel_t *ch; channel_t *ch;
int i; int i;
@@ -457,7 +469,7 @@ int S_AlterChannel( int entnum, int channel, sfx_t *sfx, int vol, int pitch, int
S_SpatializeChannel S_SpatializeChannel
================= =================
*/ */
void S_SpatializeChannel( int *left_vol, int *right_vol, int master_vol, float gain, float dot, float dist ) static void S_SpatializeChannel( int *left_vol, int *right_vol, int master_vol, float gain, float dot, float dist )
{ {
float lscale, rscale, scale; float lscale, rscale, scale;
@@ -480,7 +492,7 @@ void S_SpatializeChannel( int *left_vol, int *right_vol, int master_vol, float g
SND_Spatialize SND_Spatialize
================= =================
*/ */
void SND_Spatialize( channel_t *ch ) static void SND_Spatialize( channel_t *ch )
{ {
vec3_t source_vec; vec3_t source_vec;
float dist, dot, gain = 1.0f; float dist, dot, gain = 1.0f;
@@ -497,7 +509,7 @@ void SND_Spatialize( channel_t *ch )
pSource = ch->sfx->cache; pSource = ch->sfx->cache;
if( ch->use_loop && pSource && pSource->loopStart != -1 ) if( ch->use_loop && pSource && FBitSet( pSource->flags, SOUND_LOOPED ))
looping = true; looping = true;
if( !ch->staticsound ) if( !ch->staticsound )
@@ -635,7 +647,7 @@ void S_StartSound( const vec3_t pos, int ent, int chan, sound_t handle, float fv
if( !target_chan->leftvol && !target_chan->rightvol ) if( !target_chan->leftvol && !target_chan->rightvol )
{ {
// looping sounds don't use this optimization because they should stick around until they're killed. // looping sounds don't use this optimization because they should stick around until they're killed.
if( !sfx->cache || sfx->cache->loopStart == -1 ) if( !sfx->cache || !FBitSet( sfx->cache->flags, SOUND_LOOPED ))
{ {
// if this is a streaming sound, play the whole thing. // if this is a streaming sound, play the whole thing.
if( chan != CHAN_STREAM ) if( chan != CHAN_STREAM )
@@ -648,20 +660,6 @@ void S_StartSound( const vec3_t pos, int ent, int chan, sound_t handle, float fv
// Init client entity mouth movement vars // Init client entity mouth movement vars
SND_InitMouth( ent, chan ); SND_InitMouth( ent, chan );
for( ch_idx = NUM_AMBIENTS, check = channels + NUM_AMBIENTS; ch_idx < MAX_DYNAMIC_CHANNELS; ch_idx++, check++)
{
if( check == target_chan ) continue;
if( check->sfx == sfx && !check->pMixer.sample )
{
// skip up to 0.1 seconds of audio
int skip = COM_RandomLong( 0, (long)( 0.1f * check->sfx->cache->rate ));
S_SetSampleStart( check, sfx->cache, skip );
break;
}
}
} }
/* /*
@@ -901,7 +899,7 @@ int S_GetCurrentStaticSounds( soundlist_t *pout, int size )
VectorCopy( channels[i].origin, pout->origin ); VectorCopy( channels[i].origin, pout->origin );
pout->volume = (float)channels[i].master_vol / 255.0f; pout->volume = (float)channels[i].master_vol / 255.0f;
pout->attenuation = channels[i].dist_mult * SND_CLIP_DISTANCE; pout->attenuation = channels[i].dist_mult * SND_CLIP_DISTANCE;
pout->looping = ( channels[i].use_loop && channels[i].sfx->cache->loopStart != -1 ); pout->looping = ( channels[i].use_loop && FBitSet( channels[i].sfx->cache->flags, SOUND_LOOPED ));
pout->pitch = channels[i].basePitch; pout->pitch = channels[i].basePitch;
pout->channel = channels[i].entchannel; pout->channel = channels[i].entchannel;
pout->wordIndex = channels[i].wordIndex; pout->wordIndex = channels[i].wordIndex;
@@ -936,7 +934,7 @@ int S_GetCurrentDynamicSounds( soundlist_t *pout, int size )
if( !channels[i].sfx || !channels[i].sfx->name[0] || !Q_stricmp( channels[i].sfx->name, "*default" )) if( !channels[i].sfx || !channels[i].sfx->name[0] || !Q_stricmp( channels[i].sfx->name, "*default" ))
continue; // don't serialize default sounds continue; // don't serialize default sounds
looped = ( channels[i].use_loop && channels[i].sfx->cache->loopStart != -1 ); looped = ( channels[i].use_loop && FBitSet( channels[i].sfx->cache->flags, SOUND_LOOPED ));
if( channels[i].entchannel == CHAN_STATIC && looped && !Host_IsQuakeCompatible()) if( channels[i].entchannel == CHAN_STATIC && looped && !Host_IsQuakeCompatible())
continue; // never serialize static looped sounds. It will be restoring in game code continue; // never serialize static looped sounds. It will be restoring in game code
@@ -967,7 +965,7 @@ int S_GetCurrentDynamicSounds( soundlist_t *pout, int size )
S_InitAmbientChannels S_InitAmbientChannels
=================== ===================
*/ */
void S_InitAmbientChannels( void ) static void S_InitAmbientChannels( void )
{ {
int ambient_channel; int ambient_channel;
channel_t *chan; channel_t *chan;
@@ -989,7 +987,7 @@ void S_InitAmbientChannels( void )
S_UpdateAmbientSounds S_UpdateAmbientSounds
=================== ===================
*/ */
void S_UpdateAmbientSounds( void ) static void S_UpdateAmbientSounds( void )
{ {
mleaf_t *leaf; mleaf_t *leaf;
float vol; float vol;
@@ -1421,7 +1419,7 @@ static void S_FreeRawChannels( void )
S_ClearBuffer S_ClearBuffer
================== ==================
*/ */
void S_ClearBuffer( void ) static void S_ClearBuffer( void )
{ {
S_ClearRawChannels(); S_ClearRawChannels();
@@ -1520,7 +1518,7 @@ static int S_GetSoundtime( void )
} }
//============================================================================= //=============================================================================
void S_UpdateChannels( void ) static void S_UpdateChannels( void )
{ {
uint endtime; uint endtime;
int samps; int samps;
@@ -1607,7 +1605,6 @@ void SND_UpdateSound( void )
// release raw-channels that no longer used more than 10 secs // release raw-channels that no longer used more than 10 secs
S_FreeIdleRawChannels(); S_FreeIdleRawChannels();
VectorCopy( cl.simvel, s_listener.velocity );
s_listener.frametime = (cl.time - cl.oldtime); s_listener.frametime = (cl.time - cl.oldtime);
s_listener.waterlevel = cl.local.waterlevel; s_listener.waterlevel = cl.local.waterlevel;
s_listener.active = CL_IsInGame(); s_listener.active = CL_IsInGame();
@@ -1709,7 +1706,7 @@ console functions
=============================================================================== ===============================================================================
*/ */
void S_Play_f( void ) static void S_Play_f( void )
{ {
if( Cmd_Argc() == 1 ) if( Cmd_Argc() == 1 )
{ {
@@ -1720,7 +1717,7 @@ void S_Play_f( void )
S_StartLocalSound( Cmd_Argv( 1 ), VOL_NORM, false ); S_StartLocalSound( Cmd_Argv( 1 ), VOL_NORM, false );
} }
void S_Play2_f( void ) static void S_Play2_f( void )
{ {
int i = 1; int i = 1;
@@ -1737,7 +1734,7 @@ void S_Play2_f( void )
} }
} }
void S_PlayVol_f( void ) static void S_PlayVol_f( void )
{ {
if( Cmd_Argc() == 1 ) if( Cmd_Argc() == 1 )
{ {
@@ -1763,7 +1760,7 @@ static void S_Say( const char *name, qboolean reliable )
S_StartLocalSound( sentence, 1.0f, reliable ); S_StartLocalSound( sentence, 1.0f, reliable );
} }
void S_Say_f( void ) static void S_Say_f( void )
{ {
if( Cmd_Argc() == 1 ) if( Cmd_Argc() == 1 )
{ {
@@ -1774,7 +1771,7 @@ void S_Say_f( void )
S_Say( Cmd_Argv( 1 ), false ); S_Say( Cmd_Argv( 1 ), false );
} }
void S_SayReliable_f( void ) static void S_SayReliable_f( void )
{ {
if( Cmd_Argc() == 1 ) if( Cmd_Argc() == 1 )
{ {
@@ -1790,7 +1787,7 @@ void S_SayReliable_f( void )
S_Music_f S_Music_f
================= =================
*/ */
void S_Music_f( void ) static void S_Music_f( void )
{ {
int c = Cmd_Argc(); int c = Cmd_Argc();
@@ -1854,7 +1851,7 @@ void S_Music_f( void )
S_StopSound_f S_StopSound_f
================= =================
*/ */
void S_StopSound_f( void ) static void S_StopSound_f( void )
{ {
S_StopAllSounds( true ); S_StopAllSounds( true );
} }
@@ -1864,7 +1861,7 @@ void S_StopSound_f( void )
S_SoundFade_f S_SoundFade_f
================= =================
*/ */
void S_SoundFade_f( void ) static void S_SoundFade_f( void )
{ {
int c = Cmd_Argc(); int c = Cmd_Argc();
float fadeTime = 5.0f; float fadeTime = 5.0f;
@@ -1898,7 +1895,7 @@ void S_SoundInfo_f( void )
S_VoiceRecordStart_f S_VoiceRecordStart_f
================= =================
*/ */
void S_VoiceRecordStart_f( void ) static void S_VoiceRecordStart_f( void )
{ {
if( cls.state != ca_active || cls.legacymode ) if( cls.state != ca_active || cls.legacymode )
return; return;
@@ -1911,7 +1908,7 @@ void S_VoiceRecordStart_f( void )
S_VoiceRecordStop_f S_VoiceRecordStop_f
================= =================
*/ */
void S_VoiceRecordStop_f( void ) static void S_VoiceRecordStop_f( void )
{ {
if( cls.state != ca_active || !Voice_IsRecording() ) if( cls.state != ca_active || !Voice_IsRecording() )
return; return;

View File

@@ -17,13 +17,20 @@ GNU General Public License for more details.
#include "sound.h" #include "sound.h"
#include "client.h" #include "client.h"
#define IPAINTBUFFER 0 enum
#define IROOMBUFFER 1 {
#define ISTREAMBUFFER 2 IPAINTBUFFER = 0,
IROOMBUFFER,
ISTREAMBUFFER,
CPAINTBUFFERS,
};
#define FILTERTYPE_NONE 0 enum
#define FILTERTYPE_LINEAR 1 {
#define FILTERTYPE_CUBIC 2 FILTERTYPE_NONE = 0,
FILTERTYPE_LINEAR,
FILTERTYPE_CUBIC,
};
#define CCHANVOLUMES 2 #define CCHANVOLUMES 2
@@ -31,16 +38,35 @@ GNU General Public License for more details.
#define SND_SCALE_SHIFT ( 8 - SND_SCALE_BITS ) #define SND_SCALE_SHIFT ( 8 - SND_SCALE_BITS )
#define SND_SCALE_LEVELS ( 1 << SND_SCALE_BITS ) #define SND_SCALE_LEVELS ( 1 << SND_SCALE_BITS )
portable_samplepair_t *g_curpaintbuffer; // sound mixing buffer
portable_samplepair_t streambuffer[(PAINTBUFFER_SIZE+1)]; #define CPAINTFILTERMEM 3
portable_samplepair_t paintbuffer[(PAINTBUFFER_SIZE+1)]; #define CPAINTFILTERS 4 // maximum number of consecutive upsample passes per paintbuffer
portable_samplepair_t roombuffer[(PAINTBUFFER_SIZE+1)];
portable_samplepair_t facingbuffer[(PAINTBUFFER_SIZE+1)];
portable_samplepair_t temppaintbuffer[(PAINTBUFFER_SIZE+1)];
paintbuffer_t paintbuffers[CPAINTBUFFERS];
int snd_scaletable[SND_SCALE_LEVELS][256]; // fixed point stuff for real-time resampling
#define FIX_BITS 28
#define FIX_SCALE ( 1 << FIX_BITS )
#define FIX_MASK (( 1 << FIX_BITS ) - 1 )
#define FIX_FLOAT( a ) ((int)(( a ) * FIX_SCALE ))
#define FIX( a ) (((int)( a )) << FIX_BITS )
#define FIX_INTPART( a ) (((int)( a )) >> FIX_BITS )
#define FIX_FRACPART( a ) (( a ) & FIX_MASK )
typedef struct
{
qboolean factive; // if true, mix to this paintbuffer using flags
portable_samplepair_t *pbuf; // front stereo mix buffer, for 2 or 4 channel mixing
int ifilter; // current filter memory buffer to use for upsampling pass
portable_samplepair_t fltmem[CPAINTFILTERS][CPAINTFILTERMEM];
} paintbuffer_t;
static portable_samplepair_t *g_curpaintbuffer;
static portable_samplepair_t streambuffer[(PAINTBUFFER_SIZE+1)];
static portable_samplepair_t paintbuffer[(PAINTBUFFER_SIZE+1)];
static portable_samplepair_t roombuffer[(PAINTBUFFER_SIZE+1)];
static portable_samplepair_t temppaintbuffer[(PAINTBUFFER_SIZE+1)];
static paintbuffer_t paintbuffers[CPAINTBUFFERS];
static int snd_scaletable[SND_SCALE_LEVELS][256];
void S_InitScaletable( void ) void S_InitScaletable( void )
{ {
int i, j; int i, j;
@@ -58,7 +84,7 @@ S_TransferPaintBuffer
=================== ===================
*/ */
void S_TransferPaintBuffer( int endtime ) static void S_TransferPaintBuffer( int endtime )
{ {
int *snd_p, snd_linear_count; int *snd_p, snd_linear_count;
int lpos, lpaintedtime; int lpos, lpaintedtime;
@@ -67,7 +93,7 @@ void S_TransferPaintBuffer( int endtime )
dword *pbuf; dword *pbuf;
pbuf = (dword *)dma.buffer; pbuf = (dword *)dma.buffer;
snd_p = (int *)PAINTBUFFER; snd_p = (int *)g_curpaintbuffer;
lpaintedtime = paintedtime; lpaintedtime = paintedtime;
sampleMask = ((dma.samples >> 1) - 1); sampleMask = ((dma.samples >> 1) - 1);
@@ -111,20 +137,20 @@ void S_TransferPaintBuffer( int endtime )
//=============================================================================== //===============================================================================
// Activate a paintbuffer. All active paintbuffers are mixed in parallel within // Activate a paintbuffer. All active paintbuffers are mixed in parallel within
// MIX_MixChannelsToPaintbuffer, according to flags // MIX_MixChannelsToPaintbuffer, according to flags
_inline void MIX_ActivatePaintbuffer( int ipaintbuffer ) static void MIX_ActivatePaintbuffer( int ipaintbuffer )
{ {
Assert( ipaintbuffer < CPAINTBUFFERS ); Assert( ipaintbuffer < CPAINTBUFFERS );
paintbuffers[ipaintbuffer].factive = true; paintbuffers[ipaintbuffer].factive = true;
} }
_inline void MIX_SetCurrentPaintbuffer( int ipaintbuffer ) static void MIX_SetCurrentPaintbuffer( int ipaintbuffer )
{ {
Assert( ipaintbuffer < CPAINTBUFFERS ); Assert( ipaintbuffer < CPAINTBUFFERS );
g_curpaintbuffer = paintbuffers[ipaintbuffer].pbuf; g_curpaintbuffer = paintbuffers[ipaintbuffer].pbuf;
Assert( g_curpaintbuffer != NULL ); Assert( g_curpaintbuffer != NULL );
} }
_inline int MIX_GetCurrentPaintbufferIndex( void ) static int MIX_GetCurrentPaintbufferIndex( void )
{ {
int i; int i;
@@ -136,7 +162,7 @@ _inline int MIX_GetCurrentPaintbufferIndex( void )
return 0; return 0;
} }
_inline paintbuffer_t *MIX_GetCurrentPaintbufferPtr( void ) static paintbuffer_t *MIX_GetCurrentPaintbufferPtr( void )
{ {
int ipaint = MIX_GetCurrentPaintbufferIndex(); int ipaint = MIX_GetCurrentPaintbufferIndex();
@@ -145,7 +171,7 @@ _inline paintbuffer_t *MIX_GetCurrentPaintbufferPtr( void )
} }
// Don't mix into any paintbuffers // Don't mix into any paintbuffers
_inline void MIX_DeactivateAllPaintbuffers( void ) static void MIX_DeactivateAllPaintbuffers( void )
{ {
int i; int i;
@@ -154,7 +180,7 @@ _inline void MIX_DeactivateAllPaintbuffers( void )
} }
// set upsampling filter indexes back to 0 // set upsampling filter indexes back to 0
_inline void MIX_ResetPaintbufferFilterCounters( void ) static void MIX_ResetPaintbufferFilterCounters( void )
{ {
int i; int i;
@@ -163,13 +189,13 @@ _inline void MIX_ResetPaintbufferFilterCounters( void )
} }
// return pointer to front paintbuffer pbuf, given index // return pointer to front paintbuffer pbuf, given index
_inline portable_samplepair_t *MIX_GetPFrontFromIPaint( int ipaintbuffer ) static portable_samplepair_t *MIX_GetPFrontFromIPaint( int ipaintbuffer )
{ {
Assert( ipaintbuffer < CPAINTBUFFERS ); Assert( ipaintbuffer < CPAINTBUFFERS );
return paintbuffers[ipaintbuffer].pbuf; return paintbuffers[ipaintbuffer].pbuf;
} }
_inline paintbuffer_t *MIX_GetPPaintFromIPaint( int ipaint ) static paintbuffer_t *MIX_GetPPaintFromIPaint( int ipaint )
{ {
Assert( ipaint < CPAINTBUFFERS ); Assert( ipaint < CPAINTBUFFERS );
return &paintbuffers[ipaint]; return &paintbuffers[ipaint];
@@ -201,7 +227,7 @@ CHANNEL MIXING
=============================================================================== ===============================================================================
*/ */
void S_PaintMonoFrom8( portable_samplepair_t *pbuf, int *volume, byte *pData, int outCount ) static void S_PaintMonoFrom8( portable_samplepair_t *pbuf, int *volume, byte *pData, int outCount )
{ {
int *lscale, *rscale; int *lscale, *rscale;
int i, data; int i, data;
@@ -217,7 +243,7 @@ void S_PaintMonoFrom8( portable_samplepair_t *pbuf, int *volume, byte *pData, in
} }
} }
void S_PaintStereoFrom8( portable_samplepair_t *pbuf, int *volume, byte *pData, int outCount ) static void S_PaintStereoFrom8( portable_samplepair_t *pbuf, int *volume, byte *pData, int outCount )
{ {
int *lscale, *rscale; int *lscale, *rscale;
uint left, right; uint left, right;
@@ -237,7 +263,7 @@ void S_PaintStereoFrom8( portable_samplepair_t *pbuf, int *volume, byte *pData,
} }
} }
void S_PaintMonoFrom16( portable_samplepair_t *pbuf, int *volume, short *pData, int outCount ) static void S_PaintMonoFrom16( portable_samplepair_t *pbuf, int *volume, short *pData, int outCount )
{ {
int left, right; int left, right;
int i, data; int i, data;
@@ -252,7 +278,7 @@ void S_PaintMonoFrom16( portable_samplepair_t *pbuf, int *volume, short *pData,
} }
} }
void S_PaintStereoFrom16( portable_samplepair_t *pbuf, int *volume, short *pData, int outCount ) static void S_PaintStereoFrom16( portable_samplepair_t *pbuf, int *volume, short *pData, int outCount )
{ {
uint *data; uint *data;
int left, right; int left, right;
@@ -273,11 +299,11 @@ void S_PaintStereoFrom16( portable_samplepair_t *pbuf, int *volume, short *pData
} }
} }
void S_Mix8MonoTimeCompress( portable_samplepair_t *pbuf, int *volume, byte *pData, int inputOffset, uint rateScale, int outCount, int timecompress ) static void S_Mix8MonoTimeCompress( portable_samplepair_t *pbuf, int *volume, byte *pData, int inputOffset, uint rateScale, int outCount, int timecompress )
{ {
} }
void S_Mix8Mono( portable_samplepair_t *pbuf, int *volume, byte *pData, int inputOffset, uint rateScale, int outCount, int timecompress ) static void S_Mix8Mono( portable_samplepair_t *pbuf, int *volume, byte *pData, int inputOffset, uint rateScale, int outCount, int timecompress )
{ {
int i, sampleIndex = 0; int i, sampleIndex = 0;
uint sampleFrac = inputOffset; uint sampleFrac = inputOffset;
@@ -309,7 +335,7 @@ void S_Mix8Mono( portable_samplepair_t *pbuf, int *volume, byte *pData, int inpu
} }
} }
void S_Mix8Stereo( portable_samplepair_t *pbuf, int *volume, byte *pData, int inputOffset, uint rateScale, int outCount ) static void S_Mix8Stereo( portable_samplepair_t *pbuf, int *volume, byte *pData, int inputOffset, uint rateScale, int outCount )
{ {
int i, sampleIndex = 0; int i, sampleIndex = 0;
uint sampleFrac = inputOffset; uint sampleFrac = inputOffset;
@@ -335,7 +361,7 @@ void S_Mix8Stereo( portable_samplepair_t *pbuf, int *volume, byte *pData, int in
} }
} }
void S_Mix16Mono( portable_samplepair_t *pbuf, int *volume, short *pData, int inputOffset, uint rateScale, int outCount ) static void S_Mix16Mono( portable_samplepair_t *pbuf, int *volume, short *pData, int inputOffset, uint rateScale, int outCount )
{ {
int i, sampleIndex = 0; int i, sampleIndex = 0;
uint sampleFrac = inputOffset; uint sampleFrac = inputOffset;
@@ -357,7 +383,7 @@ void S_Mix16Mono( portable_samplepair_t *pbuf, int *volume, short *pData, int in
} }
} }
void S_Mix16Stereo( portable_samplepair_t *pbuf, int *volume, short *pData, int inputOffset, uint rateScale, int outCount ) static void S_Mix16Stereo( portable_samplepair_t *pbuf, int *volume, short *pData, int inputOffset, uint rateScale, int outCount )
{ {
int i, sampleIndex = 0; int i, sampleIndex = 0;
uint sampleFrac = inputOffset; uint sampleFrac = inputOffset;
@@ -379,7 +405,7 @@ void S_Mix16Stereo( portable_samplepair_t *pbuf, int *volume, short *pData, int
} }
} }
void S_MixChannel( channel_t *pChannel, void *pData, int outputOffset, int inputOffset, uint fracRate, int outCount, int timecompress ) static void S_MixChannel( channel_t *pChannel, void *pData, int outputOffset, int inputOffset, uint fracRate, int outCount, int timecompress )
{ {
int pvol[CCHANVOLUMES]; int pvol[CCHANVOLUMES];
paintbuffer_t *ppaint = MIX_GetCurrentPaintbufferPtr(); paintbuffer_t *ppaint = MIX_GetCurrentPaintbufferPtr();
@@ -496,7 +522,7 @@ int S_MixDataToDevice( channel_t *pChannel, int sampleCount, int outRate, int ou
return outOffset - startingOffset; return outOffset - startingOffset;
} }
qboolean S_ShouldContinueMixing( channel_t *ch ) static qboolean S_ShouldContinueMixing( channel_t *ch )
{ {
if( ch->isSentence ) if( ch->isSentence )
{ {
@@ -517,12 +543,13 @@ qboolean S_ShouldContinueMixing( channel_t *ch )
// this routine will fill the paintbuffer to endtime. Otherwise, fewer samples are mixed. // this routine will fill the paintbuffer to endtime. Otherwise, fewer samples are mixed.
// if( endtime - paintedtime ) is not aligned on boundaries of 4, // if( endtime - paintedtime ) is not aligned on boundaries of 4,
// we'll miss data if outputRate < SOUND_DMA_SPEED! // we'll miss data if outputRate < SOUND_DMA_SPEED!
void MIX_MixChannelsToPaintbuffer( int endtime, int rate, int outputRate ) static void MIX_MixChannelsToPaintbuffer( int endtime, int rate, int outputRate )
{ {
channel_t *ch; channel_t *ch;
wavdata_t *pSource; wavdata_t *pSource;
int i, sampleCount; int i, sampleCount;
qboolean bZeroVolume; qboolean bZeroVolume;
qboolean local = Host_IsLocalGame();
// mix each channel into paintbuffer // mix each channel into paintbuffer
ch = channels; ch = channels;
@@ -549,7 +576,7 @@ void MIX_MixChannelsToPaintbuffer( int endtime, int rate, int outputRate )
{ {
// play, playvol // play, playvol
} }
else if(( s_listener.inmenu || s_listener.paused ) && !ch->localsound ) else if(( s_listener.inmenu || s_listener.paused ) && !ch->localsound && local )
{ {
// play only local sounds, keep pause for other // play only local sounds, keep pause for other
continue; continue;
@@ -567,6 +594,7 @@ void MIX_MixChannelsToPaintbuffer( int endtime, int rate, int outputRate )
// Don't mix sound data for sounds with zero volume. If it's a non-looping sound, // Don't mix sound data for sounds with zero volume. If it's a non-looping sound,
// just remove the sound when its volume goes to zero. // just remove the sound when its volume goes to zero.
bZeroVolume = !ch->leftvol && !ch->rightvol; bZeroVolume = !ch->leftvol && !ch->rightvol;
if( !bZeroVolume ) if( !bZeroVolume )
@@ -576,7 +604,7 @@ void MIX_MixChannelsToPaintbuffer( int endtime, int rate, int outputRate )
bZeroVolume = true; bZeroVolume = true;
} }
if( !pSource || ( bZeroVolume && pSource->loopStart == -1 )) if( !pSource || ( bZeroVolume && !FBitSet( pSource->flags, SOUND_LOOPED )))
{ {
if( !pSource ) if( !pSource )
{ {
@@ -629,7 +657,7 @@ void MIX_MixChannelsToPaintbuffer( int endtime, int rate, int outputRate )
} }
// pass in index -1...count+2, return pointer to source sample in either paintbuffer or delay buffer // pass in index -1...count+2, return pointer to source sample in either paintbuffer or delay buffer
_inline portable_samplepair_t *S_GetNextpFilter( int i, portable_samplepair_t *pbuffer, portable_samplepair_t *pfiltermem ) static portable_samplepair_t *S_GetNextpFilter( int i, portable_samplepair_t *pbuffer, portable_samplepair_t *pfiltermem )
{ {
// The delay buffer is assumed to precede the paintbuffer by 6 duplicated samples // The delay buffer is assumed to precede the paintbuffer by 6 duplicated samples
if( i == -1 ) return (&(pfiltermem[0])); if( i == -1 ) return (&(pfiltermem[0]));
@@ -647,7 +675,7 @@ _inline portable_samplepair_t *S_GetNextpFilter( int i, portable_samplepair_t *p
// if NULL then perform no filtering. // if NULL then perform no filtering.
// count: how many samples to upsample. will become count*2 samples in buffer, in place. // count: how many samples to upsample. will become count*2 samples in buffer, in place.
void S_Interpolate2xCubic( portable_samplepair_t *pbuffer, portable_samplepair_t *pfiltermem, int cfltmem, int count ) static void S_Interpolate2xCubic( portable_samplepair_t *pbuffer, portable_samplepair_t *pfiltermem, int cfltmem, int count )
{ {
// implement cubic interpolation on 2x upsampled buffer. Effectively delays buffer contents by 2 samples. // implement cubic interpolation on 2x upsampled buffer. Effectively delays buffer contents by 2 samples.
@@ -740,7 +768,7 @@ void S_Interpolate2xCubic( portable_samplepair_t *pbuffer, portable_samplepair_t
// prevfilter: filter memory. NOTE: this must match the filtertype ie: filterlinear[] for FILTERTYPE_LINEAR // prevfilter: filter memory. NOTE: this must match the filtertype ie: filterlinear[] for FILTERTYPE_LINEAR
// if NULL then perform no filtering. // if NULL then perform no filtering.
// count: how many samples to upsample. will become count*2 samples in buffer, in place. // count: how many samples to upsample. will become count*2 samples in buffer, in place.
void S_Interpolate2xLinear( portable_samplepair_t *pbuffer, portable_samplepair_t *pfiltermem, int cfltmem, int count ) static void S_Interpolate2xLinear( portable_samplepair_t *pbuffer, portable_samplepair_t *pfiltermem, int cfltmem, int count )
{ {
int i, upCount = count<<1; int i, upCount = count<<1;
@@ -769,7 +797,7 @@ void S_Interpolate2xLinear( portable_samplepair_t *pbuffer, portable_samplepair_
// if NULL then perform no filtering. // if NULL then perform no filtering.
// cfltmem: max number of sample pairs filter can use // cfltmem: max number of sample pairs filter can use
// filtertype: FILTERTYPE_NONE, _LINEAR, _CUBIC etc. Must match prevfilter. // filtertype: FILTERTYPE_NONE, _LINEAR, _CUBIC etc. Must match prevfilter.
void S_MixBufferUpsample2x( int count, portable_samplepair_t *pbuffer, portable_samplepair_t *pfiltermem, int cfltmem, int filtertype ) static void S_MixBufferUpsample2x( int count, portable_samplepair_t *pbuffer, portable_samplepair_t *pfiltermem, int cfltmem, int filtertype )
{ {
int upCount = count<<1; int upCount = count<<1;
int i, j; int i, j;
@@ -822,7 +850,7 @@ void MIX_ClearAllPaintBuffers( int SampleCount, qboolean clearFilters )
// mixes pbuf1 + pbuf2 into pbuf3, count samples // mixes pbuf1 + pbuf2 into pbuf3, count samples
// fgain is output gain 0-1.0 // fgain is output gain 0-1.0
// NOTE: pbuf3 may equal pbuf1 or pbuf2! // NOTE: pbuf3 may equal pbuf1 or pbuf2!
void MIX_MixPaintbuffers( int ibuf1, int ibuf2, int ibuf3, int count, float fgain ) static void MIX_MixPaintbuffers( int ibuf1, int ibuf2, int ibuf3, int count, float fgain )
{ {
portable_samplepair_t *pbuf1, *pbuf2, *pbuf3; portable_samplepair_t *pbuf1, *pbuf2, *pbuf3;
int i, gain; int i, gain;
@@ -838,6 +866,14 @@ void MIX_MixPaintbuffers( int ibuf1, int ibuf2, int ibuf3, int count, float fgai
pbuf2 = paintbuffers[ibuf2].pbuf; pbuf2 = paintbuffers[ibuf2].pbuf;
pbuf3 = paintbuffers[ibuf3].pbuf; pbuf3 = paintbuffers[ibuf3].pbuf;
if( !gain )
{
// do not mix buf2 into buf3, just copy
if( pbuf1 != pbuf3 )
memcpy( pbuf3, pbuf1, sizeof( *pbuf1 ) * count );
return;
}
// destination buffer stereo - average n chans down to stereo // destination buffer stereo - average n chans down to stereo
// destination 2ch: // destination 2ch:
@@ -855,7 +891,7 @@ void MIX_MixPaintbuffers( int ibuf1, int ibuf2, int ibuf3, int count, float fgai
} }
} }
void MIX_CompressPaintbuffer( int ipaint, int count ) static void MIX_CompressPaintbuffer( int ipaint, int count )
{ {
portable_samplepair_t *pbuf; portable_samplepair_t *pbuf;
paintbuffer_t *ppaint; paintbuffer_t *ppaint;
@@ -871,7 +907,7 @@ void MIX_CompressPaintbuffer( int ipaint, int count )
} }
} }
void S_MixUpsample( int sampleCount, int filtertype ) static void S_MixUpsample( int sampleCount, int filtertype )
{ {
paintbuffer_t *ppaint = MIX_GetCurrentPaintbufferPtr(); paintbuffer_t *ppaint = MIX_GetCurrentPaintbufferPtr();
int ifilter = ppaint->ifilter; int ifilter = ppaint->ifilter;
@@ -884,7 +920,7 @@ void S_MixUpsample( int sampleCount, int filtertype )
ppaint->ifilter++; ppaint->ifilter++;
} }
void MIX_MixRawSamplesBuffer( int end ) static void MIX_MixRawSamplesBuffer( int end )
{ {
portable_samplepair_t *pbuf, *roombuf, *streambuf; portable_samplepair_t *pbuf, *roombuf, *streambuf;
uint i, j, stop; uint i, j, stop;
@@ -928,7 +964,7 @@ void MIX_MixRawSamplesBuffer( int end )
// IROOMBUFFER, IFACINGBUFFER, IFACINGAWAY // IROOMBUFFER, IFACINGBUFFER, IFACINGAWAY
// dsp fx are then applied to these buffers by the caller. // dsp fx are then applied to these buffers by the caller.
// caller also remixes all into final IPAINTBUFFER output. // caller also remixes all into final IPAINTBUFFER output.
void MIX_UpsampleAllPaintbuffers( int end, int count ) static void MIX_UpsampleAllPaintbuffers( int end, int count )
{ {
// 11khz sounds are mixed into 3 buffers based on distance from listener, and facing direction // 11khz sounds are mixed into 3 buffers based on distance from listener, and facing direction
// These buffers are facing, facingaway, room // These buffers are facing, facingaway, room
@@ -999,7 +1035,8 @@ void MIX_PaintChannels( int endtime )
MIX_UpsampleAllPaintbuffers( end, count ); MIX_UpsampleAllPaintbuffers( end, count );
// process all sounds with DSP // process all sounds with DSP
DSP_Process( idsp_room, MIX_GetPFrontFromIPaint( IROOMBUFFER ), count ); if( cls.key_dest != key_menu )
DSP_Process( MIX_GetPFrontFromIPaint( IROOMBUFFER ), count );
// add music or soundtrack from movie (no dsp) // add music or soundtrack from movie (no dsp)
MIX_MixPaintbuffers( IPAINTBUFFER, IROOMBUFFER, IPAINTBUFFER, count, S_GetMasterVolume() ); MIX_MixPaintbuffers( IPAINTBUFFER, IROOMBUFFER, IPAINTBUFFER, count, S_GetMasterVolume() );

View File

@@ -96,6 +96,7 @@ void S_StartBackgroundTrack( const char *introTrack, const char *mainTrack, int
// open stream // open stream
s_bgTrack.stream = FS_OpenStream( introTrack ); s_bgTrack.stream = FS_OpenStream( introTrack );
Q_strncpy( s_bgTrack.current, introTrack, sizeof( s_bgTrack.current )); Q_strncpy( s_bgTrack.current, introTrack, sizeof( s_bgTrack.current ));
memset( &musicfade, 0, sizeof( musicfade )); // clear any soundfade memset( &musicfade, 0, sizeof( musicfade )); // clear any soundfade
s_bgTrack.source = cls.key_dest; s_bgTrack.source = cls.key_dest;
@@ -141,7 +142,7 @@ S_StreamGetCurrentState
save\restore code save\restore code
================= =================
*/ */
qboolean S_StreamGetCurrentState( char *currentTrack, char *loopTrack, int *position ) qboolean S_StreamGetCurrentState( char *currentTrack, size_t currentTrackSize, char *loopTrack, size_t loopTrackSize, int *position )
{ {
if( !s_bgTrack.stream ) if( !s_bgTrack.stream )
return false; // not active return false; // not active
@@ -149,15 +150,15 @@ qboolean S_StreamGetCurrentState( char *currentTrack, char *loopTrack, int *posi
if( currentTrack ) if( currentTrack )
{ {
if( s_bgTrack.current[0] ) if( s_bgTrack.current[0] )
Q_strncpy( currentTrack, s_bgTrack.current, MAX_STRING ); Q_strncpy( currentTrack, s_bgTrack.current, currentTrackSize );
else Q_strncpy( currentTrack, "*", MAX_STRING ); // no track else Q_strncpy( currentTrack, "*", currentTrackSize ); // no track
} }
if( loopTrack ) if( loopTrack )
{ {
if( s_bgTrack.loopName[0] ) if( s_bgTrack.loopName[0] )
Q_strncpy( loopTrack, s_bgTrack.loopName, MAX_STRING ); Q_strncpy( loopTrack, s_bgTrack.loopName, loopTrackSize );
else Q_strncpy( loopTrack, "*", MAX_STRING ); // no track else Q_strncpy( loopTrack, "*", loopTrackSize ); // no track
} }
if( position ) if( position )

View File

@@ -16,204 +16,6 @@ GNU General Public License for more details.
#include "common.h" #include "common.h"
#include "sound.h" #include "sound.h"
// hardcoded macros to test for zero crossing
#define ZERO_X_8( b ) (( b ) < 2 && ( b ) > -2 )
#define ZERO_X_16( b ) (( b ) < 512 && ( b ) > -512 )
//-----------------------------------------------------------------------------
// Purpose: Search backward for a zero crossing starting at sample
// Input : sample - starting point
// Output : position of zero crossing
//-----------------------------------------------------------------------------
int S_ZeroCrossingBefore( wavdata_t *pWaveData, int sample )
{
if( pWaveData == NULL )
return sample;
if( pWaveData->type == WF_PCMDATA )
{
int sampleSize;
sampleSize = pWaveData->width * pWaveData->channels;
// this can never be zero -- other functions divide by this.
// This should never happen, but avoid crashing
if( sampleSize <= 0 ) sampleSize = 1;
if( pWaveData->width == 1 )
{
signed char *pData = (signed char *)(pWaveData->buffer + sample * sampleSize);
qboolean zero = false;
if( pWaveData->channels == 1 )
{
while( sample > 0 && !zero )
{
if( ZERO_X_8( *pData ))
{
zero = true;
}
else
{
sample--;
pData--;
}
}
}
else
{
while( sample > 0 && !zero )
{
if( ZERO_X_8( *pData ) && ZERO_X_8( pData[1] ))
{
zero = true;
}
else
{
sample--;
pData--;
}
}
}
}
else
{
short *pData = (short *)(pWaveData->buffer + sample * sampleSize);
qboolean zero = false;
if( pWaveData->channels == 1 )
{
while( sample > 0 && !zero )
{
if( ZERO_X_16(*pData ))
{
zero = true;
}
else
{
pData--;
sample--;
}
}
}
else
{
while( sample > 0 && !zero )
{
if( ZERO_X_16( *pData ) && ZERO_X_16( pData[1] ))
{
zero = true;
}
else
{
sample--;
pData--;
}
}
}
}
}
return sample;
}
//-----------------------------------------------------------------------------
// Purpose: Search forward for a zero crossing
// Input : sample - starting point
// Output : position of found zero crossing
//-----------------------------------------------------------------------------
int S_ZeroCrossingAfter( wavdata_t *pWaveData, int sample )
{
if( pWaveData == NULL )
return sample;
if( pWaveData->type == WF_PCMDATA )
{
int sampleSize;
sampleSize = pWaveData->width * pWaveData->channels;
// this can never be zero -- other functions divide by this.
// This should never happen, but avoid crashing
if( sampleSize <= 0 ) sampleSize = 1;
if( pWaveData->width == 1 ) // 8-bit
{
signed char *pData = (signed char *)(pWaveData->buffer + sample * sampleSize);
qboolean zero = false;
if( pWaveData->channels == 1 )
{
while( sample < pWaveData->samples && !zero )
{
if( ZERO_X_8( *pData ))
{
zero = true;
}
else
{
sample++;
pData++;
}
}
}
else
{
while( sample < pWaveData->samples && !zero )
{
if( ZERO_X_8( *pData ) && ZERO_X_8( pData[1] ))
{
zero = true;
}
else
{
sample++;
pData++;
}
}
}
}
else
{
short *pData = (short *)(pWaveData->buffer + sample * sampleSize);
qboolean zero = false;
if( pWaveData->channels == 1 )
{
while( sample > 0 && !zero )
{
if( ZERO_X_16( *pData ))
{
zero = true;
}
else
{
pData++;
sample++;
}
}
}
else
{
while( sample > 0 && !zero )
{
if( ZERO_X_16( *pData ) && ZERO_X_16( pData[1] ))
{
zero = true;
}
else
{
sample++;
pData++;
}
}
}
}
}
return sample;
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Purpose: wrap the position wrt looping // Purpose: wrap the position wrt looping
// Input : samplePosition - absolute position // Input : samplePosition - absolute position
@@ -225,7 +27,7 @@ int S_ConvertLoopedPosition( wavdata_t *pSource, int samplePosition, qboolean us
// convert to a position within the loop // convert to a position within the loop
// At the end of the loop, we return a short buffer, and subsequent call // At the end of the loop, we return a short buffer, and subsequent call
// will loop back and get the rest of the buffer // will loop back and get the rest of the buffer
if( pSource->loopStart >= 0 && samplePosition >= pSource->samples && use_loop ) if( FBitSet( pSource->flags, SOUND_LOOPED ) && samplePosition >= pSource->samples && use_loop )
{ {
// size of loop // size of loop
int loopSize = pSource->samples - pSource->loopStart; int loopSize = pSource->samples - pSource->loopStart;
@@ -279,28 +81,3 @@ int S_GetOutputData( wavdata_t *pSource, void **pData, int samplePosition, int s
return sampleCount; return sampleCount;
} }
// move the current position to newPosition
void S_SetSampleStart( channel_t *pChan, wavdata_t *pSource, int newPosition )
{
if( pSource )
newPosition = S_ZeroCrossingAfter( pSource, newPosition );
pChan->pMixer.sample = newPosition;
}
// end playback at newEndPosition
void S_SetSampleEnd( channel_t *pChan, wavdata_t *pSource, int newEndPosition )
{
// forced end of zero means play the whole sample
if( !newEndPosition ) newEndPosition = 1;
if( pSource )
newEndPosition = S_ZeroCrossingBefore( pSource, newEndPosition );
// past current position? limit.
if( newEndPosition < pChan->pMixer.sample )
newEndPosition = pChan->pMixer.sample;
pChan->pMixer.forcedEndSample = newEndPosition;
}

View File

@@ -16,13 +16,128 @@ GNU General Public License for more details.
#include "common.h" #include "common.h"
#include "sound.h" #include "sound.h"
#include "const.h" #include "const.h"
#include "sequence.h"
#include <ctype.h> #include <ctype.h>
#define TRIM_SCAN_MAX 255
#define TRIM_SAMPLES_BELOW_8 2
#define TRIM_SAMPLES_BELOW_16 512 // 65k * 2 / 256
#define CVOXFILESENTENCEMAX 4096
static int cszrawsentences = 0; static int cszrawsentences = 0;
static char *rgpszrawsentence[CVOXFILESENTENCEMAX]; static char *rgpszrawsentence[CVOXFILESENTENCEMAX];
static const char *voxperiod = "_period", *voxcomma = "_comma"; static const char *voxperiod = "_period", *voxcomma = "_comma";
static qboolean S_ShouldTrimSample8( const int8_t *buf, int channels )
{
if( abs( buf[0] ) > TRIM_SAMPLES_BELOW_8 )
return false;
if( channels >= 2 && abs( buf[1] ) > TRIM_SAMPLES_BELOW_8 )
return false;
return true;
}
static qboolean S_ShouldTrimSample16( const int16_t *buf, int channels )
{
if( abs( buf[0] ) > TRIM_SAMPLES_BELOW_16 )
return false;
if( channels >= 2 && abs( buf[1] ) > TRIM_SAMPLES_BELOW_16 )
return false;
return true;
}
static int S_TrimStart( const wavdata_t *wav, int start )
{
size_t channels = wav->channels, width = wav->width, i;
if( wav->type != WF_PCMDATA )
return start;
if( width == 1 )
{
const int8_t *data = (const int8_t *)&wav->buffer[channels * width * start];
for( i = 0; i < TRIM_SCAN_MAX && start < wav->samples; i++ )
{
if( !S_ShouldTrimSample8( data, wav->channels ))
break;
start += channels;
data += channels;
}
}
else if( width == 2 )
{
const int16_t *data = (const int16_t *)&wav->buffer[channels * width * start];
for( i = 0; i < TRIM_SCAN_MAX && start < wav->samples; i++ )
{
if( !S_ShouldTrimSample16( data, wav->channels ))
break;
start += channels;
data += channels;
}
}
return start;
}
static int S_TrimEnd( const wavdata_t *wav, int end )
{
size_t channels = wav->channels, width = wav->width, i;
if( wav->type != WF_PCMDATA )
return end;
if( width == 1 )
{
const int8_t *data = (const int8_t *)&wav->buffer[channels * width * end];
for( i = 0; i < TRIM_SCAN_MAX && end > 0; i++ )
{
if( !S_ShouldTrimSample8( data, wav->channels ))
break;
end -= channels;
data -= channels;
}
}
else if( width == 2 )
{
const int16_t *data = (const int16_t *)&wav->buffer[channels * width * end];
for( i = 0; i < TRIM_SCAN_MAX && end > 0; i++ )
{
if( !S_ShouldTrimSample16( data, wav->channels ))
break;
end -= channels;
data -= channels;
}
}
return end;
}
static void S_TrimStartEndTimes( channel_t *ch, wavdata_t *wav, int start, int end )
{
ch->pMixer.sample = start = S_TrimStart( wav, start );
// don't overrun the buffer while trimming end
if( end == 0 )
end = wav->samples - wav->channels;
if( end < start )
end = start;
ch->pMixer.forcedEndSample = S_TrimEnd( wav, end );
}
// return number of samples mixed // return number of samples mixed
int VOX_MixDataToDevice( channel_t *pchan, int sampleCount, int outputRate, int outputOffset ) int VOX_MixDataToDevice( channel_t *pchan, int sampleCount, int outputRate, int outputOffset )
{ {
@@ -79,11 +194,7 @@ void VOX_LoadWord( channel_t *ch )
if( end <= start ) end = 0; if( end <= start ) end = 0;
if( start ) S_TrimStartEndTimes( ch, data, start * 0.01f * samples, end * 0.01f * samples );
S_SetSampleStart( ch, data, start * 0.01f * samples );
if( end )
S_SetSampleEnd( ch, data, end * 0.01f * samples );
} }
void VOX_FreeWord( channel_t *ch ) void VOX_FreeWord( channel_t *ch )
@@ -165,25 +276,12 @@ static const char *VOX_LookupString( const char *pszin )
int i = -1, len; int i = -1, len;
const char *c; const char *c;
// check if we are a CSCZ or immediate sentence // check if we are an immediate sentence
if( *pszin == '#' ) 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;
return NULL;
}
else
{ {
// immediate sentence, probably coming from "speak" command // immediate sentence, probably coming from "speak" command
return pszin + 1; return pszin + 1;
} }
}
// check if we received an index // check if we received an index
if( Q_isdigit( pszin )) if( Q_isdigit( pszin ))

View File

@@ -20,57 +20,37 @@ extern poolhandle_t sndpool;
#include "xash3d_mathlib.h" #include "xash3d_mathlib.h"
// sound engine rate defines #define XASH_AUDIO_CD_QUALITY 1 // some platforms might need this
#define SOUND_DMA_SPEED 44100 // hardware playback rate
#define SOUND_11k 11025 // 11khz sample rate
#define SOUND_16k 16000 // 16khz sample rate
#define SOUND_22k 22050 // 22khz sample rate
#define SOUND_32k 32000 // 32khz sample rate
#define SOUND_44k 44100 // 44khz sample rate
#define DMA_MSEC_PER_SAMPLE ((float)(1000.0 / SOUND_DMA_SPEED))
// fixed point stuff for real-time resampling // sound engine rate defines
#define FIX_BITS 28 #if XASH_AUDIO_CD_QUALITY
#define FIX_SCALE (1 << FIX_BITS) #define SOUND_11k 11025 // 11khz sample rate
#define FIX_MASK ((1 << FIX_BITS)-1) #define SOUND_22k 22050 // 22khz sample rate
#define FIX_FLOAT(a) ((int)((a) * FIX_SCALE)) #define SOUND_44k 44100 // 44khz sample rate
#define FIX(a) (((int)(a)) << FIX_BITS) #else // XASH_AUDIO_CD_QUALITY
#define FIX_INTPART(a) (((int)(a)) >> FIX_BITS) #define SOUND_11k 12000 // 11khz sample rate
#define FIX_FRACTION(a,b) (FIX(a)/(b)) #define SOUND_22k 24000 // 22khz sample rate
#define FIX_FRACPART(a) ((a) & FIX_MASK) #define SOUND_44k 48000 // 44khz sample rate
#endif // XASH_AUDIO_CD_QUALITY
#define SOUND_DMA_SPEED SOUND_44k // hardware playback rate
// NOTE: clipped sound at 32760 to avoid overload // NOTE: clipped sound at 32760 to avoid overload
#define CLIP( x ) (( x ) > 32760 ? 32760 : (( x ) < -32760 ? -32760 : ( x ))) #define CLIP( x ) (( x ) > 32760 ? 32760 : (( x ) < -32760 ? -32760 : ( x )))
#define PAINTBUFFER_SIZE 1024 // 44k: was 512 #define PAINTBUFFER_SIZE 1024 // 44k: was 512
#define PAINTBUFFER (g_curpaintbuffer)
#define CPAINTBUFFERS 3
// sound mixing buffer
#define CPAINTFILTERMEM 3
#define CPAINTFILTERS 4 // maximum number of consecutive upsample passes per paintbuffer
#define S_RAW_SOUND_IDLE_SEC 10 // time interval for idling raw sound before it's freed #define S_RAW_SOUND_IDLE_SEC 10 // time interval for idling raw sound before it's freed
#define S_RAW_SOUND_BACKGROUNDTRACK -2 #define S_RAW_SOUND_BACKGROUNDTRACK -2
#define S_RAW_SOUND_SOUNDTRACK -1 #define S_RAW_SOUND_SOUNDTRACK -1
#define S_RAW_SAMPLES_PRECISION_BITS 14 #define S_RAW_SAMPLES_PRECISION_BITS 14
#define CIN_FRAMETIME (1.0f / 30.0f)
typedef struct typedef struct
{ {
int left; int left;
int right; int right;
} portable_samplepair_t; } portable_samplepair_t;
typedef struct
{
qboolean factive; // if true, mix to this paintbuffer using flags
portable_samplepair_t *pbuf; // front stereo mix buffer, for 2 or 4 channel mixing
int ifilter; // current filter memory buffer to use for upsampling pass
portable_samplepair_t fltmem[CPAINTFILTERS][CPAINTFILTERMEM];
} paintbuffer_t;
typedef struct sfx_s typedef struct sfx_s
{ {
char name[MAX_QPATH]; char name[MAX_QPATH];
@@ -81,12 +61,6 @@ typedef struct sfx_s
struct sfx_s *hashNext; struct sfx_s *hashNext;
} sfx_t; } sfx_t;
extern portable_samplepair_t paintbuffer[];
extern portable_samplepair_t roombuffer[];
extern portable_samplepair_t temppaintbuffer[];
extern portable_samplepair_t *g_curpaintbuffer;
extern paintbuffer_t paintbuffers[];
// structure used for fading in and out client sound volume. // structure used for fading in and out client sound volume.
typedef struct typedef struct
{ {
@@ -105,9 +79,9 @@ typedef struct
typedef struct snd_format_s typedef struct snd_format_s
{ {
unsigned int speed; uint speed;
unsigned int width; byte width;
unsigned int channels; byte channels;
} snd_format_t; } snd_format_t;
typedef struct typedef struct
@@ -115,8 +89,8 @@ typedef struct
snd_format_t format; snd_format_t format;
int samples; // mono samples in buffer int samples; // mono samples in buffer
int samplepos; // in mono samples int samplepos; // in mono samples
byte *buffer;
qboolean initialized; // sound engine is active qboolean initialized; // sound engine is active
byte *buffer;
const char *backendName; const char *backendName;
} dma_t; } dma_t;
@@ -125,7 +99,6 @@ typedef struct
typedef struct typedef struct
{ {
double sample; double sample;
wavdata_t *pData; wavdata_t *pData;
double forcedEndSample; double forcedEndSample;
qboolean finished; qboolean finished;
@@ -140,15 +113,15 @@ typedef struct rawchan_s
float dist_mult; // distance multiplier (attenuation/clipK) float dist_mult; // distance multiplier (attenuation/clipK)
vec3_t origin; // only use if fixed_origin is set vec3_t origin; // only use if fixed_origin is set
volatile uint s_rawend; volatile uint s_rawend;
wavdata_t sound_info; // advance play position
float oldtime; // catch time jumps float oldtime; // catch time jumps
wavdata_t sound_info; // advance play position
size_t max_samples; // buffer length size_t max_samples; // buffer length
portable_samplepair_t rawsamples[1]; // variable sized portable_samplepair_t rawsamples[1]; // variable sized
} rawchan_t; } rawchan_t;
typedef struct channel_s typedef struct channel_s
{ {
char name[16]; // keept sentence name char name[16]; // keep sentence name
sfx_t *sfx; // sfx number sfx_t *sfx; // sfx number
int leftvol; // 0-255 left volume int leftvol; // 0-255 left volume
@@ -159,7 +132,6 @@ typedef struct channel_s
vec3_t origin; // only use if fixed_origin is set vec3_t origin; // only use if fixed_origin is set
float dist_mult; // distance multiplier (attenuation/clipK) float dist_mult; // distance multiplier (attenuation/clipK)
int master_vol; // 0-255 master volume int master_vol; // 0-255 master volume
qboolean isSentence; // bit who indicated sentence
int basePitch; // base pitch percent (100% is normal pitch playback) int basePitch; // base pitch percent (100% is normal pitch playback)
float pitch; // real-time pitch after any modulation or shift by dynamic data float pitch; // real-time pitch after any modulation or shift by dynamic data
qboolean use_loop; // don't loop default and local sounds qboolean use_loop; // don't loop default and local sounds
@@ -168,6 +140,7 @@ typedef struct channel_s
mixer_t pMixer; mixer_t pMixer;
// sentence mixer // sentence mixer
qboolean isSentence; // bit indicating sentence
int wordIndex; int wordIndex;
mixer_t *currentWord; // NULL if sentence is finished mixer_t *currentWord; // NULL if sentence is finished
voxword_t words[CVOXWORDMAX]; voxword_t words[CVOXWORDMAX];
@@ -176,7 +149,6 @@ typedef struct channel_s
typedef struct typedef struct
{ {
vec3_t origin; // simorg + view_ofs vec3_t origin; // simorg + view_ofs
vec3_t velocity;
vec3_t forward; vec3_t forward;
vec3_t right; vec3_t right;
vec3_t up; vec3_t up;
@@ -219,10 +191,8 @@ extern dma_t dma;
extern convar_t s_musicvolume; extern convar_t s_musicvolume;
extern convar_t s_lerping; extern convar_t s_lerping;
extern convar_t *dsp_off; extern convar_t s_test; // cvar to test new effects
extern convar_t s_test; // cvar to testify new effects
extern convar_t s_samplecount; extern convar_t s_samplecount;
extern convar_t snd_mute_losefocus;
extern convar_t s_warn_late_precache; extern convar_t s_warn_late_precache;
void S_InitScaletable( void ); void S_InitScaletable( void );
@@ -256,8 +226,7 @@ void S_InitSounds( void );
void SX_Init( void ); void SX_Init( void );
void SX_Free( void ); void SX_Free( void );
void CheckNewDspPresets( void ); void CheckNewDspPresets( void );
void DSP_Process( int idsp, portable_samplepair_t *pbfront, int sampleCount ); void DSP_Process( portable_samplepair_t *pbfront, int sampleCount );
float DSP_GetGain( int idsp );
void DSP_ClearState( void ); void DSP_ClearState( void );
qboolean S_Init( void ); qboolean S_Init( void );
@@ -295,7 +264,6 @@ void SND_ForceCloseMouth( int entnum );
// //
void S_StreamSoundTrack( void ); void S_StreamSoundTrack( void );
void S_StreamBackgroundTrack( void ); void S_StreamBackgroundTrack( void );
qboolean S_StreamGetCurrentState( char *currentTrack, char *loopTrack, int *position );
void S_PrintBackgroundTrackState( void ); void S_PrintBackgroundTrackState( void );
void S_FadeMusicVolume( float fadePercent ); void S_FadeMusicVolume( float fadePercent );
@@ -306,8 +274,6 @@ int S_ZeroCrossingAfter( wavdata_t *pWaveData, int sample );
int S_ZeroCrossingBefore( 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_ConvertLoopedPosition( wavdata_t *pSource, int samplePosition, qboolean use_loop );
int S_GetOutputData( wavdata_t *pSource, void **pData, int samplePosition, int sampleCount, 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 );
// //
// s_vox.c // s_vox.c

View File

@@ -20,34 +20,20 @@ GNU General Public License for more details.
#include "vid_common.h" #include "vid_common.h"
#include "platform/platform.h" #include "platform/platform.h"
#define WINDOW_NAME XASH_ENGINE_NAME " Window" // Half-Life static CVAR_DEFINE_AUTO( vid_mode, "0", FCVAR_RENDERINFO, "current video mode index (used only for storage)" );
convar_t *vid_fullscreen; static CVAR_DEFINE_AUTO( vid_rotate, "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "screen rotation (0-3)" );
convar_t *vid_mode; static CVAR_DEFINE_AUTO( vid_scale, "1.0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "pixel scale" );
convar_t *vid_brightness;
convar_t *vid_gamma; CVAR_DEFINE_AUTO( vid_highdpi, "1", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "enable High-DPI mode" );
convar_t *vid_highdpi; 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_width, "width", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "screen width" );
CVAR_DEFINE( window_height, "height", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "screen height" );
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; glwstate_t glw_state;
convar_t *window_xpos;
convar_t *window_ypos;
convar_t *vid_rotate;
convar_t *vid_scale;
/*
=================
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 );
}
/* /*
================= =================
VID_InitDefaultResolution VID_InitDefaultResolution
@@ -66,7 +52,7 @@ void VID_InitDefaultResolution( void )
R_SaveVideoMode 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 ) if( !w || !h || !render_w || !render_h )
{ {
@@ -79,6 +65,7 @@ void R_SaveVideoMode( int w, int h, int render_w, int render_h )
Cvar_SetValue( "width", w ); Cvar_SetValue( "width", w );
Cvar_SetValue( "height", h ); Cvar_SetValue( "height", h );
Cvar_DirectSet( &vid_maximized, maximized ? "1" : "0" );
// immediately drop changed state or we may trigger // immediately drop changed state or we may trigger
// video subsystem to reapply settings // video subsystem to reapply settings
@@ -124,11 +111,11 @@ check vid modes and fullscreen
*/ */
void VID_CheckChanges( void ) void VID_CheckChanges( void )
{ {
if( FBitSet( cl_allow_levelshots->flags, FCVAR_CHANGED )) if( FBitSet( cl_allow_levelshots.flags, FCVAR_CHANGED ))
{ {
//GL_FreeTexture( cls.loadingBar ); //GL_FreeTexture( cls.loadingBar );
SCR_RegisterTextures(); // reload 'lambda' image SCR_RegisterTextures(); // reload 'lambda' image
ClearBits( cl_allow_levelshots->flags, FCVAR_CHANGED ); ClearBits( cl_allow_levelshots.flags, FCVAR_CHANGED );
} }
if( host.renderinfo_changed ) if( host.renderinfo_changed )
@@ -145,6 +132,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 ) static void VID_Mode_f( void )
{ {
int w, h; int w, h;
@@ -177,29 +194,28 @@ static void VID_Mode_f( void )
return; 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 ) void VID_Init( void )
{ {
// system screen width and height (don't suppose for change from console at all) // 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_RegisterVariable( &window_width );
Cvar_Get( "height", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "screen height" ); Cvar_RegisterVariable( &window_height );
window_xpos = Cvar_Get( "_window_xpos", "-1", FCVAR_RENDERINFO, "window position by horizontal" ); Cvar_RegisterVariable( &vid_mode );
window_ypos = Cvar_Get( "_window_ypos", "-1", FCVAR_RENDERINFO, "window position by vertical" ); Cvar_RegisterVariable( &vid_highdpi );
Cvar_RegisterVariable( &vid_rotate );
vid_gamma = Cvar_Get( "gamma", "2.5", FCVAR_ARCHIVE, "gamma amount" ); Cvar_RegisterVariable( &vid_scale );
vid_brightness = Cvar_Get( "brightness", "0.0", FCVAR_ARCHIVE, "brightness factor" ); Cvar_RegisterVariable( &vid_fullscreen );
vid_fullscreen = Cvar_Get( "fullscreen", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "enable fullscreen mode" ); Cvar_RegisterVariable( &vid_maximized );
vid_mode = Cvar_Get( "vid_mode", "0", FCVAR_RENDERINFO, "current video mode index (used just for storage)" ); Cvar_RegisterVariable( &window_xpos );
vid_highdpi = Cvar_Get( "vid_highdpi", "1", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "enable High-DPI mode" ); Cvar_RegisterVariable( &window_ypos );
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" );
// a1ba: planned to be named vid_mode for compability // a1ba: planned to be named vid_mode for compability
// but supported mode list is filled by backends, so numbers are not portable any more // but supported mode list is filled by backends, so numbers are not portable any more
Cmd_AddRestrictedCommand( "vid_setmode", VID_Mode_f, "display video mode" ); Cmd_AddRestrictedCommand( "vid_setmode", VID_Mode_f, "display video mode" );
V_Init(); // init gamma
R_Init(); // init renderer R_Init(); // init renderer
} }

View File

@@ -9,6 +9,13 @@ typedef struct vidmode_s
int height; int height;
} vidmode_t; } 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 typedef struct
{ {
@@ -21,8 +28,6 @@ typedef struct
qboolean initialized; // OpenGL subsystem started qboolean initialized; // OpenGL subsystem started
qboolean extended; // extended context allows to GL_Debug qboolean extended; // extended context allows to GL_Debug
qboolean software; qboolean software;
} glwstate_t; } glwstate_t;
extern glwstate_t glw_state; extern glwstate_t glw_state;
@@ -30,15 +35,18 @@ extern glwstate_t glw_state;
#define VID_MIN_HEIGHT 200 #define VID_MIN_HEIGHT 200
#define VID_MIN_WIDTH 320 #define VID_MIN_WIDTH 320
extern convar_t *vid_fullscreen; extern convar_t vid_fullscreen;
extern convar_t *vid_highdpi; extern convar_t vid_maximized;
extern convar_t *vid_rotate; extern convar_t vid_highdpi;
extern convar_t *vid_scale; extern convar_t window_width;
extern convar_t window_height;
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, qboolean maximized );
void R_SaveVideoMode( int w, int h, int render_w, int render_h ); void VID_SetDisplayTransform( int *render_w, int *render_h );
void VID_CheckChanges( void ); void VID_CheckChanges( void );
const char *VID_GetModeString( int vid_mode ); const char *VID_GetModeString( int vid_mode );
void VID_StartupGamma( void );
#endif // VID_COMMON #endif // VID_COMMON

View File

@@ -25,11 +25,12 @@ voice_state_t voice = { 0 };
CVAR_DEFINE_AUTO( voice_enable, "1", FCVAR_PRIVILEGED|FCVAR_ARCHIVE, "enable voice chat" ); CVAR_DEFINE_AUTO( voice_enable, "1", FCVAR_PRIVILEGED|FCVAR_ARCHIVE, "enable voice chat" );
CVAR_DEFINE_AUTO( voice_loopback, "0", FCVAR_PRIVILEGED, "loopback voice back to the speaker" ); CVAR_DEFINE_AUTO( voice_loopback, "0", FCVAR_PRIVILEGED, "loopback voice back to the speaker" );
CVAR_DEFINE_AUTO( voice_scale, "1.0", FCVAR_PRIVILEGED|FCVAR_ARCHIVE, "incoming voice volume scale" ); CVAR_DEFINE_AUTO( voice_scale, "1.0", FCVAR_PRIVILEGED|FCVAR_ARCHIVE, "incoming voice volume scale" );
CVAR_DEFINE_AUTO( voice_transmit_scale, "1.0", FCVAR_PRIVILEGED|FCVAR_ARCHIVE, "outcoming voice volume scale" );
CVAR_DEFINE_AUTO( voice_avggain, "0.5", FCVAR_PRIVILEGED|FCVAR_ARCHIVE, "automatic voice gain control (average)" ); CVAR_DEFINE_AUTO( voice_avggain, "0.5", FCVAR_PRIVILEGED|FCVAR_ARCHIVE, "automatic voice gain control (average)" );
CVAR_DEFINE_AUTO( voice_maxgain, "5.0", FCVAR_PRIVILEGED|FCVAR_ARCHIVE, "automatic voice gain control (maximum)" ); CVAR_DEFINE_AUTO( voice_maxgain, "5.0", FCVAR_PRIVILEGED|FCVAR_ARCHIVE, "automatic voice gain control (maximum)" );
CVAR_DEFINE_AUTO( voice_inputfromfile, "0", FCVAR_PRIVILEGED, "input voice from voice_input.wav" ); CVAR_DEFINE_AUTO( voice_inputfromfile, "0", FCVAR_PRIVILEGED, "input voice from voice_input.wav" );
static void Voice_ApplyGainAdjust( int16_t *samples, int count ); static void Voice_ApplyGainAdjust( int16_t *samples, int count, float scale );
/* /*
=============================================================================== ===============================================================================
@@ -39,6 +40,25 @@ static void Voice_ApplyGainAdjust( int16_t *samples, int count );
=============================================================================== ===============================================================================
*/ */
static qboolean Voice_InitCustomMode( void )
{
int err = 0;
voice.width = sizeof( opus_int16 );
voice.samplerate = VOICE_OPUS_CUSTOM_SAMPLERATE;
voice.frame_size = VOICE_OPUS_CUSTOM_FRAME_SIZE;
voice.custom_mode = opus_custom_mode_create( SOUND_44k, voice.frame_size, &err );
if( !voice.custom_mode )
{
Con_Printf( S_ERROR "Can't create Opus Custom mode: %s\n", opus_strerror( err ));
return false;
}
return true;
}
/* /*
========================= =========================
Voice_InitOpusDecoder Voice_InitOpusDecoder
@@ -47,24 +67,17 @@ Voice_InitOpusDecoder
*/ */
static qboolean Voice_InitOpusDecoder( void ) static qboolean Voice_InitOpusDecoder( void )
{ {
int err; int err = 0;
voice.width = sizeof( opus_int16 ); for( int i = 0; i < cl.maxclients; i++ )
voice.samplerate = VOICE_OPUS_CUSTOM_SAMPLERATE;
voice.frame_size = VOICE_OPUS_CUSTOM_FRAME_SIZE;
voice.custom_mode = opus_custom_mode_create( SOUND_44k, voice.frame_size, &err );
if( !voice.custom_mode )
{ {
Con_Printf( S_ERROR "Can't create Opus Custom mode: %s\n", opus_strerror( err )); voice.decoders[i] = opus_custom_decoder_create( voice.custom_mode, VOICE_PCM_CHANNELS, &err );
if( !voice.decoders[i] )
{
Con_Printf( S_ERROR "Can't create Opus decoder for %i: %s\n", i, opus_strerror( err ));
return false; return false;
} }
voice.decoder = opus_custom_decoder_create( voice.custom_mode, VOICE_PCM_CHANNELS, &err );
if( !voice.decoder )
{
Con_Printf( S_ERROR "Can't create Opus encoder: %s\n", opus_strerror( err ));
return false;
} }
return true; return true;
@@ -78,7 +91,7 @@ Voice_InitOpusEncoder
*/ */
static qboolean Voice_InitOpusEncoder( int quality ) static qboolean Voice_InitOpusEncoder( int quality )
{ {
int err; int err = 0;
voice.encoder = opus_custom_encoder_create( voice.custom_mode, VOICE_PCM_CHANNELS, &err ); voice.encoder = opus_custom_encoder_create( voice.custom_mode, VOICE_PCM_CHANNELS, &err );
if( !voice.encoder ) if( !voice.encoder )
@@ -117,10 +130,13 @@ Voice_ShutdownOpusDecoder
*/ */
static void Voice_ShutdownOpusDecoder( void ) static void Voice_ShutdownOpusDecoder( void )
{ {
if( voice.decoder ) for( int i = 0; i < MAX_CLIENTS; i++ )
{ {
opus_custom_decoder_destroy( voice.decoder ); if( !voice.decoders[i] )
voice.decoder = NULL; continue;
opus_custom_decoder_destroy( voice.decoders[i] );
voice.decoders[i] = NULL;
} }
} }
@@ -137,7 +153,10 @@ static void Voice_ShutdownOpusEncoder( void )
opus_custom_encoder_destroy( voice.encoder ); opus_custom_encoder_destroy( voice.encoder );
voice.encoder = NULL; voice.encoder = NULL;
} }
}
static void Voice_ShutdownCustomMode( void )
{
if( voice.custom_mode ) if( voice.custom_mode )
{ {
opus_custom_mode_destroy( voice.custom_mode ); opus_custom_mode_destroy( voice.custom_mode );
@@ -184,7 +203,7 @@ static uint Voice_GetOpusCompressedData( byte *out, uint maxsize, uint *frames )
if( !voice.input_file ) if( !voice.input_file )
{ {
// adjust gain before encoding, but only for input from voice // adjust gain before encoding, but only for input from voice
Voice_ApplyGainAdjust((opus_int16*)(voice.input_buffer + ofs), voice.frame_size); Voice_ApplyGainAdjust((opus_int16*)(voice.input_buffer + ofs), voice.frame_size, voice_transmit_scale.value);
} }
#endif #endif
@@ -238,10 +257,10 @@ Voice_ApplyGainAdjust
========================= =========================
*/ */
static void Voice_ApplyGainAdjust( int16_t *samples, int count ) static void Voice_ApplyGainAdjust( int16_t *samples, int count, float scale )
{ {
float gain, modifiedMax; float gain, modifiedMax;
int average, adjustedSample, blockOffset = 0; int average, blockOffset = 0;
for( ;; ) for( ;; )
{ {
@@ -260,10 +279,8 @@ static void Voice_ApplyGainAdjust( int16_t *samples, int count )
localMax = absSample; localMax = absSample;
localSum += absSample; localSum += absSample;
gain = voice.autogain.current_gain + i * voice.autogain.gain_multiplier; gain = voice.autogain.current_gain + i * voice.autogain.gain_multiplier;
adjustedSample = Q_min( SHRT_MAX, Q_max(( int )( sample * gain ), SHRT_MIN )); samples[blockOffset + i] = bound( SHRT_MIN, (int)( sample * gain ), SHRT_MAX );
samples[blockOffset + i] = adjustedSample;
} }
if( blockOffset % voice.autogain.block_size == 0 ) if( blockOffset % voice.autogain.block_size == 0 )
@@ -271,9 +288,9 @@ static void Voice_ApplyGainAdjust( int16_t *samples, int count )
average = localSum / blockSize; average = localSum / blockSize;
modifiedMax = average + ( localMax - average ) * voice_avggain.value; modifiedMax = average + ( localMax - average ) * voice_avggain.value;
voice.autogain.current_gain = voice.autogain.next_gain * voice_scale.value; voice.autogain.current_gain = voice.autogain.next_gain * scale;
voice.autogain.next_gain = Q_min( (float)SHRT_MAX / modifiedMax, voice_maxgain.value ) * voice_scale.value; voice.autogain.next_gain = Q_min( (float)SHRT_MAX / modifiedMax, voice_maxgain.value ) * scale;
voice.autogain.gain_multiplier = ( voice.autogain.next_gain - voice.autogain.current_gain ) / ( voice.autogain.block_size - 1 ); voice.autogain.gain_multiplier = ( voice.autogain.next_gain - voice.autogain.current_gain ) / ( blockSize - 1 );
} }
blockOffset += blockSize; blockOffset += blockSize;
} }
@@ -428,6 +445,9 @@ void Voice_Disconnect( void )
voice.players_status[i].talking_ack = false; voice.players_status[i].talking_ack = false;
} }
} }
VoiceCapture_Shutdown();
voice.device_opened = false;
} }
/* /*
@@ -440,7 +460,7 @@ Feed the decoded data to engine sound subsystem
static void Voice_StartChannel( uint samples, byte *data, int entnum ) static void Voice_StartChannel( uint samples, byte *data, int entnum )
{ {
SND_ForceInitMouth( entnum ); SND_ForceInitMouth( entnum );
S_RawEntSamples( entnum, samples, voice.samplerate, voice.width, VOICE_PCM_CHANNELS, data, 255 ); S_RawEntSamples( entnum, samples, voice.samplerate, voice.width, VOICE_PCM_CHANNELS, data, bound( 0, 255 * voice_scale.value, 255 ));
} }
/* /*
@@ -452,10 +472,11 @@ Received encoded voice data, decode it
*/ */
void Voice_AddIncomingData( int ent, const byte *data, uint size, uint frames ) void Voice_AddIncomingData( int ent, const byte *data, uint size, uint frames )
{ {
const int playernum = ent - 1;
int samples = 0; int samples = 0;
int ofs = 0; int ofs = 0;
if( !voice.decoder ) if( playernum < 0 || playernum >= cl.maxclients || !voice.decoders[playernum] )
return; return;
// decode frame by frame // decode frame by frame
@@ -475,7 +496,7 @@ void Voice_AddIncomingData( int ent, const byte *data, uint size, uint frames )
if( ofs + compressed_size > size ) if( ofs + compressed_size > size )
break; break;
frame_samples = opus_custom_decode( voice.decoder, data + ofs, compressed_size, frame_samples = opus_custom_decode( voice.decoders[playernum], data + ofs, compressed_size,
(opus_int16*)voice.decompress_buffer + samples, voice.frame_size ); (opus_int16*)voice.decompress_buffer + samples, voice.frame_size );
ofs += compressed_size; ofs += compressed_size;
@@ -500,7 +521,7 @@ void CL_AddVoiceToDatagram( void )
if( cls.state != ca_active || !Voice_IsRecording() || !voice.encoder ) if( cls.state != ca_active || !Voice_IsRecording() || !voice.encoder )
return; return;
size = Voice_GetOpusCompressedData( voice.output_buffer, sizeof( voice.output_buffer ), &frames ); size = Voice_GetOpusCompressedData( voice.compress_buffer, sizeof( voice.compress_buffer ), &frames );
if( size > 0 && MSG_GetNumBytesLeft( &cls.datagram ) >= size + 32 ) if( size > 0 && MSG_GetNumBytesLeft( &cls.datagram ) >= size + 32 )
{ {
@@ -508,7 +529,7 @@ void CL_AddVoiceToDatagram( void )
MSG_WriteByte( &cls.datagram, voice_loopback.value != 0 ); MSG_WriteByte( &cls.datagram, voice_loopback.value != 0 );
MSG_WriteByte( &cls.datagram, frames ); MSG_WriteByte( &cls.datagram, frames );
MSG_WriteShort( &cls.datagram, size ); MSG_WriteShort( &cls.datagram, size );
MSG_WriteBytes( &cls.datagram, voice.output_buffer, size ); MSG_WriteBytes( &cls.datagram, voice.compress_buffer, size );
} }
} }
@@ -524,6 +545,7 @@ void Voice_RegisterCvars( void )
Cvar_RegisterVariable( &voice_enable ); Cvar_RegisterVariable( &voice_enable );
Cvar_RegisterVariable( &voice_loopback ); Cvar_RegisterVariable( &voice_loopback );
Cvar_RegisterVariable( &voice_scale ); Cvar_RegisterVariable( &voice_scale );
Cvar_RegisterVariable( &voice_transmit_scale );
Cvar_RegisterVariable( &voice_avggain ); Cvar_RegisterVariable( &voice_avggain );
Cvar_RegisterVariable( &voice_maxgain ); Cvar_RegisterVariable( &voice_maxgain );
Cvar_RegisterVariable( &voice_inputfromfile ); Cvar_RegisterVariable( &voice_inputfromfile );
@@ -541,8 +563,9 @@ static void Voice_Shutdown( void )
int i; int i;
Voice_RecordStop(); Voice_RecordStop();
Voice_ShutdownOpusEncoder();
Voice_ShutdownOpusDecoder(); Voice_ShutdownOpusDecoder();
Voice_ShutdownOpusEncoder();
Voice_ShutdownCustomMode();
VoiceCapture_Shutdown(); VoiceCapture_Shutdown();
if( voice.local.talking_ack ) if( voice.local.talking_ack )
@@ -588,28 +611,28 @@ Voice_Init
Initialize the voice subsystem Initialize the voice subsystem
========================= =========================
*/ */
qboolean Voice_Init( const char *pszCodecName, int quality ) qboolean Voice_Init( const char *pszCodecName, int quality, qboolean preinit )
{ {
if( !voice_enable.value ) if( !voice_enable.value )
return false; return false;
// reinitialize only if codec parameters are different
if( Q_strcmp( pszCodecName, voice.codec ) || voice.quality != quality )
{
Voice_Shutdown();
if( Q_strcmp( pszCodecName, VOICE_OPUS_CUSTOM_CODEC )) if( Q_strcmp( pszCodecName, VOICE_OPUS_CUSTOM_CODEC ))
{ {
Con_Printf( S_ERROR "Server requested unsupported codec: %s\n", pszCodecName ); Con_Printf( S_ERROR "Server requested unsupported codec: %s\n", pszCodecName );
return false; return false;
} }
// reinitialize only if codec parameters are different
if( Q_strcmp( voice.codec, pszCodecName ) && voice.quality != quality )
Voice_Shutdown();
voice.autogain.block_size = 128; voice.autogain.block_size = 128;
if( !Voice_InitOpusDecoder( )) if( !Voice_InitCustomMode( ))
{ {
// no reason to init encoder and open audio device // no reason to init encoder and open audio device
// if we can't hear other players // if we can't hear other players
Con_Printf( S_ERROR "Voice chat disabled.\n" );
Voice_Shutdown(); Voice_Shutdown();
return false; return false;
} }
@@ -625,9 +648,25 @@ qboolean Voice_Init( const char *pszCodecName, int quality )
} }
voice.quality = quality; voice.quality = quality;
}
if( !VoiceCapture_Init( )) if( !preinit )
{
Voice_ShutdownOpusDecoder();
if( !Voice_InitOpusDecoder())
{
// no reason to init encoder and open audio device
// if we can't hear other players
Con_Printf( S_ERROR "Can't create decoders, voice chat is disabled.\n" );
Voice_Shutdown();
return false;
}
voice.device_opened = VoiceCapture_Init();
if( !voice.device_opened )
Con_Printf( S_WARN "No microphone is available.\n" ); Con_Printf( S_WARN "No microphone is available.\n" );
}
return true; return true;
} }

View File

@@ -31,7 +31,7 @@ typedef struct OpusCustomMode OpusCustomMode;
#define VOICE_PCM_CHANNELS 1 // always mono #define VOICE_PCM_CHANNELS 1 // always mono
// never change these parameters when using opuscustom // never change these parameters when using opuscustom
#define VOICE_OPUS_CUSTOM_SAMPLERATE SOUND_44k #define VOICE_OPUS_CUSTOM_SAMPLERATE 44100
// must follow opus custom requirements // must follow opus custom requirements
// also be divisible with MAX_RAW_SAMPLES // also be divisible with MAX_RAW_SAMPLES
#define VOICE_OPUS_CUSTOM_FRAME_SIZE 1024 #define VOICE_OPUS_CUSTOM_FRAME_SIZE 1024
@@ -53,6 +53,7 @@ typedef struct voice_state_s
qboolean initialized; qboolean initialized;
qboolean is_recording; qboolean is_recording;
qboolean device_opened;
double start_time; double start_time;
voice_status_t local; voice_status_t local;
@@ -61,7 +62,7 @@ typedef struct voice_state_s
// opus stuff // opus stuff
OpusCustomMode *custom_mode; OpusCustomMode *custom_mode;
OpusCustomEncoder *encoder; OpusCustomEncoder *encoder;
OpusCustomDecoder *decoder; OpusCustomDecoder *decoders[MAX_CLIENTS];
// audio info // audio info
uint width; uint width;
@@ -70,7 +71,7 @@ typedef struct voice_state_s
// buffers // buffers
byte input_buffer[MAX_RAW_SAMPLES]; byte input_buffer[MAX_RAW_SAMPLES];
byte output_buffer[MAX_RAW_SAMPLES]; byte compress_buffer[MAX_RAW_SAMPLES];
byte decompress_buffer[MAX_RAW_SAMPLES]; byte decompress_buffer[MAX_RAW_SAMPLES];
fs_offset_t input_buffer_pos; // in bytes fs_offset_t input_buffer_pos; // in bytes
@@ -92,7 +93,7 @@ extern voice_state_t voice;
void CL_AddVoiceToDatagram( void ); void CL_AddVoiceToDatagram( void );
void Voice_RegisterCvars( void ); void Voice_RegisterCvars( void );
qboolean Voice_Init( const char *pszCodecName, int quality ); qboolean Voice_Init( const char *pszCodecName, int quality, qboolean preinit );
void Voice_Idle( double frametime ); void Voice_Idle( double frametime );
qboolean Voice_IsRecording( void ); qboolean Voice_IsRecording( void );
void Voice_RecordStop( void ); void Voice_RecordStop( void );

View File

@@ -17,8 +17,6 @@ GNU General Public License for more details.
#define VOX_H #define VOX_H
#define CVOXWORDMAX 64 #define CVOXWORDMAX 64
#define CVOXFILESENTENCEMAX 4096
#define SENTENCE_INDEX -99999 // unique sentence index #define SENTENCE_INDEX -99999 // unique sentence index
typedef struct voxword_s typedef struct voxword_s

View File

@@ -19,13 +19,15 @@ GNU General Public License for more details.
#define HASH_SIZE 128 // 128 * 4 * 4 == 2048 bytes #define HASH_SIZE 128 // 128 * 4 * 4 == 2048 bytes
typedef struct base_command_hashmap_s typedef struct base_command_hashmap_s base_command_hashmap_t;
struct base_command_hashmap_s
{ {
base_command_t *basecmd; // base command: cvar, alias or command base_command_t *basecmd; // base command: cvar, alias or command
const char *name; // key for searching base_command_hashmap_t *next;
base_command_type_e type; // type for faster searching base_command_type_e type; // type for faster searching
struct base_command_hashmap_s *next; char name[1]; // key for searching
} base_command_hashmap_t; };
static base_command_hashmap_t *hashed_cmds[HASH_SIZE]; static base_command_hashmap_t *hashed_cmds[HASH_SIZE];
@@ -124,11 +126,12 @@ void BaseCmd_Insert( base_command_type_e type, base_command_t *basecmd, const ch
{ {
base_command_hashmap_t *elem, *cur, *find; base_command_hashmap_t *elem, *cur, *find;
uint hash = BaseCmd_HashKey( name ); uint hash = BaseCmd_HashKey( name );
size_t len = Q_strlen( name );
elem = Z_Malloc( sizeof( base_command_hashmap_t ) ); elem = Z_Malloc( sizeof( base_command_hashmap_t ) + len );
elem->basecmd = basecmd; elem->basecmd = basecmd;
elem->type = type; elem->type = type;
elem->name = name; Q_strncpy( elem->name, name, len + 1 );
// link the variable in alphanumerical order // link the variable in alphanumerical order
for( cur = NULL, find = hashed_cmds[hash]; for( cur = NULL, find = hashed_cmds[hash];

View File

@@ -31,8 +31,6 @@ typedef enum base_command_type
typedef void base_command_t; typedef void base_command_t;
void BaseCmd_Init( void ); void BaseCmd_Init( void );
base_command_t *BaseCmd_Find( 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, void BaseCmd_FindAll( const char *name,

View File

@@ -52,7 +52,7 @@ CSCR_ExpectString
Return true if next token is pExpext and skip it Return true if next token is pExpext and skip it
=================== ===================
*/ */
qboolean CSCR_ExpectString( parserstate_t *ps, const char *pExpect, qboolean skip, qboolean error ) static qboolean CSCR_ExpectString( parserstate_t *ps, const char *pExpect, qboolean skip, qboolean error )
{ {
char *tmp = COM_ParseFile( ps->buf, ps->token, sizeof( ps->token )); char *tmp = COM_ParseFile( ps->buf, ps->token, sizeof( ps->token ));
@@ -75,7 +75,7 @@ CSCR_ParseType
Determine script variable type Determine script variable type
=================== ===================
*/ */
cvartype_t CSCR_ParseType( parserstate_t *ps ) static cvartype_t CSCR_ParseType( parserstate_t *ps )
{ {
int i; int i;
@@ -96,7 +96,7 @@ cvartype_t CSCR_ParseType( parserstate_t *ps )
CSCR_ParseSingleCvar CSCR_ParseSingleCvar
========================= =========================
*/ */
qboolean CSCR_ParseSingleCvar( parserstate_t *ps, scrvardef_t *result ) static qboolean CSCR_ParseSingleCvar( parserstate_t *ps, scrvardef_t *result )
{ {
// read the name // read the name
ps->buf = COM_ParseFile( ps->buf, result->name, sizeof( result->name )); ps->buf = COM_ParseFile( ps->buf, result->name, sizeof( result->name ));
@@ -170,7 +170,7 @@ CSCR_ParseHeader
Check version and seek to first cvar name Check version and seek to first cvar name
====================== ======================
*/ */
qboolean CSCR_ParseHeader( parserstate_t *ps ) static qboolean CSCR_ParseHeader( parserstate_t *ps )
{ {
if( !CSCR_ExpectString( ps, "VERSION", false, true )) if( !CSCR_ExpectString( ps, "VERSION", false, true ))
return false; return false;

View File

@@ -53,7 +53,7 @@ static void Cmd_ExecuteStringWithPrivilegeCheck( const char *text, qboolean isPr
Cbuf_Init Cbuf_Init
============ ============
*/ */
void Cbuf_Init( void ) static void Cbuf_Init( void )
{ {
cmd_text.data = cmd_text_buf; cmd_text.data = cmd_text_buf;
filteredcmd_text.data = filteredcmd_text_buf; filteredcmd_text.data = filteredcmd_text_buf;
@@ -79,7 +79,7 @@ void Cbuf_Clear( void )
Cbuf_GetSpace Cbuf_GetSpace
============ ============
*/ */
void *Cbuf_GetSpace( cmdbuf_t *buf, int length ) static void *Cbuf_GetSpace( cmdbuf_t *buf, int length )
{ {
void *data; void *data;
@@ -176,7 +176,7 @@ void Cbuf_InsertText( const char *text )
Cbuf_Execute Cbuf_Execute
============ ============
*/ */
void Cbuf_ExecuteCommandsFromBuffer( cmdbuf_t *buf, qboolean isPrivileged, int cmdsToExecute ) static void Cbuf_ExecuteCommandsFromBuffer( cmdbuf_t *buf, qboolean isPrivileged, int cmdsToExecute )
{ {
char *text; char *text;
char line[MAX_CMD_LINE]; char line[MAX_CMD_LINE];
@@ -356,7 +356,7 @@ hl.exe -dev 3 +map c1a0d
hl.exe -nosound -game bshift hl.exe -nosound -game bshift
=============== ===============
*/ */
void Cmd_StuffCmds_f( void ) static void Cmd_StuffCmds_f( void )
{ {
host.stuffcmds_pending = true; host.stuffcmds_pending = true;
} }
@@ -370,7 +370,7 @@ next frame. This allows commands like:
bind g "cmd use rocket ; +attack ; wait ; -attack ; cmd use blaster" bind g "cmd use rocket ; +attack ; wait ; -attack ; cmd use blaster"
============ ============
*/ */
void Cmd_Wait_f( void ) static void Cmd_Wait_f( void )
{ {
cmd_wait = true; cmd_wait = true;
} }
@@ -382,7 +382,7 @@ Cmd_Echo_f
Just prints the rest of the line to the console Just prints the rest of the line to the console
=============== ===============
*/ */
void Cmd_Echo_f( void ) static void Cmd_Echo_f( void )
{ {
int i; int i;
@@ -398,7 +398,7 @@ Cmd_Alias_f
Creates a new command that executes a command string (possibly ; seperated) Creates a new command that executes a command string (possibly ; seperated)
=============== ===============
*/ */
void Cmd_Alias_f( void ) static void Cmd_Alias_f( void )
{ {
cmdalias_t *a; cmdalias_t *a;
char cmd[MAX_CMD_LINE]; char cmd[MAX_CMD_LINE];
@@ -529,7 +529,6 @@ typedef struct cmd_s
static int cmd_argc; static int cmd_argc;
static const char *cmd_args = NULL; static const char *cmd_args = NULL;
static char *cmd_argv[MAX_CMD_TOKENS]; static char *cmd_argv[MAX_CMD_TOKENS];
static char cmd_tokenized[MAX_CMD_BUFFER]; // will have 0 bytes inserted
static cmd_t *cmd_functions; // possible commands to execute static cmd_t *cmd_functions; // possible commands to execute
/* /*
@@ -547,7 +546,7 @@ int GAME_EXPORT Cmd_Argc( void )
Cmd_Argv Cmd_Argv
============ ============
*/ */
const char *Cmd_Argv( int arg ) const char *GAME_EXPORT Cmd_Argv( int arg )
{ {
if((uint)arg >= cmd_argc ) if((uint)arg >= cmd_argc )
return ""; return "";
@@ -559,7 +558,7 @@ const char *Cmd_Argv( int arg )
Cmd_Args Cmd_Args
============ ============
*/ */
const char *Cmd_Args( void ) const char *GAME_EXPORT Cmd_Args( void )
{ {
return cmd_args; return cmd_args;
} }
@@ -641,7 +640,7 @@ void Cmd_TokenizeString( const char *text )
while( 1 ) while( 1 )
{ {
// skip whitespace up to a /n // skip whitespace up to a /n
while( *text && *text <= ' ' && *text != '\r' && *text != '\n' ) while( *text && ((byte)*text ) <= ' ' && *text != '\r' && *text != '\n' )
text++; text++;
if( *text == '\n' || *text == '\r' ) if( *text == '\n' || *text == '\r' )
@@ -882,7 +881,7 @@ Cmd_If_f
Compare and et condition bit if true Compare and et condition bit if true
============ ============
*/ */
void Cmd_If_f( void ) static void Cmd_If_f( void )
{ {
// reset bit first // reset bit first
cmd_condition &= ~BIT( cmd_condlevel ); cmd_condition &= ~BIT( cmd_condlevel );
@@ -943,14 +942,14 @@ Cmd_Else_f
Invert condition bit Invert condition bit
============ ============
*/ */
void Cmd_Else_f( void ) static void Cmd_Else_f( void )
{ {
cmd_condition ^= BIT( cmd_condlevel ); cmd_condition ^= BIT( cmd_condlevel );
} }
static qboolean Cmd_ShouldAllowCommand( cmd_t *cmd, qboolean isPrivileged ) static qboolean Cmd_ShouldAllowCommand( cmd_t *cmd, qboolean isPrivileged )
{ {
const char *prefixes[] = { "cl_", "gl_", "r_", "m_", "hud_" }; const char *prefixes[] = { "cl_", "gl_", "r_", "m_", "hud_", "joy_", "con_", "scr_" };
int i; int i;
// always allow local commands // always allow local commands
@@ -996,7 +995,7 @@ static void Cmd_ExecuteStringWithPrivilegeCheck( const char *text, qboolean isPr
cmd_condlevel = 0; cmd_condlevel = 0;
// cvar value substitution // cvar value substitution
if( CVAR_TO_BOOL( cmd_scripting ) && isPrivileged ) if( cmd_scripting.value && isPrivileged )
{ {
while( *text ) while( *text )
{ {
@@ -1016,7 +1015,7 @@ static void Cmd_ExecuteStringWithPrivilegeCheck( const char *text, qboolean isPr
*ptoken++ = *text++; *ptoken++ = *text++;
*ptoken = 0; *ptoken = 0;
len += Q_strncpy( pcmd, Cvar_VariableString( token ), MAX_CMD_LINE - len ); len += Q_strncpy( pcmd, Cvar_VariableString( token ), sizeof( token ) - len );
pcmd = command + len; pcmd = command + len;
if( !*text ) break; if( !*text ) break;
@@ -1179,7 +1178,7 @@ void Cmd_ForwardToServer( void )
Cmd_List_f Cmd_List_f
============ ============
*/ */
void Cmd_List_f( void ) static void Cmd_List_f( void )
{ {
cmd_t *cmd; cmd_t *cmd;
int i = 0; int i = 0;
@@ -1357,7 +1356,7 @@ inserts escape sequences
void Cmd_Escape( char *newCommand, const char *oldCommand, int len ) void Cmd_Escape( char *newCommand, const char *oldCommand, int len )
{ {
int c; int c;
int scripting = CVAR_TO_BOOL( cmd_scripting ); int scripting = cmd_scripting.value;
while( (c = *oldCommand++) && len > 1 ) while( (c = *oldCommand++) && len > 1 )
{ {

View File

@@ -17,15 +17,24 @@ GNU General Public License for more details.
#define COM_STRINGS_H #define COM_STRINGS_H
// default colored message headers // default colored message headers
#define S_NOTE "^2Note:^7 " #define S_BLACK "^0"
#define S_WARN "^3Warning:^7 " #define S_RED "^1"
#define S_ERROR "^1Error:^7 " #define S_GREEN "^2"
#define S_USAGE "Usage: " #define S_YELLOW "^3"
#define S_USAGE_INDENT " " #define S_BLUE "^4"
#define S_CYAN "^5"
#define S_MAGENTA "^6"
#define S_DEFAULT "^7"
#define S_OPENGL_NOTE "^2OpenGL Note:^7 " #define S_NOTE S_GREEN "Note: " S_DEFAULT
#define S_OPENGL_WARN "^3OpenGL Warning:^7 " #define S_WARN S_YELLOW "Warning: " S_DEFAULT
#define S_OPENGL_ERROR "^3OpenGL Error:^7 " #define S_ERROR S_RED "Error: " S_DEFAULT
#define S_USAGE "Usage: "
#define S_USAGE_INDENT "\t"
#define S_OPENGL_NOTE S_GREEN "OpenGL Note: " S_DEFAULT
#define S_OPENGL_WARN S_YELLOW "OpenGL Warning: " S_DEFAULT
#define S_OPENGL_ERROR S_RED "OpenGL Error: " S_DEFAULT
// end game final default message // end game final default message
#define DEFAULT_ENDGAME_MESSAGE "The End" #define DEFAULT_ENDGAME_MESSAGE "The End"
@@ -65,6 +74,7 @@ GNU General Public License for more details.
#define DEFAULT_UPDATE_PAGE "https://github.com/FWGS/xash3d-fwgs/releases/latest" #define DEFAULT_UPDATE_PAGE "https://github.com/FWGS/xash3d-fwgs/releases/latest"
#define XASH_ENGINE_NAME "Xash3D FWGS" #define XASH_ENGINE_NAME "Xash3D FWGS"
#define XASH_DEDICATED_SERVER_NAME "XashDS"
#define XASH_VERSION "0.20" // engine current version #define XASH_VERSION "0.20" // engine current version
#define XASH_COMPAT_VERSION "0.99" // version we are based on #define XASH_COMPAT_VERSION "0.99" // version we are based on

View File

@@ -22,20 +22,22 @@ GNU General Public License for more details.
#include "const.h" #include "const.h"
#include "client.h" #include "client.h"
#include "library.h" #include "library.h"
#include "sequence.h"
static const char *file_exts[] = static const char *file_exts[] =
{ {
"cfg", // ban text files that don't make sense as resource
"lst", "cfg", "lst", "ini", "log",
"exe",
"vbs", // ban Windows code
"com", "exe", "vbs", "com", "bat",
"bat", "dll", "sys", "ps1",
"dll",
"ini", // ban common unix code
"log", // NOTE: in unix anything can be executed as long it has access flag
"sys", "so", "sh", "dylib",
// ban mobile archives
"apk", "ipa",
}; };
#ifdef _DEBUG #ifdef _DEBUG
@@ -104,7 +106,7 @@ static float fran1( void )
return temp; return temp;
} }
void COM_SetRandomSeed( int lSeed ) void GAME_EXPORT COM_SetRandomSeed( int lSeed )
{ {
if( lSeed ) idum = lSeed; if( lSeed ) idum = lSeed;
else idum = -time( NULL ); else idum = -time( NULL );
@@ -267,7 +269,7 @@ static void LZSS_BuildHash( lzss_state_t *state, const byte *source )
list->start = node; 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 *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 byte *pEnd = pStart + input_length - sizeof( lzss_header_t ) - 8; // prevent compression failure
@@ -391,6 +393,9 @@ byte *LZSS_Compress( byte *pInput, int inputLength, uint *pOutputSize )
byte *pFinal = NULL; byte *pFinal = NULL;
lzss_state_t state; lzss_state_t state;
if( !pStart )
return NULL;
memset( &state, 0, sizeof( state )); memset( &state, 0, sizeof( state ));
state.window_size = LZSS_WINDOW_SIZE; state.window_size = LZSS_WINDOW_SIZE;
@@ -532,47 +537,6 @@ int GAME_EXPORT COM_FileSize( const char *filename )
return FS_FileSize( filename, false ); return FS_FileSize( filename, false );
} }
/*
=============
COM_AddAppDirectoryToSearchPath
=============
*/
void GAME_EXPORT COM_AddAppDirectoryToSearchPath( const char *pszBaseDir, const char *appName )
{
FS_AddGameHierarchy( pszBaseDir, FS_NOWRITE_PATH );
}
/*
===========
COM_ExpandFilename
Finds the file in the search path, copies over the name with the full path name.
This doesn't search in the pak file.
===========
*/
int GAME_EXPORT COM_ExpandFilename( const char *fileName, char *nameOutBuffer, int nameOutBufferSize )
{
char result[MAX_SYSPATH];
if( !COM_CheckString( fileName ) || !nameOutBuffer || nameOutBufferSize <= 0 )
return 0;
// filename examples:
// media\sierra.avi - D:\Xash3D\valve\media\sierra.avi
// models\barney.mdl - D:\Xash3D\bshift\models\barney.mdl
if( g_fsapi.GetFullDiskPath( result, sizeof( result ), fileName, false ))
{
// check for enough room
if( Q_strlen( result ) > nameOutBufferSize )
return 0;
Q_strncpy( nameOutBuffer, result, nameOutBufferSize );
return 1;
}
return 0;
}
/* /*
============= =============
COM_TrimSpace COM_TrimSpace
@@ -613,7 +577,7 @@ COM_Nibble
Returns the 4 bit nibble for a hex character 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' )) if(( c >= '0' ) && ( c <= '9' ))
{ {
@@ -661,7 +625,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; int i, last, stop;
@@ -715,7 +679,7 @@ Cache_Check
consistency 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 ) if( !c->data )
return NULL; return NULL;
@@ -735,7 +699,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; string name;
byte *file, *pfile; byte *pfile;
fs_offset_t iLength; fs_offset_t iLength;
if( !COM_CheckString( filename )) if( !COM_CheckString( filename ))
@@ -748,21 +712,9 @@ byte* GAME_EXPORT COM_LoadFileForMe( const char *filename, int *pLength )
Q_strncpy( name, filename, sizeof( name )); Q_strncpy( name, filename, sizeof( name ));
COM_FixSlashes( name ); COM_FixSlashes( name );
pfile = FS_LoadFile( name, &iLength, false ); pfile = g_fsapi.LoadFileMalloc( name, &iLength, false );
if( pLength ) *pLength = (int)iLength; if( pLength ) *pLength = (int)iLength;
if( pfile )
{
file = malloc( iLength + 1 );
if( file != NULL )
{
memcpy( file, pfile, iLength );
file[iLength] = '\0';
}
Mem_Free( pfile );
pfile = file;
}
return pfile; return pfile;
} }
@@ -772,7 +724,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 ); return COM_LoadFileForMe( filename, pLength );
} }
@@ -858,59 +810,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;
return (cvar_t *)Cvar_Get( szName, szValue, flags|FCVAR_CLIENTDLL, Cvar_BuildAutoDescription( szName, flags|FCVAR_CLIENTDLL ));
}
/*
=============
pfnCvar_RegisterVariable
=============
*/
cvar_t *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 ));
}
/* /*
============= =============
pfnCVarGetPointer pfnCVarGetPointer
@@ -918,23 +817,11 @@ pfnCVarGetPointer
can return NULL can return NULL
============= =============
*/ */
cvar_t *pfnCVarGetPointer( const char *szVarName ) cvar_t *GAME_EXPORT pfnCVarGetPointer( const char *szVarName )
{ {
return (cvar_t *)Cvar_FindVar( szVarName ); return (cvar_t *)Cvar_FindVar( szVarName );
} }
/*
=============
pfnCVarDirectSet
allow to set cvar directly
=============
*/
void GAME_EXPORT pfnCVarDirectSet( cvar_t *var, const char *szValue )
{
Cvar_DirectSet( (convar_t *)var, szValue );
}
/* /*
============= =============
COM_CompareFileTime COM_CompareFileTime
@@ -1016,7 +903,10 @@ qboolean COM_IsSafeFileToDownload( const char *filename )
if( !COM_CheckString( filename )) if( !COM_CheckString( filename ))
return false; return false;
if( !Q_strncmp( filename, "!MD5", 4 )) ext = COM_FileExtension( lwrfilename );
// only allow extensionless files that start with !MD5
if( !Q_strncmp( filename, "!MD5", 4 ) && ext[0] == 0 )
return true; return true;
Q_strnlwr( filename, lwrfilename, sizeof( lwrfilename )); Q_strnlwr( filename, lwrfilename, sizeof( lwrfilename ));
@@ -1039,8 +929,6 @@ qboolean COM_IsSafeFileToDownload( const char *filename )
if( Q_strlen( first ) != 4 ) if( Q_strlen( first ) != 4 )
return false; return false;
ext = COM_FileExtension( lwrfilename );
for( i = 0; i < ARRAYSIZE( file_exts ); i++ ) for( i = 0; i < ARRAYSIZE( file_exts ); i++ )
{ {
if( !Q_stricmp( ext, file_exts[i] )) if( !Q_stricmp( ext, file_exts[i] ))
@@ -1050,21 +938,6 @@ qboolean COM_IsSafeFileToDownload( const char *filename )
return true; 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 ) char *_copystring( poolhandle_t mempool, const char *s, const char *filename, int fileline )
{ {
size_t size; size_t size;
@@ -1100,7 +973,7 @@ void *GAME_EXPORT pfnSequenceGet( const char *fileName, const char *entryName )
{ {
Msg( "Sequence_Get: file %s, entry %s\n", fileName, entryName ); Msg( "Sequence_Get: file %s, entry %s\n", fileName, entryName );
return Sequence_Get( fileName, entryName ); return NULL;
} }
/* /*
@@ -1114,7 +987,7 @@ void *GAME_EXPORT pfnSequencePickSentence( const char *groupName, int pickMethod
{ {
Msg( "Sequence_PickSentence: group %s, pickMethod %i\n", groupName, pickMethod ); Msg( "Sequence_PickSentence: group %s, pickMethod %i\n", groupName, pickMethod );
return Sequence_PickSentence( groupName, pickMethod, picked ); return NULL;
} }
@@ -1125,30 +998,7 @@ pfnIsCareerMatch
used by CS:CZ (client stub) used by CS:CZ (client stub)
============= =============
*/ */
int GAME_EXPORT GAME_EXPORT pfnIsCareerMatch( void ) int 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 )
{ {
return 0; return 0;
} }

View File

@@ -144,7 +144,7 @@ typedef enum
#define GameState (&host.game) #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 #ifdef _DEBUG
void DBG_AssertFunction( qboolean fExpr, const char* szExpr, const char* szFile, int szLine, const char* szMessage ); void DBG_AssertFunction( qboolean fExpr, const char* szExpr, const char* szFile, int szLine, const char* szMessage );
@@ -153,16 +153,14 @@ void DBG_AssertFunction( qboolean fExpr, const char* szExpr, const char* szFile,
#define Assert( f ) #define Assert( f )
#endif #endif
extern convar_t *gl_vsync; extern convar_t gl_vsync;
extern convar_t *scr_loading; extern convar_t scr_loading;
extern convar_t *scr_download; extern convar_t scr_download;
extern convar_t *cmd_scripting; extern convar_t cmd_scripting;
extern convar_t *sv_maxclients; extern convar_t cl_allow_levelshots;
extern convar_t *cl_allow_levelshots;
extern convar_t host_developer; extern convar_t host_developer;
extern convar_t *host_limitlocal; extern convar_t host_limitlocal;
extern convar_t *host_framerate; extern convar_t host_maxfps;
extern convar_t *host_maxfps;
extern convar_t sys_timescale; extern convar_t sys_timescale;
extern convar_t cl_filterstuffcmd; extern convar_t cl_filterstuffcmd;
extern convar_t rcon_password; extern convar_t rcon_password;
@@ -273,48 +271,14 @@ typedef struct
double forcedEnd; double forcedEnd;
} soundlist_t; } 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 typedef enum bugcomp_e
{ {
// default mode, we assume that user dlls are not relying on engine bugs // reverts fix for pfnPEntityOfEntIndex for bug compatibility with GoldSrc
BUGCOMP_OFF, BUGCOMP_PENTITYOFENTINDEX_FLAG = BIT( 0 ),
// GoldSrc mode, user dlls are relying on GoldSrc specific bugs // rewrites mod's attempts to write GoldSrc-specific messages into Xash protocol
// but fixing them may break regular Xash games // (new wrappers are added by request)
BUGCOMP_GOLDSRC, BUGCOMP_MESSAGE_REWRITE_FACILITY_FLAG = BIT( 1 ),
} bugcomp_t; } bugcomp_t;
typedef struct host_parm_s typedef struct host_parm_s
@@ -338,8 +302,12 @@ typedef struct host_parm_s
int argc; int argc;
char **argv; char **argv;
// ==== shared through RefAPI's ref_host_t
double realtime; // host.curtime double realtime; // host.curtime
double frametime; // time between engine frames double frametime; // time between engine frames
uint features; // custom features that enables by mod-maker request
// ==== shared through RefAPI's ref_host_t
double realframetime; // for some system events, e.g. console animations double realframetime; // for some system events, e.g. console animations
uint framecount; // global framecount uint framecount; // global framecount
@@ -360,8 +328,7 @@ typedef struct host_parm_s
qboolean change_game; // initialize when game is changed qboolean change_game; // initialize when game is changed
qboolean mouse_visible; // vgui override cursor control (never change outside Platform_SetCursorType!) qboolean mouse_visible; // vgui override cursor control (never change outside Platform_SetCursorType!)
qboolean shutdown_issued; // engine is shutting down qboolean shutdown_issued; // engine is shutting down
qboolean force_draw_version; // used when fraps is loaded double force_draw_version_time;
float force_draw_version_time;
qboolean apply_game_config; // when true apply only to game cvars and ignore all other commands 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 apply_opengl_config;// when true apply only to opengl cvars and ignore all other commands
qboolean config_executed; // a bit who indicated was config.cfg already executed e.g. from valve.rc qboolean config_executed; // a bit who indicated was config.cfg already executed e.g. from valve.rc
@@ -381,8 +348,6 @@ typedef struct host_parm_s
poolhandle_t imagepool; // imagelib mempool poolhandle_t imagepool; // imagelib mempool
poolhandle_t soundpool; // soundlib mempool poolhandle_t soundpool; // soundlib mempool
uint features; // custom features that enables by mod-maker request
// for IN_MouseMove() easy access // for IN_MouseMove() easy access
int window_center_x; int window_center_x;
int window_center_y; int window_center_y;
@@ -391,7 +356,7 @@ typedef struct host_parm_s
int numdecals; int numdecals;
// bug compatibility level, for very "special" games // bug compatibility level, for very "special" games
bugcomp_t bugcomp; uint32_t bugcomp;
// measure time to first frame // measure time to first frame
double starttime; double starttime;
@@ -418,11 +383,11 @@ typedef void (*xcommand_t)( void );
qboolean FS_LoadProgs( void ); qboolean FS_LoadProgs( void );
void FS_Init( void ); void FS_Init( void );
void FS_Shutdown( void ); void FS_Shutdown( void );
void *FS_GetNativeObject( const char *obj );
// //
// cmd.c // cmd.c
// //
void Cbuf_Init( void );
void Cbuf_Clear( void ); void Cbuf_Clear( void );
void Cbuf_AddText( const char *text ); void Cbuf_AddText( const char *text );
void Cbuf_AddTextf( const char *text, ... ) _format( 1 ); void Cbuf_AddTextf( const char *text, ... ) _format( 1 );
@@ -446,9 +411,6 @@ void Cmd_RemoveCommand( const char *cmd_name );
qboolean Cmd_Exists( const char *cmd_name ); qboolean Cmd_Exists( const char *cmd_name );
void Cmd_LookupCmds( void *buffer, void *ptr, setpair_t callback ); void Cmd_LookupCmds( void *buffer, void *ptr, setpair_t callback );
int Cmd_ListMaps( search_t *t , char *lastmapname, size_t len ); int Cmd_ListMaps( search_t *t , char *lastmapname, size_t len );
qboolean Cmd_GetMapList( const char *s, char *completedname, int length );
qboolean Cmd_GetDemoList( const char *s, char *completedname, int length );
qboolean Cmd_GetMovieList( const char *s, char *completedname, int length );
void Cmd_TokenizeString( const char *text ); void Cmd_TokenizeString( const char *text );
void Cmd_ExecuteString( const char *text ); void Cmd_ExecuteString( const char *text );
void Cmd_ForwardToServer( void ); void Cmd_ForwardToServer( void );
@@ -458,8 +420,8 @@ void Cmd_Escape( char *newCommand, const char *oldCommand, int len );
// zone.c // zone.c
// //
void Memory_Init( void ); void Memory_Init( void );
void *_Mem_Realloc( poolhandle_t poolptr, void *memptr, size_t size, qboolean clear, const char *filename, int fileline ); void *_Mem_Realloc( poolhandle_t poolptr, void *memptr, size_t size, qboolean clear, const char *filename, int fileline ) ALLOC_CHECK( 3 );
void *_Mem_Alloc( poolhandle_t poolptr, size_t size, qboolean clear, const char *filename, int fileline ); void *_Mem_Alloc( poolhandle_t poolptr, size_t size, qboolean clear, const char *filename, int fileline ) ALLOC_CHECK( 2 );
poolhandle_t _Mem_AllocPool( const char *name, const char *filename, int fileline ); poolhandle_t _Mem_AllocPool( const char *name, const char *filename, int fileline );
void _Mem_FreePool( poolhandle_t *poolptr, const char *filename, int fileline ); void _Mem_FreePool( poolhandle_t *poolptr, const char *filename, int fileline );
void _Mem_EmptyPool( poolhandle_t poolptr, const char *filename, int fileline ); void _Mem_EmptyPool( poolhandle_t poolptr, const char *filename, int fileline );
@@ -495,13 +457,12 @@ void FS_FreeImage( rgbdata_t *pack );
extern const bpc_desc_t PFDesc[]; // image get pixelformat extern const bpc_desc_t PFDesc[]; // image get pixelformat
qboolean Image_Process( rgbdata_t **pix, int width, int height, uint flags, float reserved ); qboolean Image_Process( rgbdata_t **pix, int width, int height, uint flags, float reserved );
void Image_PaletteHueReplace( byte *palSrc, int newHue, int start, int end, int pal_size ); void Image_PaletteHueReplace( byte *palSrc, int newHue, int start, int end, int pal_size );
void Image_PaletteTranslate( byte *palSrc, int top, int bottom, int pal_size );
void Image_SetForceFlags( uint flags ); // set image force flags on loading void Image_SetForceFlags( uint flags ); // set image force flags on loading
size_t Image_DXTGetLinearSize( int type, int width, int height, int depth );
qboolean Image_CustomPalette( void ); qboolean Image_CustomPalette( void );
void Image_ClearForceFlags( void ); void Image_ClearForceFlags( void );
void Image_SetMDLPointer( byte *p ); void Image_SetMDLPointer( byte *p );
void Image_CheckPaletteQ1( void ); void Image_CheckPaletteQ1( void );
/* /*
======================================================================== ========================================================================
@@ -518,14 +479,6 @@ typedef enum
WF_TOTALCOUNT, // must be last WF_TOTALCOUNT, // must be last
} sndformat_t; } sndformat_t;
// soundlib global settings
typedef enum
{
SL_USE_LERPING = BIT(0), // lerping sounds during resample
SL_KEEP_8BIT = BIT(1), // don't expand 8bit sounds automatically up to 16 bit
SL_ALLOW_OVERWRITE = BIT(2), // allow to overwrite stored sounds
} slFlags_t;
// wavdata output flags // wavdata output flags
typedef enum typedef enum
{ {
@@ -535,7 +488,6 @@ typedef enum
// Sound_Process manipulation flags // Sound_Process manipulation flags
SOUND_RESAMPLE = BIT( 12 ), // resample sound to specified rate SOUND_RESAMPLE = BIT( 12 ), // resample sound to specified rate
SOUND_CONVERT16BIT = BIT(13), // change sound resolution from 8 bit to 16
} sndFlags_t; } sndFlags_t;
typedef struct typedef struct
@@ -543,8 +495,8 @@ typedef struct
word rate; // num samples per second (e.g. 11025 - 11 khz) word rate; // num samples per second (e.g. 11025 - 11 khz)
byte width; // resolution - bum bits divided by 8 (8 bit is 1, 16 bit is 2) byte width; // resolution - bum bits divided by 8 (8 bit is 1, 16 bit is 2)
byte channels; // num channels (1 - mono, 2 - stereo) byte channels; // num channels (1 - mono, 2 - stereo)
int loopStart; // offset at this point sound will be looping while playing more than only once uint loopStart; // offset at this point sound will be looping while playing more than only once
int samples; // total samplecount in wav uint samples; // total samplecount in wav
uint type; // compression type uint type; // compression type
uint flags; // misc sound flags uint flags; // misc sound flags
byte *buffer; // sound buffer byte *buffer; // sound buffer
@@ -577,7 +529,6 @@ qboolean Host_IsQuakeCompatible( void );
void EXPORT Host_Shutdown( void ); void EXPORT Host_Shutdown( void );
int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGame, pfnChangeGame func ); int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGame, pfnChangeGame func );
int Host_CompareFileTime( int ft1, int ft2 ); int Host_CompareFileTime( int ft1, int ft2 );
void Host_NewInstance( const char *name, const char *finalmsg );
void Host_EndGame( qboolean abort, const char *message, ... ) _format( 2 ); void Host_EndGame( qboolean abort, const char *message, ... ) _format( 2 );
void Host_AbortCurrentFrame( void ) NORETURN; void Host_AbortCurrentFrame( void ) NORETURN;
void Host_WriteServerConfig( const char *name ); void Host_WriteServerConfig( const char *name );
@@ -588,9 +539,8 @@ qboolean Host_IsLocalGame( void );
qboolean Host_IsLocalClient( void ); qboolean Host_IsLocalClient( void );
void Host_ShutdownServer( void ); void Host_ShutdownServer( void );
void Host_Error( const char *error, ... ) _format( 1 ); void Host_Error( const char *error, ... ) _format( 1 );
void Host_PrintEngineFeatures( void ); void Host_ValidateEngineFeatures( uint32_t features );
void Host_Frame( float time ); void Host_Frame( float time );
void Host_InitDecals( void );
void Host_Credits( void ); void Host_Credits( void );
// //
@@ -629,16 +579,11 @@ 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 ); char *COM_MemFgets( byte *pMemFile, int fileSize, int *filePos, char *pBuffer, int bufferSize );
void COM_HexConvert( const char *pszInput, int nInputLength, byte *pOutput ); void COM_HexConvert( const char *pszInput, int nInputLength, byte *pOutput );
int COM_SaveFile( const char *filename, const void *data, int len ); int COM_SaveFile( const char *filename, const void *data, int len );
byte* COM_LoadFileForMe( const char *filename, int *pLength ); byte* COM_LoadFileForMe( const char *filename, int *pLength );
qboolean COM_IsSafeFileToDownload( const char *filename ); qboolean COM_IsSafeFileToDownload( const char *filename );
const char *COM_GetResourceTypeName( resourcetype_t restype );
cvar_t *pfnCVarGetPointer( const char *szVarName ); cvar_t *pfnCVarGetPointer( const char *szVarName );
int pfnDrawConsoleString( int x, int y, char *string ); int pfnDrawConsoleString( int x, int y, char *string );
void pfnDrawSetTextColor( float r, float g, float b ); void pfnDrawSetTextColor( float r, float g, float b );
@@ -646,10 +591,8 @@ void pfnDrawConsoleStringLen( const char *pText, int *length, int *height );
void *Cache_Check( poolhandle_t mempool, struct cache_user_s *c ); void *Cache_Check( poolhandle_t mempool, struct cache_user_s *c );
void COM_TrimSpace( const char *source, char *dest ); void COM_TrimSpace( const char *source, char *dest );
void pfnGetModelBounds( model_t *mod, float *mins, float *maxs ); void pfnGetModelBounds( model_t *mod, float *mins, float *maxs );
void pfnCVarDirectSet( cvar_t *var, const char *szValue );
int COM_CheckParm( char *parm, char **ppnext ); int COM_CheckParm( char *parm, char **ppnext );
void pfnGetGameDir( char *szGetGameDir ); void pfnGetGameDir( char *szGetGameDir );
int pfnDecalIndex( const char *m );
int pfnGetModelType( model_t *mod ); int pfnGetModelType( model_t *mod );
int pfnIsMapValid( char *filename ); int pfnIsMapValid( char *filename );
void Con_Reportf( const char *szFmt, ... ) _format( 1 ); void Con_Reportf( const char *szFmt, ... ) _format( 1 );
@@ -669,8 +612,6 @@ void *pfnSequencePickSentence( const char *groupName, int pickMethod, int *picke
int pfnIsCareerMatch( void ); int pfnIsCareerMatch( void );
// Decay engfuncs (stubs) // Decay engfuncs (stubs)
int pfnGetTimesTutorMessageShown( int mid );
void pfnRegisterTutorMessageShown( int mid );
void pfnConstructTutorMessageDecayBuffer( int *buffer, int buflen ); void pfnConstructTutorMessageDecayBuffer( int *buffer, int buflen );
void pfnProcessTutorMessageDecayBuffer( int *buffer, int bufferLength ); void pfnProcessTutorMessageDecayBuffer( int *buffer, int bufferLength );
void pfnResetTutorMessageDecayData( void ); void pfnResetTutorMessageDecayData( void );
@@ -691,7 +632,6 @@ void pfnResetTutorMessageDecayData( void );
// //
// con_utils.c // con_utils.c
// //
qboolean Cmd_AutocompleteName( const char *source, int arg, char *buffer, size_t bufsize );
void Con_CompleteCommand( field_t *field ); void Con_CompleteCommand( field_t *field );
void Cmd_AutoComplete( char *complete_string ); void Cmd_AutoComplete( char *complete_string );
void Cmd_AutoCompleteClear( void ); void Cmd_AutoCompleteClear( void );
@@ -747,25 +687,15 @@ void CL_LegacyUpdateInfo( void );
void CL_CharEvent( int key ); void CL_CharEvent( int key );
qboolean CL_DisableVisibility( void ); qboolean CL_DisableVisibility( void );
byte *COM_LoadFile( const char *filename, int usehunk, int *pLength ); 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 );
int COM_ExpandFilename( const char *fileName, char *nameOutBuffer, int nameOutBufferSize );
struct cmd_s *Cmd_GetFirstFunctionHandle( void ); struct cmd_s *Cmd_GetFirstFunctionHandle( void );
struct cmd_s *Cmd_GetNextFunctionHandle( struct cmd_s *cmd ); struct cmd_s *Cmd_GetNextFunctionHandle( struct cmd_s *cmd );
struct cmdalias_s *Cmd_AliasGetList( void ); struct cmdalias_s *Cmd_AliasGetList( void );
const char *Cmd_GetName( struct cmd_s *cmd ); const char *Cmd_GetName( struct cmd_s *cmd );
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 Log_Printf( const char *fmt, ... ) _format( 1 );
void SV_BroadcastCommand( const char *fmt, ... ) _format( 1 ); void SV_BroadcastCommand( const char *fmt, ... ) _format( 1 );
qboolean SV_RestoreCustomDecal( struct decallist_s *entry, edict_t *pEdict, qboolean adjacent );
void SV_BroadcastPrintf( struct sv_client_s *ignore, const char *fmt, ... ) _format( 2 ); void SV_BroadcastPrintf( struct sv_client_s *ignore, const char *fmt, ... ) _format( 2 );
int R_CreateDecalList( struct decallist_s *pList );
void R_ClearAllDecals( void );
void CL_ClearStaticEntities( void ); void CL_ClearStaticEntities( void );
qboolean S_StreamGetCurrentState( char *currentTrack, char *loopTrack, int *position ); qboolean S_StreamGetCurrentState( char *currentTrack, size_t currentTrackSize, char *loopTrack, size_t loopTrackSize, int *position );
struct cl_entity_s *CL_GetEntityByIndex( int index );
void CL_ServerCommand( qboolean reliable, const char *fmt, ... ) _format( 2 ); void CL_ServerCommand( qboolean reliable, const char *fmt, ... ) _format( 2 );
void CL_HudMessage( const char *pMessage ); void CL_HudMessage( const char *pMessage );
const char *CL_MsgInfo( int cmd ); const char *CL_MsgInfo( int cmd );
@@ -774,17 +704,14 @@ void SV_DrawOrthoTriangles( void );
double CL_GetDemoFramerate( void ); double CL_GetDemoFramerate( void );
qboolean UI_CreditsActive( void ); qboolean UI_CreditsActive( void );
void CL_StopPlayback( void ); void CL_StopPlayback( void );
void CL_ExtraUpdate( void );
int CL_GetMaxClients( void ); int CL_GetMaxClients( void );
int SV_GetMaxClients( void ); int SV_GetMaxClients( void );
qboolean CL_IsRecordDemo( void ); qboolean CL_IsRecordDemo( void );
qboolean CL_IsTimeDemo( void ); qboolean CL_IsTimeDemo( void );
qboolean CL_IsPlaybackDemo( void ); qboolean CL_IsPlaybackDemo( void );
qboolean SV_Initialized( void ); qboolean SV_Initialized( void );
qboolean CL_LoadProgs( const char *name );
void CL_ProcessFile( qboolean successfully_received, const char *filename ); void CL_ProcessFile( qboolean successfully_received, const char *filename );
int SV_GetSaveComment( const char *savename, char *comment ); int SV_GetSaveComment( const char *savename, char *comment );
qboolean SV_NewGame( const char *mapName, qboolean loadGame );
void SV_ClipPMoveToEntity( struct physent_s *pe, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, struct pmtrace_s *tr ); void SV_ClipPMoveToEntity( struct physent_s *pe, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, struct pmtrace_s *tr );
void CL_ClipPMoveToEntity( struct physent_s *pe, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, struct pmtrace_s *tr ); void CL_ClipPMoveToEntity( struct physent_s *pe, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, struct pmtrace_s *tr );
void SV_SysError( const char *error_string ); void SV_SysError( const char *error_string );
@@ -792,14 +719,10 @@ void SV_ShutdownGame( void );
void SV_ExecLoadLevel( void ); void SV_ExecLoadLevel( void );
void SV_ExecLoadGame( void ); void SV_ExecLoadGame( void );
void SV_ExecChangeLevel( void ); void SV_ExecChangeLevel( void );
void SV_InitGameProgs( void );
void SV_FreeGameProgs( void );
void CL_WriteMessageHistory( void ); void CL_WriteMessageHistory( void );
void CL_SendCmd( void );
void CL_Disconnect( void ); void CL_Disconnect( void );
void CL_ClearEdicts( void ); void CL_ClearEdicts( void );
void CL_Crashed( void ); void CL_Crashed( void );
qboolean CL_NextDemo( void );
char *SV_Serverinfo( void ); char *SV_Serverinfo( void );
void CL_Drop( void ); void CL_Drop( void );
void Con_Init( void ); void Con_Init( void );
@@ -824,7 +747,6 @@ qboolean Info_SetValueForStarKey( char *s, const char *key, const char *value, i
qboolean Info_IsValid( const char *s ); qboolean Info_IsValid( const char *s );
void Info_WriteVars( file_t *f ); void Info_WriteVars( file_t *f );
void Info_Print( const char *s ); void Info_Print( const char *s );
void Cmd_WriteVariables( file_t *f );
int Cmd_CheckMapsList( int fRefresh ); int Cmd_CheckMapsList( int fRefresh );
void COM_SetRandomSeed( int lSeed ); void COM_SetRandomSeed( int lSeed );
int COM_RandomLong( int lMin, int lMax ); int COM_RandomLong( int lMin, int lMax );
@@ -839,13 +761,14 @@ void VID_Init( void );
void UI_SetActiveMenu( qboolean fActive ); void UI_SetActiveMenu( qboolean fActive );
void UI_ShowConnectionWarning( void ); void UI_ShowConnectionWarning( void );
void Cmd_Null_f( void ); void Cmd_Null_f( void );
void Rcon_Print( const char *pMsg ); void Rcon_Print( host_redirect_t *rd, const char *pMsg );
qboolean COM_ParseVector( char **pfile, float *v, size_t size ); qboolean COM_ParseVector( char **pfile, float *v, size_t size );
void COM_NormalizeAngles( vec3_t angles ); void COM_NormalizeAngles( vec3_t angles );
int COM_FileSize( const char *filename ); int COM_FileSize( const char *filename );
void COM_FreeFile( void *buffer ); void COM_FreeFile( void *buffer );
int COM_CompareFileTime( const char *filename1, const char *filename2, int *iCompare ); int COM_CompareFileTime( const char *filename1, const char *filename2, int *iCompare );
char *va( const char *format, ... ) _format( 1 ); char *va( const char *format, ... ) _format( 1 );
qboolean CRC32_MapFile( dword *crcvalue, const char *filename, qboolean multiplayer );
// soundlib shared exports // soundlib shared exports
qboolean S_Init( void ); qboolean S_Init( void );
@@ -856,8 +779,14 @@ void S_StopBackgroundTrack( void );
void S_StopAllSounds( qboolean ambient ); void S_StopAllSounds( qboolean ambient );
// gamma routines // gamma routines
void BuildGammaTable( float gamma, float brightness );
byte LightToTexGamma( byte b ); byte LightToTexGamma( byte b );
byte TextureToGamma( byte );
uint LightToTexGammaEx( uint );
uint ScreenGammaTable( uint );
uint LinearGammaTable( uint );
void V_Init( void );
void V_CheckGamma( void );
void V_CheckGammaEnd( void );
// //
// identification.c // identification.c
@@ -878,6 +807,34 @@ void NET_MasterClear( void );
void NET_MasterShutdown( void ); void NET_MasterShutdown( void );
qboolean NET_GetMaster( netadr_t from, uint *challenge, double *last_heartbeat ); qboolean NET_GetMaster( netadr_t from, uint *challenge, double *last_heartbeat );
//
// sounds.c
//
typedef enum soundlst_group_e
{
BouncePlayerShell = 0,
BounceWeaponShell,
BounceConcrete,
BounceGlass,
BounceMetal,
BounceFlesh,
BounceWood,
Ricochet,
Explode,
PlayerWaterEnter,
PlayerWaterExit,
EntityWaterEnter,
EntityWaterExit,
SoundList_Groups // must be last
} soundlst_group_t;
int SoundList_Count( soundlst_group_t group );
const char *SoundList_GetRandom( soundlst_group_t group );
const char *SoundList_Get( soundlst_group_t group, int idx );
void SoundList_Init( void );
void SoundList_Shutdown( void );
#ifdef REF_DLL #ifdef REF_DLL
#error "common.h in ref_dll" #error "common.h in ref_dll"
#endif #endif

View File

@@ -18,7 +18,7 @@ GNU General Public License for more details.
#include "const.h" #include "const.h"
#include "kbutton.h" #include "kbutton.h"
extern convar_t *con_gamemaps; extern convar_t con_gamemaps;
#define CON_MAXCMDS 4096 // auto-complete intermediate list #define CON_MAXCMDS 4096 // auto-complete intermediate list
@@ -76,7 +76,7 @@ int Cmd_ListMaps( search_t *t, char *lastmapname, size_t len )
compiler[0] = '\0'; compiler[0] = '\0';
generator[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 ) if( f )
{ {
@@ -184,13 +184,13 @@ Cmd_GetMapList
Prints or complete map filename Prints or complete map filename
===================================== =====================================
*/ */
qboolean Cmd_GetMapList( const char *s, char *completedname, int length ) static qboolean Cmd_GetMapList( const char *s, char *completedname, int length )
{ {
search_t *t; search_t *t;
string matchbuf; string matchbuf;
int i, nummaps; 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; if( !t ) return false;
COM_FileBase( t->filenames[0], matchbuf, sizeof( matchbuf )); COM_FileBase( t->filenames[0], matchbuf, sizeof( matchbuf ));
@@ -220,7 +220,7 @@ Cmd_GetDemoList
Prints or complete demo filename Prints or complete demo filename
===================================== =====================================
*/ */
qboolean Cmd_GetDemoList( const char *s, char *completedname, int length ) static qboolean Cmd_GetDemoList( const char *s, char *completedname, int length )
{ {
search_t *t; search_t *t;
string matchbuf; string matchbuf;
@@ -267,7 +267,7 @@ Cmd_GetMovieList
Prints or complete movie filename Prints or complete movie filename
===================================== =====================================
*/ */
qboolean Cmd_GetMovieList( const char *s, char *completedname, int length ) static qboolean Cmd_GetMovieList( const char *s, char *completedname, int length )
{ {
search_t *t; search_t *t;
string matchbuf; string matchbuf;
@@ -314,7 +314,7 @@ Cmd_GetMusicList
Prints or complete background track filename Prints or complete background track filename
===================================== =====================================
*/ */
qboolean Cmd_GetMusicList( const char *s, char *completedname, int length ) static qboolean Cmd_GetMusicList( const char *s, char *completedname, int length )
{ {
search_t *t; search_t *t;
string matchbuf; string matchbuf;
@@ -362,7 +362,7 @@ Cmd_GetSavesList
Prints or complete savegame filename Prints or complete savegame filename
===================================== =====================================
*/ */
qboolean Cmd_GetSavesList( const char *s, char *completedname, int length ) static qboolean Cmd_GetSavesList( const char *s, char *completedname, int length )
{ {
search_t *t; search_t *t;
string matchbuf; string matchbuf;
@@ -409,7 +409,7 @@ Cmd_GetConfigList
Prints or complete .cfg filename Prints or complete .cfg filename
===================================== =====================================
*/ */
qboolean Cmd_GetConfigList( const char *s, char *completedname, int length ) static qboolean Cmd_GetConfigList( const char *s, char *completedname, int length )
{ {
search_t *t; search_t *t;
string matchbuf; string matchbuf;
@@ -456,7 +456,7 @@ Cmd_GetSoundList
Prints or complete sound filename Prints or complete sound filename
===================================== =====================================
*/ */
qboolean Cmd_GetSoundList( const char *s, char *completedname, int length ) static qboolean Cmd_GetSoundList( const char *s, char *completedname, int length )
{ {
search_t *t; search_t *t;
string matchbuf; string matchbuf;
@@ -465,7 +465,7 @@ qboolean Cmd_GetSoundList( const char *s, char *completedname, int length )
t = FS_Search( va( "%s%s*.*", DEFAULT_SOUNDPATH, s ), true, false ); t = FS_Search( va( "%s%s*.*", DEFAULT_SOUNDPATH, s ), true, false );
if( !t ) return false; if( !t ) return false;
Q_strncpy( matchbuf, t->filenames[0] + sizeof( DEFAULT_SOUNDPATH ) - 1, MAX_STRING ); Q_strncpy( matchbuf, t->filenames[0] + sizeof( DEFAULT_SOUNDPATH ) - 1, sizeof( matchbuf ));
COM_StripExtension( matchbuf ); COM_StripExtension( matchbuf );
if( completedname && length ) if( completedname && length )
Q_strncpy( completedname, matchbuf, length ); Q_strncpy( completedname, matchbuf, length );
@@ -478,7 +478,7 @@ qboolean Cmd_GetSoundList( const char *s, char *completedname, int length )
if( Q_stricmp( ext, "wav" ) && Q_stricmp( ext, "mp3" )) if( Q_stricmp( ext, "wav" ) && Q_stricmp( ext, "mp3" ))
continue; continue;
Q_strncpy( matchbuf, t->filenames[i] + sizeof( DEFAULT_SOUNDPATH ) - 1, MAX_STRING ); Q_strncpy( matchbuf, t->filenames[i] + sizeof( DEFAULT_SOUNDPATH ) - 1, sizeof( matchbuf ));
COM_StripExtension( matchbuf ); COM_StripExtension( matchbuf );
Con_Printf( "%16s\n", matchbuf ); Con_Printf( "%16s\n", matchbuf );
numsounds++; numsounds++;
@@ -508,7 +508,7 @@ Cmd_GetItemsList
Prints or complete item classname (weapons only) Prints or complete item classname (weapons only)
===================================== =====================================
*/ */
qboolean Cmd_GetItemsList( const char *s, char *completedname, int length ) static qboolean Cmd_GetItemsList( const char *s, char *completedname, int length )
{ {
search_t *t; search_t *t;
string matchbuf; string matchbuf;
@@ -555,7 +555,7 @@ Cmd_GetKeysList
Autocomplete for bind command Autocomplete for bind command
===================================== =====================================
*/ */
qboolean Cmd_GetKeysList( const char *s, char *completedname, int length ) static qboolean Cmd_GetKeysList( const char *s, char *completedname, int length )
{ {
size_t i, numkeys; size_t i, numkeys;
string keys[256]; string keys[256];
@@ -636,7 +636,7 @@ Cmd_GetCommandsList
Autocomplete for bind command Autocomplete for bind command
===================================== =====================================
*/ */
qboolean Cmd_GetCommandsList( const char *s, char *completedname, int length ) static qboolean Cmd_GetCommandsList( const char *s, char *completedname, int length )
{ {
size_t i; size_t i;
string matchbuf; string matchbuf;
@@ -701,7 +701,7 @@ Cmd_GetCustomList
Prints or complete .HPK filenames Prints or complete .HPK filenames
===================================== =====================================
*/ */
qboolean Cmd_GetCustomList( const char *s, char *completedname, int length ) static qboolean Cmd_GetCustomList( const char *s, char *completedname, int length )
{ {
search_t *t; search_t *t;
string matchbuf; string matchbuf;
@@ -747,17 +747,13 @@ Cmd_GetGameList
Prints or complete gamedir name Prints or complete gamedir name
===================================== =====================================
*/ */
qboolean Cmd_GetGamesList( const char *s, char *completedname, int length ) static qboolean Cmd_GetGamesList( const char *s, char *completedname, int length )
{ {
int i, numgamedirs; int i, numgamedirs;
string gamedirs[MAX_MODS]; string gamedirs[MAX_MODS];
string matchbuf; string matchbuf;
int len; int len;
// stand-alone games doesn't have cmd "game"
if( !Cmd_Exists( "game" ))
return false;
// compare gamelist with current keyword // compare gamelist with current keyword
len = Q_strlen( s ); len = Q_strlen( s );
@@ -768,14 +764,14 @@ qboolean Cmd_GetGamesList( const char *s, char *completedname, int length )
} }
if( !numgamedirs ) return false; if( !numgamedirs ) return false;
Q_strncpy( matchbuf, gamedirs[0], MAX_STRING ); Q_strncpy( matchbuf, gamedirs[0], sizeof( matchbuf ));
if( completedname && length ) if( completedname && length )
Q_strncpy( completedname, matchbuf, length ); Q_strncpy( completedname, matchbuf, length );
if( numgamedirs == 1 ) return true; if( numgamedirs == 1 ) return true;
for( i = 0; i < numgamedirs; i++ ) for( i = 0; i < numgamedirs; i++ )
{ {
Q_strncpy( matchbuf, gamedirs[i], MAX_STRING ); Q_strncpy( matchbuf, gamedirs[i], sizeof( matchbuf ));
Con_Printf( "%16s\n", matchbuf ); Con_Printf( "%16s\n", matchbuf );
} }
@@ -800,7 +796,7 @@ Cmd_GetCDList
Prints or complete CD command name Prints or complete CD command name
===================================== =====================================
*/ */
qboolean Cmd_GetCDList( const char *s, char *completedname, int length ) static qboolean Cmd_GetCDList( const char *s, char *completedname, int length )
{ {
int i, numcdcommands; int i, numcdcommands;
string cdcommands[8]; string cdcommands[8];
@@ -829,14 +825,14 @@ qboolean Cmd_GetCDList( const char *s, char *completedname, int length )
} }
if( !numcdcommands ) return false; if( !numcdcommands ) return false;
Q_strncpy( matchbuf, cdcommands[0], MAX_STRING ); Q_strncpy( matchbuf, cdcommands[0], sizeof( matchbuf ));
if( completedname && length ) if( completedname && length )
Q_strncpy( completedname, matchbuf, length ); Q_strncpy( completedname, matchbuf, length );
if( numcdcommands == 1 ) return true; if( numcdcommands == 1 ) return true;
for( i = 0; i < numcdcommands; i++ ) for( i = 0; i < numcdcommands; i++ )
{ {
Q_strncpy( matchbuf, cdcommands[i], MAX_STRING ); Q_strncpy( matchbuf, cdcommands[i], sizeof( matchbuf ));
Con_Printf( "%16s\n", matchbuf ); Con_Printf( "%16s\n", matchbuf );
} }
@@ -854,7 +850,7 @@ qboolean Cmd_GetCDList( const char *s, char *completedname, int length )
return true; return true;
} }
qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir ) static qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir )
{ {
qboolean use_filter = false; qboolean use_filter = false;
byte buf[MAX_SYSPATH]; byte buf[MAX_SYSPATH];
@@ -870,7 +866,7 @@ qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir )
return true; // exist return true; // exist
// setup mpfilter // setup mpfilter
size = Q_snprintf( mpfilter, sizeof( mpfilter ), "maps/%s", GI->mp_filter ); Q_snprintf( mpfilter, sizeof( mpfilter ), "maps/%s", GI->mp_filter );
t = FS_Search( "maps/*.bsp", false, onlyingamedir ); t = FS_Search( "maps/*.bsp", false, onlyingamedir );
if( !t ) if( !t )
@@ -904,13 +900,11 @@ qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir )
if( f ) if( f )
{ {
int num_spawnpoints = 0; qboolean have_spawnpoints = false;
dheader_t *header;
dlump_t entities; dlump_t entities;
memset( buf, 0, MAX_SYSPATH ); memset( buf, 0, MAX_SYSPATH );
FS_Read( f, buf, MAX_SYSPATH ); FS_Read( f, buf, MAX_SYSPATH );
header = (dheader_t *)buf;
// check all the lumps and some other errors // check all the lumps and some other errors
if( !Mod_TestBmodelLumps( f, t->filenames[i], buf, true, &entities )) if( !Mod_TestBmodelLumps( f, t->filenames[i], buf, true, &entities ))
@@ -941,13 +935,24 @@ qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir )
char token[MAX_TOKEN]; char token[MAX_TOKEN];
qboolean worldspawn = true; qboolean worldspawn = true;
Q_strncpy( message, "No Title", MAX_STRING ); Q_strncpy( message, "No Title", sizeof( message ));
pfile = ents; pfile = ents;
while(( pfile = COM_ParseFile( pfile, token, sizeof( token ))) != NULL ) while(( pfile = COM_ParseFile( pfile, token, sizeof( token ))) != NULL )
{ {
if( token[0] == '}' && worldspawn ) if( token[0] == '}' && worldspawn )
{
worldspawn = false; worldspawn = false;
// if mod has mp_filter set up, then it's a mod that
// might not have valid mp_entity set in GI
// if mod is multiplayer only, assume all maps are valid
if( use_filter || GI->gamemode == GAME_MULTIPLAYER_ONLY )
{
have_spawnpoints = true;
break;
}
}
else if( !Q_strcmp( token, "message" ) && worldspawn ) else if( !Q_strcmp( token, "message" ) && worldspawn )
{ {
// get the message contents // get the message contents
@@ -956,17 +961,23 @@ qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir )
else if( !Q_strcmp( token, "classname" )) else if( !Q_strcmp( token, "classname" ))
{ {
pfile = COM_ParseFile( pfile, token, sizeof( token )); pfile = COM_ParseFile( pfile, token, sizeof( token ));
if( !Q_strcmp( token, GI->mp_entity ) || use_filter )
num_spawnpoints++; if( !Q_strcmp( token, GI->mp_entity ))
{
have_spawnpoints = true;
break;
} }
if( num_spawnpoints ) break; // valid map }
if( have_spawnpoints )
break; // valid map
} }
Mem_Free( ents ); Mem_Free( ents );
} }
if( f ) FS_Close( f ); if( f ) FS_Close( f );
if( num_spawnpoints ) if( have_spawnpoints )
{ {
// format: mapname "maptitle"\n // format: mapname "maptitle"\n
Q_snprintf( result, sizeof( result ), "%s \"%s\"\n", mapname, message ); Q_snprintf( result, sizeof( result ), "%s \"%s\"\n", mapname, message );
@@ -1061,7 +1072,7 @@ Autocomplete filename
for various cmds for various cmds
============ ============
*/ */
qboolean Cmd_AutocompleteName( const char *source, int arg, char *buffer, size_t bufsize ) static qboolean Cmd_AutocompleteName( const char *source, int arg, char *buffer, size_t bufsize )
{ {
autocomplete_list_t *list; autocomplete_list_t *list;
@@ -1345,13 +1356,13 @@ static void Cmd_WriteHelp(const char *name, const char *unused, const char *desc
if( length == 0 ) FS_Printf( f, "%s \"%s\"\n", name, desc ); if( length == 0 ) FS_Printf( f, "%s \"%s\"\n", name, desc );
} }
void Cmd_WriteOpenGLVariables( file_t *f ) static void Cmd_WriteOpenGLVariables( file_t *f )
{ {
Cvar_LookupVars( FCVAR_GLCONFIG, NULL, f, (setpair_t)Cmd_WriteOpenGLCvar ); Cvar_LookupVars( FCVAR_GLCONFIG, NULL, f, (setpair_t)Cmd_WriteOpenGLCvar );
} }
#if !XASH_DEDICATED #if !XASH_DEDICATED
void Host_FinalizeConfig( file_t *f, const char *config ) static void Host_FinalizeConfig( file_t *f, const char *config )
{ {
string backup, newcfg; string backup, newcfg;
@@ -1428,8 +1439,6 @@ void GAME_EXPORT Host_WriteServerConfig( const char *name )
Q_snprintf( newconfigfile, MAX_STRING, "%s.new", name ); Q_snprintf( newconfigfile, MAX_STRING, "%s.new", name );
SV_InitGameProgs(); // collect user variables
// FIXME: move this out until menu parser is done // FIXME: move this out until menu parser is done
CSCR_LoadDefaultCVars( "settings.scr" ); CSCR_LoadDefaultCVars( "settings.scr" );
@@ -1446,8 +1455,6 @@ void GAME_EXPORT Host_WriteServerConfig( const char *name )
Host_FinalizeConfig( f, name ); Host_FinalizeConfig( f, name );
} }
else Con_DPrintf( S_ERROR "Couldn't write %s.\n", name ); else Con_DPrintf( S_ERROR "Couldn't write %s.\n", name );
SV_FreeGameProgs(); // release progs with all variables
} }
/* /*

View File

@@ -129,6 +129,22 @@ static void Sys_StackTrace( PEXCEPTION_POINTERS pInfo )
stackframe.AddrBStore.Mode = AddrModeFlat; stackframe.AddrBStore.Mode = AddrModeFlat;
stackframe.AddrStack.Offset = context.IntSp; stackframe.AddrStack.Offset = context.IntSp;
stackframe.AddrStack.Mode = AddrModeFlat; stackframe.AddrStack.Mode = AddrModeFlat;
#elif _M_ARM
image = IMAGE_FILE_MACHINE_ARMNT;
stackframe.AddrPC.Offset = context.Pc;
stackframe.AddrPC.Mode = AddrModeFlat;
stackframe.AddrFrame.Offset = context.R11;
stackframe.AddrFrame.Mode = AddrModeFlat;
stackframe.AddrStack.Offset = context.Sp;
stackframe.AddrStack.Mode = AddrModeFlat;
#elif _M_ARM64
image = IMAGE_FILE_MACHINE_ARM64;
stackframe.AddrPC.Offset = context.Pc;
stackframe.AddrPC.Mode = AddrModeFlat;
stackframe.AddrFrame.Offset = context.Fp;
stackframe.AddrFrame.Mode = AddrModeFlat;
stackframe.AddrStack.Offset = context.Sp;
stackframe.AddrStack.Mode = AddrModeFlat;
#elif #elif
#error #error
#endif #endif
@@ -320,7 +336,9 @@ void Sys_RestoreCrashHandler( void )
#elif XASH_FREEBSD || XASH_NETBSD || XASH_OPENBSD || XASH_ANDROID || XASH_LINUX #elif XASH_FREEBSD || XASH_NETBSD || XASH_OPENBSD || XASH_ANDROID || XASH_LINUX
// Posix signal handler // Posix signal handler
#ifndef XASH_OPENBSD
#include <ucontext.h> #include <ucontext.h>
#endif
#include <signal.h> #include <signal.h>
#include <sys/mman.h> #include <sys/mman.h>
#include "library.h" #include "library.h"
@@ -334,24 +352,6 @@ void Sys_RestoreCrashHandler( void )
static struct sigaction oldFilter; static struct sigaction oldFilter;
#ifdef XASH_DYNAMIC_DLADDR
static int d_dladdr( void *sym, Dl_info *info )
{
static int (*dladdr_real) ( void *sym, Dl_info *info );
if( !dladdr_real )
dladdr_real = dlsym( (void*)(size_t)(-1), "dladdr" );
memset( info, 0, sizeof( *info ) );
if( !dladdr_real )
return -1;
return dladdr_real( sym, info );
}
#define dladdr d_dladdr
#endif
static int Sys_PrintFrame( char *buf, int len, int i, void *addr ) static int Sys_PrintFrame( char *buf, int len, int i, void *addr )
{ {
Dl_info dlinfo; Dl_info dlinfo;
@@ -388,9 +388,9 @@ static void Sys_Crash( int signal, siginfo_t *si, void *context)
bp = (void**)ucontext->uc_mcontext.mc_rbp; bp = (void**)ucontext->uc_mcontext.mc_rbp;
sp = (void**)ucontext->uc_mcontext.mc_rsp; sp = (void**)ucontext->uc_mcontext.mc_rsp;
#elif XASH_NETBSD #elif XASH_NETBSD
pc = (void*)ucontext->uc_mcontext.__gregs[REG_RIP]; pc = (void*)ucontext->uc_mcontext.__gregs[_REG_RIP];
bp = (void**)ucontext->uc_mcontext.__gregs[REG_RBP]; bp = (void**)ucontext->uc_mcontext.__gregs[_REG_RBP];
sp = (void**)ucontext->uc_mcontext.__gregs[REG_RSP]; sp = (void**)ucontext->uc_mcontext.__gregs[_REG_RSP];
#elif XASH_OPENBSD #elif XASH_OPENBSD
pc = (void*)ucontext->sc_rip; pc = (void*)ucontext->sc_rip;
bp = (void**)ucontext->sc_rbp; bp = (void**)ucontext->sc_rbp;
@@ -406,9 +406,9 @@ static void Sys_Crash( int signal, siginfo_t *si, void *context)
bp = (void**)ucontext->uc_mcontext.mc_ebp; bp = (void**)ucontext->uc_mcontext.mc_ebp;
sp = (void**)ucontext->uc_mcontext.mc_esp; sp = (void**)ucontext->uc_mcontext.mc_esp;
#elif XASH_NETBSD #elif XASH_NETBSD
pc = (void*)ucontext->uc_mcontext.__gregs[REG_EIP]; pc = (void*)ucontext->uc_mcontext.__gregs[_REG_EIP];
bp = (void**)ucontext->uc_mcontext.__gregs[REG_EBP]; bp = (void**)ucontext->uc_mcontext.__gregs[_REG_EBP];
sp = (void**)ucontext->uc_mcontext.__gregs[REG_ESP]; sp = (void**)ucontext->uc_mcontext.__gregs[_REG_ESP];
#elif XASH_OPENBSD #elif XASH_OPENBSD
pc = (void*)ucontext->sc_eip; pc = (void*)ucontext->sc_eip;
bp = (void**)ucontext->sc_ebp; bp = (void**)ucontext->sc_ebp;
@@ -506,13 +506,14 @@ static void Sys_Crash( int signal, siginfo_t *si, void *context)
#ifdef XASH_SDL #ifdef XASH_SDL
SDL_SetWindowGrab( host.hWnd, SDL_FALSE ); SDL_SetWindowGrab( host.hWnd, SDL_FALSE );
#endif #endif
MSGBOX( message ); host.crashed = true;
Platform_MessageBox( "Xash Error", message, false );
// log saved, now we can try to save configs and close log correctly, it may crash // log saved, now we can try to save configs and close log correctly, it may crash
if( host.type == HOST_NORMAL ) if( host.type == HOST_NORMAL )
CL_Crashed(); CL_Crashed();
host.status = HOST_CRASHED; host.status = HOST_CRASHED;
host.crashed = true;
Sys_Quit(); Sys_Quit();
} }

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