Compare commits

..

260 Commits

Author SHA1 Message Date
Alibek Omarov
c395acad63 engine: try to detect LoadLibrary/FreeLibrary leaks 2022-06-12 03:08:47 +03:00
Alibek Omarov
8eec5389fe game_launch: fix gamedir pointer being lost 2022-06-12 03:07:43 +03:00
Alibek Omarov
5524aaae1e engine: server: fix server dll leak when no map was loaded 2022-06-12 03:07:09 +03:00
Alibek Omarov
acffeb1dad wscript: enable gl4es for Android builds 2022-06-12 03:06:31 +03:00
Alibek Omarov
6c7d57e1eb engine: client: move vgui deinitialization out of CL_UnloadProgs. Delete cls.initialized check in CL_Shutdown, that used to shutdown various client-side subsystems that usually have needed checks by themselves 2022-06-12 03:06:03 +03:00
Alibek Omarov
7c9f5f8ab1 engine: remove LoadLibrary macros, to avoid possible misuse. Although macros moved to game_launch, it's part of it's own problem from now 2022-06-11 03:25:57 +03:00
Andrey Akhmichin
6b4f55c4bf engine: common: filesystem.c: do not load archives with zip extention again 2022-06-10 23:26:14 +03:00
Velaron
89335938c1 remove accidentally added submodule 2022-06-10 23:25:43 +03:00
Velaron
437630d26d platform: win32: remove forgotten code 2022-06-10 23:25:43 +03:00
Bohdan Shulyar
341c9dae39 paltform: win32: fix typo >_< 2022-06-10 23:25:43 +03:00
Velaron
c10b70cb61 game_launch: explicitly check for SDL2 on win32 platforms 2022-06-10 23:25:43 +03:00
Velaron
4c7bf1ff44 platform: win32: improve error reporting when loading DLLs and move custom DLL loader to a separate file 2022-06-10 23:25:43 +03:00
Alibek Omarov
f467d0c807 game_launch: fix Windows build (as suggested by @SNMetamorph) 2022-06-09 20:27:27 +03:00
Alibek Omarov
a717b7fc49 game_launch: declare environ variable, by standard it must be declared by user program 2022-06-09 14:44:04 +03:00
Alibek Omarov
07a9c4602d game_launch: change game with execve on supported platforms 2022-06-09 13:42:16 +03:00
Alibek Omarov
eeb170af22 engine: client: set failed status for vgui_support if we wasn't able to load one. Unload library in case of error 2022-06-09 13:41:37 +03:00
Alibek Omarov
c532c3032c engine: menu_int: hack to compile on MotoMAGX 2022-06-09 03:28:38 +03:00
Alibek Omarov
ae6ad74994 update: mainui 2022-06-09 03:09:48 +03:00
Andrey Akhmichin
f417433f59 Documentation: opensource-mods.md: update 2022-06-03 19:54:45 +03:00
Andrey Akhmichin
080dc38f11 ci: upgrade freebsd tasks 2022-06-03 19:53:58 +03:00
Alibek Omarov
13f93412cd engine: platform: sdl: forgot to add an include, sorry\! 2022-06-02 03:01:58 +03:00
Alibek Omarov
ca975d0168 mainui: update 2022-05-30 22:44:52 +03:00
Alibek Omarov
b82d0bad7a engine: client: vgui: unload client DLLL if no vgui_support export was found 2022-05-30 22:41:28 +03:00
Alibek Omarov
d1de9e2802 engine: platform: sdl: proper cursors allocation and free 2022-05-30 03:33:03 +03:00
Alibek Omarov
efdf9e3599 scripts: gha: include activities.txt on win32 continious builds 2022-05-30 02:35:06 +03:00
Alibek Omarov
060835cf2f waf.bat: correctly parse reg query on Windows 10+, fallback only to py.exe wrapper 2022-05-29 19:22:48 +03:00
Alibek Omarov
74485f30d3 ref_gl: gl4es: update 2022-05-29 18:27:16 +03:00
Alibek Omarov
8dda35a128 mainui: update 2022-05-29 18:26:55 +03:00
Alibek Omarov
978ec27a57 waf: upgrade to temporary waifu branch with absolute path clang compilation database generator 2022-05-29 05:19:23 +03:00
Alibek Omarov
113f18cfb0 ref_soft: use correct types for pointer arithmetics 2022-05-29 04:23:07 +03:00
Alibek Omarov
6f36edfd16 engine: various const qualifier fixes 2022-05-29 04:22:43 +03:00
Alibek Omarov
5fb4edeb36 ref: simplify gldebug switchcase in output function, kinda fix const qualifiers 2022-05-29 04:00:19 +03:00
Alibek Omarov
dd29e705f8 engine: menu_int: add _format and NORETURN attributes to MenuAPI 2022-05-29 02:33:28 +03:00
Alibek Omarov
8445567ab4 engine: server: remove unused arguments passed to Con_Printf 2022-05-29 02:27:39 +03:00
Alibek Omarov
11d4cb0f1e engine: client: securedstub: cosmetic changes 2022-05-29 02:27:02 +03:00
Alibek Omarov
db48d0ded7 engine: server: fix useless double assignment 2022-05-29 01:59:15 +03:00
Alibek Omarov
86a777880f engine: common: mark AbortCurrentFrame as NORETURN, fix noreturn warnings 2022-05-29 01:58:56 +03:00
Alibek Omarov
0d195ee6fe engine: server: fix output of maps command 2022-05-29 01:29:51 +03:00
Alibek Omarov
5e4996b119 engine: server: fix bot count 2022-05-28 22:16:08 +03:00
Alibek Omarov
f25254369d engine: set useful format attribute for RefAPI, set Host_Error as NORETURN 2022-05-28 17:58:17 +03:00
Alibek Omarov
9ce8edcb38 public: moved compiler attributes to xash3d_types.h 2022-05-28 17:57:43 +03:00
Alibek Omarov
33d79ddb24 engine: server: fix possible array overruns 2022-05-25 17:57:47 +03:00
Alibek Omarov
52d1383f14 engine: client: fix various useless checks, unused variables & defines, double assignments and mistypings 2022-05-25 03:50:06 +03:00
Alibek Omarov
843c9abf9b engine: common: fix array underrun 2022-05-25 03:38:19 +03:00
Alibek Omarov
924e895753 engine: common: set Host_Error and Sys_Error as NORETURN 2022-05-25 03:38:02 +03:00
Alibek Omarov
ac40badaa5 engine: client: fix array overruns 2022-05-25 03:36:33 +03:00
Alibek Omarov
fd83b0dc17 waf: upgrade to latest waf 2022-05-25 01:40:10 +03:00
a1batross
5715023a0d ci: upgrade freebsd tasks 2022-05-21 03:14:41 +03:00
Alibek Omarov
51526948c0 engine: server: make PEntityOfEntIndex bug-compatible with GoldSrc
Add new undocumented GoldSrc eiface function, PEntityOfEntIndexAllEntities,
a bug-free version of PEntityOfEntIndex

Ref: https://github.com/ValveSoftware/halflife/issues/2272
2022-05-21 03:03:59 +03:00
Alibek Omarov
10ec32e264 waf: add Python 3.10 scan in batch script 2022-05-16 05:40:34 +03:00
Alibek Omarov
4fbd96d201 engine: common: filesystem: speed up directory existense check on POSIX by using stat() instead of opendir() 2022-05-09 07:45:51 +03:00
Alibek Omarov
81b01ac561 engine: common: remove NaN check, it's mostly useless on text data 2022-05-09 05:01:20 +03:00
Alibek Omarov
771c359ed0 engine: common: make blue-shift map detect more robust 2022-05-09 05:01:20 +03:00
SNMetamorph
d1a5c33bf1 engine: common: removed unused function Sys_SetClipboardData 2022-05-02 03:29:24 +03:00
SNMetamorph
641f0632ef engine: client: fixed compilation errors on Android 2022-05-02 03:29:24 +03:00
SNMetamorph
974f0787a4 vgui_support: added VGUI_TextInput callback stub 2022-05-02 03:29:24 +03:00
SNMetamorph
87ceb0f9cb engine: client: fixed checking client library for vgui_support interface export 2022-05-02 03:29:24 +03:00
SNMetamorph
cfcd58dd78 engine: client: extended VGUI API interface 2022-05-02 03:29:24 +03:00
SNMetamorph
8044d23e7f engine: platform: sdl: fixed Key_Event callback when text input enabled 2022-05-02 03:29:24 +03:00
SNMetamorph
b175d6d95f engine: client: fixed forced text input turn off in Key_EnableTextInput 2022-05-02 03:29:24 +03:00
SNMetamorph
d3e213aa1b engine: platform: added Platform_GetKeyModifiers 2022-05-02 03:29:24 +03:00
SNMetamorph
26e09c240a engine: platform: added Platform_SetCursorType 2022-05-02 03:29:24 +03:00
SNMetamorph
15eb6808c4 engine: platform: updated clipboard read/write functions 2022-05-02 03:29:24 +03:00
SNMetamorph
5402e1a259 ref_soft: fixed R_WorldToScreen behavior to match GoldSrc 2022-04-13 09:12:12 +03:00
SNMetamorph
74086cc4c1 ref_gl: fixed R_WorldToScreen behavior to match GoldSrc 2022-04-13 09:12:12 +03:00
SNMetamorph
9c85d114e7 engine: client: fixed TriWorldToScreen behavior to match GoldSrc 2022-04-13 09:12:12 +03:00
Alibek Omarov
81c4acab66 platform: sdl: fix right mouse button issuing wrong key code 2022-04-10 19:40:11 +03:00
SNMetamorph
6f2fda427e engine: keydefs: fixed mouse buttons code to match GoldSrc 2022-04-10 16:50:23 +03:00
SNMetamorph
09b7f22cee engine: cl_frame: fixed segfault in CL_UpdatePositions 2022-04-10 16:31:02 +03:00
Alibek Omarov
691a305f8e engine: common: reorder cmd_t fields to be compatible with GoldSrc 2022-04-09 19:38:22 +03:00
SNMetamorph
66dc20dc2d engine: platform: con_win: fixed console window visibility without developer mode (fix #818) 2022-04-08 14:18:38 +03:00
Alibek Omarov
92cfa2af48 ref_soft: light: fixed game crash in Customize multiplayer menu 2022-04-07 22:02:31 +03:00
SNMetamorph
9515cccb94 engine: client: cl_frame: fixed position history animtime for non-brush entities 2022-04-07 21:56:37 +03:00
SNMetamorph
a7d02b8268 ref_gl: gl_rlight: fixed game crash in Customize multiplayer menu 2022-04-07 21:56:37 +03:00
SNMetamorph
22815d2784 engine: server: sv_main: added status line for dedicated server console 2022-04-06 15:17:15 +03:00
SNMetamorph
95ee88720c engine: platform: win32: major refactoring of console code 2022-04-06 15:17:15 +03:00
SNMetamorph
58dbc1ba31 engine: system: disabled skipping color codes for Wcon_WinPrint 2022-04-06 15:17:15 +03:00
SNMetamorph
d7431783d4 engine: sv_save: added entity_state_t->startpos to save fields 2022-04-06 14:28:13 +03:00
Alibek Omarov
c8410f7e46 engine: server: don't issue an assert on invalid client names 2022-04-02 13:36:53 +03:00
a1batross
80e20cb55b Documentation: ports: update info about PSP port 2022-03-30 22:30:32 +03:00
Alibek Omarov
654bac83a5 scripts: do not upload branches as main continious prerelease 2022-03-20 06:38:46 +03:00
a1batross
fc7fb8b62d engine: masterlist: replace master server domain by mentality.rip
It is essentially the same as ms.xash.su but due to current situation, it is known to be blocked on some Ukrainian ISPs.

ms2.xash.su is retired for now.
2022-03-19 01:58:10 +03:00
SNMetamorph
65d624140e engine: filesystem: fixed FS_Search algorithm for ZIP files (fix #796) 2022-03-15 23:11:00 +03:00
SNMetamorph
cd2720ba81 engine: common: imagelib: fixed loading BMP files with v4/v5 headers 2022-03-13 01:50:30 +03:00
Alibek Omarov
d2f3b1974e github: disable cleanup for self-hosted runners because there are none 2022-03-11 14:05:53 +03:00
Alibek Omarov
91742d613d github: goodbye, aarch64 runner 2022-03-11 13:41:47 +03:00
Alibek Omarov
fba323cf1f engine: common: cosmetic changes to usage string generating code 2022-03-10 04:52:16 +03:00
Alibek Omarov
f67d0ffa5a engine: common: fix broken function name and strings after find&replace in socket code 2022-03-10 04:51:38 +03:00
Alibek Omarov
a6fbf5fb74 mainui: update 2022-03-09 08:16:28 +03:00
Alibek Omarov
df616b950d engine: add NET_AdrToString to menu extended API, upgrade mainui submodule 2022-03-08 07:00:36 +03:00
Alibek Omarov
37cf4da136 engine: client: switch to protocol info key in detecting old engine servers 2022-03-08 07:00:36 +03:00
Alibek Omarov
668d528e3b engine: client: delete unused function 2022-03-08 07:00:36 +03:00
Alibek Omarov
12da44a3d7 engine: server: send protocol version to distinguish old engine and new 2022-03-08 07:00:36 +03:00
SNMetamorph
51fcae8cec ref_gl: gl_image: added check for hardware support of BC6H/BC7 compression formats 2022-03-07 02:03:40 +03:00
SNMetamorph
6473efa995 engine: added support for BC7 and BC6H compression formats of DDS textures 2022-03-07 02:03:40 +03:00
SNMetamorph
cf7852832f ref_gl: gl_image: added support for BC7 and BC6H compression formats of DDS textures 2022-03-07 02:03:40 +03:00
SNMetamorph
29ad3de78a ref_gl: added support for GL_ARB_texture_compression_bptc extension 2022-03-07 02:03:40 +03:00
Alibek Omarov
8169c2a40b wscript: set rpath to current folder, LD_LIBRARY_PATH is unneeded anymore
Fix README and AppImage launch script accordingly
2022-03-03 05:57:51 +03:00
Alibek Omarov
85f99c723a engine: add sys_timescale implementation 2022-03-03 05:38:36 +03:00
SNMetamorph
edc171be04 engine: common: fixed lightmap shift again 2022-02-28 19:56:28 +03:00
SNMetamorph
9047fe2e74 ref_gl: gl_rsurf: fixed invalid lightmap texture coordinates in some cases 2022-02-28 16:54:28 +03:00
SNMetamorph
24ea8fba4b engine: common: fixed lightmap shifting caused by insufficent precision in Mod_CalcSurfaceExtents 2022-02-28 16:54:28 +03:00
Alibek Omarov
e07417aead engine: client: fix sentence word splitted by contents inside parentheses 2022-02-28 04:29:32 +03:00
Alibek Omarov
13b36e66b3 engine: client: workaround buggy position history times going backwards in interpolation code 2022-02-25 02:12:44 +03:00
Alibek Omarov
7821f425e7 engine: client: position history indexes can't be negative, use unsigned with them 2022-02-24 05:45:41 +03:00
Alibek Omarov
f0783ddee1 engine: client: fix comparing floats in interpolation code 2022-02-24 04:51:04 +03:00
Alibek Omarov
d4d39c66fb engine: client: fix double call to CL_ParametricMove 2022-02-24 02:49:10 +03:00
Alibek Omarov
a2d8a47376 engine: client: fix misplaced arguments in memcpy 2022-02-24 02:47:54 +03:00
Alibek Omarov
3f7773f83b engine: client: rewrite VOX subsystem, fix spaces being taken into sentences, add tests for parser, remove dead code 2022-02-22 09:40:15 +03:00
Alibek Omarov
18933e7981 engine: ensure all data was written to stdout when exiting 2022-02-22 09:40:15 +03:00
Andrey Akhmichin
9917cba8fc utils: mdldec: add fixed uv coords support. 2022-02-12 22:06:31 +03:00
Alibek Omarov
203afda053 engine: add render_picbutton_text flag to use mainui_cpp font renderer for rendering WON buttons 2022-02-10 02:53:35 +03:00
Alibek Omarov
6dbb694fdc wscript: define _FILE_OFFSET_BITS=64 on 32-bit systems if libc (presumably glibc) supports it 2022-02-01 19:42:38 +03:00
Alibek Omarov
0c26c24331 ref_gl: really disable VBO by default for now 2022-02-01 19:27:49 +03:00
Alibek Omarov
51635995a2 mainui: update to temporary branch with fixes until I finish picbutton text renderer 2022-02-01 19:26:26 +03:00
Bien Pham
988183a96a engine: implement support for secured client dlls 2022-02-01 05:56:54 +03:00
SNMetamorph
d8fd0b3dcb documentation: updated mainteiners list for Windows engine port 2022-01-30 01:27:22 +03:00
Alibek Omarov
a6b43fbfff engine: show additional errno string when log file cannot be opened 2022-01-29 03:04:54 +03:00
Alibek Omarov
61643585e0 engine: fix NULL ptr dereference when log file cannot be opened 2022-01-29 03:04:00 +03:00
Alibek Omarov
75e8a51058 ref_gl: disable VBO. Rename r_vbo to gl_vbo to ignore existing config values as it was enabled by default 2022-01-29 02:33:09 +03:00
Bien Pham
3a55b9cd67 engine: make pfnDrawString & pfnDrawStringReverse return width 2022-01-29 00:36:43 +03:00
Alibek Omarov
89baa633c8 engine: sdl: fix mouse activated when focus gained but not game is active 2022-01-28 01:20:14 +03:00
Alibek Omarov
1bf08cc2c3 engine: touch: fix button deletion 2022-01-27 17:10:50 +03:00
Alibek Omarov
36d757c74a engine: server: fix message trace output 2022-01-27 03:48:54 +03:00
Alibek Omarov
0891356ec5 ref_gl: use GoldSrc particle texture 2022-01-27 03:32:52 +03:00
Alibek Omarov
0fa1b4f944 engine: client: refactor tempentity parsing, make multipliers close to GoldSrc 2022-01-27 03:32:52 +03:00
Alibek Omarov
56103a90eb engine: client: limit token size in client dll parsefile to 1024 (GoldSrc value) 2022-01-27 03:32:52 +03:00
Alibek Omarov
2fa964e939 engine: server: restore sv_trace_messages from old engine 2022-01-27 03:32:52 +03:00
Alibek Omarov
0027678a56 engine: client: print which tempentity type was overflowed 2022-01-27 03:32:52 +03:00
Alibek Omarov
ffea7d9729 engine: add host_lowmemorymode cvar to indicate low memory mode level 2022-01-27 03:32:52 +03:00
Velaron
0e286f31c5 engine: client: fix DT_TIMEWINDOW_* signedness 2022-01-24 17:31:36 +03:00
Valery Klachkov
b9cec43e2c ref_soft: Fix crashes on 64bit
Just replace all long for unsigned long long :)
2022-01-16 14:26:15 +03:00
NightFox
bb84a3cb7f add /fsanitize=address for msvc (windows) when sanitize 2022-01-16 09:54:17 +03:00
Alibek Omarov
5aa6bfee85 engine: first attempts on fuzzing the engine 2022-01-15 06:24:57 +03:00
Alibek Omarov
204544f50f readme: update 2022-01-15 04:48:04 +03:00
Alibek Omarov
df4f21680c engine: client: apply local client effects only if it wasn't rejected by clientdll 2022-01-14 16:18:09 +03:00
Alibek Omarov
2c1b862654 engine: client: ignore EF_BRIGHTFIELD for local client
It must be OK, because GoldSrc don't call similar function for local client
instead adds only flashlight and muzzleflash effects.

By adding this check, behavior must be close enough
2022-01-14 16:16:13 +03:00
Alibek Omarov
ea5937bce0 engine: net_encode: remove naive clientdata/weapondata copy, only copy fields explicitly listed in deltalst 2022-01-14 14:46:52 +03:00
Alibek Omarov
6e4ab74694 engine: net_encode: split delta "no changes" copy into separate function 2022-01-14 14:33:13 +03:00
Alibek Omarov
2c74a633d0 mainui: update 2022-01-14 01:29:33 +03:00
Alibek Omarov
22e770e4d4 engine: client: disable viewsize without requested Quake compatibility 2022-01-14 01:18:22 +03:00
Alibek Omarov
1f26710bd0 engine: fix add command error messages 2022-01-14 01:06:52 +03:00
Alibek Omarov
96f35f76e1 engine: filesystem: fix creating directories with roDir 2022-01-14 00:42:24 +03:00
Alibek Omarov
fa37d153c8 engine: common: restrict alias/unalias and stuffcmds from executing by server 2022-01-14 00:26:26 +03:00
Alibek Omarov
aa5594d11f engine: client: don't let servers clear console 2022-01-14 00:03:05 +03:00
Alibek Omarov
6b332eabd2 scripts: gha: include extras in MAGX and Win32 builds too (Linux and Android already have it) 2022-01-13 18:31:12 +03:00
Alibek Omarov
13cf909b99 engine: filesystem: allow extras ZIPs 2022-01-13 18:22:06 +03:00
Alibek Omarov
606b5354e6 engine: filesystem: fix loading ZIP files 2022-01-13 17:46:54 +03:00
Alibek Omarov
e29dcb4125 engine: filesystem: accept ZIP files with zip extension, do not assert with NULL free in Zip_Close 2022-01-13 16:44:45 +03:00
Alibek Omarov
c3513b1615 engine: input: clean m_enginemouse leftovers, always enable SDL relative mouse mode for our input interface 2022-01-13 16:18:23 +03:00
Alibek Omarov
abbd0f92a4 engine: input: fix incorrect client notifying about mouse button states 2022-01-13 15:52:59 +03:00
Alibek Omarov
f9d0fba05f wscript: remove duplicated branches diagnostic for good 2022-01-04 09:01:08 +03:00
Alibek Omarov
1ffe050205 engine: print only command name in Unknown command message, rather than a full line 2022-01-04 09:01:08 +03:00
Alibek Omarov
a2f741fe8a engine: platform: sdl: try to fix 1.2 build 2022-01-04 08:39:11 +03:00
Alibek Omarov
d0a39ef492 engine: client: rework mouse input again, do what GoldSrc does, minimize SDL mouse calls 2022-01-04 08:39:11 +03:00
Alibek Omarov
f63d2d747f vgui: remove unneeded SDL calls, remove unused VGUI API function, fix mouse cursor visibility 2022-01-04 08:39:11 +03:00
Alibek Omarov
7e687b45bb engine: client always uses SDL (virtually) on non-Win32 platforms 2022-01-04 08:39:11 +03:00
Alibek Omarov
284eeea3c3 engine: client: rework mouse input, use IN_MouseEvent for clientdll, don't emit mouse events when mouse is visible or touch emulate is used 2022-01-04 08:39:11 +03:00
Alibek Omarov
01b2266b7e engine: net_encode: minor code style fix 2022-01-04 04:30:47 +03:00
Alibek Omarov
0714ab27b5 mainui: update 2022-01-04 04:29:27 +03:00
Alibek Omarov
4ae608913b console: fix Home and End buttons or equivalent hotkeys to always set start or end of input buffer 2022-01-04 03:01:59 +03:00
Alibek Omarov
295adcf222 engine: con_utils: don't also prepend backslash in autocompletion~ 2022-01-04 02:31:41 +03:00
Alibek Omarov
3351ecd754 console: ignore whitespace commands on history, ignore backslash 2022-01-04 02:31:07 +03:00
Alibek Omarov
ccf90beb7d public: crtlib: add Q_isspace function 2022-01-04 02:22:20 +03:00
Alibek Omarov
7fbbe9f015 github: ignore cleanup failure, run only on self-hosted 2022-01-04 02:20:13 +03:00
Alibek Omarov
46fd27eb14 console: remove prepending backslashes
This is a leftover from Quake, where the console and chat were
in fact same entity. Because Xash splits it, there is no need
in prepending backslashes to separate commands from chat messages
2022-01-04 02:14:34 +03:00
Alibek Omarov
f1a4d66d27 scripts: waifulib: remove nooptimize build type, use debug instead. Disable optimization for sanitize builds 2022-01-04 01:58:45 +03:00
Alibek Omarov
c619bb4af7 readme: update discord link 2022-01-03 23:21:31 +03:00
Alibek Omarov
210137c325 engine: increase model limit to the possible maximum without breaking the protocol 2022-01-03 23:07:33 +03:00
Alibek Omarov
d4d79573f6 github: try to cleanup work directory before running, useful for self-hosted runners 2022-01-03 21:13:02 +03:00
Alibek Omarov
b7a32f6843 scripts: gha: install deps on aarch64 2021-12-31 05:29:11 +03:00
Alibek Omarov
f1dabf13a1 github: try to add aarch64 runner 2021-12-31 05:25:20 +03:00
Alibek Omarov
947b94d29f engine: client: delete unused test data :) 2021-12-31 04:10:06 +03:00
Alibek Omarov
f007374866 engine: client: rewrite console history
Fix duplicate and empty lines saved into history
Fix backup copied too early
Add tests
2021-12-31 03:49:11 +03:00
Alibek Omarov
7cb06956c2 engine: platform: win32: fix compile 2021-12-28 00:16:06 +03:00
Alibek Omarov
ebfa8e6ffc engine: platform: android: fix compile 2021-12-27 03:19:50 +03:00
Alibek Omarov
7869aac2e5 wscript: add public to includes 2021-12-27 03:18:23 +03:00
Alibek Omarov
f3dfbc9219 mainui: update 2021-12-24 18:14:03 +03:00
Alibek Omarov
4f89288ccf common: cleanup port.h 2021-12-23 19:17:11 +03:00
Alibek Omarov
fb8791529e common: include build.h in xash3d_types.h 2021-12-23 18:46:40 +03:00
Alibek Omarov
f0feb1dfbf ref: remove predictable random tiling textures 2021-12-23 18:35:01 +03:00
Alibek Omarov
2df27e14a8 engine: client: make connect command available through stufftext, for future use 2021-12-23 01:25:03 +03:00
Alibek Omarov
764ef93984 common: add fs_size_t typedef, for read()/write() return value 2021-12-23 01:21:33 +03:00
Alibek Omarov
d8b3ab4dcc engine: filesystem: fix unused result warnings 2021-12-22 05:03:06 +03:00
Alibek Omarov
08e72bad35 engine: crashhandler: clean up code 2021-12-22 05:02:34 +03:00
Alibek Omarov
7e574ea42e engine: filesystem: do not create folders for files in rodir mode 2021-12-22 01:52:47 +03:00
Alibek Omarov
0963e05716 engine: restore lumps after swapping them for blue shift maps
Mod_TestBmodelLumps may modify srclumps data, which is essential for
brush model loader. BlueShift maps have swapped lumps for some reason
Restoring them to default is fix for now
2021-12-20 18:12:36 +03:00
Alibek Omarov
23e2f4d0cc wscript: fix install on Android 2021-12-18 03:46:21 +03:00
Alibek Omarov
ca3544d559 engine: server: don't assert for NULL player in FatPAS/PVS if we don't need it 2021-12-18 03:32:40 +03:00
Alibek Omarov
7a0a355baf github: grab artifacts by wildcard rather than a list 2021-12-17 04:38:23 +03:00
Alibek Omarov
f7bf081650 github: try to fix artifacts uploading (YAML is worst markup language) 2021-12-17 03:58:56 +03:00
Alibek Omarov
a4be009ce7 scripts: waifulib: disable stpcpy builtin for API level <21 2021-12-17 03:15:38 +03:00
Alibek Omarov
d3248aad66 scripts: waifulib: clean legacy Android definitions 2021-12-15 17:40:24 +03:00
Alibek Omarov
000c594596 scripts: waifulib: disable -no-canonical-prefixes for new NDKs 2021-12-15 17:37:31 +03:00
Alibek Omarov
960a8959d5 github: download ndk directly instead of sdkmanager because sdkmanager sucks and ships ndk 22 2021-12-14 23:23:52 +03:00
Alibek Omarov
2604ea39c5 github: try to upload artifacts 2021-12-14 23:17:04 +03:00
Alibek Omarov
dc186c3cba github: build android with NDK compiler 2021-12-14 23:03:31 +03:00
Alibek Omarov
f60112773f public: crtlib: include string.h for strlen 2021-12-10 01:13:08 +03:00
Alibek Omarov
37aa5b1e99 engine: gamma: use FBitSet 2021-12-08 20:28:30 +03:00
SNMetamorph
aa07dab8ab engine: added feature flag ENGINE_LINEAR_GAMMA_SPACE 2021-12-08 20:27:02 +03:00
Alibek Omarov
ac213c22ed ref: change some FCVAR_ARCHIVE to FCVAR_GLCONFIG to save in separate config 2021-12-08 17:58:16 +03:00
Alibek Omarov
e0efe0aa23 engine: remove emboss filter. There seems no real use for it. 2021-12-07 09:09:45 +03:00
Alibek Omarov
29bc0392ee scripts: compiler_optimizations: disable clang thread-safe statics 2021-12-07 09:03:51 +03:00
Alibek Omarov
054765232e waifulib: xcompile: add NDK 23 support 2021-12-07 09:03:20 +03:00
Alibek Omarov
89425e4bf2 mainui: update 2021-12-07 05:16:47 +03:00
Alibek Omarov
a777e7c80d engine, ref: add sprite and studio cvars to shared cvars list 2021-12-06 05:17:25 +03:00
Alibek Omarov
1350fd0b52 engine: ref: use right Cvar_Get function :) 2021-12-06 05:02:30 +03:00
Alibek Omarov
d7db48ce4b engine, ref: create shared cvars list, register them at engine side, make a generic macro to declare, define and get all pointers at ref side 2021-12-06 04:57:32 +03:00
Alibek Omarov
293482fbd5 engine: FCVAR_GLCONFIG are not readonly anymore. To make truly readonly cvar for renderer, one must apply FCVAR_READ_ONLY flag 2021-12-06 03:56:18 +03:00
Alibek Omarov
3771a1d6c5 public: replace our Q_strlen with standard strlen with nullptr check in macro 2021-12-03 09:44:51 +03:00
Alibek Omarov
07f1f7ded1 engine: launcher: use our Q_strncpy instead of standard strncpy 2021-12-03 09:41:58 +03:00
Alibek Omarov
1cac321c00 engine: enable filtered command buffer for dedicated to pass the tests 2021-12-03 09:41:23 +03:00
Alibek Omarov
aa7bfb4819 engine: check for non-standard alloca header 2021-12-03 09:22:40 +03:00
Alibek Omarov
0c18a06946 engine: sequence: use Q_strncpy instead of standard strcpy 2021-12-03 09:22:40 +03:00
Alibek Omarov
24edcf7d9e engine: swap lumps back after they were swapped for blue-shift maps 2021-11-29 16:28:42 +03:00
Alibek Omarov
ecddae8ee6 ref_gl, ref_soft: increase MAX_TEXTURES limit by 8192 2021-11-29 16:22:52 +03:00
Marc-Antoine Lortie
1ab49adbf2 Updated links in opensource-mods.md 2021-11-27 16:34:27 +03:00
Alibek Omarov
28b49e00e5 scripts: continious_upload: remove unused Travis CI support 2021-11-27 06:34:22 +03:00
Alibek Omarov
1e6be598e9 TravisCI is dead too\! 2021-11-27 06:27:52 +03:00
Alibek Omarov
155e15939b scripts: continious_upload: remove unused Artifactory support (JFrog is dead\!) 2021-11-27 06:25:35 +03:00
Alibek Omarov
3f014fde73 scripts: continious_upload: upload to original transfer.sh 2021-11-27 06:24:13 +03:00
Alibek Omarov
66db69862f cirrus: build all renderers available, remove unsupported -W flag for waf configure 2021-11-27 06:23:07 +03:00
Alibek Omarov
fc665527ae wscript: try to fix install on windows 2021-11-27 06:04:26 +03:00
Alibek Omarov
0c6b51fa0c waf: upgrade 2021-11-27 05:54:22 +03:00
Alibek Omarov
c00e77c02e engine: fix const qualifier discard 2021-11-27 05:27:45 +03:00
Alibek Omarov
25c0557f7f engine: platform: sdl: fix building with SDL1.2 2021-11-27 05:26:09 +03:00
Alibek Omarov
76ea3c39a0 ref_gl: disable multisample texture for gl4es too 2021-11-27 05:13:31 +03:00
Alibek Omarov
e67bd4811a ref_gl: fix gles1 and gles2 build 2021-11-25 19:02:09 +03:00
Alibek Omarov
7a215766c6 ref_gl: add missing define for glTexImage2DMultisample 2021-11-25 18:47:23 +03:00
Alibek Omarov
576f0a72c5 scripts: install with destdir option on CI 2021-11-25 16:57:02 +03:00
Alibek Omarov
55b4597390 readme: use --destdir option to install engine in selected folder 2021-11-25 16:56:37 +03:00
Alibek Omarov
c64b3db6b8 wscript: remove win-style-install option, introduce enable-packaging 2021-11-25 16:52:28 +03:00
Alibek Omarov
67e77ca099 wscript: move setting DOS options where they should be 2021-11-24 23:54:03 +03:00
SNMetamorph
f726793711 engine: client: cl_main: fixed compilation error 2021-11-23 13:10:39 +03:00
Alibek Omarov
1944f48516 engine: common: allow unlimited commands for unprivileged mode at this time to not break mods like GGM 2021-11-23 05:23:38 +03:00
Alibek Omarov
992bcd89ef engine: add cmd and cvar tests for privileged mode 2021-11-23 05:23:38 +03:00
Alibek Omarov
2356bc9905 engine: client: escape keybindings and rcon commands 2021-11-23 05:23:38 +03:00
Alibek Omarov
9159d406e3 engine: client: fix #673 2021-11-23 05:23:38 +03:00
Alibek Omarov
508eb7ab5f engine: restore command escaping 2021-11-23 05:23:38 +03:00
Alibek Omarov
1de1852409 engine: client: fix build after merging into one ParseCvarValue function 2021-11-23 05:23:38 +03:00
Alibek Omarov
664506f79e engine: client: touch security, add unprivileged for buttons added from server, force it and client flags 2021-11-23 05:23:38 +03:00
Alibek Omarov
06eb6838a9 engine: client: protect protected, privileged and server only cvars from server query 2021-11-23 05:23:38 +03:00
Alibek Omarov
f2a9f805b8 engine: client: redefine some cvars as filterable 2021-11-23 05:23:38 +03:00
Alibek Omarov
c6648a69ba engine: client: protect messagemode from command injection too 2021-11-23 05:23:38 +03:00
Alibek Omarov
3203d9a043 engine: client: wire Cbuf_AddFilteredText to svc_stufftext commands 2021-11-23 05:23:38 +03:00
Alibek Omarov
8599119c8d engine: add filterable flag support for cvars and cmds 2021-11-23 05:23:38 +03:00
Alibek Omarov
a3d6e7bcfe common: define FCVAR_FILTERABLE, change FCVAR_LATCH value (probably losing compatibility with XashXT and Paranoia 2) 2021-11-23 05:23:38 +03:00
Alibek Omarov
36702aafe7 engine: rename FCVAR_LOCALONLY and CMD_LOCALONLY into FCVAR_PRIVILEGED and CMD_PRIVILEGED 2021-11-23 05:23:38 +03:00
Alibek Omarov
b93938956e engine: allow exec command with config filenames whitelist 2021-11-23 05:23:38 +03:00
Alibek Omarov
c96f10d40b engine: client: restrict LOCALONLY cvars regardless of cl_filterstuffcmd value 2021-11-23 05:23:38 +03:00
Alibek Omarov
8a9231628e engine: restrict potentially harmful or related to user settings engine cvars 2021-11-23 05:23:38 +03:00
Alibek Omarov
66d66eb835 common: define FCVAR_LOCALONLY the same bit used in GoldSource, move FCVAR_MOVEVARS into internal engine flags 2021-11-23 05:23:38 +03:00
Alibek Omarov
9a4dec64f9 engine: describe protected and privileged cvars 2021-11-23 05:23:38 +03:00
Alibek Omarov
94dc74a37f engine: restrict potentially harmful engine commands 2021-11-23 05:23:38 +03:00
Alibek Omarov
b24c1a51d3 engine: try to mitigate outdated client.dll vulnerabilities 2021-11-23 05:23:38 +03:00
Alibek Omarov
c79a649d97 engine: client: implement pfnFilteredClientCmd 2021-11-23 05:23:38 +03:00
Alibek Omarov
f9d1d14848 engine: disable filtered command buffer for dedicated 2021-11-23 05:23:38 +03:00
Alibek Omarov
1a1d81de62 engine: add stuffcmd filtering, not wired to ClientCmd yet 2021-11-23 05:23:38 +03:00
SNMetamorph
6c9321e50c ref_gl: added multisample textures support 2021-11-23 05:17:19 +03:00
SNMetamorph
c366e25a10 ref_gl: cvar gl_wgl_msaa_samples renamed to gl_msaa_samples 2021-11-23 05:17:19 +03:00
175 changed files with 5851 additions and 4258 deletions

View File

@@ -1,22 +1,10 @@
task:
name: freebsd-11-amd64
freebsd_instance:
image_family: freebsd-11-4
setup_script:
- pkg update
- pkg install -y git sdl2 python
- git submodule update --init --recursive
test_script:
- ./scripts/cirrus/build_freebsd.sh dedicated
- ./scripts/cirrus/build_freebsd.sh full
task:
name: freebsd-12-amd64
freebsd_instance:
image_family: freebsd-12-2
image_family: freebsd-12-3
setup_script:
- pkg update
- pkg install -y git sdl2 python
- pkg install -y git sdl2 python fontconfig
- git submodule update --init --recursive
test_script:
- ./scripts/cirrus/build_freebsd.sh dedicated
@@ -25,10 +13,22 @@ task:
task:
name: freebsd-13-amd64
freebsd_instance:
image_family: freebsd-13-0-snap
image_family: freebsd-13-1
setup_script:
- pkg update
- pkg install -y git sdl2 python
- 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-14-amd64
freebsd_instance:
image_family: freebsd-14-0-snap
setup_script:
- pkg update
- pkg install -y git sdl2 python fontconfig
- git submodule update --init --recursive
test_script:
- ./scripts/cirrus/build_freebsd.sh dedicated

View File

@@ -1,6 +1,11 @@
name: Build & Deploy Engine
on: [push, pull_request]
jobs:
# cleanup:
# runs-on: self-hosted
# steps:
# - name: Cleanup
# run: rm -rf .* || true
build:
runs-on: ${{ matrix.os }}
continue-on-error: true
@@ -14,6 +19,9 @@ jobs:
- os: ubuntu-18.04
targetos: linux
targetarch: i386
# - os: ubuntu-aarch64-20.04
# targetos: linux
# targetarch: aarch64
- os: ubuntu-18.04
targetos: android
@@ -37,7 +45,6 @@ jobs:
GH_CPU_ARCH: ${{ matrix.targetarch }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ANDROID_SDK_TOOLS_VER: 4333796
ANDROID_NDK_VER: r10e
UPLOADTOOL_ISPRERELEASE: true
steps:
- name: Checkout
@@ -56,15 +63,10 @@ jobs:
- name: Build engine
run: bash scripts/gha/build_${{ matrix.targetos }}.sh
- name: Upload engine (android)
if: matrix.targetos == 'android'
run: bash scripts/continious_upload.sh xashdroid-${{ matrix.targetarch }}.apk
- name: Upload engine (motomagx)
if: matrix.targetos == 'motomagx'
run: bash scripts/continious_upload.sh xash3d-fwgs-magx.7z
- name: Upload engine (linux)
if: matrix.targetos == 'linux'
run: bash scripts/continious_upload.sh xash3d-fwgs-${{ matrix.targetarch }}.AppImage xashds-linux-${{ matrix.targetarch }}
- name: Upload engine (windows)
if: matrix.targetos == 'win32'
run: bash scripts/continious_upload.sh xash3d-fwgs-win32-${{ matrix.targetarch }}.7z
- name: Upload engine (prereleases)
run: bash scripts/continious_upload.sh artifacts/*
- name: Upload engine (artifacts)
uses: actions/upload-artifact@v2
with:
name: artifact-${{ matrix.targetos }}-${{ matrix.targetarch }}
path: artifacts/*

View File

@@ -1,35 +0,0 @@
language: c
compiler: gcc
sudo: false
env:
global:
- SDL_VERSION=2.0.14
git:
depth: 50
submodules: true
os: linux
arch:
- aarch64
- ppc64le
- s390x
addons:
apt:
update: true
packages:
- libx11-dev
- libxext-dev
- x11-utils
- libgl1-mesa-dev
- libasound-dev
- libstdc++6
- libfuse2
- unzip
before_script:
- sh scripts/travis/deps_common.sh
- sh scripts/travis/deps_${TRAVIS_OS_NAME}.sh
script:
- sh scripts/travis/build_${TRAVIS_OS_NAME}.sh
after_script:
- ccache --show-stats
- sh scripts/continious_upload.sh xash3d-fwgs-${ARCH}.tar.xz xashds-linux-${ARCH}

View File

@@ -24,6 +24,10 @@ Official github repository - https://github.com/CKFDevPowered/CKF3Alpha
## Cold Ice
Version 1.9 is available on ModDB - https://www.moddb.com/mods/cold-ice/downloads/cold-ice-sdk
Version 1.9 mirrored on github - https://github.com/solidi/hl-mods/tree/master/ci
## Cold Ice Ressurection
Mirrored on github - https://github.com/solidi/hl-mods/tree/master/cir
## Cthulhu
Uploaded to github by Oleg Cherkasky - https://github.com/gunrunners-paradise/Cthulhu-HLmod-SDK
@@ -46,8 +50,14 @@ Versions 2.0 and 3.0, available in mod archives on ModDB - https://www.moddb.com
## GT mod
Available on GamerLab - http://gamer-lab.com/eng/code_mods_goldsrc/GT_mod_(Polnie_ishodniki)
## Half-Life: Advanced Deathmatch
Mirrored on github - https://github.com/solidi/hl-mods/tree/master/hla
## Half-Life: Decay
Mirrored on github(PC Port) - https://github.com/hoaxer/Half-Life-Decay
## Half-Life: Echoes
Download link on dropbox - https://www.dropbox.com/s/s6j8gtegn10wgvj/dlls.zip?dl=1
Available on ModDB - https://www.moddb.com/mods/half-life-echoes
## Half-Life: Expanded Arsenal
Available on ModDB - https://www.moddb.com/mods/half-life-expanded-arsenal
@@ -58,6 +68,9 @@ Branch **gravgun** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/g
## Half-Life: Invasion
official github repository - https://github.com/jlecorre/hlinvasion
## Half-Life: Pong
Mirrored on github - https://github.com/solidi/hl-mods/tree/master/pong
## Half-Life: Quest Mode
Available on cs-mapping.com.ua - https://old.cs-mapping.com.ua/forum/showthread.php?t=38030
@@ -161,7 +174,7 @@ Branch **redempt** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/r
OpenAG by YaLTeR - https://github.com/YaLTeR/OpenAG
## Afraid of Monsters
malortie's recreation - https://github.com/malortie/halflife/tree/mod-hl-aom
malortie's recreation - https://github.com/malortie/hl-aom
Branch **aom** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/aom
@@ -169,17 +182,17 @@ Branch **aom** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/aom
Reverse-engineered code, branch **aomdc** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/aomdc
## Azure Sheep
malortie's recreation - https://github.com/malortie/halflife/tree/mod-hl-asheep
malortie's recreation - https://github.com/malortie/hl-asheep
Reverse-engineered code, branch **asheep** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/asheep
## Big Lolly
malortie's recreation - https://github.com/malortie/halflife/tree/mod-hl-biglolly
malortie's recreation - https://github.com/malortie/hl-biglolly
Branch **biglolly** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/biglolly
## Black Ops
malortie's recreation - https://github.com/malortie/halflife/tree/mod-hl-blackops
malortie's recreation - https://github.com/malortie/hl-blackops
Branch **blackops** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/blackops
@@ -206,7 +219,7 @@ CSO-like Xash3D-based mod, CSMoE - https://github.com/MoeMod/CSMoE
Recreation by lostgamer aka nillerusr - https://github.com/LostGamerHL/crack_life
## Escape from the Darkness
malortie's recreation - https://github.com/malortie/halflife/tree/mod-hl-eftd
malortie's recreation - https://github.com/malortie/hl-eftd
Reverse-engineered code, branch **eftd** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/eftd
@@ -229,7 +242,7 @@ Spirit of Half Life: Opposing-Force Edition - https://github.com/Hammermaps-DEV/
Reverse-engineered code, branch **rebellion** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/rebellion
## Half-Life: Visitors
malortie's recreation - https://github.com/malortie/halflife/tree/mod-hl-visitors
malortie's recreation - https://github.com/malortie/hl-visitors
Reverse-engineered code, branch **visitors** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/visitors
@@ -237,17 +250,17 @@ Reverse-engineered code, branch **visitors** in hlsdk-xash3d - https://github.co
Branch **half-secret** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/half-secret
## Night at the Office
malortie's recreation - https://github.com/malortie/halflife/tree/mod-hl-noffice
malortie's recreation - https://github.com/malortie/hl-nato
Branch **noffice** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/noffice
## Poke 646
malortie's recreation - https://github.com/malortie/halflife/tree/mod-hl-poke646
malortie's recreation - https://github.com/malortie/hl-poke646
Reverse-engineered code, branch **poke646** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/poke646
## Poke 646: Vendetta
malortie's recreation - https://github.com/malortie/halflife/tree/mod-hl-poke646
malortie's recreation - https://github.com/malortie/hl-poke646-vendetta
Reverse-engineered code, branch **poke646_vendetta** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/poke646_vendetta
@@ -261,19 +274,19 @@ Reverse-engineered code, branch **residual_point** in hlsdk-xash3d - https://git
Reverse-engineered code by Velaron - https://github.com/Velaron/tf15-client
## The Gate
malortie's recreation - https://github.com/malortie/halflife/tree/mod-hl-TheGate
malortie's recreation - https://github.com/malortie/hl-thegate
Reverse-engineered code, branch **thegate** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/thegate
## They Hunger
malortie's recreation - https://github.com/malortie/halflife/tree/mod-hl-Hunger
malortie's recreation - https://github.com/malortie/hl-theyhunger
Reverse-engineered code, branch **theyhunger** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/theyhunger
They Hunger: Tactical - https://www.moddb.com/mods/they-hunger-tactical/downloads/tht-source-code-documentation
## Times of Troubles
malortie's recreation - https://github.com/malortie/halflife/tree/mod-hl-tot
malortie's recreation - https://github.com/malortie/hl-tot
Branch **tot** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/tot
@@ -295,7 +308,7 @@ Branch **dmc** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/dmc
Branch **echoes** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/echoes
## Half-Life: Invasion
Port to HLSDK 2.4 by malortie - https://github.com/malortie/halflife/tree/mod-hl-invasion
Port to HLSDK 2.4 by malortie - https://github.com/malortie/hl-invasion
Port to Linux by fmoraw - https://github.com/fmoraw/hlinvasion
@@ -309,7 +322,7 @@ Branch **half-screwed** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/t
Port to Linux - https://github.com/fmoraw/NS
## Swiss Cheese Halloween 2002
Just more playable version by malortie - https://github.com/malortie/halflife/tree/mod-hl-halloween
Just more playable version by malortie - https://github.com/malortie/hl-shall
Branch **halloween** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/halloween

View File

@@ -15,24 +15,24 @@ Status:
Table is sorted by status.
| Platform | Status | Maintainer | Note
| -------- | ------ | ---------- | ----
| Windows | Supported | @a1batross |
| *BSD | Supported | @nekonomicon |
| GNU/Linux(x86, amd64, arm) | Supported | @a1batross, @mittorn |
| Android | Supported | @a1batross, @mittorn |
| MotoMAGX | Supported | @a1batross |
| GNU/Linux(elbrus) | Supported | @a1batross, @mittorn | Rare and eventual access to e2k machine
| Haiku | Supported | not maintained | Was added by #478 and #483
| DOS4GW | Supported | @mittorn |
| GNU/Linux(mipsel) | Supported | @mittorn |
| Switch | In progress | @fgsfdsfgs | [Github Repository](https://github.com/fgsfdsfgs/xash3d-fwgs/tree/switch_new)
| Wii | In progress | Collaborative effort | [Github Repository](https://github.com/saucesaft/xash3d-wii)
| PSP | In progress | Collaborative effort | No sources available at this moment
| Emscripten | Old Engine | not maintained |
| Oculus Quest | Old Engine fork | @DrBeef | [GitHub Repository](https://github.com/DrBeef/Lambda1VR)
| PSVita | Old Engine fork | not maintained | [GitHub Repository](https://github.com/fgsfdsfgs/vitaXash3D)
| Switch | Old Engine fork | not maintained | [GitHub Repository](https://github.com/switchports/xash3d-switch)
| 3DS | Old Engine fork | not maintained | [GitHub Repository](https://github.com/masterfeizz/Xash3DS)
| macOS | Deprecated | not maintained | See GitHub issue #61
| iOS | Deprecated | not maintained | See GitHub issue #61
| Platform | Status | Maintainer | Note
| -------- | ------ | ---------- | ----
| Windows | Supported | @a1batross, @SNMetamorph |
| *BSD | Supported | @nekonomicon |
| GNU/Linux(x86, amd64, arm) | Supported | @a1batross, @mittorn |
| Android | Supported | @a1batross, @mittorn |
| MotoMAGX | Supported | @a1batross |
| GNU/Linux(elbrus) | Supported | @a1batross, @mittorn | Rare and eventual access to e2k machine
| Haiku | Supported | not maintained | Was added by #478 and #483
| DOS4GW | Supported | @mittorn |
| GNU/Linux(mipsel) | Supported | @mittorn |
| Switch | In progress | @fgsfdsfgs | [GitHub Repository](https://github.com/fgsfdsfgs/xash3d-fwgs/tree/switch_new)
| Wii | In progress | Collaborative effort | [GitHub Repository](https://github.com/saucesaft/xash3d-wii)
| PSP | In progress | @Crow_bar, @Velaron | [GitHub Repository](https://github.com/Crow-bar/xash3d-fwgs)
| Emscripten | Old Engine | not maintained |
| Oculus Quest | Old Engine fork | @DrBeef | [GitHub Repository](https://github.com/DrBeef/Lambda1VR)
| PSVita | Old Engine fork | not maintained | [GitHub Repository](https://github.com/fgsfdsfgs/vitaXash3D)
| Switch | Old Engine fork | not maintained | [GitHub Repository](https://github.com/switchports/xash3d-switch)
| 3DS | Old Engine fork | not maintained | [GitHub Repository](https://github.com/masterfeizz/Xash3DS)
| macOS | Deprecated | not maintained | See GitHub issue #61
| iOS | Deprecated | not maintained | See GitHub issue #61

View File

@@ -1,5 +1,5 @@
# Xash3D FWGS Engine
[![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) [![Travis CI Status](https://api.travis-ci.org/FWGS/xash3d-fwgs.svg?branch=master)](https://travis-ci.org/FWGS/xash3d-fwgs) [![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://discord.fwgs.ru/) \
[![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)
Xash3D FWGS is a fork of Xash3D Engine by Unkle Mike with extended features and crossplatform.
@@ -27,16 +27,13 @@ Read more about Xash3D on ModDB: https://www.moddb.com/engines/xash3d-engine
* Vulkan renderer
## Installation & Running
0) Get Xash3D binaries: you can use [testing](https://github.com/FWGS/xash3d-fwgs/releases/tag/continuous) build or you can compile engine from source code.
Choose proper build package depending on which platform you're using.
0) Get Xash3D FWGS binaries: you can use [testing](https://github.com/FWGS/xash3d-fwgs/releases/tag/continuous) build or you can compile engine from source code.
1) Copy engine binaries to some directory.
2) Copy `valve` directory from [Half-Life](https://store.steampowered.com/app/70/HalfLife/) to directory with engine binaries.
Also if you're using Windows: you should copy `vgui.dll` library from Half-Life directory to Xash3D directory.
As alternative, you can compile [hlsdk-xash3d](https://github.com/FWGS/hlsdk-xash3d) instead of using official Valve game binaries, but you still needed to copy `valve` directory as all game resources located in there.
3) Download [extras.pak](https://github.com/FWGS/xash-extras/releases/tag/v0.19.2) and place it to `valve` directory.
4) Run `xash3d.exe`/`xash3d.sh`/`xash3d` depending on which platform you're using.
Note: on Linux, you may need to create an sh file with the command `LD_LIBRARY_PATH=. ./xash3d`.
If your CPU is NOT x86 compatible or you're running 64-bit version of the engine, you may want to compile [Half-Life SDK](https://github.com/FWGS/hlsdk-xash3d).
This repository contains our fork of HLSDK and restored source code for some of the mods. Not all of them, of course.
You still needed to copy `valve` directory as all game resources located there.
3) Run the main executable (`xash3d.exe` or AppImage).
For additional info, run Xash3D with `-help` command line key.
@@ -51,6 +48,13 @@ We are using Waf build system. If you have some Waf-related questions, I recomme
NOTE: NEVER USE GitHub's ZIP ARCHIVES. GitHub doesn't include external dependencies we're using!
### Prerequisites
If your CPU is x86 compatible, we are building 32-bit code by default. This was dont for keeping compatibility with Steam releases of Half-Life and based on it's engine games.
Even if Xash3D FWGS does support targetting 64-bit, you can't load games without recompiling them from source code!
If your CPU is NOT x86 compatible or you decided build 64-bit version of engine, you may want to compile [Half-Life SDK](https://github.com/FWGS/hlsdk-xash3d).
This repository contains our fork of HLSDK and restored source code for some of the mods. Not all of them, of course.
#### Windows (Visual Studio)
* Install Visual Studio.
* Install latest [Python](https://python.org) **OR** run `cinst python.install` if you have Chocolatey.
@@ -60,10 +64,6 @@ NOTE: NEVER USE GitHub's ZIP ARCHIVES. GitHub doesn't include external dependenc
* Make sure you have at least 12GB of free space to store all build-time dependencies: ~10GB for Visual Studio, 300 MB for Git, 100 MB for Python and other.
#### GNU/Linux
NOTE FOR USERS WITH X86 COMPATIBLE CPUs:
We have forced Waf to throw an error, if you're trying to build 64-bit engine. This was done for keeping compatibility with Steam releases of Half-Life and based on it's engine games.
Even if Xash3D FWGS does support targetting 64-bit, you can't load games without recompiling them from source code!
##### Debian/Ubuntu
* Enable i386 on your system, if you're compiling 32-bit engine on amd64. If not, skip this
@@ -81,16 +81,15 @@ Even if Xash3D FWGS does support targetting 64-bit, you can't load games without
0) Open command line
1) Navigate to `xash3d-fwgs` directory.
2) Carefully examine which build options are available: `waf --help`
3) Configure build: `waf configure -T release --sdl2=c:/path/to/SDL2 --prefix=c:/path/to/any/output/directory`
3) Configure build: `waf configure -T release --sdl2=c:/path/to/SDL2`
4) Compile: `waf build`
5) Install: `waf install`
5) Install: `waf install --destdir=c:/path/to/any/output/directory`
#### Linux
If compiling 32-bit on amd64, you may need to supply `export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig` prior to running configure.
0) Examine which build options are available: `./waf --help`
1) Configure build: `./waf configure -T release --prefix=/path/to/any/output/directory`
1) Configure build: `./waf configure -T release`
(You need to pass `-8` to compile 64-bit engine on 64-bit x86 processor)
2) Compile: `./waf build`
3) Install(optional): `./waf install`
Note: if compiling 32-bit on amd64, you may need to supply `export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig` prior to running configure.
3) Install(optional): `./waf install --destdir=/path/to/any/output/directory`

View File

@@ -9,8 +9,7 @@ NOTE: number at end of pixelformat name it's a total bitscount e.g. PF_RGB_24 ==
========================================================================
*/
#define ImageRAW( type ) (type == PF_RGBA_32 || type == PF_BGRA_32 || type == PF_RGB_24 || type == PF_BGR_24 || type == PF_LUMINANCE)
#define ImageDXT( type ) (type == PF_DXT1 || type == PF_DXT3 || type == PF_DXT5 || type == PF_ATI2)
#define Image16( type ) (type == PF_RGBA_64 || type == PF_RGB_48)
#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)
typedef enum
{
@@ -22,12 +21,13 @@ typedef enum
PF_RGB_24, // uncompressed dds or another 24-bit image
PF_BGR_24, // big-endian RGB (MacOS)
PF_LUMINANCE,
PF_DXT1, // s3tc DXT1 format
PF_DXT3, // s3tc DXT3 format
PF_DXT5, // s3tc DXT5 format
PF_ATI2, // latc ATI2N format
PF_RGBA_64, // 16-bit RGBA
PF_RGB_48, // 16-bit RGB
PF_DXT1, // s3tc DXT1/BC1 format
PF_DXT3, // s3tc DXT3/BC2 format
PF_DXT5, // s3tc DXT5/BC3 format
PF_ATI2, // latc ATI2N/BC5 format
PF_BC6H_SIGNED, // bptc BC6H signed FP16 format
PF_BC6H_UNSIGNED, // bptc BC6H unsigned FP16 format
PF_BC7, // bptc BC7 format
PF_TOTALCOUNT, // must be last
} pixformat_t;
@@ -85,7 +85,7 @@ typedef enum
IMAGE_ROT_90 = BIT(18), // flip from upper left corner to down right corner
IMAGE_ROT180 = IMAGE_FLIP_X|IMAGE_FLIP_Y,
IMAGE_ROT270 = IMAGE_FLIP_X|IMAGE_FLIP_Y|IMAGE_ROT_90,
IMAGE_EMBOSS = BIT(19), // apply emboss mapping
// reserved
IMAGE_RESAMPLE = BIT(20), // resample image to specified dims
// reserved
// reserved

View File

@@ -725,7 +725,6 @@ typedef int string_t;
typedef unsigned short word;
#include "xash3d_types.h"
#define Q_isspace( ch ) (ch < 32 || ch > 255)
typedef struct
{

View File

@@ -25,14 +25,18 @@
#define FCVAR_PRINTABLEONLY (1<<7) // This cvar's string cannot contain unprintable characters ( e.g., used for player name etc ).
#define FCVAR_UNLOGGED (1<<8) // If this is a FCVAR_SERVER, don't log changes to the log file / console if we are creating a log
#define FCVAR_NOEXTRAWHITEPACE (1<<9) // strip trailing/leading white space from this cvar
#define FCVAR_PRIVILEGED (1<<10) // only available in privileged mode
#define FCVAR_FILTERABLE (1<<11) // filtered in unprivileged mode if cl_filterstuffcmd is 1
#define FCVAR_MOVEVARS (1<<10) // this cvar is a part of movevars_t struct that shared between client and server
#define FCVAR_LATCH (1<<11) // notify client what this cvar will be applied only after server restart (but don't does more nothing)
// Xash3D extensions
#define FCVAR_GLCONFIG (1<<12) // write it into <renderer>.cfg(see RefAPI)
#define FCVAR_CHANGED (1<<13) // set each time the cvar is changed
#define FCVAR_GAMEUIDLL (1<<14) // defined by the menu DLL
#define FCVAR_CHEAT (1<<15) // can not be changed if cheats are disabled
// a1ba: let's reuse higher bits for flags extensions from now on
#define FCVAR_LATCH (1<<30) // notify client what this cvar will be applied only after server restart (but don't does more nothing)
typedef struct cvar_s
{
char *name;

View File

@@ -25,5 +25,6 @@ GNU General Public License for more details.
#define ENGINE_COMPENSATE_QUAKE_BUG (1<<5) // compensate stupid quake bug (inverse pitch) for mods where this bug is fixed
#define ENGINE_IMPROVED_LINETRACE (1<<6) // new traceline that tracing through alphatextures
#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
#endif//FEATURES_H

View File

@@ -18,6 +18,7 @@ GNU General Public License for more details.
#define GFL_NOMODELS (1<<0)
#define GFL_NOSKILLS (1<<1)
#define GFL_RENDER_PICBUTTON_TEXT (1<<2)
/*
========================================================================

View File

@@ -20,8 +20,6 @@ GNU General Public License for more details.
#include "build.h"
#if !XASH_WIN32
#if XASH_APPLE
#include <sys/syslimits.h>
#define OS_LIB_EXT "dylib"
@@ -30,67 +28,32 @@ GNU General Public License for more details.
#define OS_LIB_EXT "so"
#define OPEN_COMMAND "xdg-open"
#endif
#define OS_LIB_PREFIX "lib"
#if XASH_ANDROID
//#if defined(LOAD_HARDFP)
// #define POSTFIX "_hardfp"
//#else
#define POSTFIX
//#endif
#else
#endif
#define VGUI_SUPPORT_DLL "libvgui_support." OS_LIB_EXT
// Windows-specific
#define __cdecl
#define __stdcall
#define _inline static inline
#define FORCEINLINE inline __attribute__((always_inline))
#if XASH_POSIX
#define PATH_SPLITTER "/"
#include <unistd.h>
#include <dlfcn.h>
#define O_BINARY 0 // O_BINARY is Windows extension
#define O_TEXT 0 // O_TEXT is Windows extension
// Windows functions to posix equivalent
#define _mkdir( x ) mkdir( x, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH )
#define LoadLibrary( x ) dlopen( x, RTLD_NOW )
#define GetProcAddress( x, y ) dlsym( x, y )
#define FreeLibrary( x ) dlclose( x )
#define tell( a ) lseek(a, 0, SEEK_CUR)
#define HAVE_DUP
#endif
#if XASH_POSIX
#include <unistd.h>
#include <dlfcn.h>
#if XASH_DOS4GW
#define PATH_SPLITTER "\\"
#define LoadLibrary( x ) (0)
#define GetProcAddress( x, y ) (0)
#define FreeLibrary( x ) (0)
#endif
//#define MAKEWORD( a, b ) ((short int)(((unsigned char)(a))|(((short int)((unsigned char)(b)))<<8)))
#define max( a, b ) (((a) > (b)) ? (a) : (b))
#define min( a, b ) (((a) < (b)) ? (a) : (b))
#define PATH_SPLITTER "/"
#define HAVE_DUP
/// TODO: check if we may clean this defines, it should not appear in non-platform code!
typedef unsigned char BYTE;
typedef short int WORD;
typedef unsigned int DWORD;
typedef int LONG;
typedef unsigned int ULONG;
typedef int WPARAM;
typedef unsigned int LPARAM;
#define O_BINARY 0
#define O_TEXT 0
#define _mkdir( x ) mkdir( x, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH )
#elif XASH_DOS4GW
#define PATH_SPLITTER "\\"
#endif
typedef void* HANDLE;
typedef void* HMODULE;
typedef void* HINSTANCE;
typedef char* LPSTR;
typedef struct tagPOINT
{
int x, y;
@@ -108,19 +71,6 @@ GNU General Public License for more details.
#define read _read
#define alloca _alloca
// shut-up compiler warnings
#pragma warning(disable : 4244) // MIPS
#pragma warning(disable : 4018) // signed/unsigned mismatch
#pragma warning(disable : 4305) // truncation from const double to float
#pragma warning(disable : 4115) // named type definition in parentheses
#pragma warning(disable : 4100) // unreferenced formal parameter
#pragma warning(disable : 4127) // conditional expression is constant
#pragma warning(disable : 4057) // differs in indirection to slightly different base types
#pragma warning(disable : 4201) // nonstandard extension used
#pragma warning(disable : 4706) // assignment within conditional expression
#pragma warning(disable : 4054) // type cast' : from function pointer
#pragma warning(disable : 4310) // cast truncates constant value
#define HSPRITE WINAPI_HSPRITE
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
@@ -130,13 +80,9 @@ GNU General Public License for more details.
#define OS_LIB_PREFIX ""
#define OS_LIB_EXT "dll"
#define VGUI_SUPPORT_DLL "../vgui_support." OS_LIB_EXT
#ifdef XASH_64BIT
// windows NameForFunction not implemented yet
#define XASH_ALLOW_SAVERESTORE_OFFSETS
#endif
#define HAVE_DUP
#endif //WIN32
#ifndef XASH_LOW_MEMORY
#define XASH_LOW_MEMORY 0
#endif

View File

@@ -82,7 +82,7 @@ typedef enum
TF_KEEP_SOURCE = (1<<1), // some images keep source
TF_NOFLIP_TGA = (1<<2), // Steam background completely ignore tga attribute 0x20
TF_EXPAND_SOURCE = (1<<3), // Don't keep source as 8-bit expand to RGBA
TF_ALLOW_EMBOSS = (1<<4), // Allow emboss-mapping for this image
// reserved
TF_RECTANGLE = (1<<5), // this is GL_TEXTURE_RECTANGLE
TF_CUBEMAP = (1<<6), // it's cubemap texture
TF_DEPTHMAP = (1<<7), // custom texture filter used
@@ -107,6 +107,7 @@ typedef enum
TF_ARB_FLOAT = (1<<26), // float textures
TF_NOCOMPARE = (1<<27), // disable comparing for depth textures
TF_ARB_16BIT = (1<<28), // keep image as 16-bit (not 24)
TF_MULTISAMPLE = (1<<29) // multisampling texture
} texFlags_t;
typedef enum

View File

@@ -2,7 +2,9 @@
#ifndef XASH_TYPES_H
#define XASH_TYPES_H
#ifdef _WIN32
#include "build.h"
#if XASH_WIN32
#include <wchar.h> // off_t
#endif // _WIN32
@@ -64,19 +66,25 @@ typedef uint64_t longtime_t;
#define ColorIndex( c ) ((( c ) - '0' ) & 7 )
#if defined(__GNUC__)
#ifdef __i386__
#define EXPORT __attribute__ ((visibility ("default"),force_align_arg_pointer))
#define GAME_EXPORT __attribute((force_align_arg_pointer))
#else
#define EXPORT __attribute__ ((visibility ("default")))
#define GAME_EXPORT
#endif
#ifdef __i386__
#define EXPORT __attribute__ ((visibility ("default"),force_align_arg_pointer))
#define GAME_EXPORT __attribute((force_align_arg_pointer))
#else
#define EXPORT __attribute__ ((visibility ("default")))
#define GAME_EXPORT
#endif
#define _format(x) __attribute__((format(printf, x, x+1)))
#define NORETURN __attribute__((noreturn))
#elif defined(_MSC_VER)
#define EXPORT __declspec( dllexport )
#define GAME_EXPORT
#define EXPORT __declspec( dllexport )
#define GAME_EXPORT
#define _format(x)
#define NORETURN
#else
#define EXPORT
#define GAME_EXPORT
#define EXPORT
#define GAME_EXPORT
#define _format(x)
#define NORETURN
#endif
@@ -117,6 +125,11 @@ typedef struct file_s file_t; // normal file
typedef struct wfile_s wfile_t; // wad file
typedef struct stream_s stream_t; // sound stream for background music playing
typedef off_t fs_offset_t;
#if XASH_WIN32
typedef int fs_size_t; // return type of _read, _write funcs
#else /* !XASH_WIN32 */
typedef ssize_t fs_size_t;
#endif /* !XASH_WIN32 */
typedef struct dllfunc_s
{
@@ -132,7 +145,7 @@ typedef struct dll_info_s
void *link; // hinstance of loading library
} dll_info_t;
typedef void (*setpair_t)( const char *key, const void *value, void *buffer, void *numpairs );
typedef void (*setpair_t)( const char *key, const void *value, const void *buffer, void *numpairs );
// config strings are a general means of communication from
// the server to all connected clients.

View File

@@ -106,7 +106,7 @@ void CL_RemoveFromResourceList( resource_t *pResource )
if( pResource->pPrev == NULL || pResource->pNext == NULL )
Host_Error( "mislinked resource in CL_RemoveFromResourceList\n" );
if ( pResource->pNext == pResource || pResource->pPrev == pResource )
if( pResource->pNext == pResource || pResource->pPrev == pResource )
Host_Error( "attempt to free last entry in list.\n" );
pResource->pPrev->pNext = pResource->pNext;

View File

@@ -188,8 +188,6 @@ void R_StoreEfrags( efrag_t **ppefrag, int framecount )
case mod_brush:
case mod_studio:
case mod_sprite:
pent = pefrag->entity;
if( pent->visframe != framecount )
{
if( CL_AddVisibleEntity( pent, ET_FRAGMENTED ))

View File

@@ -46,7 +46,7 @@ short GAME_EXPORT R_LookupColor( byte r, byte g, byte b )
float rf, gf, bf;
bestdiff = 999999;
best = 65535;
best = -1;
for( i = 0; i < 256; i++ )
{
@@ -683,42 +683,46 @@ void CL_ParseViewBeam( sizebuf_t *msg, int beamType )
switch( beamType )
{
case TE_BEAMPOINTS:
start[0] = MSG_ReadCoord( msg );
start[1] = MSG_ReadCoord( msg );
start[2] = MSG_ReadCoord( msg );
end[0] = MSG_ReadCoord( msg );
end[1] = MSG_ReadCoord( msg );
end[2] = MSG_ReadCoord( msg );
modelIndex = MSG_ReadShort( msg );
startFrame = MSG_ReadByte( msg );
frameRate = (float)MSG_ReadByte( msg );
life = (float)(MSG_ReadByte( msg ) * 0.1f);
width = (float)(MSG_ReadByte( msg ) * 0.1f);
noise = (float)(MSG_ReadByte( msg ) * 0.01f);
r = (float)MSG_ReadByte( msg ) / 255.0f;
g = (float)MSG_ReadByte( msg ) / 255.0f;
b = (float)MSG_ReadByte( msg ) / 255.0f;
a = (float)MSG_ReadByte( msg ) / 255.0f;
speed = (float)(MSG_ReadByte( msg ) * 0.1f);
R_BeamPoints( start, end, modelIndex, life, width, noise, a, speed, startFrame, frameRate, r, g, b );
break;
case TE_BEAMENTPOINT:
startEnt = MSG_ReadShort( msg );
end[0] = MSG_ReadCoord( msg );
end[1] = MSG_ReadCoord( msg );
end[2] = MSG_ReadCoord( msg );
case TE_BEAMENTS:
if( beamType == TE_BEAMENTS )
{
startEnt = MSG_ReadShort( msg );
endEnt = MSG_ReadShort( msg );
}
else
{
if( beamType == TE_BEAMENTPOINT )
{
startEnt = MSG_ReadShort( msg );
}
else
{
start[0] = MSG_ReadCoord( msg );
start[1] = MSG_ReadCoord( msg );
start[2] = MSG_ReadCoord( msg );
}
end[0] = MSG_ReadCoord( msg );
end[1] = MSG_ReadCoord( msg );
end[2] = MSG_ReadCoord( msg );
}
modelIndex = MSG_ReadShort( msg );
startFrame = MSG_ReadByte( msg );
frameRate = (float)MSG_ReadByte( msg );
life = (float)(MSG_ReadByte( msg ) * 0.1f);
width = (float)(MSG_ReadByte( msg ) * 0.1f);
noise = (float)(MSG_ReadByte( msg ) * 0.01f);
frameRate = (float)MSG_ReadByte( msg ) * 0.1f;
life = (float)MSG_ReadByte( msg ) * 0.1f;
width = (float)MSG_ReadByte( msg ) * 0.1f;
noise = (float)MSG_ReadByte( msg ) * 0.01f;
r = (float)MSG_ReadByte( msg ) / 255.0f;
g = (float)MSG_ReadByte( msg ) / 255.0f;
b = (float)MSG_ReadByte( msg ) / 255.0f;
a = (float)MSG_ReadByte( msg ) / 255.0f;
speed = (float)(MSG_ReadByte( msg ) * 0.1f);
R_BeamEntPoint( startEnt, end, modelIndex, life, width, noise, a, speed, startFrame, frameRate, r, g, b );
speed = (float)MSG_ReadByte( msg ) * 0.1f;
if( beamType == TE_BEAMENTS )
R_BeamEnts( startEnt, endEnt, modelIndex, life, width, noise, a, speed, startFrame, frameRate, r, g, b );
else if( beamType == TE_BEAMENTPOINT )
R_BeamEntPoint( startEnt, end, modelIndex, life, width, noise, a, speed, startFrame, frameRate, r, g, b );
else
R_BeamPoints( start, end, modelIndex, life, width, noise, a, speed, startFrame, frameRate, r, g, b );
break;
case TE_LIGHTNING:
start[0] = MSG_ReadCoord( msg );
@@ -727,27 +731,11 @@ void CL_ParseViewBeam( sizebuf_t *msg, int beamType )
end[0] = MSG_ReadCoord( msg );
end[1] = MSG_ReadCoord( msg );
end[2] = MSG_ReadCoord( msg );
life = (float)(MSG_ReadByte( msg ) * 0.1f);
width = (float)(MSG_ReadByte( msg ) * 0.1f);
noise = (float)(MSG_ReadByte( msg ) * 0.01f);
life = (float)MSG_ReadByte( msg ) * 0.1f;
width = (float)MSG_ReadByte( msg ) * 0.1f;
noise = (float)MSG_ReadByte( msg ) * 0.01f;
modelIndex = MSG_ReadShort( msg );
R_BeamLightning( start, end, modelIndex, life, width, noise, 0.6F, 3.5f );
break;
case TE_BEAMENTS:
startEnt = MSG_ReadShort( msg );
endEnt = MSG_ReadShort( msg );
modelIndex = MSG_ReadShort( msg );
startFrame = MSG_ReadByte( msg );
frameRate = (float)(MSG_ReadByte( msg ) * 0.1f);
life = (float)(MSG_ReadByte( msg ) * 0.1f);
width = (float)(MSG_ReadByte( msg ) * 0.1f);
noise = (float)(MSG_ReadByte( msg ) * 0.01f);
r = (float)MSG_ReadByte( msg ) / 255.0f;
g = (float)MSG_ReadByte( msg ) / 255.0f;
b = (float)MSG_ReadByte( msg ) / 255.0f;
a = (float)MSG_ReadByte( msg ) / 255.0f;
speed = (float)(MSG_ReadByte( msg ) * 0.1f);
R_BeamEnts( startEnt, endEnt, modelIndex, life, width, noise, a, speed, startFrame, frameRate, r, g, b );
R_BeamLightning( start, end, modelIndex, life, width, noise, 0.6f, 3.5f );
break;
case TE_BEAM:
break;
@@ -773,21 +761,21 @@ void CL_ParseViewBeam( sizebuf_t *msg, int beamType )
end[2] = MSG_ReadCoord( msg );
modelIndex = MSG_ReadShort( msg );
startFrame = MSG_ReadByte( msg );
frameRate = (float)(MSG_ReadByte( msg ));
life = (float)(MSG_ReadByte( msg ) * 0.1f);
width = (float)(MSG_ReadByte( msg ));
noise = (float)(MSG_ReadByte( msg ) * 0.1f);
frameRate = (float)MSG_ReadByte( msg ) * 0.1f;
life = (float)MSG_ReadByte( msg ) * 0.1f;
width = (float)MSG_ReadByte( msg );
noise = (float)MSG_ReadByte( msg ) * 0.01f;
r = (float)MSG_ReadByte( msg ) / 255.0f;
g = (float)MSG_ReadByte( msg ) / 255.0f;
b = (float)MSG_ReadByte( msg ) / 255.0f;
a = (float)MSG_ReadByte( msg ) / 255.0f;
speed = (float)(MSG_ReadByte( msg ) / 0.1f);
speed = (float)MSG_ReadByte( msg ) * 0.1f;
R_BeamCirclePoints( beamType, start, end, modelIndex, life, width, noise, a, speed, startFrame, frameRate, r, g, b );
break;
case TE_BEAMFOLLOW:
startEnt = MSG_ReadShort( msg );
modelIndex = MSG_ReadShort( msg );
life = (float)(MSG_ReadByte( msg ) * 0.1f);
life = (float)MSG_ReadByte( msg ) * 0.1f;
width = (float)MSG_ReadByte( msg );
r = (float)MSG_ReadByte( msg ) / 255.0f;
g = (float)MSG_ReadByte( msg ) / 255.0f;
@@ -800,15 +788,15 @@ void CL_ParseViewBeam( sizebuf_t *msg, int beamType )
endEnt = MSG_ReadShort( msg );
modelIndex = MSG_ReadShort( msg );
startFrame = MSG_ReadByte( msg );
frameRate = (float)MSG_ReadByte( msg );
life = (float)(MSG_ReadByte( msg ) * 0.1f);
width = (float)(MSG_ReadByte( msg ) * 0.1f);
noise = (float)(MSG_ReadByte( msg ) * 0.01f);
frameRate = (float)MSG_ReadByte( msg ) * 0.1f;
life = (float)MSG_ReadByte( msg ) * 0.1f;
width = (float)MSG_ReadByte( msg ) * 0.1f;
noise = (float)MSG_ReadByte( msg ) * 0.01f;
r = (float)MSG_ReadByte( msg ) / 255.0f;
g = (float)MSG_ReadByte( msg ) / 255.0f;
b = (float)MSG_ReadByte( msg ) / 255.0f;
a = (float)MSG_ReadByte( msg ) / 255.0f;
speed = (float)(MSG_ReadByte( msg ) * 0.1f);
speed = (float)MSG_ReadByte( msg ) * 0.1f;
R_BeamRing( startEnt, endEnt, modelIndex, life, width, noise, a, speed, startFrame, frameRate, r, g, b );
break;
case TE_BEAMHOSE:
@@ -1265,7 +1253,7 @@ void GAME_EXPORT R_BloodStream( const vec3_t org, const vec3_t dir, int pcolor,
particle_t *p;
int i, j;
float arc;
float accel = speed;
int accel = speed; // must be integer due to bug in GoldSrc
for( arc = 0.05f, i = 0; i < 100; i++ )
{

View File

@@ -158,7 +158,7 @@ CL_EventIndex
*/
word CL_EventIndex( const char *name )
{
int i;
word i;
if( !COM_CheckString( name ))
return 0;
@@ -484,7 +484,7 @@ void GAME_EXPORT CL_PlaybackEvent( int flags, const edict_t *pInvoker, word even
return;
// first check event for out of bounds
if( eventindex < 1 || eventindex > MAX_EVENTS )
if( eventindex < 1 || eventindex >= MAX_EVENTS )
{
Con_DPrintf( S_ERROR "CL_PlaybackEvent: invalid eventindex %i\n", eventindex );
return;

View File

@@ -58,10 +58,13 @@ void CL_UpdatePositions( cl_entity_t *ent )
ent->current_position = (ent->current_position + 1) & HISTORY_MASK;
ph = &ent->ph[ent->current_position];
VectorCopy( ent->curstate.origin, ph->origin );
VectorCopy( ent->curstate.angles, ph->angles );
ph->animtime = ent->curstate.animtime; // !!!
if( ent->model && ent->model->type == mod_brush )
ph->animtime = ent->curstate.animtime;
else
ph->animtime = cl.time;
}
/*
@@ -219,7 +222,7 @@ void CL_UpdateLatchedVars( cl_entity_t *ent )
if( ent->curstate.sequence != ent->prevstate.sequence )
{
memcpy( ent->prevstate.blending, ent->latched.prevseqblending, sizeof( ent->prevstate.blending ));
memcpy( ent->latched.prevseqblending, ent->prevstate.blending, sizeof( ent->latched.prevseqblending ));
ent->latched.prevsequence = ent->prevstate.sequence;
ent->latched.sequencetime = ent->curstate.animtime;
}
@@ -310,7 +313,7 @@ void CL_ProcessEntityUpdate( cl_entity_t *ent )
if( FBitSet( ent->curstate.entityType, ENTITY_NORMAL ))
COM_NormalizeAngles( ent->curstate.angles );
parametric = CL_ParametricMove( ent );
parametric = ent->curstate.starttime != 0.0f && ent->curstate.impacttime != 0.0f;
// allow interpolation on bmodels too
if( ent->model && ent->model->type == mod_brush )
@@ -349,7 +352,7 @@ find two timestamps
qboolean CL_FindInterpolationUpdates( cl_entity_t *ent, float targettime, position_history_t **ph0, position_history_t **ph1 )
{
qboolean extrapolate = true;
int i, i0, i1, imod;
uint i, i0, i1, imod;
float at;
imod = ent->current_position;
@@ -406,7 +409,7 @@ void CL_PureOrigin( cl_entity_t *ent, float t, vec3_t outorigin, vec3_t outangle
VectorSubtract( ph0->origin, ph1->origin, delta );
if( t0 != t1 )
if( !Q_equal( t0, t1 ))
frac = ( t - t1 ) / ( t0 - t1 );
else frac = 1.0f;
@@ -486,7 +489,9 @@ int CL_InterpolateModel( cl_entity_t *e )
return 0;
}
if( t2 == t1 )
// HACKHACK: workaround buggy position history animtime
// going backward sometimes
if( Q_equal( t2, t1 ) || t2 < t1 )
{
VectorCopy( ph0->origin, e->origin );
VectorCopy( ph0->angles, e->angles );
@@ -978,8 +983,13 @@ qboolean CL_AddVisibleEntity( cl_entity_t *ent, int entityType )
}
// don't add the player in firstperson mode
if( RP_LOCALCLIENT( ent ) && !CL_IsThirdPerson( ) && ( ent->index == cl.viewentity ))
return false;
if( RP_LOCALCLIENT( ent ))
{
cl.local.apply_effects = true;
if( !CL_IsThirdPerson( ) && ( ent->index == cl.viewentity ))
return false;
}
if( entityType == ET_BEAM )
{
@@ -993,12 +1003,8 @@ qboolean CL_AddVisibleEntity( cl_entity_t *ent, int entityType )
// because pTemp->entity.curstate.effects
// is already occupied by FTENT_FLICKER
if( entityType != ET_TEMPENTITY )
if( entityType != ET_TEMPENTITY && !RP_LOCALCLIENT( ent ) )
{
// no reason to do it twice
if( RP_LOCALCLIENT( ent ))
cl.local.apply_effects = false;
// apply client-side effects
CL_AddEntityEffects( ent );
@@ -1050,7 +1056,6 @@ void CL_LinkPlayers( frame_t *frame )
// apply muzzleflash to weaponmodel
if( ent && FBitSet( ent->curstate.effects, EF_MUZZLEFLASH ))
SetBits( clgame.viewent.curstate.effects, EF_MUZZLEFLASH );
cl.local.apply_effects = true;
// check all the clients but add only visible
for( i = 0, state = frame->playerstate; i < MAX_CLIENTS; i++, state++ )

View File

@@ -1744,6 +1744,29 @@ static int GAME_EXPORT pfnClientCmd( const char *szCmdString )
return 1;
}
/*
=============
pfnFilteredClientCmd
=============
*/
static int GAME_EXPORT pfnFilteredClientCmd( const char *szCmdString )
{
if( !COM_CheckString( szCmdString ))
return 0;
// a1ba:
// there should be stufftext validator, that checks
// hardcoded commands and disallows them before passing to
// filtered buffer, returning 0
// I've replaced it by hooking potentially exploitable
// commands and variables(motd_write, motdfile, etc) in client interfaces
Cbuf_AddFilteredText( szCmdString );
Cbuf_AddFilteredText( "\n" );
return 1;
}
/*
=============
pfnGetPlayerInfo
@@ -2276,9 +2299,9 @@ static void GAME_EXPORT pfnKillEvents( int entnum, const char *eventname )
int i;
event_state_t *es;
event_info_t *ei;
int eventIndex = CL_EventIndex( eventname );
word eventIndex = CL_EventIndex( eventname );
if( eventIndex < 0 || eventIndex >= MAX_EVENTS )
if( eventIndex >= MAX_EVENTS )
return;
if( entnum < 0 || entnum > clgame.maxEntities )
@@ -2906,15 +2929,16 @@ pfnDrawString
*/
static int GAME_EXPORT pfnDrawString( int x, int y, const char *str, int r, int g, int b )
{
int iWidth = 0;
Con_UtfProcessChar(0);
// draw the string until we hit the null character or a newline character
for ( ; *str != 0 && *str != '\n'; str++ )
{
x += pfnVGUI2DrawCharacterAdditive( x, y, (unsigned char)*str, r, g, b, 0 );
iWidth += pfnVGUI2DrawCharacterAdditive( x + iWidth, y, (unsigned char)*str, r, g, b, 0 );
}
return x;
return iWidth;
}
/*
@@ -2929,8 +2953,7 @@ static int GAME_EXPORT pfnDrawStringReverse( int x, int y, const char *str, int
char *szIt;
for( szIt = (char*)str; *szIt != 0; szIt++ )
x -= clgame.scrInfo.charWidths[ (unsigned char) *szIt ];
pfnDrawString( x, y, str, r, g, b );
return x;
return pfnDrawString( x, y, str, r, g, b );
}
/*
@@ -3066,7 +3089,7 @@ char *pfnParseFile( char *data, char *token )
{
char *out;
out = _COM_ParseFileSafe( data, token, INT_MAX, PFILE_HANDLECOLON, NULL );
out = _COM_ParseFileSafe( data, token, PFILE_TOKEN_MAX_LENGTH, PFILE_HANDLECOLON, NULL );
return out;
}
@@ -3155,16 +3178,7 @@ convert world coordinates (x,y,z) into screen (x, y)
*/
int TriWorldToScreen( const float *world, float *screen )
{
int retval;
retval = ref.dllFuncs.WorldToScreen( world, screen );
screen[0] = 0.5f * screen[0] * (float)clgame.viewport[2];
screen[1] = -0.5f * screen[1] * (float)clgame.viewport[3];
screen[0] += 0.5f * (float)clgame.viewport[2];
screen[1] += 0.5f * (float)clgame.viewport[3];
return retval;
return ref.dllFuncs.WorldToScreen( world, screen );
}
/*
@@ -3878,10 +3892,7 @@ static cl_enginefunc_t gEngfuncs =
pfnGetAppID,
Cmd_AliasGetList,
pfnVguiWrap2_GetMouseDelta,
// HACKHACK: added it here so it wouldn't cause overflow or segfault
// TODO: itself client command filtering is not implemented yet
pfnClientCmd
pfnFilteredClientCmd
};
void CL_UnloadProgs( void )
@@ -3903,7 +3914,6 @@ void CL_UnloadProgs( void )
Cvar_FullSet( "host_clientloaded", "0", FCVAR_READ_ONLY );
COM_FreeLibrary( clgame.hInstance );
VGui_Shutdown();
Mem_FreePool( &cls.mempool );
Mem_FreePool( &clgame.mempool );
memset( &clgame, 0, sizeof( clgame ));
@@ -3947,7 +3957,7 @@ qboolean CL_LoadProgs( const char *name )
#else
// this doesn't mean other platforms uses SDL2 in any case
// it just helps input code to stay platform-independent
clgame.client_dll_uses_sdl = false;
clgame.client_dll_uses_sdl = true;
#endif
clgame.hInstance = COM_LoadLibrary( name, false, false );
@@ -3964,7 +3974,17 @@ qboolean CL_LoadProgs( const char *name )
// trying to fill interface now
GetClientAPI( &clgame.dllFuncs );
}
else if(( GetClientAPI = (void *)COM_GetProcAddress( clgame.hInstance, "F" )) != NULL )
{
Con_Reportf( "CL_LoadProgs: found single callback export (secured client dlls)\n" );
// trying to fill interface now
CL_GetSecuredClientAPI( GetClientAPI );
}
if ( GetClientAPI != NULL )
{
// check critical functions again
for( func = cdll_exports; func && func->name; func++ )
{

View File

@@ -417,6 +417,8 @@ static void UI_ConvertGameInfo( GAMEINFO *out, gameinfo_t *in )
out->flags |= GFL_NOMODELS;
if( in->noskills )
out->flags |= GFL_NOSKILLS;
if( in->render_picbutton_text )
out->flags |= GFL_RENDER_PICBUTTON_TEXT;
}
static qboolean PIC_Scissor( float *x, float *y, float *width, float *height, float *u0, float *v0, float *u1, float *v1 )
@@ -1233,7 +1235,8 @@ static ui_extendedfuncs_t gExtendedfuncs =
Con_UtfMoveRight,
pfnGetRenderers,
Sys_DoubleTime,
_COM_ParseFileSafe
_COM_ParseFileSafe,
NET_AdrToString
};
void UI_UnloadProgs( void )

View File

@@ -243,7 +243,7 @@ void CL_SignonReply( void )
float CL_LerpInterval( void )
{
return max( cl_interp->value, 1.f / cl_updaterate->value );
return Q_max( cl_interp->value, 1.f / cl_updaterate->value );
}
/*
@@ -296,7 +296,7 @@ static float CL_LerpPoint( void )
if( cl_interp->value > 0.001f )
{
// manual lerp value (goldsrc mode)
float td = max( 0.f, cl.time - cl.mtime[0] );
float td = Q_max( 0.f, cl.time - cl.mtime[0] );
frac = td / CL_LerpInterval();
}
else if( server_frametime > 0.001f )
@@ -528,7 +528,7 @@ qboolean CL_ProcessShowTexturesCmds( usercmd_t *cmd )
if( released & ( IN_RIGHT|IN_MOVERIGHT ))
Cvar_SetValue( "r_showtextures", gl_showtextures->value + 1 );
if( released & ( IN_LEFT|IN_MOVELEFT ))
Cvar_SetValue( "r_showtextures", max( 1, gl_showtextures->value - 1 ));
Cvar_SetValue( "r_showtextures", Q_max( 1, gl_showtextures->value - 1 ));
oldbuttons = cmd->buttons;
return true;
@@ -1284,6 +1284,7 @@ void CL_Rcon_f( void )
{
char message[1024];
netadr_t to;
string command;
int i;
if( !COM_CheckString( rcon_client_password->string ))
@@ -1306,7 +1307,8 @@ void CL_Rcon_f( void )
for( i = 1; i < Cmd_Argc(); i++ )
{
Q_strcat( message, Cmd_Argv( i ));
Cmd_Escape( command, Cmd_Argv( i ), sizeof( command ));
Q_strcat( message, command );
Q_strcat( message, " " );
}
@@ -1561,7 +1563,6 @@ void CL_LocalServers_f( void )
Con_Printf( "Scanning for servers on the local network area...\n" );
NET_Config( true ); // allow remote
cls.legacyservercount = 0;
// send a broadcast packet
adr.type = NA_BROADCAST;
@@ -1589,7 +1590,6 @@ void CL_InternetServers_f( void )
Info_SetValueForKey( info, "gamedir", GI->gamefolder, remaining );
Info_SetValueForKey( info, "clver", XASH_VERSION, remaining ); // let master know about client version
// Info_SetValueForKey( info, "nat", cl_nat->string, remaining );
cls.legacyservercount = 0;
cls.internetservers_wait = NET_SendToMasters( NS_CLIENT, sizeof( MS_SCAN_REQUEST ) + Q_strlen( info ), fullquery );
cls.internetservers_pending = true;
@@ -1720,8 +1720,6 @@ void CL_ParseStatusMessage( netadr_t from, sizebuf_t *msg )
{
Netchan_OutOfBandPrint( NS_CLIENT, from, "info %i", PROTOCOL_LEGACY_VERSION );
Con_Printf( "^1Server^7: %s, Info: %s\n", NET_AdrToString( from ), infostring );
if( cls.legacyservercount < MAX_LEGACY_SERVERS )
cls.legacyservers[cls.legacyservercount++] = from;
return;
}
@@ -1731,14 +1729,10 @@ void CL_ParseStatusMessage( netadr_t from, sizebuf_t *msg )
return; // unsupported proto
}
for( i = 0; i < cls.legacyservercount; i++ )
if( !COM_CheckString( Info_ValueForKey( infostring, "p" )))
{
if( NET_CompareAdr( cls.legacyservers[i], from ) )
{
Info_SetValueForKey( infostring, "legacy", "1", sizeof( infostring ) );
Con_Print("Legacy: ");
break;
}
Info_SetValueForKey( infostring, "legacy", "1", sizeof( infostring ) );
Con_Print("Legacy: ");
}
// more info about servers
@@ -2351,11 +2345,10 @@ Replace the displayed name for some resources
*/
const char *CL_CleanFileName( const char *filename )
{
const char *pfilename = filename;
if( COM_CheckString( filename ) && filename[0] == '!' )
pfilename = "customization";
return pfilename;
return "customization";
return filename;
}
@@ -2820,13 +2813,13 @@ void CL_InitLocal( void )
cl_nodelta = Cvar_Get ("cl_nodelta", "0", 0, "disable delta-compression for server messages" );
cl_idealpitchscale = Cvar_Get( "cl_idealpitchscale", "0.8", 0, "how much to look up/down slopes and stairs when not using freelook" );
cl_solid_players = Cvar_Get( "cl_solid_players", "1", 0, "Make all players not solid (can't traceline them)" );
cl_interp = Cvar_Get( "ex_interp", "0.1", FCVAR_ARCHIVE, "Interpolate object positions starting this many seconds in past" );
cl_interp = Cvar_Get( "ex_interp", "0.1", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "Interpolate object positions starting this many seconds in past" );
cl_timeout = Cvar_Get( "cl_timeout", "60", 0, "connect timeout (in-seconds)" );
cl_charset = Cvar_Get( "cl_charset", "utf-8", FCVAR_ARCHIVE, "1-byte charset to use (iconv style)" );
hud_utf8 = Cvar_Get( "hud_utf8", "0", FCVAR_ARCHIVE, "Use utf-8 encoding for hud text" );
rcon_client_password = Cvar_Get( "rcon_password", "", 0, "remote control client password" );
rcon_address = Cvar_Get( "rcon_address", "", 0, "remote control address" );
rcon_client_password = Cvar_Get( "rcon_password", "", FCVAR_PRIVILEGED, "remote control client password" );
rcon_address = Cvar_Get( "rcon_address", "", FCVAR_PRIVILEGED, "remote control address" );
cl_trace_messages = Cvar_Get( "cl_trace_messages", "0", FCVAR_ARCHIVE|FCVAR_CHEAT, "enable message names tracing (good for developers)");
@@ -2837,7 +2830,7 @@ void CL_InitLocal( void )
cl_updaterate = Cvar_Get( "cl_updaterate", "20", FCVAR_USERINFO|FCVAR_ARCHIVE, "refresh rate of server messages" );
cl_dlmax = Cvar_Get( "cl_dlmax", "0", FCVAR_USERINFO|FCVAR_ARCHIVE, "max allowed outcoming fragment size" );
cl_upmax = Cvar_Get( "cl_upmax", "1200", FCVAR_ARCHIVE, "max allowed incoming fragment size" );
rate = Cvar_Get( "rate", "3500", FCVAR_USERINFO|FCVAR_ARCHIVE, "player network rate" );
rate = Cvar_Get( "rate", "3500", FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_FILTERABLE, "player network rate" );
topcolor = Cvar_Get( "topcolor", "0", FCVAR_USERINFO|FCVAR_ARCHIVE, "player top color" );
bottomcolor = Cvar_Get( "bottomcolor", "0", FCVAR_USERINFO|FCVAR_ARCHIVE, "player bottom color" );
cl_lw = Cvar_Get( "cl_lw", "1", FCVAR_ARCHIVE|FCVAR_USERINFO, "enable client weapon predicting" );
@@ -2876,7 +2869,7 @@ void CL_InitLocal( void )
Cmd_AddCommand ("give", NULL, "give specified item or weapon" );
Cmd_AddCommand ("drop", NULL, "drop current/specified item or weapon" );
Cmd_AddCommand ("gametitle", NULL, "show game logo" );
Cmd_AddCommand( "kill", NULL, "die instantly" );
Cmd_AddRestrictedCommand ("kill", NULL, "die instantly" );
Cmd_AddCommand ("god", NULL, "enable godmode" );
Cmd_AddCommand ("fov", NULL, "set client field of view" );
Cmd_AddCommand ("log", NULL, "logging server events" );
@@ -2889,8 +2882,8 @@ void CL_InitLocal( void )
Cmd_AddCommand ("mp3", CL_PlayCDTrack_f, "Play mp3-track (based on virtual cd-player)" );
Cmd_AddCommand ("waveplaylen", CL_WavePlayLen_f, "Get approximate length of wave file");
Cmd_AddCommand ("setinfo", CL_SetInfo_f, "examine or change the userinfo string (alias of userinfo)" );
Cmd_AddCommand ("userinfo", CL_SetInfo_f, "examine or change the userinfo string (alias of setinfo)" );
Cmd_AddRestrictedCommand ("setinfo", CL_SetInfo_f, "examine or change the userinfo string (alias of userinfo)" );
Cmd_AddRestrictedCommand ("userinfo", CL_SetInfo_f, "examine or change the userinfo string (alias of setinfo)" );
Cmd_AddCommand ("physinfo", CL_Physinfo_f, "print current client physinfo" );
Cmd_AddCommand ("disconnect", CL_Disconnect_f, "disconnect from server" );
Cmd_AddCommand ("record", CL_Record_f, "record a demo" );
@@ -2909,8 +2902,8 @@ void CL_InitLocal( void )
Cmd_AddCommand ("fullserverinfo", CL_FullServerinfo_f, "sent by server when serverinfo changes" );
Cmd_AddCommand ("upload", CL_BeginUpload_f, "uploading file to the server" );
Cmd_AddCommand ("quit", CL_Quit_f, "quit from game" );
Cmd_AddCommand ("exit", CL_Quit_f, "quit from game" );
Cmd_AddRestrictedCommand ("quit", CL_Quit_f, "quit from game" );
Cmd_AddRestrictedCommand ("exit", CL_Quit_f, "quit from game" );
Cmd_AddCommand ("screenshot", CL_ScreenShot_f, "takes a screenshot of the next rendered frame" );
Cmd_AddCommand ("snapshot", CL_SnapShot_f, "takes a snapshot of the next rendered frame" );
@@ -3076,7 +3069,6 @@ void CL_Init( void )
MSG_Init( &cls.datagram, "cls.datagram", cls.datagram_buf, sizeof( cls.datagram_buf ));
// IN_TouchInit();
Con_LoadHistory();
COM_GetCommonLibraryPath( LIBRARY_CLIENT, libpath, sizeof( libpath ));
@@ -3097,10 +3089,6 @@ CL_Shutdown
*/
void CL_Shutdown( void )
{
// already freed
if( !cls.initialized ) return;
cls.initialized = false;
Con_Printf( "CL_Shutdown()\n" );
if( !host.crashed )
@@ -3117,6 +3105,9 @@ void CL_Shutdown( void )
Mobile_Shutdown ();
SCR_Shutdown ();
CL_UnloadProgs ();
cls.initialized = false;
VGui_Shutdown();
FS_Delete( "demoheader.tmp" ); // remove tmp file
SCR_FreeCinematic (); // release AVI's *after* client.dll because custom renderer may use them
@@ -3124,4 +3115,5 @@ void CL_Shutdown( void )
R_Shutdown ();
Con_Shutdown ();
}

View File

@@ -93,6 +93,15 @@ static void *pfnGetNativeObject( const char *obj )
return Platform_GetNativeObject( obj );
}
static void pfnTouch_HideButtons( const char *name, byte state )
{
Touch_HideButtons( name, state, true );
}
static void pfnTouch_RemoveButton( const char *name )
{
Touch_RemoveButton( name, true );
}
static mobile_engfuncs_t gpMobileEngfuncs =
{
@@ -101,9 +110,9 @@ static mobile_engfuncs_t gpMobileEngfuncs =
pfnEnableTextInput,
Touch_AddClientButton,
Touch_AddDefaultButton,
Touch_HideButtons,
Touch_RemoveButton,
(void*)Touch_SetClientOnly,
pfnTouch_HideButtons,
pfnTouch_RemoveButton,
Touch_SetClientOnly,
Touch_ResetDefaultButtons,
pfnDrawScaledCharacter,
Sys_Warn,
@@ -125,8 +134,8 @@ qboolean Mobile_Init( void )
success = true;
Cmd_AddCommand( "vibrate", (xcommand_t)Vibrate_f, "Vibrate for specified time");
vibration_length = Cvar_Get( "vibration_length", "1.0", FCVAR_ARCHIVE, "Vibration length");
vibration_enable = Cvar_Get( "vibration_enable", "1", FCVAR_ARCHIVE, "Enable vibration");
vibration_length = Cvar_Get( "vibration_length", "1.0", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "Vibration length");
vibration_enable = Cvar_Get( "vibration_enable", "1", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "Enable vibration");
return success;
}

View File

@@ -484,6 +484,8 @@ void CL_BatchResourceRequest( qboolean initialize )
switch( p->type )
{
case t_sound:
case t_model:
case t_eventscript:
if( !CL_CheckFile( &msg, p ))
break;
CL_MoveToOnHandList( p );
@@ -491,11 +493,6 @@ void CL_BatchResourceRequest( qboolean initialize )
case t_skin:
CL_MoveToOnHandList( p );
break;
case t_model:
if( !CL_CheckFile( &msg, p ))
break;
CL_MoveToOnHandList( p );
break;
case t_decal:
if( !HPAK_GetDataPointer( CUSTOM_RES_PATH, p, NULL, NULL ))
{
@@ -520,11 +517,6 @@ void CL_BatchResourceRequest( qboolean initialize )
break;
CL_MoveToOnHandList( p );
break;
case t_eventscript:
if( !CL_CheckFile( &msg, p ))
break;
CL_MoveToOnHandList( p );
break;
case t_world:
ASSERT( 0 );
break;
@@ -1322,30 +1314,6 @@ void CL_RegisterUserMessage( sizebuf_t *msg )
CL_LinkUserMessage( pszName, svc_num, size );
}
/*
================
CL_RegisterUserMessage
register new user message or update existing
================
*/
/*
void CL_LegacyRegisterUserMessage( sizebuf_t *msg )
{
char *pszName;
int svc_num, size;
svc_num = MSG_ReadByte( msg );
size = MSG_ReadByte( msg );
pszName = MSG_ReadString( msg );
// important stuff
if( size == 0xFF ) size = -1;
svc_num = bound( 0, svc_num, 255 );
CL_LinkUserMessage( pszName, svc_num, size );
}
*/
/*
================
CL_UpdateUserinfo
@@ -1819,7 +1787,7 @@ void CL_ParseScreenShake( sizebuf_t *msg )
clgame.shake.amplitude = (float)(word)MSG_ReadShort( msg ) * (1.0f / (float)(1<<12));
clgame.shake.duration = (float)(word)MSG_ReadShort( msg ) * (1.0f / (float)(1<<12));
clgame.shake.frequency = (float)(word)MSG_ReadShort( msg ) * (1.0f / (float)(1<<8));
clgame.shake.time = cl.time + max( clgame.shake.duration, 0.01f );
clgame.shake.time = cl.time + Q_max( clgame.shake.duration, 0.01f );
clgame.shake.next_shake = 0.0f; // apply immediately
}
@@ -1883,46 +1851,42 @@ Find the client cvar value
and sent it back to the server
==============
*/
void CL_ParseCvarValue( sizebuf_t *msg )
void CL_ParseCvarValue( sizebuf_t *msg, const qboolean ext )
{
const char *cvarName = MSG_ReadString( msg );
convar_t *cvar = Cvar_FindVar( cvarName );
const char *cvarName, *response;
convar_t *cvar;
int requestID;
// build the answer
MSG_BeginClientCmd( &cls.netchan.message, clc_requestcvarvalue );
MSG_WriteString( &cls.netchan.message, cvar ? cvar->string : "Not Found" );
}
if( ext )
requestID = MSG_ReadLong( msg );
/*
==============
CL_ParseCvarValue2
Find the client cvar value
and sent it back to the server
==============
*/
void CL_ParseCvarValue2( sizebuf_t *msg )
{
int requestID = MSG_ReadLong( msg );
const char *cvarName = MSG_ReadString( msg );
convar_t *cvar = Cvar_FindVar( cvarName );
// build the answer
MSG_BeginClientCmd( &cls.netchan.message, clc_requestcvarvalue2 );
MSG_WriteLong( &cls.netchan.message, requestID );
MSG_WriteString( &cls.netchan.message, cvarName );
cvarName = MSG_ReadString( msg );
cvar = Cvar_FindVar( cvarName );
if( cvar )
{
// cheater can change value ignoring Cvar_Set so we responce incorrect value
if( cvar->value != Q_atof( cvar->string ))
MSG_WriteString( &cls.netchan.message, va( "%s (%g)", cvar->string, cvar->value ));
else MSG_WriteString( &cls.netchan.message, cvar->string );
if( cvar->flags & FCVAR_PRIVILEGED )
response = "CVAR is privileged";
else if( cvar->flags & FCVAR_SERVER )
response = "CVAR is server-only";
else if( cvar->flags & FCVAR_PROTECTED )
response = "CVAR is protected";
else
response = cvar->string;
}
else response = "Bad CVAR request";
if( ext )
{
MSG_BeginClientCmd( &cls.netchan.message, clc_requestcvarvalue2 );
MSG_WriteLong( &cls.netchan.message, requestID );
MSG_WriteString( &cls.netchan.message, cvarName );
}
else
{
MSG_WriteString( &cls.netchan.message, "Not Found" );
MSG_BeginClientCmd( &cls.netchan.message, clc_requestcvarvalue );
}
MSG_WriteString( &cls.netchan.message, response );
}
/*
@@ -2226,11 +2190,11 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
case svc_stufftext:
s = MSG_ReadString( msg );
#ifdef HACKS_RELATED_HLMODS
// dsiable Cry Of Fear antisave protection
// disable Cry Of Fear antisave protection
if( !Q_strnicmp( s, "disconnect", 10 ) && cls.signon != SIGNONS )
break; // too early
#endif
Cbuf_AddText( s );
Cbuf_AddFilteredText( s );
break;
case svc_setangle:
CL_ParseSetAngle( msg );
@@ -2376,10 +2340,10 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
CL_ParseResLocation( msg );
break;
case svc_querycvarvalue:
CL_ParseCvarValue( msg );
CL_ParseCvarValue( msg, false );
break;
case svc_querycvarvalue2:
CL_ParseCvarValue2( msg );
CL_ParseCvarValue( msg, true );
break;
case svc_exec:
CL_ParseExec( msg );
@@ -2417,14 +2381,11 @@ CL_ParseBaseline
void CL_LegacyParseBaseline( sizebuf_t *msg )
{
int i, newnum;
entity_state_t nullstate;
qboolean player;
cl_entity_t *ent;
Delta_InitClient (); // finalize client delta's
memset( &nullstate, 0, sizeof( nullstate ));
newnum = MSG_ReadWord( msg );
player = CL_IsPlayerIndex( newnum );
@@ -2994,13 +2955,13 @@ void CL_ParseLegacyServerMessage( sizebuf_t *msg, qboolean normal_message )
case svc_stufftext:
s = MSG_ReadString( msg );
#ifdef HACKS_RELATED_HLMODS
// dsiable Cry Of Fear antisave protection
// disable Cry Of Fear antisave protection
if( !Q_strnicmp( s, "disconnect", 10 ) && cls.signon != SIGNONS )
break; // too early
#endif
Con_Reportf( "Stufftext: %s", s );
Cbuf_AddText( s );
Cbuf_AddFilteredText( s );
break;
case svc_setangle:
CL_ParseSetAngle( msg );
@@ -3166,10 +3127,10 @@ void CL_ParseLegacyServerMessage( sizebuf_t *msg, qboolean normal_message )
CL_ParseResLocation( msg );
break;
case svc_querycvarvalue:
CL_ParseCvarValue( msg );
CL_ParseCvarValue( msg, false );
break;
case svc_querycvarvalue2:
CL_ParseCvarValue2( msg );
CL_ParseCvarValue( msg, true );
break;
default:
CL_ParseUserMessage( msg, cmd );

View File

@@ -992,7 +992,6 @@ void CL_SetupPMove( playermove_t *pmove, local_state_t *from, usercmd_t *ucmd, q
pmove->flFallVelocity = ps->flFallVelocity;
pmove->flSwimTime = cd->flSwimTime;
VectorCopy( cd->punchangle, pmove->punchangle );
pmove->flSwimTime = cd->flSwimTime;
pmove->flNextPrimaryAttack = 0.0f; // not used by PM_ code
pmove->effects = ps->effects;
pmove->flags = cd->flags;

View File

@@ -825,6 +825,9 @@ CL_QuakeStuffText
void CL_QuakeStuffText( const char *text )
{
Q_strncat( cmd_buf, text, sizeof( cmd_buf ));
// a1ba: didn't filtered, anyway quake protocol
// only supported for demos, not network games
Cbuf_AddText( text );
}

View File

@@ -117,7 +117,7 @@ static void R_EnvShot( const float *vieworg, const char *name, qboolean skyshot,
else cls.scrshot_action = scrshot_envshot;
// catch negative values
cls.envshot_viewsize = max( 0, shotsize );
cls.envshot_viewsize = Q_max( 0, shotsize );
}
/*

View File

@@ -781,6 +781,7 @@ SCR_VidInit
*/
void SCR_VidInit( void )
{
string libpath;
if( !ref.initialized ) // don't call VidInit too soon
return;
@@ -795,7 +796,8 @@ void SCR_VidInit( void )
gameui.globals->scrHeight = refState.height;
}
VGui_Startup( NULL, refState.width, refState.height ); // initialized already, so pass NULL
COM_GetCommonLibraryPath( LIBRARY_CLIENT, libpath, sizeof( libpath ));
VGui_Startup( libpath, refState.width, refState.height );
CL_ClearSpriteTextures(); // now all hud sprites are invalid

View File

@@ -0,0 +1,460 @@
/*
cl_securedstub.c - secured client dll stub
Copyright (C) 2022 FWGS
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"
typedef struct cldll_func_src_s
{
int (*pfnInitialize)( cl_enginefunc_t *pEnginefuncs, int iVersion );
void (*pfnInit)( void );
int (*pfnVidInit)( void );
int (*pfnRedraw)( float flTime, int intermission );
int (*pfnUpdateClientData)( client_data_t *cdata, float flTime );
void (*pfnReset)( void );
void (*pfnPlayerMove)( struct playermove_s *ppmove, int server );
void (*pfnPlayerMoveInit)( struct playermove_s *ppmove );
char (*pfnPlayerMoveTexture)( char *name );
void (*IN_ActivateMouse)( void );
void (*IN_DeactivateMouse)( void );
void (*IN_MouseEvent)( int mstate );
void (*IN_ClearStates)( void );
void (*IN_Accumulate)( void );
void (*CL_CreateMove)( float frametime, struct usercmd_s *cmd, int active );
int (*CL_IsThirdPerson)( void );
void (*CL_CameraOffset)( float *ofs ); // unused
void *(*KB_Find)( const char *name );
void (*CAM_Think)( void ); // camera stuff
void (*pfnCalcRefdef)( ref_params_t *pparams );
int (*pfnAddEntity)( int type, cl_entity_t *ent, const char *modelname );
void (*pfnCreateEntities)( void );
void (*pfnDrawNormalTriangles)( void );
void (*pfnDrawTransparentTriangles)( void );
void (*pfnStudioEvent)( const struct mstudioevent_s *event, const cl_entity_t *entity );
void (*pfnPostRunCmd)( struct local_state_s *from, struct local_state_s *to, usercmd_t *cmd, int runfuncs, double time, unsigned int random_seed );
void (*pfnShutdown)( void );
void (*pfnTxferLocalOverrides)( entity_state_t *state, const clientdata_t *client );
void (*pfnProcessPlayerState)( entity_state_t *dst, const entity_state_t *src );
void (*pfnTxferPredictionData)( entity_state_t *ps, const entity_state_t *pps, clientdata_t *pcd, const clientdata_t *ppcd, weapon_data_t *wd, const weapon_data_t *pwd );
void (*pfnDemo_ReadBuffer)( int size, byte *buffer );
int (*pfnConnectionlessPacket)( const struct netadr_s *net_from, const char *args, char *buffer, int *size );
int (*pfnGetHullBounds)( int hullnumber, float *mins, float *maxs );
void (*pfnFrame)( double time );
int (*pfnKey_Event)( int eventcode, int keynum, const char *pszCurrentBinding );
void (*pfnTempEntUpdate)( double frametime, double client_time, double cl_gravity, struct tempent_s **ppTempEntFree, struct tempent_s **ppTempEntActive, int ( *Callback_AddVisibleEntity )( cl_entity_t *pEntity ), void ( *Callback_TempEntPlaySound )( struct tempent_s *pTemp, float damp ));
cl_entity_t *(*pfnGetUserEntity)( int index );
void (*pfnVoiceStatus)( int entindex, qboolean bTalking );
void (*pfnDirectorMessage)( int iSize, void *pbuf );
int (*pfnGetStudioModelInterface)( int version, struct r_studio_interface_s **ppinterface, struct engine_studio_api_s *pstudio );
void (*pfnChatInputPosition)( int *x, int *y );
int (*pfnGetPlayerTeam)( int iPlayer );
void *(*pfnClientFactory)( void );
} cldll_func_src_t;
typedef struct cldll_func_dst_s
{
void (*pfnInitialize)( cl_enginefunc_t **pEnginefuncs, int *iVersion );
void (*pfnInit)( void );
void (*pfnVidInit)( void );
void (*pfnRedraw)( float *flTime, int *intermission );
void (*pfnUpdateClientData)( client_data_t **cdata, float *flTime );
void (*pfnReset)( void );
void (*pfnPlayerMove)( struct playermove_s **ppmove, int *server );
void (*pfnPlayerMoveInit)( struct playermove_s **ppmove );
void (*pfnPlayerMoveTexture)( char **name );
void (*IN_ActivateMouse)( void );
void (*IN_DeactivateMouse)( void );
void (*IN_MouseEvent)( int *mstate );
void (*IN_ClearStates)( void );
void (*IN_Accumulate)( void );
void (*CL_CreateMove)( float *frametime, struct usercmd_s **cmd, int *active );
void (*CL_IsThirdPerson)( void );
void (*CL_CameraOffset)( float **ofs );
void (*KB_Find)( const char **name );
void (*CAM_Think)( void );
void (*pfnCalcRefdef)( ref_params_t **pparams );
void (*pfnAddEntity)( int *type, cl_entity_t **ent, const char **modelname );
void (*pfnCreateEntities)( void );
void (*pfnDrawNormalTriangles)( void );
void (*pfnDrawTransparentTriangles)( void );
void (*pfnStudioEvent)( const struct mstudioevent_s **event, const cl_entity_t **entity );
void (*pfnPostRunCmd)( struct local_state_s **from, struct local_state_s **to, usercmd_t **cmd, int *runfuncs, double *time, unsigned int *random_seed );
void (*pfnShutdown)( void );
void (*pfnTxferLocalOverrides)( entity_state_t **state, const clientdata_t **client );
void (*pfnProcessPlayerState)( entity_state_t **dst, const entity_state_t **src );
void (*pfnTxferPredictionData)( entity_state_t **ps, const entity_state_t **pps, clientdata_t **pcd, const clientdata_t **ppcd, weapon_data_t **wd, const weapon_data_t **pwd );
void (*pfnDemo_ReadBuffer)( int *size, byte **buffer );
void (*pfnConnectionlessPacket)( const struct netadr_s **net_from, const char **args, char **buffer, int **size );
void (*pfnGetHullBounds)( int *hullnumber, float **mins, float **maxs );
void (*pfnFrame)( double *time );
void (*pfnKey_Event)( int *eventcode, int *keynum, const char **pszCurrentBinding );
void (*pfnTempEntUpdate)( double *frametime, double *client_time, double *cl_gravity, struct tempent_s ***ppTempEntFree, struct tempent_s ***ppTempEntActive, int ( **Callback_AddVisibleEntity )( cl_entity_t *pEntity ), void ( **Callback_TempEntPlaySound )( struct tempent_s *pTemp, float damp ));
void (*pfnGetUserEntity)( int *index );
void (*pfnVoiceStatus)( int *entindex, qboolean *bTalking );
void (*pfnDirectorMessage)( int *iSize, void **pbuf );
void (*pfnGetStudioModelInterface)( int *version, struct r_studio_interface_s ***ppinterface, struct engine_studio_api_s **pstudio );
void (*pfnChatInputPosition)( int **x, int **y );
void (*pfnGetPlayerTeam)( int *iPlayer );
} cldll_func_dst_t;
struct cl_enginefunc_dst_s;
struct modshelpers_s;
struct modchelpers_s;
struct engdata_s;
typedef struct modfuncs_s
{
void (*m_pfnLoadMod)( char *pchModule );
void (*m_pfnCloseMod)( void );
int (*m_pfnNCall)( int ijump, int cnArg, ... );
void (*m_pfnGetClDstAddrs)( cldll_func_dst_t *pcldstAddrs );
void (*m_pfnGetEngDstAddrs)( struct cl_enginefunc_dst_s *pengdstAddrs );
void (*m_pfnModuleLoaded)( void );
void (*m_pfnProcessOutgoingNet)( struct netchan_s *pchan, struct sizebuf_s *psizebuf );
qboolean (*m_pfnProcessIncomingNet)( struct netchan_s *pchan, struct sizebuf_s *psizebuf );
void (*m_pfnTextureLoad)( char *pszName, int dxWidth, int dyHeight, char *pbData );
void (*m_pfnModelLoad)( struct model_s *pmodel, void *pvBuf );
void (*m_pfnFrameBegin)( void );
void (*m_pfnFrameRender1)( void );
void (*m_pfnFrameRender2)( void );
void (*m_pfnSetModSHelpers)( struct modshelpers_s *pmodshelpers );
void (*m_pfnSetModCHelpers)( struct modchelpers_s *pmodchelpers );
void (*m_pfnSetEngData)( struct engdata_s *pengdata );
int m_nVersion;
void (*m_pfnConnectClient)( int iPlayer );
void (*m_pfnRecordIP)( unsigned int pnIP );
void (*m_pfnPlayerStatus)( unsigned char *pbData, int cbData );
void (*m_pfnSetEngineVersion)( int nVersion );
int m_nVoid2;
int m_nVoid3;
int m_nVoid4;
int m_nVoid5;
int m_nVoid6;
int m_nVoid7;
int m_nVoid8;
int m_nVoid9;
} modfuncs_t;
static void DstInitialize( cl_enginefunc_t **pEnginefuncs, int *iVersion )
{
// stub
}
static void DstInit( void )
{
// stub
}
static void DstVidInit( void )
{
// stub
}
static void DstRedraw( float *flTime, int *intermission )
{
// stub
}
static void DstUpdateClientData( client_data_t **cdata, float *flTime )
{
// stub
}
static void DstReset( void )
{
// stub
}
static void DstPlayerMove( struct playermove_s **ppmove, int *server )
{
// stub
}
static void DstPlayerMoveInit( struct playermove_s **ppmove )
{
// stub
}
static void DstPlayerMoveTexture( char **name )
{
// stub
}
static void DstIN_ActivateMouse( void )
{
// stub
}
static void DstIN_DeactivateMouse( void )
{
// stub
}
static void DstIN_MouseEvent( int *mstate )
{
// stub
}
static void DstIN_ClearStates( void )
{
// stub
}
static void DstIN_Accumulate( void )
{
// stub
}
static void DstCL_CreateMove( float *frametime, struct usercmd_s **cmd, int *active )
{
// stub
}
static void DstCL_IsThirdPerson( void )
{
// stub
}
static void DstCL_CameraOffset( float **ofs )
{
// stub
}
static void DstKB_Find( const char **name )
{
// stub
}
static void DstCAM_Think( void )
{
// stub
}
static void DstCalcRefdef( ref_params_t **pparams )
{
// stub
}
static void DstAddEntity( int *type, cl_entity_t **ent, const char **modelname )
{
// stub
}
static void DstCreateEntities( void )
{
// stub
}
static void DstDrawNormalTriangles( void )
{
// stub
}
static void DstDrawTransparentTriangles( void )
{
// stub
}
static void DstStudioEvent( const struct mstudioevent_s **event, const cl_entity_t **entity )
{
// stub
}
static void DstPostRunCmd( struct local_state_s **from, struct local_state_s **to, usercmd_t **cmd, int *runfuncs, double *time, unsigned int *random_seed )
{
// stub
}
static void DstShutdown( void )
{
// stub
}
static void DstTxferLocalOverrides( entity_state_t **state, const clientdata_t **client )
{
// stub
}
static void DstProcessPlayerState( entity_state_t **dst, const entity_state_t **src )
{
// stub
}
static void DstTxferPredictionData( entity_state_t **ps, const entity_state_t **pps, clientdata_t **pcd, const clientdata_t **ppcd, weapon_data_t **wd, const weapon_data_t **pwd )
{
// stub
}
static void DstDemo_ReadBuffer( int *size, byte **buffer )
{
// stub
}
static void DstConnectionlessPacket( const struct netadr_s **net_from, const char **args, char **buffer, int **size )
{
// stub
}
static void DstGetHullBounds( int *hullnumber, float **mins, float **maxs )
{
// stub
}
static void DstFrame( double *time )
{
// stub
}
static void DstKey_Event( int *eventcode, int *keynum, const char **pszCurrentBinding )
{
// stub
}
static void DstTempEntUpdate( double *frametime, double *client_time, double *cl_gravity, struct tempent_s ***ppTempEntFree, struct tempent_s ***ppTempEntActive, int ( **Callback_AddVisibleEntity )( cl_entity_t *pEntity ), void ( **Callback_TempEntPlaySound )( struct tempent_s *pTemp, float damp ) )
{
// stub
}
static void DstGetUserEntity( int *index )
{
// stub
}
static void DstVoiceStatus( int *entindex, qboolean *bTalking )
{
// stub
}
static void DstDirectorMessage( int *iSize, void **pbuf )
{
// stub
}
static void DstGetStudioModelInterface( int *version, struct r_studio_interface_s ***ppinterface, struct engine_studio_api_s **pstudio )
{
// stub
}
static void DstChatInputPosition( int **x, int **y )
{
// stub
}
static void DstGetPlayerTeam( int *iPlayer )
{
// stub
}
static cldll_func_dst_t cldllFuncDst =
{
DstInitialize,
DstInit,
DstVidInit,
DstRedraw,
DstUpdateClientData,
DstReset,
DstPlayerMove,
DstPlayerMoveInit,
DstPlayerMoveTexture,
DstIN_ActivateMouse,
DstIN_DeactivateMouse,
DstIN_MouseEvent,
DstIN_ClearStates,
DstIN_Accumulate,
DstCL_CreateMove,
DstCL_IsThirdPerson,
DstCL_CameraOffset,
DstKB_Find,
DstCAM_Think,
DstCalcRefdef,
DstAddEntity,
DstCreateEntities,
DstDrawNormalTriangles,
DstDrawTransparentTriangles,
DstStudioEvent,
DstPostRunCmd,
DstShutdown,
DstTxferLocalOverrides,
DstProcessPlayerState,
DstTxferPredictionData,
DstDemo_ReadBuffer,
DstConnectionlessPacket,
DstGetHullBounds,
DstFrame,
DstKey_Event,
DstTempEntUpdate,
DstGetUserEntity,
DstVoiceStatus,
DstDirectorMessage,
DstGetStudioModelInterface,
DstChatInputPosition,
DstGetPlayerTeam,
};
void CL_GetSecuredClientAPI( CL_EXPORT_FUNCS F )
{
cldll_func_src_t cldllFuncSrc = { 0 };
modfuncs_t modFuncs = { 0 };
// secured client dlls need these
*(cldll_func_dst_t **)&cldllFuncSrc.pfnVidInit = &cldllFuncDst;
*(modfuncs_t **)&cldllFuncSrc.pfnInitialize = &modFuncs;
// trying to fill interface now
F( &cldllFuncSrc );
// map exports to xash's cldll_func_t
clgame.dllFuncs.pfnInitialize = cldllFuncSrc.pfnInitialize;
clgame.dllFuncs.pfnInit = cldllFuncSrc.pfnInit;
clgame.dllFuncs.pfnVidInit = cldllFuncSrc.pfnVidInit;
clgame.dllFuncs.pfnRedraw = cldllFuncSrc.pfnRedraw;
clgame.dllFuncs.pfnUpdateClientData = cldllFuncSrc.pfnUpdateClientData;
clgame.dllFuncs.pfnReset = cldllFuncSrc.pfnReset;
clgame.dllFuncs.pfnPlayerMove = cldllFuncSrc.pfnPlayerMove;
clgame.dllFuncs.pfnPlayerMoveInit = cldllFuncSrc.pfnPlayerMoveInit;
clgame.dllFuncs.pfnPlayerMoveTexture = cldllFuncSrc.pfnPlayerMoveTexture;
clgame.dllFuncs.IN_ActivateMouse = cldllFuncSrc.IN_ActivateMouse;
clgame.dllFuncs.IN_DeactivateMouse = cldllFuncSrc.IN_DeactivateMouse;
clgame.dllFuncs.IN_MouseEvent = cldllFuncSrc.IN_MouseEvent;
clgame.dllFuncs.IN_ClearStates = cldllFuncSrc.IN_ClearStates;
clgame.dllFuncs.IN_Accumulate = cldllFuncSrc.IN_Accumulate;
clgame.dllFuncs.CL_CreateMove = cldllFuncSrc.CL_CreateMove;
clgame.dllFuncs.CL_IsThirdPerson = cldllFuncSrc.CL_IsThirdPerson;
clgame.dllFuncs.CL_CameraOffset = cldllFuncSrc.CL_CameraOffset;
clgame.dllFuncs.KB_Find = cldllFuncSrc.KB_Find;
clgame.dllFuncs.CAM_Think = cldllFuncSrc.CAM_Think;
clgame.dllFuncs.pfnCalcRefdef = cldllFuncSrc.pfnCalcRefdef;
clgame.dllFuncs.pfnAddEntity = cldllFuncSrc.pfnAddEntity;
clgame.dllFuncs.pfnCreateEntities = cldllFuncSrc.pfnCreateEntities;
clgame.dllFuncs.pfnDrawNormalTriangles = cldllFuncSrc.pfnDrawNormalTriangles;
clgame.dllFuncs.pfnDrawTransparentTriangles = cldllFuncSrc.pfnDrawTransparentTriangles;
clgame.dllFuncs.pfnStudioEvent = cldllFuncSrc.pfnStudioEvent;
clgame.dllFuncs.pfnPostRunCmd = cldllFuncSrc.pfnPostRunCmd;
clgame.dllFuncs.pfnShutdown = cldllFuncSrc.pfnShutdown;
clgame.dllFuncs.pfnTxferLocalOverrides = cldllFuncSrc.pfnTxferLocalOverrides;
clgame.dllFuncs.pfnProcessPlayerState = cldllFuncSrc.pfnProcessPlayerState;
clgame.dllFuncs.pfnTxferPredictionData = cldllFuncSrc.pfnTxferPredictionData;
clgame.dllFuncs.pfnDemo_ReadBuffer = cldllFuncSrc.pfnDemo_ReadBuffer;
clgame.dllFuncs.pfnConnectionlessPacket = cldllFuncSrc.pfnConnectionlessPacket;
clgame.dllFuncs.pfnGetHullBounds = cldllFuncSrc.pfnGetHullBounds;
clgame.dllFuncs.pfnFrame = cldllFuncSrc.pfnFrame;
clgame.dllFuncs.pfnKey_Event = cldllFuncSrc.pfnKey_Event;
clgame.dllFuncs.pfnTempEntUpdate = cldllFuncSrc.pfnTempEntUpdate;
clgame.dllFuncs.pfnGetUserEntity = cldllFuncSrc.pfnGetUserEntity;
clgame.dllFuncs.pfnVoiceStatus = cldllFuncSrc.pfnVoiceStatus;
clgame.dllFuncs.pfnDirectorMessage = cldllFuncSrc.pfnDirectorMessage;
clgame.dllFuncs.pfnGetStudioModelInterface = cldllFuncSrc.pfnGetStudioModelInterface;
clgame.dllFuncs.pfnChatInputPosition = cldllFuncSrc.pfnChatInputPosition;
}

View File

@@ -361,8 +361,8 @@ void CL_TempEntPlaySound( TEMPENTITY *pTemp, float damp )
sound_t handle;
if( isshellcasing )
fvol *= min ( 1.0f, ((float)zvel) / 350.0f );
else fvol *= min ( 1.0f, ((float)zvel) / 450.0f );
fvol *= Q_min( 1.0f, ((float)zvel) / 350.0f );
else fvol *= Q_min( 1.0f, ((float)zvel) / 450.0f );
if( !COM_RandomLong( 0, 3 ) && !isshellcasing )
pitch = COM_RandomLong( 95, 105 );
@@ -1482,7 +1482,6 @@ void GAME_EXPORT R_FunnelSprite( const vec3_t org, int modelIndex, int reverse )
pTemp->entity.baseline.angles[2] = COM_RandomFloat( -100.0f, 100.0f );
pTemp->entity.curstate.framerate = COM_RandomFloat( 0.1f, 0.4f );
pTemp->flags = FTENT_ROTATE|FTENT_FADEOUT;
pTemp->entity.curstate.framerate = 10;
vel = dest[2] / 8.0f;
if( vel < 64.0f ) vel = 64.0f;
@@ -1515,17 +1514,18 @@ R_RicochetSound
Make a random ricochet sound
==============
*/
void GAME_EXPORT R_RicochetSound( const vec3_t pos )
static void R_RicochetSound_( const vec3_t pos, int sound )
{
int iPitch = COM_RandomLong( 90, 105 );
float fvol = COM_RandomFloat( 0.7f, 0.9f );
char soundpath[32];
sound_t handle;
Q_strncpy( soundpath, cl_ricochet_sounds[COM_RandomLong( 0, 4 )], sizeof( soundpath ) );
handle = S_RegisterSound( soundpath );
handle = S_RegisterSound( cl_ricochet_sounds[sound] );
S_StartSound( pos, 0, CHAN_AUTO, handle, fvol, ATTN_NORM, iPitch, 0 );
S_StartSound( pos, 0, CHAN_AUTO, handle, VOL_NORM, 1.0, 100, 0 );
}
void GAME_EXPORT R_RicochetSound( const vec3_t pos )
{
R_RicochetSound_( pos, COM_RandomLong( 0, 4 ));
}
/*
@@ -1656,7 +1656,7 @@ void GAME_EXPORT R_Explosion( vec3_t pos, int model, float scale, float framerat
dl->color.g = 250;
dl->color.b = 150;
dl->die = cl.time + 0.01f;
dl->decay = 80;
dl->decay = 800;
// red glow
dl = CL_AllocDlight( 0 );
@@ -1915,6 +1915,7 @@ void CL_ParseTempEntity( sizebuf_t *msg )
TEMPENTITY *pTemp;
cl_entity_t *pEnt;
dlight_t *dl;
sound_t hSound;
if( cls.legacymode )
iSize = MSG_ReadByte( msg );
@@ -2014,15 +2015,46 @@ void CL_ParseTempEntity( sizebuf_t *msg )
color = MSG_ReadByte( &buf );
count = MSG_ReadByte( &buf );
R_ParticleExplosion2( pos, color, count );
dl = CL_AllocDlight( 0 );
VectorCopy( pos, dl->origin );
dl->radius = 350;
dl->die = cl.time + 0.5;
dl->decay = 300;
hSound = S_RegisterSound( cl_explode_sounds[0] );
S_StartSound( pos, 0, CHAN_STATIC, hSound, VOL_NORM, 0.6f, PITCH_NORM, 0 );
break;
case TE_BSPDECAL:
case TE_DECAL:
case TE_WORLDDECAL:
case TE_WORLDDECALHIGH:
case TE_DECALHIGH:
pos[0] = MSG_ReadCoord( &buf );
pos[1] = MSG_ReadCoord( &buf );
pos[2] = MSG_ReadCoord( &buf );
decalIndex = MSG_ReadShort( &buf );
entityIndex = MSG_ReadShort( &buf );
if( entityIndex ) modelIndex = MSG_ReadShort( &buf );
CL_DecalShoot( CL_DecalIndex( decalIndex ), entityIndex, modelIndex, pos, FDECAL_PERMANENT );
if( type == TE_BSPDECAL )
{
decalIndex = MSG_ReadShort( &buf );
entityIndex = MSG_ReadShort( &buf );
if( entityIndex )
modelIndex = MSG_ReadShort( &buf );
else modelIndex = 0;
}
else
{
decalIndex = MSG_ReadByte( &buf );
if( type == TE_DECALHIGH || type == TE_WORLDDECALHIGH )
decalIndex += 256;
if( type == TE_DECALHIGH || type == TE_DECAL )
entityIndex = MSG_ReadShort( &buf );
else entityIndex = 0;
pEnt = CL_GetEntityByIndex( entityIndex );
modelIndex = pEnt->curstate.modelindex;
}
CL_DecalShoot( CL_DecalIndex( decalIndex ), entityIndex, modelIndex, pos, type == TE_BSPDECAL ? FDECAL_PERMANENT : 0 );
break;
case TE_IMPLOSION:
pos[0] = MSG_ReadCoord( &buf );
@@ -2042,10 +2074,12 @@ void CL_ParseTempEntity( sizebuf_t *msg )
pos2[2] = MSG_ReadCoord( &buf );
modelIndex = MSG_ReadShort( &buf );
count = MSG_ReadByte( &buf );
life = (float)(MSG_ReadByte( &buf ) * 0.1f);
scale = (float)(MSG_ReadByte( &buf ) * 0.1f);
vel = (float)MSG_ReadByte( &buf );
random = (float)MSG_ReadByte( &buf );
life = (float)MSG_ReadByte( &buf ) * 0.1f;
scale = (float)MSG_ReadByte( &buf );
if( !scale ) scale = 1.0f;
else scale *= 0.1f;
vel = (float)MSG_ReadByte( &buf ) * 10;
random = (float)MSG_ReadByte( &buf ) * 10;
R_Sprite_Trail( type, pos, pos2, modelIndex, count, life, scale, random, 255, vel );
break;
case TE_SPRITE:
@@ -2053,36 +2087,23 @@ void CL_ParseTempEntity( sizebuf_t *msg )
pos[1] = MSG_ReadCoord( &buf );
pos[2] = MSG_ReadCoord( &buf );
modelIndex = MSG_ReadShort( &buf );
scale = (float)(MSG_ReadByte( &buf ) * 0.1f);
brightness = (float)MSG_ReadByte( &buf );
scale = (float)MSG_ReadByte( &buf ) * 0.1f;
brightness = (float)MSG_ReadByte( &buf ) / 255.0f;
if(( pTemp = R_DefaultSprite( pos, modelIndex, 0 )) != NULL )
{
pTemp->entity.curstate.scale = scale;
pTemp->entity.baseline.renderamt = brightness;
pTemp->entity.curstate.renderamt = brightness;
pTemp->entity.curstate.rendermode = kRenderTransAdd;
}
R_TempSprite( pos, vec3_origin, scale, modelIndex,
kRenderTransAdd, kRenderFxNone, brightness, 0.0, FTENT_SPRANIMATE );
break;
case TE_GLOWSPRITE:
pos[0] = MSG_ReadCoord( &buf );
pos[1] = MSG_ReadCoord( &buf );
pos[2] = MSG_ReadCoord( &buf );
modelIndex = MSG_ReadShort( &buf );
life = (float)(MSG_ReadByte( &buf ) * 0.1f);
scale = (float)(MSG_ReadByte( &buf ) * 0.1f);
brightness = (float)MSG_ReadByte( &buf );
life = (float)MSG_ReadByte( &buf ) * 0.1f;
scale = (float)MSG_ReadByte( &buf ) * 0.1f;
brightness = (float)MSG_ReadByte( &buf ) / 255.0f;
if(( pTemp = R_DefaultSprite( pos, modelIndex, 0 )) != NULL )
{
pTemp->entity.curstate.scale = scale;
pTemp->entity.curstate.rendermode = kRenderGlow;
pTemp->entity.curstate.renderfx = kRenderFxNoDissipation;
pTemp->entity.baseline.renderamt = brightness;
pTemp->entity.curstate.renderamt = brightness;
pTemp->flags = FTENT_FADEOUT;
pTemp->die = cl.time + life;
}
R_TempSprite( pos, vec3_origin, scale, modelIndex,
kRenderGlow, kRenderFxNoDissipation, brightness, life, FTENT_FADEOUT );
break;
case TE_STREAK_SPLASH:
pos[0] = MSG_ReadCoord( &buf );
@@ -2172,23 +2193,6 @@ void CL_ParseTempEntity( sizebuf_t *msg )
pos2[2] = MSG_ReadCoord( &buf );
R_ShowLine( pos, pos2 );
break;
case TE_DECAL:
case TE_DECALHIGH:
case TE_WORLDDECAL:
case TE_WORLDDECALHIGH:
pos[0] = MSG_ReadCoord( &buf );
pos[1] = MSG_ReadCoord( &buf );
pos[2] = MSG_ReadCoord( &buf );
decalIndex = MSG_ReadByte( &buf );
if( type == TE_DECAL || type == TE_DECALHIGH )
entityIndex = MSG_ReadShort( &buf );
else entityIndex = 0;
if( type == TE_DECALHIGH || type == TE_WORLDDECALHIGH )
decalIndex += 256;
pEnt = CL_GetEntityByIndex( entityIndex );
if( pEnt ) modelIndex = pEnt->curstate.modelindex;
CL_DecalShoot( CL_DecalIndex( decalIndex ), entityIndex, modelIndex, pos, 0 );
break;
case TE_FIZZ:
entityIndex = MSG_ReadShort( &buf );
modelIndex = MSG_ReadShort( &buf );
@@ -2244,10 +2248,11 @@ void CL_ParseTempEntity( sizebuf_t *msg )
pos[2] = MSG_ReadCoord( &buf );
entityIndex = MSG_ReadShort( &buf );
decalIndex = MSG_ReadByte( &buf );
pEnt = CL_GetEntityByIndex( entityIndex );
CL_DecalShoot( CL_DecalIndex( decalIndex ), entityIndex, 0, pos, 0 );
R_BulletImpactParticles( pos );
R_RicochetSound( pos );
flags = COM_RandomLong( 0, 0x7fff );
if( flags < 0x3fff )
R_RicochetSound_( pos, flags % 5 );
break;
case TE_SPRAY:
case TE_SPRITE_SPRAY:
@@ -2393,7 +2398,7 @@ void CL_ParseTempEntity( sizebuf_t *msg )
// throw warning
if( MSG_CheckOverflow( &buf ))
Con_DPrintf( S_WARN "ParseTempEntity: overflow TE message\n" );
Con_DPrintf( S_WARN "ParseTempEntity: overflow TE message %i\n", type );
}
@@ -2693,7 +2698,7 @@ apply various effects to entity origin or attachment
void CL_AddEntityEffects( cl_entity_t *ent )
{
// yellow flies effect 'monster stuck in the wall'
if( FBitSet( ent->curstate.effects, EF_BRIGHTFIELD ))
if( FBitSet( ent->curstate.effects, EF_BRIGHTFIELD ) && !RP_LOCALCLIENT( ent ))
R_EntityParticles( ent );
if( FBitSet( ent->curstate.effects, EF_DIMLIGHT ))
@@ -2914,7 +2919,7 @@ void CL_PlayerDecal( int playernum, int customIndex, int entityIndex, float *pos
{
if( FBitSet( pCust->resource.ucFlags, RES_CUSTOM ) && pCust->resource.type == t_decal && pCust->bTranslated )
{
if( !pCust->nUserData1 && pCust->pInfo != NULL )
if( !pCust->nUserData1 )
{
const char *decalname = va( "player%dlogo%d", playernum, customIndex );
pCust->nUserData1 = GL_LoadTextureInternal( decalname, pCust->pInfo, TF_DECAL );

View File

@@ -35,30 +35,39 @@ void V_CalcViewRect( void )
int sb_lines;
float size;
// intermission is always full screen
if( cl.intermission ) size = 120.0f;
else size = scr_viewsize->value;
if( FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ))
{
// intermission is always full screen
if( cl.intermission ) size = 120.0f;
else size = scr_viewsize->value;
if( size >= 120.0f )
sb_lines = 0; // no status bar at all
else if( size >= 110.0f )
sb_lines = 24; // no inventory
else sb_lines = 48;
if( size >= 120.0f )
sb_lines = 0; // no status bar at all
else if( size >= 110.0f )
sb_lines = 24; // no inventory
else sb_lines = 48;
if( scr_viewsize->value >= 100.0f )
if( scr_viewsize->value >= 100.0f )
{
full = true;
size = 100.0f;
}
else size = scr_viewsize->value;
if( cl.intermission )
{
size = 100.0f;
sb_lines = 0;
full = true;
}
size /= 100.0f;
}
else
{
full = true;
size = 100.0f;
}
else size = scr_viewsize->value;
if( cl.intermission )
{
size = 100.0f;
sb_lines = 0;
full = true;
size = 1.0f;
}
size /= 100.0f;
clgame.viewport[2] = refState.width * size;
clgame.viewport[3] = refState.height * size;

View File

@@ -625,8 +625,6 @@ typedef struct
// legacy mode support
qboolean legacymode; // one-way 48 protocol compatibility
netadr_t legacyserver;
netadr_t legacyservers[MAX_LEGACY_SERVERS];
int legacyservercount;
int extensions;
netadr_t serveradr;
@@ -679,7 +677,6 @@ extern convar_t *cl_fixtimerate;
extern convar_t *hud_scale;
extern convar_t *gl_showtextures;
extern convar_t *cl_bmodelinterp;
extern convar_t *cl_righthand;
extern convar_t *cl_lw; // local weapons
extern convar_t *cl_charset;
extern convar_t *cl_trace_messages;
@@ -1049,7 +1046,6 @@ void Con_Bottom( void );
void Con_Top( void );
void Con_PageDown( int lines );
void Con_PageUp( int lines );
void Con_LoadHistory( void );
//
// s_main.c
@@ -1113,6 +1109,11 @@ void pfnPIC_DrawAdditive( int x, int y, int width, int height, const wrect_t *pr
qboolean Mobile_Init( void );
void Mobile_Shutdown( void );
//
// cl_securedstub.c
//
void CL_GetSecuredClientAPI( CL_EXPORT_FUNCS F );
//
// cl_video.c
//

View File

@@ -33,6 +33,8 @@ convar_t *con_color;
static int g_codepage = 0;
static qboolean g_utf8 = false;
static qboolean g_messagemode_privileged = true;
#define CON_TIMES 4 // notify lines
#define CON_MAX_TIMES 64 // notify max lines
#define COLOR_DEFAULT '7'
@@ -79,6 +81,14 @@ typedef struct con_lineinfo_s
double addtime; // notify stuff
} con_lineinfo_t;
typedef struct con_history_s
{
field_t lines[CON_HISTORY];
field_t backup;
int line; // the line being displayed from history buffer will be <= nextHistoryLine
int next; // the last line in the history buffer, not masked
} con_history_t;
typedef struct
{
qboolean initialized;
@@ -116,10 +126,8 @@ typedef struct
string chat_cmd; // can be overrieded by user
// console history
field_t historyLines[CON_HISTORY];
int historyLine; // the line being displayed from history buffer will be <= nextHistoryLine
int nextHistoryLine; // the last line in the history buffer, not masked
field_t backup;
con_history_t history;
qboolean historyLoaded;
notify_t notify[MAX_DBG_NOTIFY]; // for Con_NXPrintf
qboolean draw_notify; // true if we have NXPrint message
@@ -133,6 +141,9 @@ static console_t con;
void Con_ClearField( field_t *edit );
void Field_CharEvent( field_t *edit, int ch );
static void Con_LoadHistory( con_history_t *self );
static void Con_SaveHistory( con_history_t *self );
/*
================
Con_Clear_f
@@ -196,8 +207,6 @@ Con_ClearTyping
*/
void Con_ClearTyping( void )
{
int i;
Con_ClearField( &con.input );
con.input.widthInChars = con.linewidth;
@@ -242,6 +251,8 @@ Con_MessageMode_f
*/
void Con_MessageMode_f( void )
{
g_messagemode_privileged = Cmd_CurrentCommandIsPrivileged();
if( Cmd_Argc() == 2 )
Q_strncpy( con.chat_cmd, Cmd_Argv( 1 ), sizeof( con.chat_cmd ));
else Q_strncpy( con.chat_cmd, "say", sizeof( con.chat_cmd ));
@@ -256,6 +267,8 @@ Con_MessageMode2_f
*/
void Con_MessageMode2_f( void )
{
g_messagemode_privileged = Cmd_CurrentCommandIsPrivileged();
Q_strncpy( con.chat_cmd, "say_team", sizeof( con.chat_cmd ));
Key_SetKeyDest( key_message );
}
@@ -480,7 +493,7 @@ void Con_CheckResize( void )
con.input.widthInChars = con.linewidth;
for( i = 0; i < CON_HISTORY; i++ )
con.historyLines[i].widthInChars = con.linewidth;
con.history.lines[i].widthInChars = con.linewidth;
}
/*
@@ -1056,7 +1069,7 @@ int Con_DrawGenericString( int x, int y, const char *string, rgba_t setColor, qb
Con_UtfProcessChar( 0 );
// draw the colored text
*(uint *)color = *(uint *)setColor;
memcpy( color, setColor, sizeof( color ));
s = string;
while( *s )
@@ -1107,61 +1120,6 @@ int Con_DrawString( int x, int y, const char *string, rgba_t setColor )
return Con_DrawGenericString( x, y, string, setColor, false, -1 );
}
void Con_LoadHistory( void )
{
const byte *aFile = FS_LoadFile( "console_history.txt", NULL, true );
const char *pLine = (char *)aFile, *pFile = (char *)aFile;
int i;
if( !aFile )
return;
while( true )
{
if( !*pFile )
break;
if( *pFile == '\n')
{
int len = pFile - pLine + 1;
field_t *f;
if( len > 255 ) len = 255;
Con_ClearField( &con.historyLines[con.nextHistoryLine] );
f = &con.historyLines[con.nextHistoryLine % CON_HISTORY];
f->widthInChars = con.linewidth;
f->cursor = len - 1;
Q_strncpy( f->buffer, pLine, len);
con.nextHistoryLine++;
pLine = pFile + 1;
}
pFile++;
}
for( i = con.nextHistoryLine; i < CON_HISTORY; i++ )
{
Con_ClearField( &con.historyLines[i] );
con.historyLines[i].widthInChars = con.linewidth;
}
con.historyLine = con.nextHistoryLine;
}
void Con_SaveHistory( void )
{
int historyStart = con.nextHistoryLine - CON_HISTORY;
int i;
file_t *f;
if( historyStart < 0 )
historyStart = 0;
f = FS_Open("console_history.txt", "w", true );
for( i = historyStart; i < con.nextHistoryLine; i++ )
FS_Printf( f, "%s\n", con.historyLines[i % CON_HISTORY].buffer );
FS_Close(f);
}
/*
================
@@ -1201,7 +1159,7 @@ void Con_Init( void )
con.chat.widthInChars = con.linewidth;
Cmd_AddCommand( "toggleconsole", Con_ToggleConsole_f, "opens or closes the console" );
Cmd_AddCommand( "clear", Con_Clear_f, "clear console history" );
Cmd_AddRestrictedCommand( "clear", Con_Clear_f, "clear console history" );
Cmd_AddCommand( "messagemode", Con_MessageMode_f, "enable message mode \"say\"" );
Cmd_AddCommand( "messagemode2", Con_MessageMode2_f, "enable message mode \"say_team\"" );
Cmd_AddCommand( "contimes", Con_SetTimes_f, "change number of console overlay lines (4-64)" );
@@ -1227,7 +1185,7 @@ void Con_Shutdown( void )
con.buffer = NULL;
con.lines = NULL;
Con_SaveHistory();
Con_SaveHistory( &con.history );
}
/*
@@ -1462,11 +1420,22 @@ Con_ClearField
*/
void Con_ClearField( field_t *edit )
{
memset(edit->buffer, 0, MAX_STRING);
memset( edit->buffer, 0, MAX_STRING );
edit->cursor = 0;
edit->scroll = 0;
}
/*
================
Field_Set
================
*/
static void Field_Set( field_t *f, const char *string )
{
f->scroll = 0;
f->cursor = Q_strncpy( f->buffer, string, MAX_STRING );
}
/*
================
Field_Paste
@@ -1486,6 +1455,18 @@ void Field_Paste( field_t *edit )
Field_CharEvent( edit, cbd[i] );
}
/*
=================
Field_GoTo
=================
*/
static void Field_GoTo( field_t *edit, int pos )
{
edit->cursor = pos;
edit->scroll = Q_max( 0, edit->cursor - edit->widthInChars );
}
/*
=================
Field_KeyDownEvent
@@ -1538,20 +1519,20 @@ void Field_KeyDownEvent( field_t *edit, int key )
if( key == K_LEFTARROW )
{
if( edit->cursor > 0 ) edit->cursor= Con_UtfMoveLeft( edit->buffer, edit->cursor );
if( edit->cursor > 0 ) edit->cursor = Con_UtfMoveLeft( edit->buffer, edit->cursor );
if( edit->cursor < edit->scroll ) edit->scroll--;
return;
}
if( key == K_HOME || ( Q_tolower(key) == 'a' && Key_IsDown( K_CTRL )))
{
edit->cursor = 0;
Field_GoTo( edit, 0 );
return;
}
if( key == K_END || ( Q_tolower(key) == 'e' && Key_IsDown( K_CTRL )))
{
edit->cursor = len;
Field_GoTo( edit, len );
return;
}
@@ -1590,16 +1571,14 @@ void Field_CharEvent( field_t *edit, int ch )
if( ch == 'a' - 'a' + 1 )
{
// ctrl-a is home
edit->cursor = 0;
edit->scroll = 0;
Field_GoTo( edit, 0 );
return;
}
if( ch == 'e' - 'a' + 1 )
{
// ctrl-e is end
edit->cursor = len;
edit->scroll = edit->cursor - edit->widthInChars;
Field_GoTo( edit, len );
return;
}
@@ -1702,12 +1681,134 @@ void Field_DrawInputLine( int x, int y, field_t *edit )
}
}
/*
=============================================================================
CONSOLE HISTORY HANDLING
=============================================================================
*/
/*
===================
Con_HistoryUp
===================
*/
static void Con_HistoryUp( con_history_t *self, field_t *in )
{
if( self->line == self->next )
self->backup = *in;
if(( self->next - self->line ) < CON_HISTORY )
self->line = Q_max( 0, self->line - 1 );
*in = self->lines[self->line % CON_HISTORY];
}
/*
===================
Con_HistoryDown
===================
*/
static void Con_HistoryDown( con_history_t *self, field_t *in )
{
self->line = Q_min( self->next, self->line + 1 );
if( self->line == self->next )
*in = self->backup;
else *in = self->lines[self->line % CON_HISTORY];
}
/*
===================
Con_HistoryAppend
===================
*/
static void Con_HistoryAppend( con_history_t *self, field_t *from )
{
int prevLine = Q_max( 0, self->line - 1 );
const char *buf = from->buffer;
// skip backslashes
if( from->buffer[0] == '\\' || from->buffer[1] == '/' )
buf++;
// only if non-empty
if( !from->buffer[0] )
return;
// skip empty commands
if( Q_isspace( buf ))
return;
// if not copy (don't ignore backslashes)
if( !Q_strcmp( from->buffer, self->lines[prevLine % CON_HISTORY].buffer ))
return;
self->lines[self->next % CON_HISTORY] = *from;
self->line = ++self->next;
}
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;
if( !aFile )
return;
for( pFile = pLine = (char *)aFile; *pFile; pFile++ )
{
if( *pFile != '\n' )
continue;
Con_ClearField( &self->lines[self->next] );
len = Q_min( pFile - pLine + 1, sizeof( f->buffer ));
f = &self->lines[self->next % CON_HISTORY];
f->widthInChars = con.linewidth;
f->cursor = len - 1;
Q_strncpy( f->buffer, pLine, len);
self->next++;
pLine = pFile + 1;
}
for( i = self->next; i < CON_HISTORY; i++ )
{
Con_ClearField( &self->lines[i] );
self->lines[i].widthInChars = con.linewidth;
}
self->line = self->next;
}
static void Con_SaveHistory( con_history_t *self )
{
int historyStart = self->next - CON_HISTORY, i;
file_t *f;
if( historyStart < 0 )
historyStart = 0;
f = FS_Open( "console_history.txt", "w", true );
for( i = historyStart; i < self->next; i++ )
FS_Printf( f, "%s\n", self->lines[i % CON_HISTORY].buffer );
FS_Close( f );
}
/*
=============================================================================
CONSOLE LINE EDITING
==============================================================================
=============================================================================
*/
/*
====================
@@ -1728,16 +1829,6 @@ void Key_Console( int key )
// enter finishes the line
if( key == K_ENTER || key == K_KP_ENTER )
{
// if not in the game explicitly prepent a slash if needed
if( cls.state != ca_active && con.input.buffer[0] != '\\' && con.input.buffer[0] != '/' )
{
char temp[MAX_SYSPATH];
Q_strncpy( temp, con.input.buffer, sizeof( temp ));
Q_sprintf( con.input.buffer, "\\%s", temp );
con.input.cursor++;
}
// backslash text are commands, else chat
if( con.input.buffer[0] == '\\' || con.input.buffer[0] == '/' )
Cbuf_AddText( con.input.buffer + 1 ); // skip backslash
@@ -1748,9 +1839,7 @@ void Key_Console( int key )
Con_Printf( ">%s\n", con.input.buffer );
// copy line to history buffer
con.historyLines[con.nextHistoryLine % CON_HISTORY] = con.input;
con.nextHistoryLine++;
con.historyLine = con.nextHistoryLine;
Con_HistoryAppend( &con.history, &con.input );
Con_ClearField( &con.input );
con.input.widthInChars = con.linewidth;
@@ -1775,23 +1864,13 @@ void Key_Console( int key )
// command history (ctrl-p ctrl-n for unix style)
if(( key == K_MWHEELUP && Key_IsDown( K_SHIFT )) || ( key == K_UPARROW ) || (( Q_tolower(key) == 'p' ) && Key_IsDown( K_CTRL )))
{
if( con.historyLine == con.nextHistoryLine )
con.backup = con.input;
if( con.nextHistoryLine - con.historyLine < CON_HISTORY && con.historyLine > 0 )
con.historyLine--;
con.input = con.historyLines[con.historyLine % CON_HISTORY];
Con_HistoryUp( &con.history, &con.input );
return;
}
if(( key == K_MWHEELDOWN && Key_IsDown( K_SHIFT )) || ( key == K_DOWNARROW ) || (( Q_tolower(key) == 'n' ) && Key_IsDown( K_CTRL )))
{
if( con.historyLine >= con.nextHistoryLine - 1 )
con.input = con.backup;
else
{
con.historyLine++;
con.input = con.historyLines[con.historyLine % CON_HISTORY];
}
Con_HistoryDown( &con.history, &con.input );
return;
}
@@ -1865,7 +1944,10 @@ void Key_Message( int key )
if( con.chat.buffer[0] && cls.state == ca_active )
{
Q_snprintf( buffer, sizeof( buffer ), "%s \"%s\"\n", con.chat_cmd, con.chat.buffer );
Cbuf_AddText( buffer );
if( g_messagemode_privileged )
Cbuf_AddText( buffer );
else Cbuf_AddFilteredText( buffer );
}
Key_SetKeyDest( key_game );
@@ -2092,6 +2174,9 @@ void Con_DrawSolidConsole( int lines )
int i, x, y;
float fraction;
int start;
int stringLen, width = 0, charH;
string curbuild;
byte color[4];
if( lines <= 0 ) return;
@@ -2105,28 +2190,20 @@ void Con_DrawSolidConsole( int lines )
if( !con.curFont || !host.allow_console )
return; // nothing to draw
if( host.allow_console )
{
// draw current version
int stringLen, width = 0, charH;
string curbuild;
byte color[4];
// draw current version
memcpy( color, g_color_table[7], sizeof( color ));
memcpy( color, g_color_table[7], sizeof( color ));
Q_snprintf( curbuild, MAX_STRING, "%s %i/%s (%s-%s build %i)", XASH_ENGINE_NAME, PROTOCOL_VERSION, XASH_VERSION, Q_buildos(), Q_buildarch(), Q_buildnum( ));
Con_DrawStringLen( curbuild, &stringLen, &charH );
start = refState.width - stringLen;
stringLen = Con_StringLength( curbuild );
Q_snprintf( curbuild, MAX_STRING, "%s %i/%s (%s-%s build %i)", XASH_ENGINE_NAME, PROTOCOL_VERSION, XASH_VERSION, Q_buildos(), Q_buildarch(), Q_buildnum( ));
fraction = lines / (float)refState.height;
color[3] = Q_min( fraction * 2.0f, 1.0f ) * 255; // fadeout version number
Con_DrawStringLen( curbuild, &stringLen, &charH );
start = refState.width - stringLen;
stringLen = Con_StringLength( curbuild );
fraction = lines / (float)refState.height;
color[3] = Q_min( fraction * 2.0f, 1.0f ) * 255; // fadeout version number
for( i = 0; i < stringLen; i++ )
width += Con_DrawCharacter( start + width, 0, curbuild[i], color );
}
for( i = 0; i < stringLen; i++ )
width += Con_DrawCharacter( start + width, 0, curbuild[i], color );
// draw the text
if( CON_LINES_COUNT > 0 )
@@ -2163,7 +2240,7 @@ void Con_DrawSolidConsole( int lines )
Con_DrawInput( lines );
y = lines - ( con.curFont->charHeight * 1.2f );
SCR_DrawFPS( max( y, 4 )); // to avoid to hide fps counter
SCR_DrawFPS( Q_max( y, 4 )); // to avoid to hide fps counter
ref.dllFuncs.Color4ub( 255, 255, 255, 255 );
}
@@ -2379,6 +2456,12 @@ INTERNAL RESOURCE
*/
void Con_VidInit( void )
{
if( !con.historyLoaded )
{
Con_LoadHistory( &con.history );
con.historyLoaded = true;
}
Con_LoadConchars();
Con_CheckResize();
#if XASH_LOW_MEMORY
@@ -2414,7 +2497,6 @@ void Con_VidInit( void )
}
}
if( !con.background ) // last chance - quake conback image
{
qboolean draw_to_console = false;
@@ -2502,3 +2584,48 @@ void GAME_EXPORT Con_DefaultColor( int r, int g, int b )
b = bound( 0, b, 255 );
MakeRGBA( g_color_table[7], r, g, b, 255 );
}
#if XASH_ENGINE_TESTS
#include "tests.h"
static void Test_RunConHistory( void )
{
con_history_t hist = { 0 };
field_t input = { 0 };
const char *strs1[] = { "map t0a0", "quit", "wtf", "wtf", "", "nyan" };
const char *strs2[] = { "nyan", "wtf", "quit", "map t0a0" };
const char *testbackup = "unfinished_edit";
int i;
for( i = 0; i < ARRAYSIZE( strs1 ); i++ )
{
Field_Set( &input, strs1[i] );
Con_HistoryAppend( &hist, &input );
}
Field_Set( &input, testbackup );
for( i = 0; i < ARRAYSIZE( strs2 ); i++ )
{
Con_HistoryUp( &hist, &input );
TASSERT_STR( input.buffer, strs2[i] );
}
// check for overrun
Con_HistoryUp( &hist, &input );
for( i = ARRAYSIZE( strs2 ) - 1; i >= 0; i-- )
{
TASSERT_STR( input.buffer, strs2[i] );
Con_HistoryDown( &hist, &input );
}
TASSERT_STR( input.buffer, testbackup );
}
void Test_RunCon( void )
{
TRUN( Test_RunConHistory() );
}
#endif /* XASH_ENGINE_TESTS */

View File

@@ -380,32 +380,32 @@ Main init procedure
*/
void Joy_Init( void )
{
joy_pitch = Cvar_Get( "joy_pitch", "100.0", FCVAR_ARCHIVE, "joystick pitch sensitivity" );
joy_yaw = Cvar_Get( "joy_yaw", "100.0", FCVAR_ARCHIVE, "joystick yaw sensitivity" );
joy_side = Cvar_Get( "joy_side", "1.0", FCVAR_ARCHIVE, "joystick side sensitivity. Values from -1.0 to 1.0" );
joy_forward = Cvar_Get( "joy_forward", "1.0", FCVAR_ARCHIVE, "joystick forward sensitivity. Values from -1.0 to 1.0" );
joy_pitch = Cvar_Get( "joy_pitch", "100.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "joystick pitch sensitivity" );
joy_yaw = Cvar_Get( "joy_yaw", "100.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "joystick yaw sensitivity" );
joy_side = Cvar_Get( "joy_side", "1.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "joystick side sensitivity. Values from -1.0 to 1.0" );
joy_forward = Cvar_Get( "joy_forward", "1.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "joystick forward sensitivity. Values from -1.0 to 1.0" );
joy_lt_threshold = Cvar_Get( "joy_lt_threshold", "16384", FCVAR_ARCHIVE, "left trigger threshold. Value from 0 to 32767");
joy_rt_threshold = Cvar_Get( "joy_rt_threshold", "16384", FCVAR_ARCHIVE, "right trigger threshold. Value from 0 to 32767" );
joy_lt_threshold = Cvar_Get( "joy_lt_threshold", "16384", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "left trigger threshold. Value from 0 to 32767");
joy_rt_threshold = Cvar_Get( "joy_rt_threshold", "16384", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "right trigger threshold. Value from 0 to 32767" );
// emit a key event at 75% axis move
joy_side_key_threshold = Cvar_Get( "joy_side_key_threshold", "24576", FCVAR_ARCHIVE, "side axis key event emit threshold. Value from 0 to 32767" );
joy_forward_key_threshold = Cvar_Get( "joy_forward_key_threshold", "24576", FCVAR_ARCHIVE, "forward axis key event emit threshold. Value from 0 to 32767");
joy_side_key_threshold = Cvar_Get( "joy_side_key_threshold", "24576", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "side axis key event emit threshold. Value from 0 to 32767" );
joy_forward_key_threshold = Cvar_Get( "joy_forward_key_threshold", "24576", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "forward axis key event emit threshold. Value from 0 to 32767");
// by default, we rely on deadzone detection come from system, but some glitchy devices report false deadzones
joy_side_deadzone = Cvar_Get( "joy_side_deadzone", "0", FCVAR_ARCHIVE, "side axis deadzone. Value from 0 to 32767" );
joy_forward_deadzone = Cvar_Get( "joy_forward_deadzone", "0", FCVAR_ARCHIVE, "forward axis deadzone. Value from 0 to 32767");
joy_pitch_deadzone = Cvar_Get( "joy_pitch_deadzone", "0", FCVAR_ARCHIVE, "pitch axis deadzone. Value from 0 to 32767");
joy_yaw_deadzone = Cvar_Get( "joy_yaw_deadzone", "0", FCVAR_ARCHIVE, "yaw axis deadzone. Value from 0 to 32767" );
joy_side_deadzone = Cvar_Get( "joy_side_deadzone", "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "side axis deadzone. Value from 0 to 32767" );
joy_forward_deadzone = Cvar_Get( "joy_forward_deadzone", "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "forward axis deadzone. Value from 0 to 32767");
joy_pitch_deadzone = Cvar_Get( "joy_pitch_deadzone", "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "pitch axis deadzone. Value from 0 to 32767");
joy_yaw_deadzone = Cvar_Get( "joy_yaw_deadzone", "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "yaw axis deadzone. Value from 0 to 32767" );
joy_axis_binding = Cvar_Get( "joy_axis_binding", "sfpyrl", FCVAR_ARCHIVE, "axis hardware id to engine inner axis binding, "
joy_axis_binding = Cvar_Get( "joy_axis_binding", "sfpyrl", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "axis hardware id to engine inner axis binding, "
"s - side, f - forward, y - yaw, p - pitch, r - left trigger, l - right trigger" );
joy_found = Cvar_Get( "joy_found", "0", FCVAR_READ_ONLY, "is joystick is connected" );
// we doesn't loaded config.cfg yet, so this cvar is not archive.
// change by +set joy_index in cmdline
joy_index = Cvar_Get( "joy_index", "0", FCVAR_READ_ONLY, "current active joystick" );
joy_enable = Cvar_Get( "joy_enable", "1", FCVAR_ARCHIVE, "enable joystick" );
joy_enable = Cvar_Get( "joy_enable", "1", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enable joystick" );
if( Sys_CheckParm( "-nojoy" ))
{

View File

@@ -134,6 +134,9 @@ struct touch_s
qboolean configchanged;
} touch;
// private to the engine flags
#define TOUCH_FL_UNPRIVILEGED BIT( 10 )
touchdefaultbutton_t g_DefaultButtons[256];
int g_LastDefaultButton;
@@ -194,6 +197,8 @@ static inline int Touch_ExportButtonToConfig( file_t *f, touch_button_t *button,
if( FBitSet( flags, TOUCH_FL_DEF_HIDE ))
SetBits( flags, TOUCH_FL_HIDE );
Cmd_Escape( newCommand, B( command ), sizeof( newCommand ));
FS_Printf( f, "touch_addbutton \"%s\" \"%s\" \"%s\" %f %f %f %f %d %d %d %d %d",
B(name), B(texturefile), newCommand,
B(x1), B(y1), B(x2), B(y2),
@@ -455,28 +460,42 @@ static void Touch_Stroke_f( void )
MakeRGBA( touch.scolor, Q_atoi( Cmd_Argv( 2 ) ), Q_atoi( Cmd_Argv( 3 ) ), Q_atoi( Cmd_Argv( 4 ) ), Q_atoi( Cmd_Argv( 5 ) ) );
}
static touch_button_t *Touch_FindButton( touchbuttonlist_t *list, const char *name )
static touch_button_t *Touch_FindButton( touchbuttonlist_t *list, const char *name, qboolean privileged )
{
touch_button_t *button;
for( button = list->first; button; button = button->next )
if( !Q_strncmp( button->name, name, sizeof( button->name )))
return button;
{
if( !privileged && !FBitSet( button->flags, TOUCH_FL_UNPRIVILEGED ))
continue;
if( Q_strncmp( button->name, name, sizeof( button->name )))
continue;
return button;
}
return NULL;
}
static touch_button_t *Touch_FindFirst( touchbuttonlist_t *list, const char *name )
static touch_button_t *Touch_FindFirst( touchbuttonlist_t *list, const char *name, qboolean privileged )
{
touch_button_t *button;
for( button = list->first; button; button = button->next )
{
if( !privileged && !FBitSet( button->flags, TOUCH_FL_UNPRIVILEGED ))
continue;
if(( Q_strchr( name, '*' ) && Q_stricmpext( name, button->name )) || !Q_strncmp( name, button->name, sizeof( button->name )))
{
return button;
}
}
return NULL;
}
void Touch_SetClientOnly( qboolean state )
void Touch_SetClientOnly( byte state )
{
touch.clientonly = state;
host.mouse_visible = state;
@@ -484,20 +503,14 @@ void Touch_SetClientOnly( qboolean state )
touch.move_finger = touch.look_finger = -1;
touch.forward = touch.side = 0;
/// TODO: touch sdl platform
#if 0
if( state )
{
SDL_SetRelativeMouseMode( SDL_FALSE );
SDL_ShowCursor( true );
IN_DeactivateMouse();
}
else
{
SDL_ShowCursor( false );
SDL_GetRelativeMouseState( 0, 0 );
IN_ActivateMouse();
}
#endif
}
static void Touch_SetClientOnly_f( void )
@@ -511,13 +524,13 @@ static void Touch_SetClientOnly_f( void )
Touch_SetClientOnly( Q_atoi( Cmd_Argv( 1 )));
}
static void Touch_RemoveButtonFromList( touchbuttonlist_t *list, const char *name )
static void Touch_RemoveButtonFromList( touchbuttonlist_t *list, const char *name, qboolean privileged )
{
touch_button_t *button;
IN_TouchEditClear();
while(( button = Touch_FindFirst( &touch.list_user, name )))
while(( button = Touch_FindFirst( &touch.list_user, name, privileged )))
{
if( button->prev )
button->prev->next = button->next;
@@ -534,9 +547,9 @@ static void Touch_RemoveButtonFromList( touchbuttonlist_t *list, const char *nam
}
void Touch_RemoveButton( const char *name )
void Touch_RemoveButton( const char *name, qboolean privileged )
{
Touch_RemoveButtonFromList( &touch.list_user, name );
Touch_RemoveButtonFromList( &touch.list_user, name, privileged );
}
static void IN_TouchRemoveButton_f( void )
@@ -547,7 +560,7 @@ static void IN_TouchRemoveButton_f( void )
return;
}
Touch_RemoveButton( Cmd_Argv( 1 ));
Touch_RemoveButton( Cmd_Argv( 1 ), Cmd_CurrentCommandIsPrivileged());
}
static void Touch_ClearList( touchbuttonlist_t *list )
@@ -578,9 +591,9 @@ static void Touch_SetColor( touchbuttonlist_t *list, const char *name, byte *col
}
}
static void Touch_SetTexture( touchbuttonlist_t *list, const char *name, const char *texture )
static void Touch_SetTexture( touchbuttonlist_t *list, const char *name, const char *texture, qboolean privileged )
{
touch_button_t *button = Touch_FindButton( list, name );
touch_button_t *button = Touch_FindButton( list, name, privileged );
if( !button )
return;
@@ -605,12 +618,15 @@ static void Touch_SetCommand( touch_button_t *button, const char *command )
button->type = touch_wheel;
}
void Touch_HideButtons( const char *name, byte hide )
void Touch_HideButtons( const char *name, byte hide, qboolean privileged )
{
touch_button_t *button;
for( button = touch.list_user.first; button; button = button->next)
{
if( !privileged && !FBitSet( button->flags, TOUCH_FL_UNPRIVILEGED ))
continue;
if(( Q_strchr( name, '*' ) && Q_stricmpext( name, button->name )) || !Q_strncmp( name, button->name, sizeof( button->name )))
{
if( hide )
@@ -635,7 +651,7 @@ static void Touch_Hide_f( void )
return;
}
Touch_HideButtons( Cmd_Argv( 1 ), true );
Touch_HideButtons( Cmd_Argv( 1 ), true, Cmd_CurrentCommandIsPrivileged() );
}
static void Touch_Show_f( void )
@@ -646,14 +662,17 @@ static void Touch_Show_f( void )
return;
}
Touch_HideButtons( Cmd_Argv( 1 ), false );
Touch_HideButtons( Cmd_Argv( 1 ), false, Cmd_CurrentCommandIsPrivileged() );
}
static void Touch_FadeButtons( touchbuttonlist_t *list, const char *name, float speed, float end, float start )
static void Touch_FadeButtons( touchbuttonlist_t *list, const char *name, float speed, float end, float start, qboolean privileged )
{
touch_button_t *button;
for( button = list->first; button; button = button->next)
{
if( !privileged && !FBitSet( button->flags, TOUCH_FL_UNPRIVILEGED ))
continue;
if(( Q_strchr( name, '*' ) && Q_stricmpext( name, button->name )) || !Q_strncmp( name, button->name, sizeof( button->name )))
{
if( start >= 0 )
@@ -678,7 +697,8 @@ static void Touch_Fade_f( void )
return;
}
Touch_FadeButtons( &touch.list_user, Cmd_Argv( 1 ), Q_atof( Cmd_Argv( 2 )), Q_atof( Cmd_Argv( 3 )), start );
Touch_FadeButtons( &touch.list_user,Cmd_Argv( 1 ), Q_atof( Cmd_Argv( 2 )), Q_atof( Cmd_Argv( 3 )),
start, Cmd_CurrentCommandIsPrivileged() );
}
static void Touch_SetColor_f( void )
@@ -686,7 +706,7 @@ static void Touch_SetColor_f( void )
rgba_t color;
if( Cmd_Argc() == 6 )
{
MakeRGBA( color, Q_atoi( Cmd_Argv(2) ), Q_atoi( Cmd_Argv(3) ), Q_atoi( Cmd_Argv(4) ), Q_atoi( Cmd_Argv(5) ) );
MakeRGBA( color, Q_atoi( Cmd_Argv(2) ), Q_atoi( Cmd_Argv(3) ), Q_atoi( Cmd_Argv(4) ), Q_atoi( Cmd_Argv(5) ) );
Touch_SetColor( &touch.list_user, Cmd_Argv(1), color );
return;
}
@@ -697,7 +717,7 @@ static void Touch_SetTexture_f( void )
{
if( Cmd_Argc() == 3 )
{
Touch_SetTexture( &touch.list_user, Cmd_Argv( 1 ), Cmd_Argv( 2 ) );
Touch_SetTexture( &touch.list_user, Cmd_Argv( 1 ), Cmd_Argv( 2 ), Cmd_CurrentCommandIsPrivileged() );
return;
}
Con_Printf( S_USAGE "touch_settexture <name> <file>\n" );
@@ -707,9 +727,13 @@ static void Touch_SetFlags_f( void )
{
if( Cmd_Argc() == 3 )
{
touch_button_t *button = Touch_FindButton( &touch.list_user, Cmd_Argv( 1 ) );
qboolean privileged = Cmd_CurrentCommandIsPrivileged();
touch_button_t *button = Touch_FindButton( &touch.list_user, Cmd_Argv( 1 ), privileged );
if( button )
button->flags = Q_atoi( Cmd_Argv( 2 ) );
{
button->flags = ( privileged ? 0 : TOUCH_FL_UNPRIVILEGED | TOUCH_FL_CLIENT ) | Q_atoi( Cmd_Argv( 2 ));
}
return;
}
Con_Printf( S_USAGE "touch_setflags <name> <file>\n" );
@@ -719,7 +743,7 @@ static void Touch_SetCommand_f( void )
{
if( Cmd_Argc() == 3 )
{
touch_button_t *button = Touch_FindButton( &touch.list_user, Cmd_Argv(1) );
touch_button_t *button = Touch_FindButton( &touch.list_user, Cmd_Argv(1), Cmd_CurrentCommandIsPrivileged() );
if( !button )
Con_Printf( S_ERROR "no such button" );
@@ -744,21 +768,24 @@ static void Touch_ReloadConfig_f( void )
Cbuf_AddText( va("exec %s\n", touch_config_file->string ) );
}
static touch_button_t *Touch_AddButton( touchbuttonlist_t *list, const char *name, const char *texture, const char *command, float x1, float y1, float x2, float y2, byte *color )
static touch_button_t *Touch_AddButton( touchbuttonlist_t *list,
const char *name, const char *texture, const char *command,
float x1, float y1, float x2, float y2, byte *color,
qboolean privileged )
{
touch_button_t *button = Mem_Calloc( touch.mempool, sizeof( touch_button_t ) );
button->texture = -1;
Q_strncpy( button->texturefile, texture, sizeof( B( texturefile )));
Q_strncpy( button->name, name, sizeof( B( name )));
Touch_RemoveButtonFromList( list, name ); //replace if exist
Touch_RemoveButtonFromList( list, name, privileged ); //replace if exist
button->x1 = x1;
button->y1 = y1;
button->x2 = x2;
button->y2 = y2;
button->flags = privileged ? 0 : TOUCH_FL_UNPRIVILEGED | TOUCH_FL_CLIENT;
MakeRGBA( button->color, color[0], color[1], color[2], color[3] );
button->command[0] = 0;
button->flags = 0;
button->fade = 1;
Touch_SetCommand( button, command );
@@ -788,7 +815,7 @@ void Touch_AddClientButton( const char *name, const char *texture, const char *c
{
y2 = y1 + ( x2 - x1 ) * (SCR_W/SCR_H) * aspect;
}
button = Touch_AddButton( &touch.list_user, name, texture, command, x1, y1, x2, y2, color );
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->aspect = aspect;
}
@@ -815,7 +842,7 @@ static void Touch_LoadDefaults_f( void )
}
IN_TouchCheckCoords( &x1, &y1, &x2, &y2 );
button = Touch_AddButton( &touch.list_user, g_DefaultButtons[i].name, g_DefaultButtons[i].texturefile, g_DefaultButtons[i].command, x1, y1, x2, y2, g_DefaultButtons[i].color );
button = Touch_AddButton( &touch.list_user, g_DefaultButtons[i].name, g_DefaultButtons[i].texturefile, g_DefaultButtons[i].command, x1, y1, x2, y2, g_DefaultButtons[i].color, true );
button->flags |= g_DefaultButtons[i].flags;
button->aspect = g_DefaultButtons[i].aspect;
}
@@ -855,51 +882,66 @@ static void Touch_AddButton_f( void )
{
rgba_t color;
int argc = Cmd_Argc( );
touch_button_t *button = NULL;
const char *name, *texture, *command;
float x1, y1, x2, y2;
qboolean privileged = Cmd_CurrentCommandIsPrivileged();
if( argc >= 12 )
if( argc < 4 )
{
touch_button_t *button;
MakeRGBA( color, Q_atoi( Cmd_Argv(8) ), Q_atoi( Cmd_Argv(9) ),
Q_atoi( Cmd_Argv(10) ), Q_atoi( Cmd_Argv(11) ) );
button = Touch_AddButton( &touch.list_user, Cmd_Argv(1), Cmd_Argv(2), Cmd_Argv(3),
Q_atof( Cmd_Argv(4) ), Q_atof( Cmd_Argv(5) ),
Q_atof( Cmd_Argv(6) ), Q_atof( Cmd_Argv(7) ) ,
color );
if( argc >= 13 )
{
button->flags = Q_atoi( Cmd_Argv(12) );
}
if( argc >= 14 )
{
// Recalculate button coordinates aspect ratio
// This is feature for distributed configs
float aspect = Q_atof( Cmd_Argv(13) );
if( aspect )
{
if( B(texturefile)[0] != '#' )
B(y2) = B(y1) + ( B(x2) - B(x1) ) * (SCR_W/SCR_H) * aspect;
B(aspect) = aspect;
}
}
Con_Printf( S_USAGE "touch_addbutton <name> <texture> <command> [<x1> <y1> <x2> <y2> [ r g b a ] ]\n" );
return;
}
if( argc == 8 )
name = Cmd_Argv( 1 );
texture = Cmd_Argv( 2 );
command = Cmd_Argv( 3 );
if( argc < 8 )
{
x1 = y1 = 0.4f;
x2 = y2 = 0.6f;
}
else
{
x1 = Q_atof( Cmd_Argv( 4 ));
y1 = Q_atof( Cmd_Argv( 5 ));
x2 = Q_atof( Cmd_Argv( 6 ));
y2 = Q_atof( Cmd_Argv( 7 ));
}
if( argc < 12 )
{
MakeRGBA( color, 255, 255, 255, 255 );
Touch_AddButton( &touch.list_user, Cmd_Argv(1), Cmd_Argv(2), Cmd_Argv(3),
Q_atof( Cmd_Argv(4) ), Q_atof( Cmd_Argv(5) ),
Q_atof( Cmd_Argv(6) ), Q_atof( Cmd_Argv(7) ),
color );
return;
}
if( argc == 4 )
else
{
MakeRGBA( color, 255, 255, 255, 255 );
Touch_AddButton( &touch.list_user, Cmd_Argv(1), Cmd_Argv(2), Cmd_Argv(3), 0.4, 0.4, 0.6, 0.6, color );
return;
MakeRGBA( color,
Q_atoi( Cmd_Argv( 8 )),
Q_atoi( Cmd_Argv( 9 )),
Q_atoi( Cmd_Argv( 10 )),
Q_atoi( Cmd_Argv( 11 )));
}
button = Touch_AddButton( &touch.list_user, name, texture, command, x1, y1, x2, y2, color, privileged );
if( argc >= 13 )
{
SetBits( button->flags, Q_atoi( Cmd_Argv( 12 )));
}
if( argc >= 14 )
{
// Recalculate button coordinates aspect ratio
// This is feature for distributed configs
float aspect = Q_atof( Cmd_Argv( 13 ));
if( aspect )
{
if( B( texturefile )[0] != '#' )
B( y2 ) = B( y1 ) + ( B( x2 ) - B( x1 )) * ( SCR_W / SCR_H ) * aspect;
B( aspect ) = aspect;
}
}
Con_Printf( S_USAGE "touch_addbutton <name> <texture> <command> [<x1> <y1> <x2> <y2> [ r g b a ] ]\n" );
}
static void Touch_EnableEdit_f( void )
@@ -925,7 +967,7 @@ static void Touch_DisableEdit_f( void )
{
Cvar_Set( "touch_in_menu", "0" );
}
else if( cls.key_dest == key_game )
else if( cls.key_dest == key_game )
Touch_WriteConfig();
}
@@ -946,26 +988,29 @@ static void Touch_InitEditor( void )
float x = 0.1f * (SCR_H/SCR_W);
float y = 0.05f;
touch_button_t *temp;
rgba_t color;
MakeRGBA( color, 255, 255, 255, 255 );
Touch_ClearList( &touch.list_edit );
temp = Touch_AddButton( &touch.list_edit, "close", "touch_default/edit_close.tga", "touch_disableedit", 0, y, x, y + 0.1f, (byte*)"\xff\xff\xff\xff" );
temp = Touch_AddButton( &touch.list_edit, "close", "touch_default/edit_close.tga", "touch_disableedit", 0, y, x, y + 0.1f, color, true );
SetBits( temp->flags, TOUCH_FL_NOEDIT );
temp = Touch_AddButton( &touch.list_edit, "close", "#Close and save", "", x, y, x + 0.2f, y + 0.1f, (byte*)"\xff\xff\xff\xff" );
temp = Touch_AddButton( &touch.list_edit, "close", "#Close and save", "", x, y, x + 0.2f, y + 0.1f, color, true );
SetBits( temp->flags, TOUCH_FL_NOEDIT );
y += 0.2f;
temp = Touch_AddButton( &touch.list_edit, "cancel", "touch_default/edit_reset.tga", "touch_reloadconfig", 0, y, x, y + 0.1f, (byte*)"\xff\xff\xff\xff" );
temp = Touch_AddButton( &touch.list_edit, "cancel", "touch_default/edit_reset.tga", "touch_reloadconfig", 0, y, x, y + 0.1f, color, true );
SetBits( temp->flags, TOUCH_FL_NOEDIT );
temp = Touch_AddButton( &touch.list_edit, "close", "#Cancel and reset", "", x, y, x + 0.2f, y + 0.1f, (byte*)"\xff\xff\xff\xff" );
temp = Touch_AddButton( &touch.list_edit, "close", "#Cancel and reset", "", x, y, x + 0.2f, y + 0.1f, color, true );
SetBits( temp->flags, TOUCH_FL_NOEDIT );
y += 0.2f;
touch.hidebutton = Touch_AddButton( &touch.list_edit, "showhide", "touch_default/edit_hide.tga", "touch_toggleselection", 0, y, x, y + 0.1f, (byte*)"\xff\xff\xff\xff" );
touch.hidebutton = Touch_AddButton( &touch.list_edit, "showhide", "touch_default/edit_hide.tga", "touch_toggleselection", 0, y, x, y + 0.1f, color, true );
SetBits( touch.hidebutton->flags, TOUCH_FL_HIDE | TOUCH_FL_NOEDIT );
}
@@ -1014,58 +1059,58 @@ void Touch_Init( void )
Cmd_AddCommand( "touch_addbutton", Touch_AddButton_f, "add native touch button" );
Cmd_AddCommand( "touch_removebutton", IN_TouchRemoveButton_f, "remove native touch button" );
Cmd_AddCommand( "touch_enableedit", Touch_EnableEdit_f, "enable button editing mode" );
Cmd_AddCommand( "touch_disableedit", Touch_DisableEdit_f, "disable button editing mode" );
Cmd_AddRestrictedCommand( "touch_enableedit", Touch_EnableEdit_f, "enable button editing mode" );
Cmd_AddRestrictedCommand( "touch_disableedit", Touch_DisableEdit_f, "disable button editing mode" );
Cmd_AddCommand( "touch_settexture", Touch_SetTexture_f, "change button texture" );
Cmd_AddCommand( "touch_setcolor", Touch_SetColor_f, "change button color" );
Cmd_AddCommand( "touch_setcommand", Touch_SetCommand_f, "change button command" );
Cmd_AddCommand( "touch_setflags", Touch_SetFlags_f, "change button flags (be careful)" );
Cmd_AddCommand( "touch_show", Touch_Show_f, "show button" );
Cmd_AddCommand( "touch_hide", Touch_Hide_f, "hide button" );
Cmd_AddCommand( "touch_list", Touch_ListButtons_f, "list buttons" );
Cmd_AddCommand( "touch_removeall", Touch_RemoveAll_f, "remove all buttons" );
Cmd_AddCommand( "touch_loaddefaults", Touch_LoadDefaults_f, "generate config from defaults" );
Cmd_AddCommand( "touch_roundall", Touch_RoundAll_f, "round all buttons coordinates to grid" );
Cmd_AddCommand( "touch_exportconfig", Touch_ExportConfig_f, "export config keeping aspect ratio" );
Cmd_AddRestrictedCommand( "touch_list", Touch_ListButtons_f, "list buttons" );
Cmd_AddRestrictedCommand( "touch_removeall", Touch_RemoveAll_f, "remove all buttons" );
Cmd_AddRestrictedCommand( "touch_loaddefaults", Touch_LoadDefaults_f, "generate config from defaults" );
Cmd_AddRestrictedCommand( "touch_roundall", Touch_RoundAll_f, "round all buttons coordinates to grid" );
Cmd_AddRestrictedCommand( "touch_exportconfig", Touch_ExportConfig_f, "export config keeping aspect ratio" );
Cmd_AddCommand( "touch_set_stroke", Touch_Stroke_f, "set global stroke width and color" );
Cmd_AddCommand( "touch_setclientonly", Touch_SetClientOnly_f, "when 1, only client buttons are shown" );
Cmd_AddCommand( "touch_reloadconfig", Touch_ReloadConfig_f, "load config, not saving changes" );
Cmd_AddCommand( "touch_writeconfig", Touch_WriteConfig, "save current config" );
Cmd_AddCommand( "touch_deleteprofile", Touch_DeleteProfile_f, "delete profile by name" );
Cmd_AddCommand( "touch_generate_code", Touch_GenerateCode_f, "create code sample for mobility API" );
Cmd_AddRestrictedCommand( "touch_reloadconfig", Touch_ReloadConfig_f, "load config, not saving changes" );
Cmd_AddRestrictedCommand( "touch_writeconfig", Touch_WriteConfig, "save current config" );
Cmd_AddRestrictedCommand( "touch_deleteprofile", Touch_DeleteProfile_f, "delete profile by name" );
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_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" );
// not saved, just runtime state for scripting
touch_in_menu = Cvar_Get( "touch_in_menu", "0", 0, "draw touch in menu (for internal use only)" );
touch_in_menu = Cvar_Get( "touch_in_menu", "0", FCVAR_FILTERABLE, "draw touch in menu (for internal use only)" );
// sensitivity configuration
touch_forwardzone = Cvar_Get( "touch_forwardzone", "0.06", 0, "forward touch zone" );
touch_sidezone = Cvar_Get( "touch_sidezone", "0.06", 0, "side touch zone" );
touch_pitch = Cvar_Get( "touch_pitch", "90", 0, "touch pitch sensitivity" );
touch_yaw = Cvar_Get( "touch_yaw", "120", 0, "touch yaw sensitivity" );
touch_nonlinear_look = Cvar_Get( "touch_nonlinear_look", "0", 0, "enable nonlinear touch look" );
touch_pow_factor = Cvar_Get( "touch_pow_factor", "1.3", 0, "set > 1 to enable" );
touch_pow_mult = Cvar_Get( "touch_pow_mult", "400.0", 0, "power multiplier, usually 200-1000" );
touch_exp_mult = Cvar_Get( "touch_exp_mult", "0", 0, "exponent multiplier, usually 20-200, 0 to disable" );
touch_forwardzone = Cvar_Get( "touch_forwardzone", "0.06", FCVAR_FILTERABLE, "forward touch zone" );
touch_sidezone = Cvar_Get( "touch_sidezone", "0.06", FCVAR_FILTERABLE, "side touch zone" );
touch_pitch = Cvar_Get( "touch_pitch", "90", FCVAR_FILTERABLE, "touch pitch sensitivity" );
touch_yaw = Cvar_Get( "touch_yaw", "120", FCVAR_FILTERABLE, "touch yaw sensitivity" );
touch_nonlinear_look = Cvar_Get( "touch_nonlinear_look", "0", FCVAR_FILTERABLE, "enable nonlinear touch look" );
touch_pow_factor = Cvar_Get( "touch_pow_factor", "1.3", FCVAR_FILTERABLE, "set > 1 to enable" );
touch_pow_mult = Cvar_Get( "touch_pow_mult", "400.0", FCVAR_FILTERABLE, "power multiplier, usually 200-1000" );
touch_exp_mult = Cvar_Get( "touch_exp_mult", "0", FCVAR_FILTERABLE, "exponent multiplier, usually 20-200, 0 to disable" );
// touch.cfg
touch_grid_count = Cvar_Get( "touch_grid_count", "50", 0, "touch grid count" );
touch_grid_enable = Cvar_Get( "touch_grid_enable", "1", 0, "enable touch grid" );
touch_config_file = Cvar_Get( "touch_config_file", "touch.cfg", FCVAR_ARCHIVE, "current touch profile file" );
touch_precise_amount = Cvar_Get( "touch_precise_amount", "0.5", 0, "sensitivity multiplier for precise-look" );
touch_grid_count = Cvar_Get( "touch_grid_count", "50", FCVAR_FILTERABLE, "touch grid count" );
touch_grid_enable = Cvar_Get( "touch_grid_enable", "1", FCVAR_FILTERABLE, "enable touch grid" );
touch_config_file = Cvar_Get( "touch_config_file", "touch.cfg", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "current touch profile file" );
touch_precise_amount = Cvar_Get( "touch_precise_amount", "0.5", FCVAR_FILTERABLE, "sensitivity multiplier for precise-look" );
touch_highlight_r = Cvar_Get( "touch_highlight_r", "1.0", 0, "highlight r color" );
touch_highlight_g = Cvar_Get( "touch_highlight_g", "1.0", 0, "highlight g color" );
touch_highlight_b = Cvar_Get( "touch_highlight_b", "1.0", 0, "highlight b color" );
touch_highlight_a = Cvar_Get( "touch_highlight_a", "1.0", 0, "highlight alpha" );
touch_dpad_radius = Cvar_Get( "touch_dpad_radius", "1.0", 0, "dpad radius multiplier" );
touch_joy_radius = Cvar_Get( "touch_joy_radius", "1.0", 0, "joy radius multiplier" );
touch_move_indicator = Cvar_Get( "touch_move_indicator", "0.0", 0, "indicate move events (0 to disable)" );
touch_joy_texture = Cvar_Get( "touch_joy_texture", "touch_default/joy.tga", 0, "texture for move indicator");
touch_dpad_radius = Cvar_Get( "touch_dpad_radius", "1.0", FCVAR_FILTERABLE, "dpad radius multiplier" );
touch_joy_radius = Cvar_Get( "touch_joy_radius", "1.0", FCVAR_FILTERABLE, "joy radius multiplier" );
touch_move_indicator = Cvar_Get( "touch_move_indicator", "0.0", FCVAR_FILTERABLE, "indicate move events (0 to disable)" );
touch_joy_texture = Cvar_Get( "touch_joy_texture", "touch_default/joy.tga", FCVAR_FILTERABLE, "texture for move indicator");
// input devices cvar
touch_enable = Cvar_Get( "touch_enable", DEFAULT_TOUCH_ENABLE, FCVAR_ARCHIVE, "enable touch controls" );
touch_emulate = Cvar_Get( "touch_emulate", "0", FCVAR_ARCHIVE, "emulate touch with mouse" );
touch_enable = Cvar_Get( "touch_enable", DEFAULT_TOUCH_ENABLE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enable touch controls" );
touch_emulate = Cvar_Get( "touch_emulate", "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "emulate touch with mouse" );
/// TODO: touch sdl platform
// SDL_SetHint( SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH, "1" );
@@ -1630,7 +1675,9 @@ static qboolean Touch_ButtonPress( touchbuttonlist_t *list, touchEventType type,
// command down: just execute command
Q_snprintf( command, sizeof( command ), "%s\n", button->command );
Cbuf_AddText( command );
if( FBitSet( B( flags ), TOUCH_FL_UNPRIVILEGED ))
Cbuf_AddFilteredText( command );
else Cbuf_AddText( command );
// increase precision
if( FBitSet( B(flags), TOUCH_FL_PRECISION ))
@@ -1654,7 +1701,9 @@ static qboolean Touch_ButtonPress( touchbuttonlist_t *list, touchEventType type,
Q_snprintf( touch.wheel_end, sizeof( touch.wheel_end ), "%s\n", Cmd_Argv( 3 ) );
if( Q_snprintf( command, sizeof( command ), "%s\n", Cmd_Argv( 4 ) ) > 1)
{
Cbuf_AddText( command );
if( FBitSet( B( flags ), TOUCH_FL_UNPRIVILEGED ))
Cbuf_AddFilteredText( command );
else Cbuf_AddText( command );
touch.wheel_count++;
}
@@ -1776,8 +1825,12 @@ static qboolean Touch_ButtonPress( touchbuttonlist_t *list, touchEventType type,
char command[256];
Q_snprintf( command, sizeof( command ), "%s\n", button->command );
command[0] = '-';
Cbuf_AddText( command );
if( FBitSet( B( flags ), TOUCH_FL_UNPRIVILEGED ))
Cbuf_AddFilteredText( command );
else Cbuf_AddText( command );
}
// disable precision mode
@@ -1791,7 +1844,11 @@ static qboolean Touch_ButtonPress( touchbuttonlist_t *list, touchEventType type,
if( button->type == touch_wheel )
{
if( touch.wheel_count )
Cbuf_AddText( touch.wheel_end );
{
if( FBitSet( B( flags ), TOUCH_FL_UNPRIVILEGED ))
Cbuf_AddFilteredText( touch.wheel_end );
else Cbuf_AddText( touch.wheel_end );
}
// disable precision mode
if( B(flags) & TOUCH_FL_PRECISION )

View File

@@ -18,7 +18,7 @@ GNU General Public License for more details.
#include "client.h"
#include "vgui_draw.h"
#ifdef XASH_SDL
#if XASH_SDL
#include <SDL.h>
#endif
@@ -30,17 +30,16 @@ qboolean in_mouseinitialized;
qboolean in_mouse_suspended;
POINT in_lastvalidpos;
qboolean in_mouse_savedpos;
static int in_mstate = 0;
static struct inputstate_s
{
float lastpitch, lastyaw;
} inputstate;
extern convar_t *vid_fullscreen;
convar_t *m_enginemouse;
convar_t *m_pitch;
convar_t *m_yaw;
convar_t *m_enginesens;
convar_t *m_ignore;
convar_t *cl_forwardspeed;
convar_t *cl_sidespeed;
@@ -48,6 +47,8 @@ convar_t *cl_backspeed;
convar_t *look_filter;
convar_t *m_rawinput;
static qboolean s_bRawInput, s_bMouseGrab;
/*
================
IN_CollectInputDevices
@@ -111,14 +112,12 @@ IN_StartupMouse
*/
void IN_StartupMouse( void )
{
m_ignore = Cvar_Get( "m_ignore", DEFAULT_M_IGNORE, FCVAR_ARCHIVE , "ignore mouse events" );
m_ignore = Cvar_Get( "m_ignore", DEFAULT_M_IGNORE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "ignore mouse events" );
m_enginemouse = Cvar_Get( "m_enginemouse", "0", FCVAR_ARCHIVE, "read mouse events in engine instead of client" );
m_enginesens = Cvar_Get( "m_enginesens", "0.3", FCVAR_ARCHIVE, "mouse sensitivity, when m_enginemouse enabled" );
m_pitch = Cvar_Get( "m_pitch", "0.022", FCVAR_ARCHIVE, "mouse pitch value" );
m_yaw = Cvar_Get( "m_yaw", "0.022", FCVAR_ARCHIVE, "mouse yaw value" );
look_filter = Cvar_Get( "look_filter", "0", FCVAR_ARCHIVE, "filter look events making it smoother" );
m_rawinput = Cvar_Get( "m_rawinput", "1", FCVAR_ARCHIVE, "enable mouse raw input" );
m_pitch = Cvar_Get( "m_pitch", "0.022", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "mouse pitch value" );
m_yaw = Cvar_Get( "m_yaw", "0.022", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "mouse yaw value" );
look_filter = Cvar_Get( "look_filter", "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "filter look events making it smoother" );
m_rawinput = Cvar_Get( "m_rawinput", "1", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enable mouse raw input" );
// You can use -nomouse argument to prevent using mouse from client
// -noenginemouse will disable all mouse input
@@ -127,21 +126,9 @@ void IN_StartupMouse( void )
in_mouseinitialized = true;
}
static void IN_ActivateCursor( void )
{
if( cls.key_dest == key_menu )
{
#ifdef XASH_SDL
SDL_SetCursor( in_mousecursor );
#endif
}
}
void GAME_EXPORT IN_SetCursor( void *hCursor )
{
in_mousecursor = hCursor;
IN_ActivateCursor();
// stub
}
/*
@@ -190,47 +177,15 @@ void IN_ToggleClientMouse( int newstate, int oldstate )
if( oldstate == key_game )
{
if( cls.initialized )
clgame.dllFuncs.IN_DeactivateMouse();
IN_DeactivateMouse();
}
else if( newstate == key_game )
{
// reset mouse pos, so cancel effect in game
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
if( CVAR_TO_BOOL( touch_enable ) )
{
SDL_SetRelativeMouseMode( SDL_FALSE );
SDL_SetWindowGrab( host.hWnd, SDL_FALSE );
}
else
#endif
{
Platform_SetMousePos( host.window_center_x, host.window_center_y );
#if XASH_SDL
SDL_SetWindowGrab( host.hWnd, SDL_TRUE );
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
if ( clgame.dllFuncs.pfnLookEvent || ( clgame.client_dll_uses_sdl && CVAR_TO_BOOL( m_rawinput ) ) )
{
SDL_SetRelativeMouseMode( SDL_TRUE );
}
#endif
#endif // XASH_SDL
}
if( cls.initialized )
clgame.dllFuncs.IN_ActivateMouse();
IN_ActivateMouse();
}
if( ( newstate == key_menu || newstate == key_console || newstate == key_message ) && ( !CL_IsBackgroundMap() || CL_IsBackgroundDemo( )))
{
#ifdef XASH_SDL
SDL_SetWindowGrab(host.hWnd, SDL_FALSE);
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
if ( clgame.dllFuncs.pfnLookEvent || ( clgame.client_dll_uses_sdl && CVAR_TO_BOOL( m_rawinput ) ) )
{
SDL_SetRelativeMouseMode( SDL_FALSE );
}
#endif
#endif // XASH_SDL
#if XASH_ANDROID
Android_ShowMouse( true );
#endif
@@ -249,6 +204,65 @@ void IN_ToggleClientMouse( int newstate, int oldstate )
}
}
void IN_CheckMouseState( qboolean active )
{
#if XASH_WIN32
qboolean useRawInput = CVAR_TO_BOOL( m_rawinput ) && clgame.client_dll_uses_sdl || clgame.dllFuncs.pfnLookEvent;
#else
qboolean useRawInput = true; // always use SDL code
#endif
if( active && useRawInput && !host.mouse_visible && cls.state == ca_active )
{
if( !s_bRawInput )
{
#if XASH_SDL == 2
SDL_GetRelativeMouseState( NULL, NULL );
SDL_SetRelativeMouseMode( SDL_TRUE );
#endif
// Con_Printf( "Enable relative mode\n" );
s_bRawInput = true;
}
}
else
{
if( s_bRawInput )
{
#if XASH_SDL == 2
SDL_GetRelativeMouseState( NULL, NULL );
SDL_SetRelativeMouseMode( SDL_FALSE );
#endif
// Con_Printf( "Disable relative mode\n" );
s_bRawInput = false;
}
}
if( active && !host.mouse_visible && cls.state == ca_active )
{
if( !s_bMouseGrab )
{
#if XASH_SDL
SDL_SetWindowGrab( host.hWnd, SDL_TRUE );
#endif
// Con_Printf( "Enable grab\n" );
s_bMouseGrab = true;
}
}
else
{
if( s_bMouseGrab )
{
#if XASH_SDL
SDL_SetWindowGrab( host.hWnd, SDL_FALSE );
#endif
// Con_Printf( "Disable grab\n" );
s_bMouseGrab = false;
}
}
}
/*
===========
IN_ActivateMouse
@@ -256,58 +270,14 @@ IN_ActivateMouse
Called when the window gains focus or changes in some way
===========
*/
void IN_ActivateMouse( qboolean force )
void IN_ActivateMouse( void )
{
int width, height;
static int oldstate;
if( !in_mouseinitialized )
return;
if( CL_Active() && host.mouse_visible && !force )
return; // VGUI controls
if( cls.key_dest == key_menu && !Cvar_VariableInteger( "fullscreen" ))
{
// check for mouse leave-entering
if( !in_mouse_suspended && !UI_MouseInRect( ))
in_mouse_suspended = true;
if( oldstate != in_mouse_suspended )
{
if( in_mouse_suspended )
{
#ifdef XASH_SDL
/// TODO: Platform_ShowCursor
if( !touch_emulate )
SDL_ShowCursor( SDL_FALSE );
#endif
UI_ShowCursor( false );
}
}
oldstate = in_mouse_suspended;
if( in_mouse_suspended )
{
in_mouse_suspended = false;
in_mouseactive = false; // re-initialize mouse
UI_ShowCursor( true );
}
}
if( in_mouseactive ) return;
IN_CheckMouseState( true );
clgame.dllFuncs.IN_ActivateMouse();
in_mouseactive = true;
if( UI_IsVisible( )) return;
if( cls.key_dest == key_game )
{
clgame.dllFuncs.IN_ActivateMouse();
#ifdef XASH_SDL
SDL_GetRelativeMouseState( 0, 0 ); // Reset mouse position
#endif
}
}
/*
@@ -319,20 +289,16 @@ Called when the window loses focus
*/
void IN_DeactivateMouse( void )
{
if( !in_mouseinitialized || !in_mouseactive )
if( !in_mouseinitialized )
return;
if( cls.key_dest == key_game )
{
clgame.dllFuncs.IN_DeactivateMouse();
}
IN_CheckMouseState( false );
clgame.dllFuncs.IN_DeactivateMouse();
in_mouseactive = false;
#ifdef XASH_SDL
SDL_SetWindowGrab( host.hWnd, SDL_FALSE );
#endif // XASH_SDL
}
/*
================
IN_MouseMove
@@ -342,7 +308,7 @@ void IN_MouseMove( void )
{
POINT current_pos;
if( !in_mouseinitialized || !in_mouseactive || !UI_IsVisible( ))
if( !in_mouseinitialized )
return;
// find mouse movement
@@ -352,15 +318,13 @@ void IN_MouseMove( void )
// HACKHACK: show cursor in UI, as mainui doesn't call
// platform-dependent SetCursor anymore
#ifdef XASH_SDL
#if XASH_SDL
if( UI_IsVisible() )
SDL_ShowCursor( SDL_TRUE );
#endif
// if the menu is visible, move the menu cursor
UI_MouseMove( current_pos.x, current_pos.y );
IN_ActivateCursor();
}
/*
@@ -368,73 +332,32 @@ void IN_MouseMove( void )
IN_MouseEvent
===========
*/
void IN_MouseEvent( void )
void IN_MouseEvent( int key, int down )
{
int i;
// touch emu: handle motion
if( CVAR_TO_BOOL( touch_emulate ))
{
if( Key_IsDown( K_SHIFT ) )
Touch_KeyEvent( K_MOUSE2, 2 );
else
Touch_KeyEvent( K_MOUSE1, 2 );
}
if( !in_mouseinitialized || !in_mouseactive )
if( !in_mouseinitialized )
return;
if( m_ignore->value )
return;
if( down )
SetBits( in_mstate, BIT( key ));
else ClearBits( in_mstate, BIT( key ));
if( cls.key_dest == key_game )
{
#if defined( XASH_SDL )
static qboolean ignore; // igonre mouse warp event
int x, y;
Platform_GetMousePos(&x, &y);
if( host.mouse_visible )
SDL_ShowCursor( SDL_TRUE );
else if( !CVAR_TO_BOOL( touch_emulate ) )
SDL_ShowCursor( SDL_FALSE );
// perform button actions
VGui_KeyEvent( K_MOUSE1 + key, down );
if( x < host.window_center_x / 2 ||
y < host.window_center_y / 2 ||
x > host.window_center_x + host.window_center_x / 2 ||
y > host.window_center_y + host.window_center_y / 2 )
{
Platform_SetMousePos( host.window_center_x, host.window_center_y );
ignore = 1; // next mouse event will be mouse warp
return;
}
if ( !ignore )
{
if( !m_enginemouse->value )
{
// a1ba: mouse keys are now separated
// so pass 0 here
clgame.dllFuncs.IN_MouseEvent( 0 );
}
}
else
{
SDL_GetRelativeMouseState( 0, 0 ); // reset relative state
ignore = 0;
}
#endif
return;
// don't do Key_Event here
// client may override IN_MouseEvent
// but by default it calls back to Key_Event anyway
if( in_mouseactive )
clgame.dllFuncs.IN_MouseEvent( in_mstate );
}
else
{
#if XASH_SDL && !XASH_WIN32
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
SDL_SetRelativeMouseMode( SDL_FALSE );
#endif // SDL_VERSION_ATLEAST( 2, 0, 0 )
SDL_ShowCursor( SDL_TRUE );
#endif // XASH_SDL && !XASH_WIN32
IN_MouseMove();
// perform button actions
Key_Event( K_MOUSE1 + key, down );
}
}
@@ -462,9 +385,9 @@ IN_Init
*/
void IN_Init( void )
{
cl_forwardspeed = Cvar_Get( "cl_forwardspeed", "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL, "Default forward move speed" );
cl_backspeed = Cvar_Get( "cl_backspeed", "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL, "Default back move speed" );
cl_sidespeed = Cvar_Get( "cl_sidespeed", "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL, "Default side move speed" );
cl_forwardspeed = Cvar_Get( "cl_forwardspeed", "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL | FCVAR_FILTERABLE, "Default forward move speed" );
cl_backspeed = Cvar_Get( "cl_backspeed", "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL | FCVAR_FILTERABLE, "Default back move speed" );
cl_sidespeed = Cvar_Get( "cl_sidespeed", "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL | FCVAR_FILTERABLE, "Default side move speed" );
if( !Host_IsDedicated() )
{
@@ -571,13 +494,9 @@ static void IN_JoyAppendMove( usercmd_t *cmd, float forwardmove, float sidemove
}
}
void IN_CollectInput( float *forward, float *side, float *pitch, float *yaw, qboolean includeMouse, qboolean includeSdlMouse )
static void IN_CollectInput( float *forward, float *side, float *pitch, float *yaw, qboolean includeMouse )
{
if( includeMouse
#if XASH_SDL
&& includeSdlMouse
#endif
)
if( includeMouse )
{
float x, y;
Platform_MouseMove( &x, &y );
@@ -626,7 +545,7 @@ void IN_EngineAppendMove( float frametime, void *cmd1, qboolean active )
{
float sensitivity = 1;//( (float)cl.local.scr_fov / (float)90.0f );
IN_CollectInput( &forward, &side, &pitch, &yaw, in_mouseinitialized && !CVAR_TO_BOOL( m_ignore ), m_enginemouse->value );
IN_CollectInput( &forward, &side, &pitch, &yaw, false );
IN_JoyAppendMove( cmd, forward, side );
@@ -635,32 +554,22 @@ void IN_EngineAppendMove( float frametime, void *cmd1, qboolean active )
cmd->viewangles[YAW] += yaw * sensitivity;
cmd->viewangles[PITCH] += pitch * sensitivity;
cmd->viewangles[PITCH] = bound( -90, cmd->viewangles[PITCH], 90 );
VectorCopy(cmd->viewangles, cl.viewangles);
VectorCopy( cmd->viewangles, cl.viewangles );
}
}
}
/*
==================
Host_InputFrame
Called every frame, even if not generating commands
==================
*/
void Host_InputFrame( void )
void IN_Commands( void )
{
qboolean shutdownMouse = false;
float forward = 0, side = 0, pitch = 0, yaw = 0;
Sys_SendKeyEvents ();
#ifdef XASH_USE_EVDEV
IN_EvdevFrame();
#endif
if( clgame.dllFuncs.pfnLookEvent )
{
IN_CollectInput( &forward, &side, &pitch, &yaw, in_mouseinitialized && !CVAR_TO_BOOL( m_ignore ), true );
float forward = 0, side = 0, pitch = 0, yaw = 0;
IN_CollectInput( &forward, &side, &pitch, &yaw, in_mouseinitialized && !CVAR_TO_BOOL( m_ignore ) );
if( cls.key_dest == key_game )
{
@@ -672,22 +581,21 @@ void Host_InputFrame( void )
if( !in_mouseinitialized )
return;
if( host.status != HOST_FRAME )
{
IN_DeactivateMouse();
return;
}
IN_CheckMouseState( in_mouseactive );
}
// release mouse during pause or console typeing
if( cl.paused && cls.key_dest == key_game )
shutdownMouse = true;
/*
==================
Host_InputFrame
if( shutdownMouse && !Cvar_VariableInteger( "fullscreen" ))
{
IN_DeactivateMouse();
return;
}
Called every frame, even if not generating commands
==================
*/
void Host_InputFrame( void )
{
Sys_SendKeyEvents ();
IN_Commands();
IN_ActivateMouse( false );
IN_MouseMove();
}

View File

@@ -33,8 +33,8 @@ extern qboolean in_mouseinitialized;
void IN_Init( void );
void Host_InputFrame( void );
void IN_Shutdown( void );
void IN_MouseEvent( void );
void IN_ActivateMouse( qboolean force );
void IN_MouseEvent( int key, int down );
void IN_ActivateMouse( void );
void IN_DeactivateMouse( void );
void IN_MouseSavePos( void );
void IN_MouseRestorePos( void );
@@ -61,12 +61,9 @@ extern convar_t *touch_enable;
extern convar_t *touch_emulate;
void Touch_Draw( void );
void Touch_SetClientOnly( qboolean state );
void Touch_RemoveButton( const char *name );
void Touch_HideButtons( const char *name, unsigned char hide );
//void IN_TouchSetCommand( const char *name, const char *command );
//void IN_TouchSetTexture( const char *name, const char *texture );
//void IN_TouchSetColor( const char *name, byte *color );
void Touch_SetClientOnly( byte state );
void Touch_RemoveButton( const char *name, qboolean privileged );
void Touch_HideButtons( const char *name, unsigned char hide, qboolean privileged );
void Touch_AddClientButton( const char *name, const char *texture, const char *command, float x1, float y1, float x2, float y2, byte *color, int round, float aspect, int flags );
void Touch_AddDefaultButton( const char *name, const char *texturefile, const char *command, float x1, float y1, float x2, float y2, byte *color, int round, float aspect, int flags );
void Touch_WriteConfig( void );

View File

@@ -462,6 +462,7 @@ Writes lines containing "bind key value"
void Key_WriteBindings( file_t *f )
{
int i;
string newCommand;
if( !f ) return;
@@ -472,7 +473,8 @@ void Key_WriteBindings( file_t *f )
if( !COM_CheckString( keys[i].binding ))
continue;
FS_Printf( f, "bind %s \"%s\"\n", Key_KeynumToString( i ), keys[i].binding );
Cmd_Escape( newCommand, keys[i].binding, sizeof( newCommand ));
FS_Printf( f, "bind %s \"%s\"\n", Key_KeynumToString( i ), newCommand );
}
}
@@ -512,18 +514,18 @@ void Key_Init( void )
keyname_t *kn;
// register our functions
Cmd_AddCommand( "bind", Key_Bind_f, "binds a command to the specified key in bindmap" );
Cmd_AddCommand( "unbind", Key_Unbind_f, "removes a command on the specified key in bindmap" );
Cmd_AddCommand( "unbindall", Key_Unbindall_f, "removes all commands from all keys in bindmap" );
Cmd_AddCommand( "resetkeys", Key_Reset_f, "reset all keys to their default values" );
Cmd_AddRestrictedCommand( "bind", Key_Bind_f, "binds a command to the specified key in bindmap" );
Cmd_AddRestrictedCommand( "unbind", Key_Unbind_f, "removes a command on the specified key in bindmap" );
Cmd_AddRestrictedCommand( "unbindall", Key_Unbindall_f, "removes all commands from all keys in bindmap" );
Cmd_AddRestrictedCommand( "resetkeys", Key_Reset_f, "reset all keys to their default values" );
Cmd_AddCommand( "bindlist", Key_Bindlist_f, "display current key bindings" );
Cmd_AddCommand( "makehelp", Key_EnumCmds_f, "write help.txt that contains all console cvars and cmds" );
// setup default binding. "unbindall" from config.cfg will be reset it
for( kn = keynames; kn->name; kn++ ) Key_SetBinding( kn->keynum, kn->binding );
osk_enable = Cvar_Get( "osk_enable", "0", FCVAR_ARCHIVE, "enable built-in on-screen keyboard" );
key_rotate = Cvar_Get( "key_rotate", "0", FCVAR_ARCHIVE, "rotate arrow keys (0-3)" );
osk_enable = Cvar_Get( "osk_enable", "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enable built-in on-screen keyboard" );
key_rotate = Cvar_Get( "key_rotate", "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "rotate arrow keys (0-3)" );
}
@@ -812,9 +814,9 @@ void Key_EnableTextInput( qboolean enable, qboolean force )
OSK_EnableTextInput( enable, force );
return;
}
if( enable && ( !host.textmode || force ) )
if( enable && ( !host.textmode || force ))
Platform_EnableTextInput( true );
else if( !enable )
else if( !enable && ( host.textmode || force ))
Platform_EnableTextInput( false );
host.textmode = enable;
@@ -1042,7 +1044,7 @@ static qboolean OSK_KeyEvent( int key, int down )
else
osk.curlayout++;
osk.shift = osk.curbutton.val == OSK_SHIFT;
osk.shift = true;
osk.curbutton.val = osk_keylayout[osk.curlayout][osk.curbutton.y][osk.curbutton.x];
break;
case OSK_BACKSPACE:

View File

@@ -13,7 +13,7 @@ convar_t *gl_showtextures;
convar_t *r_decals;
convar_t *r_adjust_fov;
convar_t *r_showtree;
convar_t *gl_wgl_msaa_samples;
convar_t *gl_msaa_samples;
convar_t *gl_clear;
convar_t *r_refdll;
@@ -330,7 +330,7 @@ static ref_api_t gEngfuncs =
_Mem_Realloc,
_Mem_Free,
COM_LoadLibrary,
_COM_LoadLibrary,
COM_FreeLibrary,
COM_GetProcAddress,
@@ -642,11 +642,28 @@ qboolean R_Init( void )
gl_showtextures = Cvar_Get( "r_showtextures", "0", FCVAR_CHEAT, "show all uploaded textures" );
r_adjust_fov = Cvar_Get( "r_adjust_fov", "1", FCVAR_ARCHIVE, "making FOV adjustment for wide-screens" );
r_decals = Cvar_Get( "r_decals", "4096", FCVAR_ARCHIVE, "sets the maximum number of decals" );
gl_wgl_msaa_samples = Cvar_Get( "gl_wgl_msaa_samples", "0", FCVAR_GLCONFIG, "samples number for multisample anti-aliasing" );
gl_msaa_samples = Cvar_Get( "gl_msaa_samples", "0", FCVAR_GLCONFIG, "samples number for multisample anti-aliasing" );
gl_clear = Cvar_Get( "gl_clear", "0", FCVAR_ARCHIVE, "clearing screen after each frame" );
r_showtree = Cvar_Get( "r_showtree", "0", FCVAR_ARCHIVE, "build the graph of visible BSP tree" );
r_refdll = Cvar_Get( "r_refdll", "", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "choose renderer implementation, if supported" );
// cvars that are expected to exist
Cvar_Get( "r_speeds", "0", FCVAR_ARCHIVE, "shows renderer speeds" );
Cvar_Get( "r_fullbright", "0", FCVAR_CHEAT, "disable lightmaps, get fullbright for entities" );
Cvar_Get( "r_norefresh", "0", 0, "disable 3D rendering (use with caution)" );
Cvar_Get( "r_dynamic", "1", FCVAR_ARCHIVE, "allow dynamic lighting (dlights, lightstyles)" );
Cvar_Get( "r_lightmap", "0", FCVAR_CHEAT, "lightmap debugging tool" );
Cvar_Get( "tracerred", "0.8", 0, "tracer red component weight ( 0 - 1.0 )" );
Cvar_Get( "tracergreen", "0.8", 0, "tracer green component weight ( 0 - 1.0 )" );
Cvar_Get( "tracerblue", "0.4", 0, "tracer blue component weight ( 0 - 1.0 )" );
Cvar_Get( "traceralpha", "0.5", 0, "tracer alpha amount ( 0 - 1.0 )" );
Cvar_Get( "r_sprite_lerping", "1", FCVAR_ARCHIVE, "enables sprite animation lerping" );
Cvar_Get( "r_sprite_lighting", "1", FCVAR_ARCHIVE, "enables sprite lighting (blood etc)" );
Cvar_Get( "r_drawviewmodel", "1", 0, "draw firstperson weapon model" );
Cvar_Get( "r_glowshellfreq", "2.2", 0, "glowing shell frequency update" );
// cvars that are expected to exist by client.dll
// refdll should just get pointer to them
Cvar_Get( "r_drawentities", "1", FCVAR_CHEAT, "render entities" );

View File

@@ -33,7 +33,6 @@ GNU General Public License for more details.
#define MAXDLY (STEREODLY + 1)
#define MAXLP 10
#define MAXPRESETS 29
typedef struct sx_preset_s
{
@@ -79,7 +78,7 @@ typedef struct dly_s
int *lpdelayline;
} dly_t;
const sx_preset_t rgsxpre[MAXPRESETS] =
const sx_preset_t rgsxpre[] =
{
// -------reverb-------- -------delay--------
// lp mod size refl rvblp delay feedback dlylp left
@@ -116,7 +115,7 @@ const sx_preset_t rgsxpre[MAXPRESETS] =
// 0x0045dca8 enginegl.exe
// SHA256: 42383d32cd712e59ee2c1bd78b7ba48814e680e7026c4223e730111f34a60d66
const sx_preset_t rgsxpre_hlalpha052[MAXPRESETS] =
const sx_preset_t rgsxpre_hlalpha052[] =
{
// -------reverb-------- -------delay--------
// lp mod size refl rvblp delay feedback dlylp left
@@ -482,7 +481,7 @@ void DLY_CheckNewDelayVal( void )
}
else
{
delay = min( delay, MAX_MONO_DELAY );
delay = Q_min( delay, MAX_MONO_DELAY );
dly->delaysamples = (int)(delay * idsp_dma_speed) << sxhires;
// init dly
@@ -882,7 +881,7 @@ void CheckNewDspPresets( void )
else idsp_room = room_type->value;
// don't pass invalid presets
idsp_room = bound( 0, idsp_room, MAXPRESETS - 1 );
idsp_room = bound( 0, idsp_room, MAX_ROOM_TYPES );
if( FBitSet( hisound->flags, FCVAR_CHANGED ))
{
@@ -893,9 +892,6 @@ void CheckNewDspPresets( void )
if( idsp_room == room_typeprev && idsp_room == 0 )
return;
if( idsp_room > MAX_ROOM_TYPES )
return;
if( idsp_room != room_typeprev )
{
const sx_preset_t *cur;

View File

@@ -35,18 +35,18 @@ int total_channels;
int soundtime; // sample PAIRS
int paintedtime; // sample PAIRS
static CVAR_DEFINE( s_volume, "volume", "0.7", FCVAR_ARCHIVE, "sound volume" );
CVAR_DEFINE( s_musicvolume, "MP3Volume", "1.0", FCVAR_ARCHIVE, "background music volume" );
static CVAR_DEFINE( s_mixahead, "_snd_mixahead", "0.12", 0, "how much sound to mix ahead of time" );
static CVAR_DEFINE_AUTO( s_show, "0", FCVAR_ARCHIVE, "show playing sounds" );
CVAR_DEFINE_AUTO( s_lerping, "0", FCVAR_ARCHIVE, "apply interpolation to sound output" );
static CVAR_DEFINE( s_ambient_level, "ambient_level", "0.3", FCVAR_ARCHIVE, "volume of environment noises (water and wind)" );
static CVAR_DEFINE( s_ambient_fade, "ambient_fade", "1000", FCVAR_ARCHIVE, "rate of volume fading when client is moving" );
static CVAR_DEFINE_AUTO( s_combine_sounds, "0", FCVAR_ARCHIVE, "combine channels with same sounds" );
CVAR_DEFINE_AUTO( snd_mute_losefocus, "1", FCVAR_ARCHIVE, "silence the audio when game window loses focus" );
static CVAR_DEFINE( s_volume, "volume", "0.7", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "sound volume" );
CVAR_DEFINE( s_musicvolume, "MP3Volume", "1.0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "background music volume" );
static CVAR_DEFINE( s_mixahead, "_snd_mixahead", "0.12", FCVAR_FILTERABLE, "how much sound to mix ahead of time" );
static CVAR_DEFINE_AUTO( s_show, "0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "show playing sounds" );
CVAR_DEFINE_AUTO( s_lerping, "0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "apply interpolation to sound output" );
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_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" );
CVAR_DEFINE_AUTO( s_test, "0", 0, "engine developer cvar for quick testing new features" );
CVAR_DEFINE_AUTO( s_samplecount, "0", FCVAR_ARCHIVE, "sample count (0 for default value)" );
CVAR_DEFINE_AUTO( s_warn_late_precache, "0", FCVAR_ARCHIVE, "warn about late precached sounds on client-side" );
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" );
/*
=============================================================================
@@ -533,6 +533,8 @@ void S_StartSound( const vec3_t pos, int ent, int chan, sound_t handle, float fv
// spatialize
memset( target_chan, 0, sizeof( *target_chan ));
pitch *= (sys_timescale.value + 1) / 2;
VectorCopy( pos, target_chan->origin );
target_chan->staticsound = ( ent == 0 ) ? true : false;
target_chan->use_loop = (flags & SND_STOP_LOOPING) ? false : true;
@@ -788,6 +790,8 @@ void S_AmbientSound( const vec3_t pos, int ent, sound_t handle, float fvol, floa
return;
}
pitch *= (sys_timescale.value + 1) / 2;
// never update positions if source entity is 0
ch->staticsound = ( ent == 0 ) ? true : false;
ch->use_loop = (flags & SND_STOP_LOOPING) ? false : true;
@@ -1151,7 +1155,6 @@ void S_RawSamples( uint samples, uint rate, word width, word channels, const byt
int snd_vol = 128;
if( entnum < 0 ) snd_vol = 256; // bg track or movie track
if( snd_vol < 0 ) snd_vol = 0; // fixup negative values
S_RawEntSamples( entnum, samples, rate, width, channels, data, snd_vol );
}

View File

@@ -809,7 +809,7 @@ void S_MixBufferUpsample2x( int count, portable_samplepair_t *pbuffer, portable_
// zero out all paintbuffers
void MIX_ClearAllPaintBuffers( int SampleCount, qboolean clearFilters )
{
int count = min( SampleCount, PAINTBUFFER_SIZE );
int count = Q_min( SampleCount, PAINTBUFFER_SIZE );
int i;
// zero out all paintbuffer data (ignore sampleCount)

File diff suppressed because it is too large Load Diff

View File

@@ -21,31 +21,13 @@ GNU General Public License for more details.
#include "keydefs.h"
#include "ref_common.h"
#include "input.h"
#ifdef XASH_SDL
#include <SDL.h>
static SDL_Cursor* s_pDefaultCursor[20];
#endif
#include "platform/platform.h"
static enum VGUI_KeyCode s_pVirtualKeyTrans[256];
static enum VGUI_DefaultCursor s_currentCursor;
static VGUI_DefaultCursor s_currentCursor;
static HINSTANCE s_pVGuiSupport; // vgui_support library
static convar_t *vgui_utf8 = NULL;
// Helper functions for vgui backend
/*void VGUI_HideCursor( void )
{
host.mouse_visible = false;
SDL_HideCursor();
}
void VGUI_ShowCursor( void )
{
host.mouse_visible = true;
SDL_ShowCursor();
}*/
void GAME_EXPORT *VGUI_EngineMalloc(size_t size)
{
return Z_Malloc( size );
@@ -66,70 +48,10 @@ void GAME_EXPORT VGUI_GetMousePos( int *_x, int *_y )
*_x = x / xscale, *_y = y / yscale;
}
void VGUI_InitCursors( void )
void GAME_EXPORT VGUI_CursorSelect( VGUI_DefaultCursor cursor )
{
// load up all default cursors
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
s_pDefaultCursor[dc_none] = NULL;
s_pDefaultCursor[dc_arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
s_pDefaultCursor[dc_ibeam] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM);
s_pDefaultCursor[dc_hourglass]= SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_WAIT);
s_pDefaultCursor[dc_crosshair]= SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_CROSSHAIR);
s_pDefaultCursor[dc_up] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
s_pDefaultCursor[dc_sizenwse] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE);
s_pDefaultCursor[dc_sizenesw] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW);
s_pDefaultCursor[dc_sizewe] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE);
s_pDefaultCursor[dc_sizens] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS);
s_pDefaultCursor[dc_sizeall] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL);
s_pDefaultCursor[dc_no] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO);
s_pDefaultCursor[dc_hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND);
//host.mouse_visible = true;
SDL_SetCursor( s_pDefaultCursor[dc_arrow] );
#endif
}
void GAME_EXPORT VGUI_CursorSelect(enum VGUI_DefaultCursor cursor )
{
qboolean visible;
if( cls.key_dest != key_game || cl.paused )
return;
switch( cursor )
{
case dc_user:
case dc_none:
visible = false;
break;
default:
visible = true;
break;
}
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
/// TODO: platform cursors
if( CVAR_TO_BOOL( touch_emulate ) )
return;
if( host.mouse_visible )
{
SDL_SetRelativeMouseMode( SDL_FALSE );
SDL_SetCursor( s_pDefaultCursor[cursor] );
SDL_ShowCursor( true );
}
else
{
SDL_ShowCursor( false );
if( host.mouse_visible )
SDL_GetRelativeMouseState( NULL, NULL );
Key_EnableTextInput( false, true );
}
//SDL_SetRelativeMouseMode(false);
#endif
if( s_currentCursor == cursor )
return;
Platform_SetCursorType( cursor );
s_currentCursor = cursor;
host.mouse_visible = visible;
}
byte GAME_EXPORT VGUI_GetColor( int i, int j)
@@ -138,21 +60,9 @@ byte GAME_EXPORT VGUI_GetColor( int i, int j)
}
// Define and initialize vgui API
void GAME_EXPORT VGUI_SetVisible( qboolean state )
{
host.mouse_visible=state;
#ifdef XASH_SDL
SDL_ShowCursor( state );
if( !state )
SDL_GetRelativeMouseState( NULL, NULL );
#endif
Key_EnableTextInput( false, true );
}
int GAME_EXPORT VGUI_UtfProcessChar( int in )
{
if( CVAR_TO_BOOL( vgui_utf8 ) )
if( CVAR_TO_BOOL( vgui_utf8 ))
return Con_UtfProcessCharForce( in );
else
return in;
@@ -175,14 +85,15 @@ vguiapi_t vgui =
NULL, // VGUI_GetTextureSizes,
NULL, // VGUI_GenerateTexture,
VGUI_EngineMalloc,
/* VGUI_ShowCursor,
VGUI_HideCursor,*/
VGUI_CursorSelect,
VGUI_GetColor,
VGUI_IsInGame,
VGUI_SetVisible,
NULL,
VGUI_GetMousePos,
VGUI_UtfProcessChar,
Platform_GetClipboardText,
Platform_SetClipboardText,
Platform_GetKeyModifiers,
NULL,
NULL,
NULL,
@@ -190,6 +101,7 @@ vguiapi_t vgui =
NULL,
NULL,
NULL,
NULL
};
qboolean VGui_IsActive( void )
@@ -240,7 +152,6 @@ void VGui_Startup( const char *clientlib, int width, int height )
VGui_FillAPIFromRef( &vgui, &ref.dllFuncs );
#ifdef XASH_INTERNAL_GAMELIBS
s_pVGuiSupport = COM_LoadLibrary( clientlib, false, false );
if( s_pVGuiSupport )
@@ -250,58 +161,70 @@ void VGui_Startup( const char *clientlib, int width, int height )
{
F( &vgui );
vgui.initialized = true;
VGUI_InitCursors();
Con_Reportf( "vgui_support: found interal client support\n" );
Con_Reportf( "vgui_support: found internal client support\n" );
}
else
{
COM_FreeLibrary( s_pVGuiSupport );
}
}
#endif // XASH_INTERNAL_GAMELIBS
// HACKHACK: load vgui with correct path first if specified.
// it will be reused while resolving vgui support and client deps
if( Sys_GetParmFromCmdLine( "-vguilib", vguilib ) )
if( !vgui.initialized )
{
if( Q_strstr( vguilib, ".dll") )
// HACKHACK: load vgui with correct path first if specified.
// it will be reused while resolving vgui support and client deps
if( Sys_GetParmFromCmdLine( "-vguilib", vguilib ))
{
if( Q_strstr( vguilib, ".dll" ))
Q_strncpy( vguiloader, "vgui_support.dll", 256 );
else
Q_strncpy( vguiloader, VGUI_SUPPORT_DLL, 256 );
if( !COM_LoadLibrary( vguilib, false, false ))
Con_Reportf( S_WARN "VGUI preloading failed. Default library will be used! Reason: %s\n", COM_GetLibraryError() );
}
if( Q_strstr( clientlib, ".dll" ))
Q_strncpy( vguiloader, "vgui_support.dll", 256 );
else
if( !vguiloader[0] && !Sys_GetParmFromCmdLine( "-vguiloader", vguiloader ))
Q_strncpy( vguiloader, VGUI_SUPPORT_DLL, 256 );
if( !COM_LoadLibrary( vguilib, false, false ) )
Con_Reportf( S_WARN "VGUI preloading failed. Default library will be used! Reason: %s\n", COM_GetLibraryError());
}
s_pVGuiSupport = COM_LoadLibrary( vguiloader, false, false );
if( Q_strstr( clientlib, ".dll" ) )
Q_strncpy( vguiloader, "vgui_support.dll", 256 );
if( !vguiloader[0] && !Sys_GetParmFromCmdLine( "-vguiloader", vguiloader ) )
Q_strncpy( vguiloader, VGUI_SUPPORT_DLL, 256 );
s_pVGuiSupport = COM_LoadLibrary( vguiloader, false, false );
if( !s_pVGuiSupport )
{
s_pVGuiSupport = COM_LoadLibrary( va( "../%s", vguiloader ), false, false );
}
if( !s_pVGuiSupport )
{
if( FS_FileExists( vguiloader, false ) )
Con_Reportf( S_ERROR "Failed to load vgui_support library: %s\n", COM_GetLibraryError() );
else
Con_Reportf( "vgui_support: not found\n" );
}
else
{
F = COM_GetProcAddress( s_pVGuiSupport, "InitAPI" );
if( F )
if( !s_pVGuiSupport )
{
F( &vgui );
vgui.initialized = true;
VGUI_InitCursors();
s_pVGuiSupport = COM_LoadLibrary( va( "../%s", vguiloader ), false, false );
}
if( !s_pVGuiSupport )
{
if( FS_FileExists( vguiloader, false ))
{
Con_Reportf( S_ERROR "Failed to load vgui_support library: %s\n", COM_GetLibraryError() );
}
else
{
Con_Reportf( "vgui_support: not found\n" );
}
failed = true;
}
else
Con_Reportf( S_ERROR "Failed to find vgui_support library entry point!\n" );
{
F = COM_GetProcAddress( s_pVGuiSupport, "InitAPI" );
if( F )
{
F( &vgui );
vgui.initialized = true;
}
else
{
Con_Reportf( S_ERROR "Failed to find vgui_support library entry point!\n" );
failed = true;
COM_FreeLibrary( s_pVGuiSupport );
}
}
}
}
if( height < 480 )
@@ -498,8 +421,9 @@ void VGui_KeyEvent( int key, int down )
switch( key )
{
case K_MOUSE1:
if( down && host.mouse_visible )
Key_EnableTextInput( true, false );
if( down && host.mouse_visible ) {
Key_EnableTextInput(true, false);
}
vgui.Mouse( down ? MA_PRESSED : MA_RELEASED, MOUSE_LEFT );
return;
case K_MOUSE2:
@@ -535,7 +459,7 @@ void VGui_MouseMove( int x, int y )
void VGui_Paint( void )
{
if(vgui.initialized)
if( vgui.initialized )
vgui.Paint();
}
@@ -551,3 +475,9 @@ void *GAME_EXPORT VGui_GetPanel( void )
return vgui.GetPanel();
return NULL;
}
void VGui_ReportTextInput( const char *text )
{
if ( vgui.initialized )
vgui.TextInput( text );
}

View File

@@ -33,6 +33,7 @@ void VGui_KeyEvent( int key, int down );
void VGui_MouseMove( int x, int y );
qboolean VGui_IsActive( void );
void *VGui_GetPanel( void );
void VGui_ReportTextInput( const char *text );
#ifdef __cplusplus
}
#endif

View File

@@ -190,7 +190,7 @@ void VID_Init( void )
// a1ba: planned to be named vid_mode for compability
// but supported mode list is filled by backends, so numbers are not portable any more
Cmd_AddCommand( "vid_setmode", VID_Mode_f, "display video mode" );
Cmd_AddRestrictedCommand( "vid_setmode", VID_Mode_f, "display video mode" );
R_Init(); // init renderer
}

View File

@@ -36,7 +36,7 @@ extern convar_t *vid_highdpi;
extern convar_t *vid_rotate;
extern convar_t *vid_scale;
extern convar_t *gl_wgl_msaa_samples;
extern convar_t *gl_msaa_samples;
void R_SaveVideoMode( int w, int h, int render_w, int render_h );
void VID_CheckChanges( void );
const char *VID_GetModeString( int vid_mode );

View File

@@ -16,9 +16,9 @@ GNU General Public License for more details.
#ifndef VOX_H
#define VOX_H
#define CVOXWORDMAX 64
#define CVOXZEROSCANMAX 255 // scan up to this many samples for next zero crossing
#define MAX_SENTENCES 4096
#define CVOXWORDMAX 64
#define CVOXFILESENTENCEMAX 4096
#define SENTENCE_INDEX -99999 // unique sentence index
typedef struct voxword_s
@@ -34,13 +34,6 @@ typedef struct voxword_s
sfx_t *sfx; // name and cache pointer
} voxword_t;
typedef struct
{
char *pName;
float length;
} sentence_t;
struct channel_s;
void VOX_LoadWord( struct channel_s *pchan );
void VOX_FreeWord( struct channel_s *pchan );

View File

@@ -229,7 +229,7 @@ void BaseCmd_Stats_f( void )
Con_Printf( "Empty buckets: %d\n", empty );
}
static void BaseCmd_CheckCvars( const char *key, const char *value, void *buffer, void *ptr )
static void BaseCmd_CheckCvars( const char *key, const char *value, const void *unused, void *ptr )
{
base_command_t *v = BaseCmd_Find( HM_CVAR, key );
qboolean *invalid = ptr;

View File

@@ -30,11 +30,15 @@ typedef struct
} cmdbuf_t;
qboolean cmd_wait;
cmdbuf_t cmd_text;
cmdbuf_t cmd_text, filteredcmd_text;
byte cmd_text_buf[MAX_CMD_BUFFER];
byte filteredcmd_text_buf[MAX_CMD_BUFFER];
cmdalias_t *cmd_alias;
uint cmd_condition;
int cmd_condlevel;
static qboolean cmd_currentCommandIsPrivileged;
static void Cmd_ExecuteStringWithPrivilegeCheck( const char *text, qboolean isPrivileged );
/*
=============================================================================
@@ -52,8 +56,10 @@ Cbuf_Init
void Cbuf_Init( void )
{
cmd_text.data = cmd_text_buf;
cmd_text.maxsize = MAX_CMD_BUFFER;
cmd_text.cursize = 0;
filteredcmd_text.data = filteredcmd_text_buf;
filteredcmd_text.maxsize = cmd_text.maxsize = MAX_CMD_BUFFER;
filteredcmd_text.cursize = cmd_text.cursize = 0;
}
/*
@@ -63,8 +69,9 @@ Cbuf_Clear
*/
void Cbuf_Clear( void )
{
memset( cmd_text.data, 0, sizeof( cmd_text_buf ));
cmd_text.cursize = 0;
memset( cmd_text.data, 0, cmd_text.maxsize );
memset( filteredcmd_text.data, 0, filteredcmd_text.maxsize );
cmd_text.cursize = filteredcmd_text.cursize = 0;
}
/*
@@ -88,6 +95,19 @@ void *Cbuf_GetSpace( cmdbuf_t *buf, int length )
return data;
}
static void Cbuf_AddTextToBuffer( cmdbuf_t *buf, const char *text )
{
int l = Q_strlen( text );
if(( buf->cursize + l ) >= buf->maxsize )
{
Con_Reportf( S_WARN "%s: overflow\n", __func__ );
return;
}
memcpy( Cbuf_GetSpace( buf, l ), text, l );
}
/*
============
Cbuf_AddText
@@ -97,16 +117,17 @@ Adds command text at the end of the buffer
*/
void Cbuf_AddText( const char *text )
{
int l = Q_strlen( text );
Cbuf_AddTextToBuffer( &cmd_text, text );
}
if(( cmd_text.cursize + l ) >= cmd_text.maxsize )
{
Con_Reportf( S_WARN "Cbuf_AddText: overflow\n" );
}
else
{
memcpy( Cbuf_GetSpace( &cmd_text, l ), text, l );
}
/*
============
Cbuf_AddFilteredText
============
*/
void Cbuf_AddFilteredText( const char *text )
{
Cbuf_AddTextToBuffer( &filteredcmd_text, text );
}
/*
@@ -117,43 +138,55 @@ Adds command text immediately after the current command
Adds a \n to the text
============
*/
void Cbuf_InsertText( const char *text )
static void Cbuf_InsertTextToBuffer( cmdbuf_t *buf, const char *text )
{
int l = Q_strlen( text );
if(( cmd_text.cursize + l ) >= cmd_text.maxsize )
if(( buf->cursize + l ) >= buf->maxsize )
{
Con_Reportf( S_WARN "Cbuf_InsertText: overflow\n" );
}
else
{
memmove( cmd_text.data + l, cmd_text.data, cmd_text.cursize );
memcpy( cmd_text.data, text, l );
cmd_text.cursize += l;
memmove( buf->data + l, buf->data, buf->cursize );
memcpy( buf->data, text, l );
buf->cursize += l;
}
}
void Cbuf_InsertText( const char *text )
{
Cbuf_InsertTextToBuffer( &cmd_text, text );
}
/*
============
Cbuf_Execute
============
*/
void Cbuf_Execute( void )
void Cbuf_ExecuteCommandsFromBuffer( cmdbuf_t *buf, qboolean isPrivileged, int cmdsToExecute )
{
char *text;
char line[MAX_CMD_LINE];
int i, quotes;
char *comment;
while( cmd_text.cursize )
while( buf->cursize )
{
// limit amount of commands that can be issued
if( cmdsToExecute >= 0 )
{
if( !cmdsToExecute-- )
break;
}
// find a \n or ; line break
text = (char *)cmd_text.data;
text = (char *)buf->data;
quotes = false;
comment = NULL;
for( i = 0; i < cmd_text.cursize; i++ )
for( i = 0; i < buf->cursize; i++ )
{
if( !comment )
{
@@ -162,7 +195,7 @@ void Cbuf_Execute( void )
if( quotes )
{
// make sure i doesn't get > cursize which causes a negative size in memmove, which is fatal --blub
if( i < ( cmd_text.cursize - 1 ) && ( text[i+0] == '\\' && (text[i+1] == '"' || text[i+1] == '\\')))
if( i < ( buf->cursize - 1 ) && ( text[i+0] == '\\' && (text[i+1] == '"' || text[i+1] == '\\')))
i++;
}
else
@@ -191,19 +224,19 @@ void Cbuf_Execute( void )
// delete the text from the command buffer and move remaining commands down
// this is necessary because commands (exec) can insert data at the
// beginning of the text buffer
if( i == cmd_text.cursize )
if( i == buf->cursize )
{
cmd_text.cursize = 0;
buf->cursize = 0;
}
else
{
i++;
cmd_text.cursize -= i;
memmove( cmd_text.data, text + i, cmd_text.cursize );
buf->cursize -= i;
memmove( buf->data, text + i, buf->cursize );
}
// execute the command line
Cmd_ExecuteString( line );
Cmd_ExecuteStringWithPrivilegeCheck( line, isPrivileged );
if( cmd_wait )
{
@@ -215,6 +248,20 @@ void Cbuf_Execute( void )
}
}
/*
============
Cbuf_Execute
============
*/
void Cbuf_Execute( void )
{
Cbuf_ExecuteCommandsFromBuffer( &cmd_text, true, -1 );
// a1ba: unlimited commands for filtered buffer per frame
// I don't see any sense in restricting that at this moment
// but in future we may limit this
Cbuf_ExecuteCommandsFromBuffer( &filteredcmd_text, false, -1 );
}
/*
===============
Cbuf_ExecStuffCmds
@@ -282,6 +329,11 @@ void Cbuf_ExecStuffCmds( void )
==============================================================================
*/
qboolean Cmd_CurrentCommandIsPrivileged( void )
{
return cmd_currentCommandIsPrivileged;
}
/*
===============
Cmd_StuffCmds_f
@@ -458,8 +510,8 @@ typedef struct cmd_s
struct cmd_s *next;
char *name;
xcommand_t function;
char *desc;
int flags;
char *desc;
} cmd_t;
static int cmd_argc;
@@ -619,21 +671,21 @@ static int Cmd_AddCommandEx( const char *funcname, const char *cmd_name, xcomman
if( !COM_CheckString( cmd_name ))
{
Con_Reportf( S_ERROR "Cmd_AddCommand: NULL name\n" );
Con_Reportf( S_ERROR "%s: NULL name\n", funcname );
return 0;
}
// fail if the command is a variable name
if( Cvar_FindVar( cmd_name ))
{
Con_DPrintf( S_ERROR "Cmd_AddServerCommand: %s already defined as a var\n", cmd_name );
Con_DPrintf( S_ERROR "%s: %s already defined as a var\n", funcname, cmd_name );
return 0;
}
// fail if the command already exists
if( Cmd_Exists( cmd_name ))
{
Con_DPrintf( S_ERROR "Cmd_AddServerCommand: %s already defined\n", cmd_name );
Con_DPrintf( S_ERROR "%s: %s already defined\n", funcname, cmd_name );
return 0;
}
@@ -676,7 +728,7 @@ Cmd_AddRestrictedCommand
*/
void Cmd_AddRestrictedCommand( const char *cmd_name, xcommand_t function, const char *cmd_desc )
{
Cmd_AddCommandEx( __FUNCTION__, cmd_name, function, cmd_desc, CMD_LOCALONLY );
Cmd_AddCommandEx( __FUNCTION__, cmd_name, function, cmd_desc, CMD_PRIVILEGED );
}
/*
@@ -696,7 +748,15 @@ Cmd_AddClientCommand
*/
int GAME_EXPORT Cmd_AddClientCommand( const char *cmd_name, xcommand_t function )
{
return Cmd_AddCommandEx( __FUNCTION__, cmd_name, function, "client command", CMD_CLIENTDLL );
int flags = CMD_CLIENTDLL;
// a1ba: try to mitigate outdated client.dll vulnerabilities
if( !Q_stricmp( cmd_name, "motd_write" ))
{
flags |= CMD_PRIVILEGED;
}
return Cmd_AddCommandEx( __FUNCTION__, cmd_name, function, "client command", flags );
}
/*
@@ -876,6 +936,35 @@ void Cmd_Else_f( void )
cmd_condition ^= BIT( cmd_condlevel );
}
static qboolean Cmd_ShouldAllowCommand( cmd_t *cmd, qboolean isPrivileged )
{
const char *prefixes[] = { "cl_", "gl_", "r_", "m_", "hud_" };
int i;
// always allow local commands
if( isPrivileged )
return true;
// never allow local only commands from remote
if( FBitSet( cmd->flags, CMD_PRIVILEGED ))
return false;
// allow engine commands if user don't mind
if( cl_filterstuffcmd.value <= 0.0f )
return true;
if( FBitSet( cmd->flags, CMD_FILTERABLE ))
return false;
for( i = 0; i < ARRAYSIZE( prefixes ); i++ )
{
if( !Q_strnicmp( cmd->name, prefixes[i], Q_strlen( prefixes[i] )))
return false;
}
return true;
}
/*
============
Cmd_ExecuteString
@@ -883,7 +972,7 @@ Cmd_ExecuteString
A complete command line has been parsed, so try to execute it
============
*/
void Cmd_ExecuteString( const char *text )
static void Cmd_ExecuteStringWithPrivilegeCheck( const char *text, qboolean isPrivileged )
{
cmd_t *cmd = NULL;
cmdalias_t *a = NULL;
@@ -895,7 +984,7 @@ void Cmd_ExecuteString( const char *text )
cmd_condlevel = 0;
// cvar value substitution
if( cmd_scripting && cmd_scripting->value )
if( CVAR_TO_BOOL( cmd_scripting ))
{
while( *text )
{
@@ -952,47 +1041,59 @@ void Cmd_ExecuteString( const char *text )
if( !host.apply_game_config )
{
// check aliases
if( a ) // already found in basecmd
if( !a ) // if not found in basecmd
{
Cbuf_InsertText( a->value );
return;
for( a = cmd_alias; a; a = a->next )
{
if( !Q_stricmp( cmd_argv[0], a->name ))
break;
}
}
for( a = cmd_alias; a; a = a->next )
if( a )
{
if( !Q_stricmp( cmd_argv[0], a->name ))
{
Cbuf_InsertText( a->value );
return;
}
Cbuf_InsertTextToBuffer(
isPrivileged ? &cmd_text : &filteredcmd_text,
a->value );
return;
}
}
// special mode for restore game.dll archived cvars
if( !host.apply_game_config || !Q_strcmp( cmd_argv[0], "exec" ))
{
// check functions
if( cmd && cmd->function ) // already found in basecmd
if( !cmd || !cmd->function ) // if not found in basecmd
{
cmd->function();
return;
for( cmd = cmd_functions; cmd; cmd = cmd->next )
{
if( !Q_stricmp( cmd_argv[0], cmd->name ) && cmd->function )
break;
}
}
for( cmd = cmd_functions; cmd; cmd = cmd->next )
// check functions
if( cmd && cmd->function )
{
if( !Q_stricmp( cmd_argv[0], cmd->name ) && cmd->function )
if( Cmd_ShouldAllowCommand( cmd, isPrivileged ))
{
cmd_currentCommandIsPrivileged = isPrivileged;
cmd->function();
return;
cmd_currentCommandIsPrivileged = true;
}
else
{
Con_Printf( S_WARN "Could not execute privileged command %s\n", cmd->name );
}
return;
}
}
// check cvars
if( Cvar_Command( cvar )) return;
if( Cvar_CommandWithPrivilegeCheck( cvar, isPrivileged )) return;
if( host.apply_game_config )
return; // don't send nothing to server: we is a server!
return; // don't send nothing to server: we are a server!
// forward the command line to the server, so the entity DLL can parse it
if( host.type == HOST_NORMAL )
@@ -1006,11 +1107,16 @@ void Cmd_ExecuteString( const char *text )
#endif // XASH_DEDICATED
if( Cvar_VariableInteger( "host_gameloaded" ))
{
Con_Printf( S_WARN "Unknown command \"%s\"\n", text );
Con_Printf( S_WARN "Unknown command \"%s\"\n", Cmd_Argv( 0 ) );
}
}
}
void Cmd_ExecuteString( const char *text )
{
Cmd_ExecuteStringWithPrivilegeCheck( text, true );
}
/*
===================
Cmd_ForwardToServer
@@ -1225,9 +1331,43 @@ void Cmd_Null_f( void )
{
}
/*
==========
Cmd_Escape
inserts escape sequences
==========
*/
void Cmd_Escape( char *newCommand, const char *oldCommand, int len )
{
int c;
int scripting = CVAR_TO_BOOL( cmd_scripting );
while( (c = *oldCommand++) && len > 1 )
{
if( c == '"' )
{
*newCommand++ = '\\';
len--;
}
if( scripting && c == '$')
{
*newCommand++ = '$';
len--;
}
*newCommand++ = c; len--;
}
*newCommand++ = 0;
}
/*
============
Cmd_Init
============
*/
void Cmd_Init( void )
@@ -1244,13 +1384,13 @@ void Cmd_Init( void )
Cmd_AddCommand( "echo", Cmd_Echo_f, "print a message to the console (useful in scripts)" );
Cmd_AddCommand( "wait", Cmd_Wait_f, "make script execution wait for some rendered frames" );
Cmd_AddCommand( "cmdlist", Cmd_List_f, "display all console commands beginning with the specified prefix" );
Cmd_AddCommand( "stuffcmds", Cmd_StuffCmds_f, "execute commandline parameters (must be present in .rc script)" );
Cmd_AddRestrictedCommand( "stuffcmds", Cmd_StuffCmds_f, "execute commandline parameters (must be present in .rc script)" );
Cmd_AddCommand( "apropos", Cmd_Apropos_f, "lists all console variables/commands/aliases containing the specified string in the name or description" );
#if !XASH_DEDICATED
Cmd_AddCommand( "cmd", Cmd_ForwardToServer, "send a console commandline to the server" );
#endif // XASH_DEDICATED
Cmd_AddCommand( "alias", Cmd_Alias_f, "create a script function. Without arguments show the list of all alias" );
Cmd_AddCommand( "unalias", Cmd_UnAlias_f, "remove a script function" );
Cmd_AddRestrictedCommand( "alias", Cmd_Alias_f, "create a script function. Without arguments show the list of all alias" );
Cmd_AddRestrictedCommand( "unalias", Cmd_UnAlias_f, "remove a script function" );
Cmd_AddCommand( "if", Cmd_If_f, "compare and set condition bits" );
Cmd_AddCommand( "else", Cmd_Else_f, "invert condition bit" );
@@ -1259,3 +1399,64 @@ void Cmd_Init( void )
Cmd_AddCommand( "basecmd_test", BaseCmd_Test_f, "test basecmd" );
#endif
}
#if XASH_ENGINE_TESTS
#include "tests.h"
enum
{
NO_CALL = 0,
PRIV = 1,
UNPRIV = 2
};
static int test_flags[3] = { NO_CALL, NO_CALL, NO_CALL };
static void Test_PrivilegedCommand_f( void )
{
test_flags[0] = Cmd_CurrentCommandIsPrivileged() ? PRIV : UNPRIV;
}
static void Test_UnprivilegedCommand_f( void )
{
test_flags[1] = Cmd_CurrentCommandIsPrivileged() ? PRIV : UNPRIV;
}
static void Test_FilteredCommand_f( void )
{
test_flags[2] = Cmd_CurrentCommandIsPrivileged() ? PRIV : UNPRIV;
}
void Test_RunCmd( void )
{
Cmd_AddCommand( "test_privileged", Test_PrivilegedCommand_f, "bark bark" );
Cmd_AddRestrictedCommand( "test_unprivileged", Test_UnprivilegedCommand_f, "meow meow" );
Cmd_AddCommand( "hud_filtered", Test_FilteredCommand_f, "dummy description" );
Cbuf_AddText( "test_privileged; test_unprivileged; hud_filtered\n" );
Cbuf_Execute();
TASSERT( test_flags[0] == PRIV );
TASSERT( test_flags[1] == PRIV );
TASSERT( test_flags[2] == PRIV );
VectorSet( test_flags, NO_CALL, NO_CALL, NO_CALL );
Cvar_DirectSet( &cl_filterstuffcmd, "0" );
Cbuf_AddFilteredText( "test_privileged; test_unprivileged; hud_filtered\n" );
Cbuf_Execute();
TASSERT( test_flags[0] == UNPRIV );
TASSERT( test_flags[1] == NO_CALL );
TASSERT( test_flags[2] == UNPRIV );
VectorSet( test_flags, NO_CALL, NO_CALL, NO_CALL );
Cvar_DirectSet( &cl_filterstuffcmd, "1" );
Cbuf_AddFilteredText( "test_privileged; test_unprivileged; hud_filtered\n" );
Cbuf_Execute();
TASSERT( test_flags[0] == UNPRIV );
TASSERT( test_flags[1] == NO_CALL );
TASSERT( test_flags[2] == NO_CALL );
Cmd_RemoveCommand( "hud_filtered" );
Cmd_RemoveCommand( "test_unprivileged" );
Cmd_RemoveCommand( "test_privileged" );
}
#endif

View File

@@ -13,6 +13,9 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#if defined( ALLOCA_H )
#include ALLOCA_H
#endif
#include "common.h"
#include "studio.h"
#include "xash3d_mathlib.h"
@@ -886,6 +889,10 @@ pfnCvar_RegisterVariable
*/
cvar_t *pfnCvar_RegisterClientVariable( const char *szName, const char *szValue, int flags )
{
// a1ba: try to mitigate outdated client.dll vulnerabilities
if( !Q_stricmp( szName, "motdfile" ))
flags |= FCVAR_PRIVILEGED;
if( FBitSet( flags, FCVAR_GLCONFIG ))
return (cvar_t *)Cvar_Get( szName, szValue, flags, va( CVAR_GLCONFIG_DESCRIPTION, szName ));
return (cvar_t *)Cvar_Get( szName, szValue, flags|FCVAR_CLIENTDLL, Cvar_BuildAutoDescription( flags|FCVAR_CLIENTDLL ));

View File

@@ -184,6 +184,8 @@ extern convar_t host_developer;
extern convar_t *host_limitlocal;
extern convar_t *host_framerate;
extern convar_t *host_maxfps;
extern convar_t sys_timescale;
extern convar_t cl_filterstuffcmd;
/*
==============================================================
@@ -229,6 +231,7 @@ typedef struct gameinfo_s
qboolean secure; // prevent to console acess
qboolean nomodels; // don't let player to choose model (use player.mdl always)
qboolean noskills; // disable skill menu selection
qboolean render_picbutton_text; // use font renderer to render WON buttons
char sp_entity[32]; // e.g. info_player_start
char mp_entity[32]; // e.g. info_player_deathmatch
@@ -464,8 +467,9 @@ extern sysinfo_t SI;
#define CMD_SERVERDLL BIT( 0 ) // added by server.dll
#define CMD_CLIENTDLL BIT( 1 ) // added by client.dll
#define CMD_GAMEUIDLL BIT( 2 ) // added by GameUI.dll
#define CMD_LOCALONLY BIT( 3 ) // restricted from server commands
#define CMD_REFDLL BIT( 4 ) // added by ref.dll
#define CMD_PRIVILEGED BIT( 3 ) // only available in privileged mode
#define CMD_FILTERABLE BIT( 4 ) // filtered in unprivileged mode if cl_filterstuffcmd is 1
#define CMD_REFDLL BIT( 5 ) // added by ref.dll
typedef void (*xcommand_t)( void );
@@ -475,9 +479,11 @@ typedef void (*xcommand_t)( void );
void Cbuf_Init( void );
void Cbuf_Clear( void );
void Cbuf_AddText( const char *text );
void Cbuf_AddFilteredText( const char *text );
void Cbuf_InsertText( const char *text );
void Cbuf_ExecStuffCmds( void );
void Cbuf_Execute (void);
qboolean Cmd_CurrentCommandIsPrivileged( void );
int Cmd_Argc( void );
const char *Cmd_Args( void );
const char *Cmd_Argv( int arg );
@@ -499,6 +505,7 @@ qboolean Cmd_GetMovieList( const char *s, char *completedname, int length );
void Cmd_TokenizeString( const char *text );
void Cmd_ExecuteString( const char *text );
void Cmd_ForwardToServer( void );
void Cmd_Escape( char *newCommand, const char *oldCommand, int len );
//
// zone.c
@@ -589,7 +596,7 @@ qboolean FS_SaveImage( const char *filename, rgbdata_t *pix );
rgbdata_t *FS_CopyImage( rgbdata_t *in );
void FS_FreeImage( rgbdata_t *pack );
extern const bpc_desc_t PFDesc[]; // image get pixelformat
qboolean Image_Process( rgbdata_t **pix, int width, int height, uint flags, float bumpscale );
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_PaletteTranslate( byte *palSrc, int top, int bottom, int pal_size );
void Image_SetForceFlags( uint flags ); // set image force flags on loading
@@ -684,7 +691,7 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
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_AbortCurrentFrame( void );
void Host_AbortCurrentFrame( void ) NORETURN;
void Host_WriteServerConfig( const char *name );
void Host_WriteOpenGLConfig( void );
void Host_WriteVideoConfig( void );
@@ -692,7 +699,7 @@ void Host_WriteConfig( void );
qboolean Host_IsLocalGame( void );
qboolean Host_IsLocalClient( void );
void Host_ShutdownServer( void );
void Host_Error( const char *error, ... ) _format( 1 );
void Host_Error( const char *error, ... ) _format( 1 ) NORETURN;
void Host_PrintEngineFeatures( void );
void Host_Frame( float time );
void Host_InitDecals( void );
@@ -749,7 +756,6 @@ void pfnDrawSetTextColor( float r, float g, float b );
void pfnDrawConsoleStringLen( const char *pText, int *length, int *height );
void *Cache_Check( poolhandle_t mempool, struct cache_user_s *c );
void COM_TrimSpace( const char *source, char *dest );
edict_t* pfnPEntityOfEntIndex( int iEntIndex );
void pfnGetModelBounds( model_t *mod, float *mins, float *maxs );
void pfnCVarDirectSet( cvar_t *var, const char *szValue );
int COM_CheckParm( char *parm, char **ppnext );

View File

@@ -1216,7 +1216,7 @@ void Con_CompleteCommand( field_t *field )
if( con.matchCount == 1 )
{
Q_sprintf( con.completionField->buffer, "\\%s", con.cmds[0] );
Q_strncpy( con.completionField->buffer, con.cmds[0], sizeof( con.completionField->buffer ));
if( Cmd_Argc() == 1 ) Q_strncat( con.completionField->buffer, " ", sizeof( con.completionField->buffer ) );
else Con_ConcatRemaining( temp.buffer, con.completionString );
con.completionField->cursor = Q_strlen( con.completionField->buffer );
@@ -1244,7 +1244,7 @@ void Con_CompleteCommand( field_t *field )
con.shortestMatch[len] = 0;
// multiple matches, complete to shortest
Q_sprintf( con.completionField->buffer, "\\%s", con.shortestMatch );
Q_strncpy( con.completionField->buffer, con.shortestMatch, sizeof( con.completionField->buffer ));
con.completionField->cursor = Q_strlen( con.completionField->buffer );
Con_ConcatRemaining( temp.buffer, con.completionString );

View File

@@ -24,9 +24,11 @@ Crash handler, called from system
================
*/
#if XASH_CRASHHANDLER == CRASHHANDLER_DBGHELP || XASH_CRASHHANDLER == CRASHHANDLER_WIN32
#if XASH_CRASHHANDLER == CRASHHANDLER_DBGHELP
#pragma comment( lib, "dbghelp" )
#pragma comment( lib, "psapi" )
#include <winnt.h>
#include <dbghelp.h>
#include <psapi.h>
@@ -35,7 +37,7 @@ Crash handler, called from system
typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR;
#endif
int ModuleName( HANDLE process, char *name, void *address, int len )
static int Sys_ModuleName( HANDLE process, char *name, void *address, int len )
{
DWORD_PTR baseAddress = 0;
static HMODULE *moduleArray;
@@ -44,27 +46,24 @@ int ModuleName( HANDLE process, char *name, void *address, int len )
DWORD bytesRequired;
int i;
if(len < 3)
if( len < 3 )
return 0;
if ( !moduleArray && EnumProcessModules( process, NULL, 0, &bytesRequired ) )
if( !moduleArray && EnumProcessModules( process, NULL, 0, &bytesRequired ) )
{
if ( bytesRequired )
{
moduleArrayBytes = (LPBYTE)LocalAlloc( LPTR, bytesRequired );
if ( moduleArrayBytes )
if( moduleArrayBytes && EnumProcessModules( process, (HMODULE *)moduleArrayBytes, bytesRequired, &bytesRequired ) )
{
if( EnumProcessModules( process, (HMODULE *)moduleArrayBytes, bytesRequired, &bytesRequired ) )
{
moduleCount = bytesRequired / sizeof( HMODULE );
moduleArray = (HMODULE *)moduleArrayBytes;
}
moduleCount = bytesRequired / sizeof( HMODULE );
moduleArray = (HMODULE *)moduleArrayBytes;
}
}
}
for( i = 0; i<moduleCount; i++ )
for( i = 0; i < moduleCount; i++ )
{
MODULEINFO info;
GetModuleInformation( process, moduleArray[i], &info, sizeof(MODULEINFO) );
@@ -73,9 +72,10 @@ int ModuleName( HANDLE process, char *name, void *address, int len )
( (DWORD64)address < (DWORD64)info.lpBaseOfDll + (DWORD64)info.SizeOfImage ) )
return GetModuleBaseName( process, moduleArray[i], name, len );
}
return Q_snprintf(name, len, "???");
return Q_snprintf( name, len, "???" );
}
static void stack_trace( PEXCEPTION_POINTERS pInfo )
static void Sys_StackTrace( PEXCEPTION_POINTERS pInfo )
{
char message[1024];
int len = 0;
@@ -89,7 +89,8 @@ static void stack_trace( PEXCEPTION_POINTERS pInfo )
STACKFRAME64 stackframe;
DWORD image;
memcpy( &context, pInfo->ContextRecord, sizeof(CONTEXT) );
memcpy( &context, pInfo->ContextRecord, sizeof( CONTEXT ));
options = SymGetOptions();
options |= SYMOPT_DEBUG;
options |= SYMOPT_LOAD_LINES;
@@ -97,9 +98,7 @@ static void stack_trace( PEXCEPTION_POINTERS pInfo )
SymInitialize( process, NULL, TRUE );
ZeroMemory( &stackframe, sizeof(STACKFRAME64) );
ZeroMemory( &stackframe, sizeof( STACKFRAME64 ));
#ifdef _M_IX86
image = IMAGE_FILE_MACHINE_I386;
@@ -127,19 +126,25 @@ static void stack_trace( PEXCEPTION_POINTERS pInfo )
stackframe.AddrBStore.Mode = AddrModeFlat;
stackframe.AddrStack.Offset = context.IntSp;
stackframe.AddrStack.Mode = AddrModeFlat;
#elif
#error
#endif
len += Q_snprintf( message + len, 1024 - len, "Sys_Crash: address %p, code %p\n", pInfo->ExceptionRecord->ExceptionAddress, (void*)pInfo->ExceptionRecord->ExceptionCode );
len += Q_snprintf( message + len, 1024 - len, "Sys_Crash: address %p, code %p\n",
pInfo->ExceptionRecord->ExceptionAddress, (void*)pInfo->ExceptionRecord->ExceptionCode );
if( SymGetLineFromAddr64( process, (DWORD64)pInfo->ExceptionRecord->ExceptionAddress, &dline, &line ) )
{
len += Q_snprintf(message + len, 1024 - len,"Exception: %s:%d:%d\n", (char*)line.FileName, (int)line.LineNumber, (int)dline);
len += Q_snprintf(message + len, 1024 - len, "Exception: %s:%d:%d\n",
(char*)line.FileName, (int)line.LineNumber, (int)dline);
}
if( SymGetLineFromAddr64( process, stackframe.AddrPC.Offset, &dline, &line ) )
{
len += Q_snprintf(message + len, 1024 - len,"PC: %s:%d:%d\n", (char*)line.FileName, (int)line.LineNumber, (int)dline);
len += Q_snprintf(message + len, 1024 - len,"PC: %s:%d:%d\n",
(char*)line.FileName, (int)line.LineNumber, (int)dline);
}
if( SymGetLineFromAddr64( process, stackframe.AddrFrame.Offset, &dline, &line ) )
{
len += Q_snprintf(message + len, 1024 - len,"Frame: %s:%d:%d\n", (char*)line.FileName, (int)line.LineNumber, (int)dline);
len += Q_snprintf(message + len, 1024 - len,"Frame: %s:%d:%d\n",
(char*)line.FileName, (int)line.LineNumber, (int)dline);
}
for( i = 0; i < 25; i++ )
{
@@ -149,39 +154,43 @@ static void stack_trace( PEXCEPTION_POINTERS pInfo )
image, process, thread,
&stackframe, &context, NULL,
SymFunctionTableAccess64, SymGetModuleBase64, NULL);
DWORD64 displacement = 0;
if( !result )
break;
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
symbol->MaxNameLen = MAX_SYM_NAME;
len += Q_snprintf( message + len, 1024 - len, "% 2d %p", i, (void*)stackframe.AddrPC.Offset );
len += Q_snprintf( message + len, 1024 - len, "% 2d %p",
i, (void*)stackframe.AddrPC.Offset );
if( SymFromAddr( process, stackframe.AddrPC.Offset, &displacement, symbol ) )
{
len += Q_snprintf( message + len, 1024 - len, " %s ", symbol->Name );
}
if( SymGetLineFromAddr64( process, stackframe.AddrPC.Offset, &dline, &line ) )
{
len += Q_snprintf(message + len, 1024 - len,"(%s:%d:%d) ", (char*)line.FileName, (int)line.LineNumber, (int)dline);
len += Q_snprintf(message + len, 1024 - len,"(%s:%d:%d) ",
(char*)line.FileName, (int)line.LineNumber, (int)dline);
}
len += Q_snprintf( message + len, 1024 - len, "(");
len += ModuleName( process, message + len, (void*)stackframe.AddrPC.Offset, 1024 - len );
len += Sys_ModuleName( process, message + len, (void*)stackframe.AddrPC.Offset, 1024 - len );
len += Q_snprintf( message + len, 1024 - len, ")\n");
}
#ifdef XASH_SDL
if( host.type != HOST_DEDICATED ) // let system to restart server automaticly
SDL_ShowSimpleMessageBox( SDL_MESSAGEBOX_ERROR,"Sys_Crash", message, host.hWnd );
#endif
Sys_PrintLog(message);
SymCleanup(process);
#if XASH_SDL == 2
if( host.type != HOST_DEDICATED ) // let system to restart server automaticly
SDL_ShowSimpleMessageBox( SDL_MESSAGEBOX_ERROR, "Sys_Crash", message, host.hWnd );
#endif
Sys_PrintLog( message );
SymCleanup( process );
}
#endif //DBGHELP
#endif /* XASH_CRASHHANDLER == CRASHHANDLER_DBGHELP */
LPTOP_LEVEL_EXCEPTION_FILTER oldFilter;
long _stdcall Sys_Crash( PEXCEPTION_POINTERS pInfo )
static long _stdcall Sys_Crash( PEXCEPTION_POINTERS pInfo )
{
// save config
if( host.status != HOST_CRASHED )
@@ -190,7 +199,7 @@ long _stdcall Sys_Crash( PEXCEPTION_POINTERS pInfo )
host.crashed = true;
#if XASH_CRASHHANDLER == CRASHHANDLER_DBGHELP
stack_trace( pInfo );
Sys_StackTrace( pInfo );
#else
Sys_Warn( "Sys_Crash: call %p at address %p", pInfo->ExceptionRecord->ExceptionAddress, pInfo->ExceptionRecord->ExceptionCode );
#endif
@@ -233,13 +242,14 @@ void Sys_RestoreCrashHandler( void )
#include "library.h"
#if XASH_FREEBSD || XASH_NETBSD || XASH_ANDROID || XASH_LINUX
#if XASH_FREEBSD || XASH_NETBSD || XASH_OPENBSD || XASH_ANDROID || XASH_LINUX
#define HAVE_UCONTEXT_H 1
#endif
#ifdef HAVE_UCONTEXT_H
#include <ucontext.h>
#endif
#include <signal.h>
#include <sys/mman.h>
@@ -261,7 +271,7 @@ static int d_dladdr( void *sym, Dl_info *info )
#define dladdr d_dladdr
#endif
int printframe( char *buf, int len, int i, void *addr )
static int Sys_PrintFrame( char *buf, int len, int i, void *addr )
{
Dl_info dlinfo;
if( len <= 0 )
@@ -271,7 +281,7 @@ int printframe( char *buf, int len, int i, void *addr )
{
if( dlinfo.dli_sname )
return Q_snprintf( buf, len, "%2d: %p <%s+%lu> (%s)\n", i, addr, dlinfo.dli_sname,
(unsigned long)addr - (unsigned long)dlinfo.dli_saddr, dlinfo.dli_fname ); // print symbol, module and address
(unsigned long)addr - (unsigned long)dlinfo.dli_saddr, dlinfo.dli_fname ); // print symbol, module and address
else
return Q_snprintf( buf, len, "%2d: %p (%s)\n", i, addr, dlinfo.dli_fname ); // print module and address
}
@@ -281,10 +291,11 @@ int printframe( char *buf, int len, int i, void *addr )
struct sigaction oldFilter;
#define STACK_BACKTRACE_STR_LEN 17
#define STACK_BACKTRACE_STR "Stack backtrace:\n"
#define STACK_DUMP_STR_LEN 12
#define STACK_DUMP_STR "Stack dump:\n"
#define STACK_BACKTRACE_STR "Stack backtrace:\n"
#define STACK_DUMP_STR "Stack dump:\n"
#define STACK_BACKTRACE_STR_LEN (sizeof( STACK_BACKTRACE_STR ) - 1)
#define STACK_DUMP_STR_LEN (sizeof( STACK_DUMP_STR ) - 1)
#define ALIGN( x, y ) (((uintptr_t) (x) + ((y)-1)) & ~((y)-1))
static void Sys_Crash( int signal, siginfo_t *si, void *context)
@@ -356,7 +367,7 @@ static void Sys_Crash( int signal, siginfo_t *si, void *context)
len += Q_snprintf( message + len, sizeof( message ) - len, "Crash: signal %d errno %d with code %d at %p\n", signal, si->si_errno, si->si_code, si->si_addr );
#endif
write( 2, message, len );
write( STDERR_FILENO, message, len );
// flush buffers before writing directly to descriptors
fflush( stdout );
@@ -370,9 +381,9 @@ static void Sys_Crash( int signal, siginfo_t *si, void *context)
{
size_t pagesize = sysconf( _SC_PAGESIZE );
// try to print backtrace
write( 2, STACK_BACKTRACE_STR, STACK_BACKTRACE_STR_LEN );
write( STDERR_FILENO, STACK_BACKTRACE_STR, STACK_BACKTRACE_STR_LEN );
write( logfd, STACK_BACKTRACE_STR, STACK_BACKTRACE_STR_LEN );
strncpy( message + len, STACK_BACKTRACE_STR, sizeof( message ) - len );
Q_strncpy( message + len, STACK_BACKTRACE_STR, sizeof( message ) - len );
len += STACK_BACKTRACE_STR_LEN;
// false on success, true on failure
@@ -384,8 +395,8 @@ static void Sys_Crash( int signal, siginfo_t *si, void *context)
do
{
int line = printframe( message + len, sizeof( message ) - len, ++i, pc);
write( 2, message + len, line );
int line = Sys_PrintFrame( message + len, sizeof( message ) - len, ++i, pc);
write( STDERR_FILENO, message + len, line );
write( logfd, message + len, line );
len += line;
//if( !dladdr(bp,0) ) break; // only when bp is in module
@@ -399,17 +410,17 @@ static void Sys_Crash( int signal, siginfo_t *si, void *context)
while( bp && i < 128 );
// try to print stack
write( 2, STACK_DUMP_STR, STACK_DUMP_STR_LEN );
write( STDERR_FILENO, STACK_DUMP_STR, STACK_DUMP_STR_LEN );
write( logfd, STACK_DUMP_STR, STACK_DUMP_STR_LEN );
strncpy( message + len, STACK_DUMP_STR, sizeof( message ) - len );
Q_strncpy( message + len, STACK_DUMP_STR, sizeof( message ) - len );
len += STACK_DUMP_STR_LEN;
if( !try_allow_read( sp, pagesize ) )
{
for( i = 0; i < 32; i++ )
{
int line = printframe( message + len, sizeof( message ) - len, i, sp[i] );
write( 2, message + len, line );
int line = Sys_PrintFrame( message + len, sizeof( message ) - len, i, sp[i] );
write( STDERR_FILENO, message + len, line );
write( logfd, message + len, line );
len += line;
}

View File

@@ -16,10 +16,13 @@ GNU General Public License for more details.
#include <math.h> // fabs...
#include "common.h"
#include "base_cmd.h"
#include "eiface.h" // ARRAYSIZE
convar_t *cvar_vars = NULL; // head of list
convar_t *cmd_scripting;
CVAR_DEFINE_AUTO( cl_filterstuffcmd, "1", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "filter commands coming from server" );
/*
============
Cvar_GetList
@@ -71,7 +74,7 @@ build cvar auto description that based on the setup flags
*/
const char *Cvar_BuildAutoDescription( int flags )
{
static char desc[128];
static char desc[256];
desc[0] = '\0';
@@ -91,6 +94,12 @@ const char *Cvar_BuildAutoDescription( int flags )
if( FBitSet( flags, FCVAR_ARCHIVE ))
Q_strncat( desc, "archived ", sizeof( desc ));
if( FBitSet( flags, FCVAR_PROTECTED ))
Q_strncat( desc, "protected ", sizeof( desc ));
if( FBitSet( flags, FCVAR_PRIVILEGED ))
Q_strncat( desc, "privileged ", sizeof( desc ));
Q_strncat( desc, "cvar", sizeof( desc ));
return desc;
@@ -510,7 +519,7 @@ void Cvar_DirectSet( convar_t *var, const char *value )
if( var != Cvar_FindVar( var->name ))
return; // how this possible?
if( FBitSet( var->flags, FCVAR_READ_ONLY|FCVAR_GLCONFIG ))
if( FBitSet( var->flags, FCVAR_READ_ONLY ))
{
Con_Printf( "%s is read-only.\n", var->name );
return;
@@ -754,6 +763,32 @@ static void Cvar_SetGL( const char *name, const char *value )
Cvar_FullSet( name, value, FCVAR_GLCONFIG );
}
static qboolean Cvar_ShouldSetCvar( convar_t *v, qboolean isPrivileged )
{
const char *prefixes[] = { "cl_", "gl_", "m_", "r_", "hud_" };
int i;
if( isPrivileged )
return true;
if( FBitSet( v->flags, FCVAR_PRIVILEGED ))
return false;
if( cl_filterstuffcmd.value <= 0.0f )
return true;
if( FBitSet( v->flags, FCVAR_FILTERABLE ))
return false;
for( i = 0; i < ARRAYSIZE( prefixes ); i++ )
{
if( !Q_strnicmp( v->name, prefixes[i], Q_strlen( prefixes[i] )))
return false;
}
return true;
}
/*
============
Cvar_Command
@@ -761,7 +796,7 @@ Cvar_Command
Handles variable inspection and changing from the console
============
*/
qboolean Cvar_Command( convar_t *v )
qboolean Cvar_CommandWithPrivilegeCheck( convar_t *v, qboolean isPrivileged )
{
// special case for setup opengl configuration
if( host.apply_opengl_config )
@@ -773,7 +808,8 @@ qboolean Cvar_Command( convar_t *v )
// check variables
if( !v ) // already found in basecmd
v = Cvar_FindVar( Cmd_Argv( 0 ));
if( !v ) return false;
if( !v )
return false;
// perform a variable print or set
if( Cmd_Argc() == 1 )
@@ -796,6 +832,11 @@ qboolean Cvar_Command( convar_t *v )
Con_Printf( "can't set \"%s\" in multiplayer\n", v->name );
return false;
}
else if( !Cvar_ShouldSetCvar( v, isPrivileged ))
{
Con_Printf( "%s is a privileged variable\n", v->name );
return true;
}
else
{
Cvar_DirectSet( v, Cmd_Argv( 1 ));
@@ -953,11 +994,59 @@ Reads in all archived cvars
void Cvar_Init( void )
{
cvar_vars = NULL;
cmd_scripting = Cvar_Get( "cmd_scripting", "0", FCVAR_ARCHIVE, "enable simple condition checking and variable operations" );
cmd_scripting = Cvar_Get( "cmd_scripting", "0", FCVAR_ARCHIVE|FCVAR_PRIVILEGED, "enable simple condition checking and variable operations" );
Cvar_RegisterVariable (&host_developer); // early registering for dev
Cvar_RegisterVariable( &cl_filterstuffcmd );
Cmd_AddCommand( "setgl", Cvar_SetGL_f, "change the value of a opengl variable" ); // OBSOLETE
Cmd_AddCommand( "toggle", Cvar_Toggle_f, "toggles a console variable's values (use for more info)" );
Cmd_AddCommand( "reset", Cvar_Reset_f, "reset any type variable to initial value" );
Cmd_AddRestrictedCommand( "setgl", Cvar_SetGL_f, "change the value of a opengl variable" ); // OBSOLETE
Cmd_AddRestrictedCommand( "toggle", Cvar_Toggle_f, "toggles a console variable's values (use for more info)" );
Cmd_AddRestrictedCommand( "reset", Cvar_Reset_f, "reset any type variable to initial value" );
Cmd_AddCommand( "cvarlist", Cvar_List_f, "display all console variables beginning with the specified prefix" );
}
#if XASH_ENGINE_TESTS
#include "tests.h"
void Test_RunCvar( void )
{
convar_t *test_privileged = Cvar_Get( "test_privileged", "0", FCVAR_PRIVILEGED, "bark bark" );
convar_t *test_unprivileged = Cvar_Get( "test_unprivileged", "0", 0, "meow meow" );
convar_t *hud_filtered = Cvar_Get( "hud_filtered", "0", 0, "dummy description" );
convar_t *filtered2 = Cvar_Get( "filtered2", "0", FCVAR_FILTERABLE, "filtered2" );
Cbuf_AddText( "test_privileged 1; test_unprivileged 1; hud_filtered 1; filtered2 1\n" );
Cbuf_Execute();
TASSERT( test_privileged->value != 0.0f );
TASSERT( test_unprivileged->value != 0.0f );
TASSERT( hud_filtered->value != 0.0f );
TASSERT( filtered2->value != 0.0f );
Cvar_DirectSet( test_privileged, "0" );
Cvar_DirectSet( test_unprivileged, "0" );
Cvar_DirectSet( hud_filtered, "0" );
Cvar_DirectSet( filtered2, "0" );
Cvar_DirectSet( &cl_filterstuffcmd, "0" );
Cbuf_AddFilteredText( "test_privileged 1; test_unprivileged 1; hud_filtered 1; filtered2 1\n" );
Cbuf_Execute();
Cbuf_Execute();
Cbuf_Execute();
TASSERT( test_privileged->value == 0.0f );
TASSERT( test_unprivileged->value != 0.0f );
TASSERT( hud_filtered->value != 0.0f );
TASSERT( filtered2->value != 0.0f );
Cvar_DirectSet( test_privileged, "0" );
Cvar_DirectSet( test_unprivileged, "0" );
Cvar_DirectSet( hud_filtered, "0" );
Cvar_DirectSet( filtered2, "0" );
Cvar_DirectSet( &cl_filterstuffcmd, "1" );
Cbuf_AddFilteredText( "test_privileged 1; test_unprivileged 1; hud_filtered 1; filtered2 1\n" );
Cbuf_Execute();
Cbuf_Execute();
Cbuf_Execute();
TASSERT( test_privileged->value == 0.0f );
TASSERT( test_unprivileged->value != 0.0f );
TASSERT( hud_filtered->value == 0.0f );
TASSERT( filtered2->value == 0.0f );
}
#endif

View File

@@ -47,7 +47,7 @@ typedef struct convar_s
#define FCVAR_ALLOCATED (1<<19) // this convar_t is fully dynamic allocated (include description)
#define FCVAR_VIDRESTART (1<<20) // recreate the window is cvar with this flag was changed
#define FCVAR_TEMPORARY (1<<21) // these cvars holds their values and can be unlink in any time
#define FCVAR_LOCALONLY (1<<22) // can be set only from local buffers
#define FCVAR_MOVEVARS (1<<22) // this cvar is a part of movevars_t struct that shared between client and server
#define CVAR_DEFINE( cv, cvname, cvstr, cvflags, cvdesc ) \
convar_t cv = { (char*)cvname, (char*)cvstr, cvflags, 0.0f, (void *)CVAR_SENTINEL, (char*)cvdesc, NULL }
@@ -75,7 +75,7 @@ void Cvar_WriteVariables( file_t *f, int group );
qboolean Cvar_Exists( const char *var_name );
void Cvar_Reset( const char *var_name );
void Cvar_SetCheatState( void );
qboolean Cvar_Command( convar_t *v );
qboolean Cvar_CommandWithPrivilegeCheck( convar_t *v, qboolean isPrivileged );
void Cvar_Init( void );
void Cvar_Unlink( int group );

View File

@@ -306,11 +306,6 @@ void SCR_CheckStartupVids( void )
}
void Sys_SetClipboardData( const char *text, size_t size )
{
}
void CL_StopPlayback( void )
{

View File

@@ -406,7 +406,8 @@ static const char *FS_FixFileCase( const char *path )
out[i] = 0;
return out;
#elif !XASH_WIN32 && !XASH_IOS // assume case insensitive
DIR *dir; struct dirent *entry;
DIR *dir;
struct dirent *entry;
char path2[PATH_MAX], *fname;
if( !fs_caseinsensitive )
@@ -600,11 +601,12 @@ of the list so they override previous pack files.
*/
pack_t *FS_LoadPackPAK( const char *packfile, int *error )
{
dpackheader_t header;
int packhandle;
int i, numpackfiles;
pack_t *pack;
dpackfile_t *info;
dpackheader_t header;
int packhandle;
int i, numpackfiles;
pack_t *pack;
dpackfile_t *info;
fs_size_t c;
packhandle = open( packfile, O_RDONLY|O_BINARY );
@@ -612,21 +614,21 @@ pack_t *FS_LoadPackPAK( const char *packfile, int *error )
if( packhandle < 0 )
{
const char *fpackfile = FS_FixFileCase( packfile );
if( fpackfile!= packfile )
if( fpackfile != packfile )
packhandle = open( fpackfile, O_RDONLY|O_BINARY );
}
#endif
if( packhandle < 0 )
{
Con_Reportf( "%s couldn't open\n", packfile );
Con_Reportf( "%s couldn't open: %s\n", packfile, strerror( errno ));
if( error ) *error = PAK_LOAD_COULDNT_OPEN;
return NULL;
}
read( packhandle, (void *)&header, sizeof( header ));
c = read( packhandle, (void *)&header, sizeof( header ));
if( header.ident != IDPACKV1HEADER )
if( c != sizeof( header ) || header.ident != IDPACKV1HEADER )
{
Con_Reportf( "%s is not a packfile. Ignored.\n", packfile );
if( error ) *error = PAK_LOAD_BAD_HEADER;
@@ -685,7 +687,7 @@ pack_t *FS_LoadPackPAK( const char *packfile, int *error )
#ifdef XASH_REDUCE_FD
// will reopen when needed
close(pack->handle);
close( pack->handle );
pack->handle = -1;
#endif
@@ -715,11 +717,12 @@ static zip_t *FS_LoadZip( const char *zipfile, int *error )
int numpackfiles = 0, i;
zip_cdf_header_t header_cdf;
zip_header_eocd_t header_eocd;
uint signature;
uint32_t signature;
fs_offset_t filepos = 0, length;
zipfile_t *info = NULL;
char filename_buffer[MAX_SYSPATH];
zip_t *zip = (zip_t *)Mem_Calloc( fs_mempool, sizeof( zip_t ) );
zip_t *zip = (zip_t *)Mem_Calloc( fs_mempool, sizeof( *zip ));
fs_size_t c;
zip->handle = open( zipfile, O_RDONLY|O_BINARY );
@@ -758,9 +761,9 @@ static zip_t *FS_LoadZip( const char *zipfile, int *error )
lseek( zip->handle, 0, SEEK_SET );
read( zip->handle, &signature, sizeof( signature ) );
c = read( zip->handle, &signature, sizeof( signature ) );
if( signature == ZIP_HEADER_EOCD )
if( c != sizeof( signature ) || signature == ZIP_HEADER_EOCD )
{
Con_Reportf( S_WARN "%s has no files. Ignored.\n", zipfile );
@@ -789,9 +792,9 @@ static zip_t *FS_LoadZip( const char *zipfile, int *error )
while ( filepos > 0 )
{
lseek( zip->handle, filepos, SEEK_SET );
read( zip->handle, &signature, sizeof( signature ) );
c = read( zip->handle, &signature, sizeof( signature ) );
if( signature == ZIP_HEADER_EOCD )
if( c == sizeof( signature ) && signature == ZIP_HEADER_EOCD )
break;
filepos -= sizeof( char ); // step back one byte
@@ -808,19 +811,30 @@ static zip_t *FS_LoadZip( const char *zipfile, int *error )
return NULL;
}
read( zip->handle, &header_eocd, sizeof( zip_header_eocd_t ) );
c = read( zip->handle, &header_eocd, sizeof( header_eocd ) );
if( c != sizeof( header_eocd ))
{
Con_Reportf( S_ERROR "invalid EOCD header in %s. Zip file corrupted.\n", zipfile );
if( error )
*error = ZIP_LOAD_BAD_HEADER;
Zip_Close( zip );
return NULL;
}
// Move to CDF start
lseek( zip->handle, header_eocd.central_directory_offset, SEEK_SET );
// Calc count of files in archive
info = (zipfile_t *)Mem_Calloc( fs_mempool, sizeof( zipfile_t ) * header_eocd.total_central_directory_record );
info = (zipfile_t *)Mem_Calloc( fs_mempool, sizeof( *info ) * header_eocd.total_central_directory_record );
for( i = 0; i < header_eocd.total_central_directory_record; i++ )
{
read( zip->handle, &header_cdf, sizeof( header_cdf ) );
c = read( zip->handle, &header_cdf, sizeof( header_cdf ) );
if( header_cdf.signature != ZIP_HEADER_CDF )
if( c != sizeof( header_cdf ) || header_cdf.signature != ZIP_HEADER_CDF )
{
Con_Reportf( S_ERROR "CDF signature mismatch in %s. Zip file corrupted.\n", zipfile );
@@ -835,7 +849,20 @@ static zip_t *FS_LoadZip( const char *zipfile, int *error )
if( header_cdf.uncompressed_size && header_cdf.filename_len && ( header_cdf.filename_len < MAX_SYSPATH ) )
{
memset( &filename_buffer, '\0', MAX_SYSPATH );
read( zip->handle, &filename_buffer, header_cdf.filename_len );
c = read( zip->handle, &filename_buffer, header_cdf.filename_len );
if( c != header_cdf.filename_len )
{
Con_Reportf( S_ERROR "filename length mismatch in %s. Zip file corrupted.\n", zipfile );
if( error )
*error = ZIP_LOAD_CORRUPTED;
Mem_Free( info );
Zip_Close( zip );
return NULL;
}
Q_strncpy( info[numpackfiles].name, filename_buffer, MAX_SYSPATH );
info[numpackfiles].size = header_cdf.uncompressed_size;
@@ -859,7 +886,20 @@ static zip_t *FS_LoadZip( const char *zipfile, int *error )
zip_header_t header;
lseek( zip->handle, info[i].offset, SEEK_SET );
read( zip->handle, &header, sizeof( header ) );
c = read( zip->handle, &header, sizeof( header ) );
if( c != sizeof( header ))
{
Con_Reportf( S_ERROR "header length mismatch in %s. Zip file corrupted.\n", zipfile );
if( error )
*error = ZIP_LOAD_CORRUPTED;
Mem_Free( info );
Zip_Close( zip );
return NULL;
}
info[i].flags = header.compression_flags;
info[i].offset = info[i].offset + header.filename_len + header.extrafield_len + sizeof( header );
}
@@ -869,7 +909,7 @@ static zip_t *FS_LoadZip( const char *zipfile, int *error )
zip->numfiles = numpackfiles;
zip->files = info;
qsort( zip->files, zip->numfiles, sizeof( zipfile_t ), FS_SortZip );
qsort( zip->files, zip->numfiles, sizeof( *zip->files ), FS_SortZip );
#ifdef XASH_REDUCE_FD
// will reopen when needed
@@ -888,7 +928,8 @@ void Zip_Close( zip_t *zip )
if( !zip )
return;
Mem_Free( zip->files );
if( zip->files )
Mem_Free( zip->files );
FS_EnsureOpenZip( NULL );
@@ -907,6 +948,7 @@ static byte *Zip_LoadFile( const char *path, fs_offset_t *sizeptr, qboolean game
int zlib_result = 0;
dword test_crc, final_crc;
z_stream decompress_stream;
size_t c;
if( sizeptr ) *sizeptr = 0;
@@ -936,7 +978,13 @@ static byte *Zip_LoadFile( const char *path, fs_offset_t *sizeptr, qboolean game
decompressed_buffer = Mem_Malloc( fs_mempool, file->size + 1 );
decompressed_buffer[file->size] = '\0';
read( search->zip->handle, decompressed_buffer, file->size );
c = read( search->zip->handle, decompressed_buffer, file->size );
if( c != file->size )
{
Con_Reportf( S_ERROR "Zip_LoadFile: %s size doesn't match\n", file->name );
return NULL;
}
#if 0
CRC32_Init( &test_crc );
CRC32_ProcessBuffer( &test_crc, decompressed_buffer, file->size );
@@ -961,7 +1009,12 @@ static byte *Zip_LoadFile( const char *path, fs_offset_t *sizeptr, qboolean game
decompressed_buffer = Mem_Malloc( fs_mempool, file->size + 1 );
decompressed_buffer[file->size] = '\0';
read( search->zip->handle, compressed_buffer, file->compressed_size );
c = read( search->zip->handle, compressed_buffer, file->compressed_size );
if( c != file->compressed_size )
{
Con_Reportf( S_ERROR "Zip_LoadFile: %s compressed size doesn't match\n", file->name );
return NULL;
}
memset( &decompress_stream, 0, sizeof( decompress_stream ) );
@@ -1139,7 +1192,7 @@ static qboolean FS_AddPak_Fullpath( const char *pakfile, qboolean *already_loade
}
}
qboolean FS_AddZip_Fullpath( const char *zipfile, qboolean *already_loaded, int flags )
static qboolean FS_AddZip_Fullpath( const char *zipfile, qboolean *already_loaded, int flags )
{
searchpath_t *search;
zip_t *zip = NULL;
@@ -1192,6 +1245,24 @@ qboolean FS_AddZip_Fullpath( const char *zipfile, qboolean *already_loaded, int
}
}
/*
================
FS_AddArchive_Fullpath
================
*/
static qboolean FS_AddArchive_Fullpath( const char *file, qboolean *already_loaded, int flags )
{
const char *ext = COM_FileExtension( file );
if( !Q_stricmp( ext, "pk3" ) )
return FS_AddZip_Fullpath( file, already_loaded, flags );
else if ( !Q_stricmp( ext, "pak" ))
return FS_AddPak_Fullpath( file, already_loaded, flags );
// skip wads, this function only meant to be used for extras
return false;
}
/*
================
FS_AddGameDirectory
@@ -1226,7 +1297,7 @@ void FS_AddGameDirectory( const char *dir, uint flags )
// add any Zip package in the directory
for( i = 0; i < list.numstrings; i++ )
{
if( !Q_stricmp( COM_FileExtension( list.strings[i] ), "zip" ) || !Q_stricmp( COM_FileExtension( list.strings[i] ), "pk3" ))
if( !Q_stricmp( COM_FileExtension( list.strings[i] ), "pk3" ) )
{
Q_sprintf( fullpath, "%s%s", dir, list.strings[i] );
FS_AddZip_Fullpath( fullpath, NULL, flags );
@@ -1417,11 +1488,12 @@ void FS_Rescan( void )
}
#else
str = getenv( "XASH3D_EXTRAS_PAK1" );
if( COM_CheckString( str ) )
FS_AddPak_Fullpath( str, NULL, extrasFlags );
if( COM_CheckString( str ))
FS_AddArchive_Fullpath( str, NULL, extrasFlags );
str = getenv( "XASH3D_EXTRAS_PAK2" );
if( COM_CheckString( str ) )
FS_AddPak_Fullpath( str, NULL, extrasFlags );
if( COM_CheckString( str ))
FS_AddArchive_Fullpath( str, NULL, extrasFlags );
#endif
if( Q_stricmp( GI->basedir, GI->gamefolder ))
@@ -1791,6 +1863,11 @@ void FS_ParseGenericGameInfo( gameinfo_t *GameInfo, const char *buf, const qbool
pfile = COM_ParseFile( pfile, token, sizeof( token ));
GameInfo->noskills = Q_atoi( token );
}
else if( !Q_stricmp( token, "render_picbutton_text" ))
{
pfile = COM_ParseFile( pfile, token, sizeof( token ));
GameInfo->render_picbutton_text = Q_atoi( token );
}
}
}
@@ -2061,9 +2138,9 @@ void FS_Init( void )
FS_InitMemory();
Cmd_AddCommand( "fs_rescan", FS_Rescan_f, "rescan filesystem search pathes" );
Cmd_AddCommand( "fs_path", FS_Path_f, "show filesystem search pathes" );
Cmd_AddCommand( "fs_clearpaths", FS_ClearPaths_f, "clear filesystem search pathes" );
Cmd_AddRestrictedCommand( "fs_rescan", FS_Rescan_f, "rescan filesystem search pathes" );
Cmd_AddRestrictedCommand( "fs_path", FS_Path_f, "show filesystem search pathes" );
Cmd_AddRestrictedCommand( "fs_clearpaths", FS_ClearPaths_f, "clear filesystem search pathes" );
#if !XASH_WIN32
if( Sys_CheckParm( "-casesensitive" ) )
@@ -2114,9 +2191,15 @@ void FS_Init( void )
for( i = 0; i < dirs.numstrings; i++ )
{
// no need to check folders here, FS_CreatePath will not fail if path exists
// and listdirectory returns only really existing directories
FS_CreatePath( va( "%s" PATH_SPLITTER "%s/", host.rootdir, dirs.strings[i] ));
char *roPath = va( "%s" PATH_SPLITTER "%s" PATH_SPLITTER, host.rodir, dirs.strings[i] );
char *rwPath = va( "%s" PATH_SPLITTER "%s" PATH_SPLITTER, host.rootdir, dirs.strings[i] );
// check if it's a directory
if( !FS_SysFolderExists( roPath ))
continue;
// no need to check folders here, FS_CreatePath will not fail
FS_CreatePath( rwPath );
}
stringlistfreecontents( &dirs );
@@ -2394,7 +2477,7 @@ qboolean FS_SysFileExists( const char *path, qboolean caseinsensitive )
close( desc );
return true;
#else
#elif XASH_POSIX
int ret;
struct stat buf;
@@ -2412,6 +2495,8 @@ qboolean FS_SysFileExists( const char *path, qboolean caseinsensitive )
return false;
return S_ISREG( buf.st_mode );
#else
#error
#endif
}
@@ -2446,23 +2531,18 @@ qboolean FS_SysFolderExists( const char *path )
DWORD dwFlags = GetFileAttributes( path );
return ( dwFlags != -1 ) && ( dwFlags & FILE_ATTRIBUTE_DIRECTORY );
#else
DIR *dir = opendir( path );
#elif XASH_POSIX
struct stat buf;
if( dir )
{
closedir( dir );
return true;
}
else if( (errno == ENOENT) || (errno == ENOTDIR) )
if( stat( path, &buf ) < 0 )
{
Con_Reportf( S_ERROR "FS_SysFolderExists: problem while opening dir: %s\n", strerror( errno ));
return false;
}
else
{
Con_Reportf( S_ERROR "FS_SysFolderExists: problem while opening dir: %s\n", strerror( errno ) );
return false;
}
return S_ISDIR( buf.st_mode );
#else
#error
#endif
}
@@ -3575,6 +3655,7 @@ search_t *FS_Search( const char *pattern, int caseinsensitive, int gamedironly )
searchpath_t *searchpath;
pack_t *pak;
wfile_t *wad;
zip_t *zip;
int i, basepathlength, numfiles, numchars;
int resultlistindex, dirlistindex;
const char *slash, *backslash, *colon, *separator;
@@ -3591,8 +3672,8 @@ search_t *FS_Search( const char *pattern, int caseinsensitive, int gamedironly )
slash = Q_strrchr( pattern, '/' );
backslash = Q_strrchr( pattern, '\\' );
colon = Q_strrchr( pattern, ':' );
separator = max( slash, backslash );
separator = max( separator, colon );
separator = Q_max( slash, backslash );
separator = Q_max( separator, colon );
basepathlength = separator ? (separator + 1 - pattern) : 0;
basepath = Mem_Calloc( fs_mempool, basepathlength + 1 );
if( basepathlength ) memcpy( basepath, pattern, basepathlength );
@@ -3642,6 +3723,42 @@ search_t *FS_Search( const char *pattern, int caseinsensitive, int gamedironly )
}
}
}
else if( searchpath->zip )
{
zip = searchpath->zip;
for( i = 0; i < zip->numfiles; i++ )
{
Q_strncpy( temp, zip->files[i].name, sizeof(temp) );
while( temp[0] )
{
if( matchpattern( temp, (char *)pattern, true ))
{
for( resultlistindex = 0; resultlistindex < resultlist.numstrings; resultlistindex++ )
{
if( !Q_strcmp( resultlist.strings[resultlistindex], temp ))
break;
}
if( resultlistindex == resultlist.numstrings )
stringlistappend( &resultlist, temp );
}
// strip off one path element at a time until empty
// this way directories are added to the listing if they match the pattern
slash = Q_strrchr( temp, '/' );
backslash = Q_strrchr( temp, '\\' );
colon = Q_strrchr( temp, ':' );
separator = temp;
if( separator < slash )
separator = slash;
if( separator < backslash )
separator = backslash;
if( separator < colon )
separator = colon;
*((char *)separator) = 0;
}
}
}
else if( searchpath->wad )
{
string wadpattern, wadname, temp2;

View File

@@ -15,6 +15,7 @@ GNU General Public License for more details.
#include "common.h"
#include "xash3d_mathlib.h"
#include "enginefeatures.h"
//-----------------------------------------------------------------------------
// Gamma conversion support
@@ -78,10 +79,16 @@ void BuildGammaTable( float lightgamma, float brightness )
byte LightToTexGamma( byte b )
{
return lightgammatable[b];
if( FBitSet( host.features, ENGINE_LINEAR_GAMMA_SPACE ))
return b;
else
return lightgammatable[b];
}
byte TextureToGamma( byte b )
{
return texgammatable[b];
if( FBitSet( host.features, ENGINE_LINEAR_GAMMA_SPACE ))
return b;
else
return texgammatable[b];
}

View File

@@ -50,7 +50,8 @@ sysinfo_t SI;
struct tests_stats_s tests_stats;
#endif
CVAR_DEFINE( host_developer, "developer", "0", 0, "engine is in development-mode" );
CVAR_DEFINE( host_developer, "developer", "0", FCVAR_FILTERABLE, "engine is in development-mode" );
CVAR_DEFINE_AUTO( sys_timescale, "1.0", FCVAR_CHEAT|FCVAR_FILTERABLE, "scale frame time" );
CVAR_DEFINE_AUTO( sys_ticrate, "100", 0, "framerate in dedicated mode" );
convar_t *host_serverstate;
@@ -85,9 +86,11 @@ void Sys_PrintUsage( void )
O("-dev [level] ","set log verbosity 0-2")
O("-log ","write log to \"engine.log\"")
O("-nowriteconfig ","disable config save")
#if !XASH_WIN32
O("-casesensitive ","disable case-insensitive FS emulation")
#endif // !XASH_WIN32
#if !XASH_MOBILE_PLATFORM
O("-daemonize ","run engine in background, dedicated only")
#endif // !XASH_MOBILE_PLATFORM
@@ -98,53 +101,53 @@ void Sys_PrintUsage( void )
O("-height <n> ","set window height")
O("-oldfont ","enable unused Quake font in Half-Life")
#if !XASH_MOBILE_PLATFORM
#if !XASH_MOBILE_PLATFORM
O("-fullscreen ","run engine in fullscreen mode")
O("-windowed ","run engine in windowed mode")
O("-dedicated ","run engine in dedicated server mode")
#endif // XASH_MOBILE_PLATFORM
#endif // XASH_MOBILE_PLATFORM
#if XASH_ANDROID
O("-nativeegl ","use native egl implementation. Use if screen does not update or black")
#endif // XASH_ANDROID
#if XASH_ANDROID
O("-nativeegl ","use native egl implementation. Use if screen does not update or black")
#endif // XASH_ANDROID
#if XASH_WIN32
O("-noavi ","disable AVI support")
O("-nointro ","disable intro video")
#endif // XASH_WIN32
#if XASH_WIN32
O("-noavi ","disable AVI support")
O("-nointro ","disable intro video")
#endif // XASH_WIN32
#if XASH_DOS
#if XASH_DOS
O("-novesa ","disable vesa")
#endif // XASH_DOS
#endif // XASH_DOS
#if XASH_VIDEO == VIDEO_FBDEV
#if XASH_VIDEO == VIDEO_FBDEV
O("-fbdev <path> ","open selected framebuffer")
O("-ttygfx ","set graphics mode in tty")
O("-doublebuffer ","enable doublebuffering")
#endif // XASH_VIDEO == VIDEO_FBDEV
#endif // XASH_VIDEO == VIDEO_FBDEV
#if XASH_SOUND == SOUND_ALSA
#if XASH_SOUND == SOUND_ALSA
O("-alsadev <dev> ","open selected ALSA device")
#endif // XASH_SOUND == SOUND_ALSA
#endif // XASH_SOUND == SOUND_ALSA
O("-nojoy ","disable joystick support")
#ifdef XASH_SDL
#ifdef XASH_SDL
O("-sdl_joy_old_api ","use SDL legacy joystick API")
O("-sdl_renderer <n>","use alternative SDL_Renderer for software")
#endif // XASH_SDL
#endif // XASH_SDL
O("-nosound ","disable sound")
O("-noenginemouse ","disable mouse completely")
O("-ref <name> ","use selected renderer dll")
O("-gldebug ","enable OpenGL debug log")
O("-gldebug ","enable OpenGL debug log")
#endif // XASH_DEDICATED
O("-noip ","disable TCP/IP")
O("-noch ","disable crashhandler")
O("-disablehelp ","disable this message")
O("-dll <path> ","override server DLL path")
#ifndef XASH_DEDICATED
#if !XASH_DEDICATED
O("-clientlib <path>","override client DLL path")
#endif
O("-rodir <path> ","set read-only base directory, experimental")
@@ -353,10 +356,11 @@ Host_Exec_f
*/
void Host_Exec_f( void )
{
string cfgpath;
string cfgpath;
byte *f;
char *txt;
fs_offset_t len;
const char *arg;
if( Cmd_Argc() != 2 )
{
@@ -364,14 +368,47 @@ void Host_Exec_f( void )
return;
}
if( !Q_stricmp( "game.cfg", Cmd_Argv( 1 )))
arg = Cmd_Argv( 1 );
#ifndef XASH_DEDICATED
if( !Cmd_CurrentCommandIsPrivileged() )
{
const char *unprivilegedWhitelist[] =
{
NULL, "mapdefault.cfg", "scout.cfg", "sniper.cfg",
"soldier.cfg", "demoman.cfg", "medic.cfg", "hwguy.cfg",
"pyro.cfg", "spy.cfg", "engineer.cfg", "civilian.cfg"
};
int i;
qboolean allow = false;
unprivilegedWhitelist[0] = va( "%s.cfg", clgame.mapname );
for( i = 0; i < ARRAYSIZE( unprivilegedWhitelist ); i++ )
{
if( !Q_strcmp( arg, unprivilegedWhitelist[i] ))
{
allow = true;
break;
}
}
if( !allow )
{
Con_Printf( "exec %s: not privileged or in whitelist\n", arg );
return;
}
}
#endif // XASH_DEDICATED
if( !Q_stricmp( "game.cfg", arg ))
{
// don't execute game.cfg in singleplayer
if( SV_GetMaxClients() == 1 )
return;
}
Q_strncpy( cfgpath, Cmd_Argv( 1 ), sizeof( cfgpath ));
Q_strncpy( cfgpath, arg, sizeof( cfgpath ));
COM_DefaultExtension( cfgpath, ".cfg" ); // append as default
f = FS_LoadFile( cfgpath, &len, false );
@@ -381,7 +418,7 @@ void Host_Exec_f( void )
return;
}
if( !Q_stricmp( "config.cfg", Cmd_Argv( 1 )))
if( !Q_stricmp( "config.cfg", arg ))
host.config_executed = true;
// adds \n\0 at end of the file
@@ -391,7 +428,7 @@ void Host_Exec_f( void )
Mem_Free( f );
if( !host.apply_game_config )
Con_Printf( "execing %s\n", Cmd_Argv( 1 ));
Con_Printf( "execing %s\n", arg );
Cbuf_InsertText( txt );
Mem_Free( txt );
}
@@ -592,8 +629,9 @@ qboolean Host_FilterTime( float time )
{
static double oldtime;
double fps;
double scale = sys_timescale.value;
host.realtime += time;
host.realtime += time * scale;
fps = Host_CalcFPS( );
// clamp the fps in multiplayer games
@@ -604,12 +642,12 @@ qboolean Host_FilterTime( float time )
if( Host_IsDedicated() )
{
if(( host.realtime - oldtime ) < ( 1.0 / ( fps + 1.0 )))
if(( host.realtime - oldtime ) < ( 1.0 / ( fps + 1.0 )) * scale)
return false;
}
else
{
if(( host.realtime - oldtime ) < ( 1.0 / fps ))
if(( host.realtime - oldtime ) < ( 1.0 / fps ) * scale )
return false;
}
}
@@ -620,7 +658,7 @@ qboolean Host_FilterTime( float time )
// NOTE: allow only in singleplayer while demos are not active
if( host_framerate->value > 0.0f && Host_IsLocalGame() && !CL_IsPlaybackDemo() && !CL_IsRecordDemo( ))
host.frametime = bound( MIN_FRAMETIME, host_framerate->value, MAX_FRAMETIME );
host.frametime = bound( MIN_FRAMETIME, host_framerate->value * scale, MAX_FRAMETIME );
else host.frametime = bound( MIN_FRAMETIME, host.frametime, MAX_FRAMETIME );
return true;
@@ -683,7 +721,6 @@ void GAME_EXPORT Host_Error( const char *error, ... )
else if( host.framecount == host.errorframe )
{
Sys_Error( "Host_MultiError: %s", hosterror2 );
return;
}
else
{
@@ -703,7 +740,6 @@ void GAME_EXPORT Host_Error( const char *error, ... )
{
Con_Printf( "Host_RecursiveError: %s", hosterror2 );
Sys_Error( "%s", hosterror1 );
return; // don't multiple executes
}
recursive = true;
@@ -784,9 +820,17 @@ static void Host_RunTests( int stage )
memset( &tests_stats, 0, sizeof( tests_stats ));
Test_RunLibCommon();
Test_RunCommon();
Test_RunCmd();
Test_RunCvar();
#if !XASH_DEDICATED
Test_RunCon();
#endif /* XASH_DEDICATED */
break;
case 1: // after FS load
Test_RunImagelib();
#if !XASH_DEDICATED
Test_RunVOX();
#endif
Msg( "Done! %d passed, %d failed\n", tests_stats.passed, tests_stats.failed );
Sys_Quit();
}
@@ -962,7 +1006,7 @@ void Host_InitCommon( int argc, char **argv, const char *progname, qboolean bCha
len = Q_strlen( host.rootdir );
if( host.rootdir[len - 1] == '/' )
if( len && host.rootdir[len - 1] == '/' )
host.rootdir[len - 1] = 0;
// get readonly root. The order is: check for arg, then env.
@@ -990,7 +1034,7 @@ void Host_InitCommon( int argc, char **argv, const char *progname, qboolean bCha
Cmd_AddCommand( "exec", Host_Exec_f, "execute a script file" );
Cmd_AddCommand( "memlist", Host_MemStats_f, "prints memory pool information" );
Cmd_AddCommand( "userconfigd", Host_Userconfigd_f, "execute all scripts from userconfig.d" );
Cmd_AddRestrictedCommand( "userconfigd", Host_Userconfigd_f, "execute all scripts from userconfig.d" );
FS_Init();
Image_Init();
@@ -1046,23 +1090,25 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
// init commands and vars
if( host_developer.value >= DEV_EXTENDED )
{
Cmd_AddCommand ( "sys_error", Sys_Error_f, "just throw a fatal error to test shutdown procedures");
Cmd_AddCommand ( "host_error", Host_Error_f, "just throw a host error to test shutdown procedures");
Cmd_AddCommand ( "crash", Host_Crash_f, "a way to force a bus error for development reasons");
Cmd_AddRestrictedCommand ( "sys_error", Sys_Error_f, "just throw a fatal error to test shutdown procedures");
Cmd_AddRestrictedCommand ( "host_error", Host_Error_f, "just throw a host error to test shutdown procedures");
Cmd_AddRestrictedCommand ( "crash", Host_Crash_f, "a way to force a bus error for development reasons");
}
host_serverstate = Cvar_Get( "host_serverstate", "0", FCVAR_READ_ONLY, "displays current server state" );
host_maxfps = Cvar_Get( "fps_max", "72", FCVAR_ARCHIVE, "host fps upper limit" );
host_framerate = Cvar_Get( "host_framerate", "0", 0, "locks frame timing to this value in seconds" );
host_sleeptime = Cvar_Get( "sleeptime", "1", FCVAR_ARCHIVE, "milliseconds to sleep for each frame. higher values reduce fps accuracy" );
host_maxfps = Cvar_Get( "fps_max", "72", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "host fps upper limit" );
host_framerate = Cvar_Get( "host_framerate", "0", FCVAR_FILTERABLE, "locks frame timing to this value in seconds" );
host_sleeptime = Cvar_Get( "sleeptime", "1", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "milliseconds to sleep for each frame. higher values reduce fps accuracy" );
host_gameloaded = Cvar_Get( "host_gameloaded", "0", FCVAR_READ_ONLY, "inidcates a loaded game.dll" );
host_clientloaded = Cvar_Get( "host_clientloaded", "0", FCVAR_READ_ONLY, "inidcates a loaded client.dll" );
host_limitlocal = Cvar_Get( "host_limitlocal", "0", 0, "apply cl_cmdrate and rate to loopback connection" );
con_gamemaps = Cvar_Get( "con_mapfilter", "1", FCVAR_ARCHIVE, "when true show only maps in game folder" );
Cvar_RegisterVariable( &sys_timescale );
build = Cvar_Get( "buildnum", va( "%i", Q_buildnum_compat()), FCVAR_READ_ONLY, "returns a current build number" );
ver = Cvar_Get( "ver", va( "%i/%s (hw build %i)", PROTOCOL_VERSION, XASH_COMPAT_VERSION, Q_buildnum_compat()), FCVAR_READ_ONLY, "shows an engine version" );
Cvar_Get( "host_ver", va( "%i %s %s %s %s", Q_buildnum(), XASH_VERSION, Q_buildos(), Q_buildarch(), Q_buildcommit() ), FCVAR_READ_ONLY, "detailed info about this build" );
Cvar_Get( "host_lowmemorymode", va( "%i", XASH_LOW_MEMORY ), FCVAR_READ_ONLY, "indicates if engine compiled for low RAM consumption (0 - normal, 1 - low engine limits, 2 - low protocol limits)" );
Mod_Init();
NET_Init();
@@ -1072,7 +1118,7 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
// allow to change game from the console
if( pChangeGame != NULL )
{
Cmd_AddCommand( "game", Host_ChangeGame_f, "change game" );
Cmd_AddRestrictedCommand( "game", Host_ChangeGame_f, "change game" );
Cvar_Get( "host_allow_changegame", "1", FCVAR_READ_ONLY, "allows to change games" );
}
else
@@ -1092,10 +1138,10 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
Wcon_InitConsoleCommands ();
#endif
Cmd_AddCommand( "quit", Sys_Quit, "quit the game" );
Cmd_AddCommand( "exit", Sys_Quit, "quit the game" );
Cmd_AddRestrictedCommand( "quit", Sys_Quit, "quit the game" );
Cmd_AddRestrictedCommand( "exit", Sys_Quit, "quit the game" );
}
else Cmd_AddCommand( "minimize", Host_Minimize_f, "minimize main window to tray" );
else Cmd_AddRestrictedCommand( "minimize", Host_Minimize_f, "minimize main window to tray" );
host.errorframe = 0;
@@ -1151,6 +1197,8 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
return 0;
}
void DLL_PrintLeaks( void );
/*
=================
Host_Shutdown
@@ -1179,6 +1227,8 @@ void EXPORT Host_Shutdown( void )
Host_FreeCommon();
Platform_Shutdown();
DLL_PrintLeaks();
// must be last, console uses this
Mem_FreePool( &host.mempool );

View File

@@ -1077,10 +1077,10 @@ void HPAK_Validate_f( void )
void HPAK_Init( void )
{
Cmd_AddCommand( "hpklist", HPAK_List_f, "list all files in specified HPK-file" );
Cmd_AddCommand( "hpkremove", HPAK_Remove_f, "remove specified file from HPK-file" );
Cmd_AddCommand( "hpkval", HPAK_Validate_f, "validate specified HPK-file" );
Cmd_AddCommand( "hpkextract", HPAK_Extract_f, "extract all lumps from specified HPK-file" );
Cmd_AddRestrictedCommand( "hpklist", HPAK_List_f, "list all files in specified HPK-file" );
Cmd_AddRestrictedCommand( "hpkremove", HPAK_Remove_f, "remove specified file from HPK-file" );
Cmd_AddRestrictedCommand( "hpkval", HPAK_Validate_f, "validate specified HPK-file" );
Cmd_AddRestrictedCommand( "hpkextract", HPAK_Extract_f, "extract all lumps from specified HPK-file" );
hpk_maxsize = Cvar_Get( "hpk_maxsize", "0", FCVAR_ARCHIVE, "set limit by size for all HPK-files ( 0 - unlimited )" );
gp_hpak_queue = NULL;

View File

@@ -614,10 +614,10 @@ void ID_Init( void )
byte md5[16];
int i;
Cmd_AddCommand( "bloomfilter", ID_BloomFilter_f, "print bloomfilter raw value of arguments set");
Cmd_AddCommand( "verifyhex", ID_VerifyHEX_f, "check if id source seems to be fake" );
Cmd_AddRestrictedCommand( "bloomfilter", ID_BloomFilter_f, "print bloomfilter raw value of arguments set");
Cmd_AddRestrictedCommand( "verifyhex", ID_VerifyHEX_f, "check if id source seems to be fake" );
#if XASH_LINUX
Cmd_AddCommand( "testcpuinfo", ID_TestCPUInfo_f, "try read cpu serial" );
Cmd_AddRestrictedCommand( "testcpuinfo", ID_TestCPUInfo_f, "try read cpu serial" );
#endif
#if XASH_ANDROID && !XASH_DEDICATED

View File

@@ -41,7 +41,7 @@ qboolean Image_LoadBMP( const char *name, const byte *buffer, fs_offset_t filesi
buf_p = (byte *)buffer;
memcpy( &bhdr, buf_p, sizeof( bmp_t ));
buf_p += sizeof( bmp_t );
buf_p += BI_FILE_HEADER_SIZE + bhdr.bitmapHeaderSize;
// bogus file header check
if( bhdr.reserved0 != 0 ) return false;
@@ -53,9 +53,9 @@ qboolean Image_LoadBMP( const char *name, const byte *buffer, fs_offset_t filesi
return false;
}
if( bhdr.bitmapHeaderSize != 0x28 )
if(!( bhdr.bitmapHeaderSize == 40 || bhdr.bitmapHeaderSize == 108 || bhdr.bitmapHeaderSize == 124 ))
{
Con_DPrintf( S_ERROR "Image_LoadBMP: invalid header size %i\n", bhdr.bitmapHeaderSize );
Con_DPrintf( S_ERROR "Image_LoadBMP: %s have non-standard header size %i\n", name, bhdr.bitmapHeaderSize );
return false;
}
@@ -187,6 +187,7 @@ qboolean Image_LoadBMP( const char *name, const byte *buffer, fs_offset_t filesi
return false;
}
image.depth = 1;
image.size = image.width * image.height * bpp;
image.rgba = Mem_Malloc( host.imagepool, image.size );
@@ -313,8 +314,8 @@ qboolean Image_LoadBMP( const char *name, const byte *buffer, fs_offset_t filesi
}
VectorDivide( reflectivity, ( image.width * image.height ), image.fogParams );
if( image.palette ) Image_GetPaletteBMP( image.palette );
image.depth = 1;
if( image.palette )
Image_GetPaletteBMP( image.palette );
return true;
}

View File

@@ -22,6 +22,7 @@ GNU General Public License for more details.
========================================================================
*/
#define BI_FILE_HEADER_SIZE 14
#define BI_SIZE 40 // size of bitmap info header.
#if !defined(BI_RGB)
#define BI_RGB 0 // uncompressed RGB bitmap(defined in wingdi.h)

View File

@@ -91,7 +91,7 @@ qboolean Image_CheckDXT5Alpha( dds_t *hdr, byte *fin )
return false;
}
void Image_DXTGetPixelFormat( dds_t *hdr )
void Image_DXTGetPixelFormat( dds_t *hdr, dds_header_dxt10_t *headerExt )
{
uint bits = hdr->dsPixelFormat.dwRGBBitCount;
@@ -100,29 +100,53 @@ void Image_DXTGetPixelFormat( dds_t *hdr )
if( FBitSet( hdr->dsPixelFormat.dwFlags, DDS_FOURCC ))
{
switch( hdr->dsPixelFormat.dwFourCC )
if( hdr->dsPixelFormat.dwFourCC == TYPE_DX10 )
{
case TYPE_DXT1:
image.type = PF_DXT1;
break;
case TYPE_DXT2:
image.flags &= ~IMAGE_HAS_ALPHA; // alpha is already premultiplied by color
// intentionally fallthrough
case TYPE_DXT3:
image.type = PF_DXT3;
break;
case TYPE_DXT4:
image.flags &= ~IMAGE_HAS_ALPHA; // alpha is already premultiplied by color
// intentionally fallthrough
case TYPE_DXT5:
image.type = PF_DXT5;
break;
case TYPE_ATI2:
image.type = PF_ATI2;
break;
default:
image.type = PF_UNKNOWN; // assume error
break;
switch( headerExt->dxgiFormat )
{
case DXGI_FORMAT_BC6H_SF16:
image.type = PF_BC6H_SIGNED;
break;
case DXGI_FORMAT_BC6H_UF16:
case DXGI_FORMAT_BC6H_TYPELESS:
image.type = PF_BC6H_UNSIGNED;
break;
case DXGI_FORMAT_BC7_UNORM:
case DXGI_FORMAT_BC7_UNORM_SRGB:
case DXGI_FORMAT_BC7_TYPELESS:
image.type = PF_BC7;
break;
default:
image.type = PF_UNKNOWN;
break;
}
}
else
{
switch( hdr->dsPixelFormat.dwFourCC )
{
case TYPE_DXT1:
image.type = PF_DXT1;
break;
case TYPE_DXT2:
image.flags &= ~IMAGE_HAS_ALPHA; // alpha is already premultiplied by color
// intentionally fallthrough
case TYPE_DXT3:
image.type = PF_DXT3;
break;
case TYPE_DXT4:
image.flags &= ~IMAGE_HAS_ALPHA; // alpha is already premultiplied by color
// intentionally fallthrough
case TYPE_DXT5:
image.type = PF_DXT5;
break;
case TYPE_ATI2:
image.type = PF_ATI2;
break;
default:
image.type = PF_UNKNOWN; // assume error
break;
}
}
}
else
@@ -171,6 +195,9 @@ size_t Image_DXTGetLinearSize( int type, int width, int height, int depth )
case PF_DXT1: return ((( width + 3 ) / 4 ) * (( height + 3 ) / 4 ) * depth * 8 );
case PF_DXT3:
case PF_DXT5:
case PF_BC6H_SIGNED:
case PF_BC6H_UNSIGNED:
case PF_BC7:
case PF_ATI2: return ((( width + 3 ) / 4 ) * (( height + 3 ) / 4 ) * depth * 16 );
case PF_LUMINANCE: return (width * height * depth);
case PF_BGR_24:
@@ -254,16 +281,18 @@ qboolean Image_LoadDDS( const char *name, const byte *buffer, fs_offset_t filesi
{
dds_t header;
byte *fin;
int headersOffset;
dds_header_dxt10_t header2;
if( filesize < sizeof( dds_t ))
if( filesize < sizeof( header ))
return false;
memcpy( &header, buffer, sizeof( dds_t ));
memcpy( &header, buffer, sizeof( header ));
if( header.dwIdent != DDSHEADER )
return false; // it's not a dds file, just skip it
if( header.dwSize != sizeof( dds_t ) - sizeof( uint )) // size of the structure (minus MagicNum)
if( header.dwSize != sizeof( header ) - sizeof( uint )) // size of the structure (minus MagicNum)
{
Con_DPrintf( S_ERROR "Image_LoadDDS: (%s) have corrupted header\n", name );
return false;
@@ -275,6 +304,13 @@ qboolean Image_LoadDDS( const char *name, const byte *buffer, fs_offset_t filesi
return false;
}
headersOffset = sizeof( header );
if( header.dsPixelFormat.dwFourCC == TYPE_DX10 )
{
memcpy( &header2, buffer + sizeof( header ), sizeof( header2 ));
headersOffset += sizeof( header2 );
}
image.width = header.dwWidth;
image.height = header.dwHeight;
@@ -284,7 +320,7 @@ qboolean Image_LoadDDS( const char *name, const byte *buffer, fs_offset_t filesi
if( !Image_ValidSize( name )) return false;
Image_DXTGetPixelFormat( &header ); // and image type too :)
Image_DXTGetPixelFormat( &header, &header2 ); // and image type too :)
Image_DXTAdjustVolume( &header );
if( !Image_CheckFlag( IL_DDS_HARDWARE ) && ImageDXT( image.type ))
@@ -296,9 +332,9 @@ qboolean Image_LoadDDS( const char *name, const byte *buffer, fs_offset_t filesi
return false;
}
image.size = Image_DXTCalcSize( name, &header, filesize - 128 );
image.size = Image_DXTCalcSize( name, &header, filesize - headersOffset );
if( image.size == 0 ) return false; // just in case
fin = (byte *)(buffer + sizeof( dds_t ));
fin = (byte *)( buffer + headersOffset );
// copy an encode method
image.encode = (word)header.dwReserved1[0];
@@ -320,6 +356,8 @@ qboolean Image_LoadDDS( const char *name, const byte *buffer, fs_offset_t filesi
SetBits( image.flags, IMAGE_HAS_ALPHA );
else if( image.type == PF_DXT5 && Image_CheckDXT5Alpha( &header, fin ))
SetBits( image.flags, IMAGE_HAS_ALPHA );
else if ( image.type == PF_BC7 )
SetBits(image.flags, IMAGE_HAS_ALPHA);
if( !FBitSet( header.dsPixelFormat.dwFlags, DDS_LUMINANCE ))
SetBits( image.flags, IMAGE_HAS_COLOR );
break;

View File

@@ -29,6 +29,7 @@ GNU General Public License for more details.
#define TYPE_DXT3 (('3'<<24)+('T'<<16)+('X'<<8)+'D') // little-endian "DXT3"
#define TYPE_DXT4 (('4'<<24)+('T'<<16)+('X'<<8)+'D') // little-endian "DXT4"
#define TYPE_DXT5 (('5'<<24)+('T'<<16)+('X'<<8)+'D') // little-endian "DXT5"
#define TYPE_DX10 (('0'<<24)+('1'<<16)+('X'<<8)+'D') // little-endian "DX10"
#define TYPE_ATI1 (('1'<<24)+('I'<<16)+('T'<<8)+'A') // little-endian "ATI1"
#define TYPE_ATI2 (('2'<<24)+('I'<<16)+('T'<<8)+'A') // little-endian "ATI2"
#define TYPE_RXGB (('B'<<24)+('G'<<16)+('X'<<8)+'R') // little-endian "RXGB" doom3 normalmaps
@@ -75,6 +76,141 @@ GNU General Public License for more details.
#define DDS_CUBEMAP_ALL_SIDES 0x0000FC00L
#define DDS_VOLUME 0x00200000L
typedef enum
{
DXGI_FORMAT_UNKNOWN = 0,
DXGI_FORMAT_R32G32B32A32_TYPELESS = 1,
DXGI_FORMAT_R32G32B32A32_FLOAT = 2,
DXGI_FORMAT_R32G32B32A32_UINT = 3,
DXGI_FORMAT_R32G32B32A32_SINT = 4,
DXGI_FORMAT_R32G32B32_TYPELESS = 5,
DXGI_FORMAT_R32G32B32_FLOAT = 6,
DXGI_FORMAT_R32G32B32_UINT = 7,
DXGI_FORMAT_R32G32B32_SINT = 8,
DXGI_FORMAT_R16G16B16A16_TYPELESS = 9,
DXGI_FORMAT_R16G16B16A16_FLOAT = 10,
DXGI_FORMAT_R16G16B16A16_UNORM = 11,
DXGI_FORMAT_R16G16B16A16_UINT = 12,
DXGI_FORMAT_R16G16B16A16_SNORM = 13,
DXGI_FORMAT_R16G16B16A16_SINT = 14,
DXGI_FORMAT_R32G32_TYPELESS = 15,
DXGI_FORMAT_R32G32_FLOAT = 16,
DXGI_FORMAT_R32G32_UINT = 17,
DXGI_FORMAT_R32G32_SINT = 18,
DXGI_FORMAT_R32G8X24_TYPELESS = 19,
DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20,
DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21,
DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22,
DXGI_FORMAT_R10G10B10A2_TYPELESS = 23,
DXGI_FORMAT_R10G10B10A2_UNORM = 24,
DXGI_FORMAT_R10G10B10A2_UINT = 25,
DXGI_FORMAT_R11G11B10_FLOAT = 26,
DXGI_FORMAT_R8G8B8A8_TYPELESS = 27,
DXGI_FORMAT_R8G8B8A8_UNORM = 28,
DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29,
DXGI_FORMAT_R8G8B8A8_UINT = 30,
DXGI_FORMAT_R8G8B8A8_SNORM = 31,
DXGI_FORMAT_R8G8B8A8_SINT = 32,
DXGI_FORMAT_R16G16_TYPELESS = 33,
DXGI_FORMAT_R16G16_FLOAT = 34,
DXGI_FORMAT_R16G16_UNORM = 35,
DXGI_FORMAT_R16G16_UINT = 36,
DXGI_FORMAT_R16G16_SNORM = 37,
DXGI_FORMAT_R16G16_SINT = 38,
DXGI_FORMAT_R32_TYPELESS = 39,
DXGI_FORMAT_D32_FLOAT = 40,
DXGI_FORMAT_R32_FLOAT = 41,
DXGI_FORMAT_R32_UINT = 42,
DXGI_FORMAT_R32_SINT = 43,
DXGI_FORMAT_R24G8_TYPELESS = 44,
DXGI_FORMAT_D24_UNORM_S8_UINT = 45,
DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46,
DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47,
DXGI_FORMAT_R8G8_TYPELESS = 48,
DXGI_FORMAT_R8G8_UNORM = 49,
DXGI_FORMAT_R8G8_UINT = 50,
DXGI_FORMAT_R8G8_SNORM = 51,
DXGI_FORMAT_R8G8_SINT = 52,
DXGI_FORMAT_R16_TYPELESS = 53,
DXGI_FORMAT_R16_FLOAT = 54,
DXGI_FORMAT_D16_UNORM = 55,
DXGI_FORMAT_R16_UNORM = 56,
DXGI_FORMAT_R16_UINT = 57,
DXGI_FORMAT_R16_SNORM = 58,
DXGI_FORMAT_R16_SINT = 59,
DXGI_FORMAT_R8_TYPELESS = 60,
DXGI_FORMAT_R8_UNORM = 61,
DXGI_FORMAT_R8_UINT = 62,
DXGI_FORMAT_R8_SNORM = 63,
DXGI_FORMAT_R8_SINT = 64,
DXGI_FORMAT_A8_UNORM = 65,
DXGI_FORMAT_R1_UNORM = 66,
DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67,
DXGI_FORMAT_R8G8_B8G8_UNORM = 68,
DXGI_FORMAT_G8R8_G8B8_UNORM = 69,
DXGI_FORMAT_BC1_TYPELESS = 70,
DXGI_FORMAT_BC1_UNORM = 71,
DXGI_FORMAT_BC1_UNORM_SRGB = 72,
DXGI_FORMAT_BC2_TYPELESS = 73,
DXGI_FORMAT_BC2_UNORM = 74,
DXGI_FORMAT_BC2_UNORM_SRGB = 75,
DXGI_FORMAT_BC3_TYPELESS = 76,
DXGI_FORMAT_BC3_UNORM = 77,
DXGI_FORMAT_BC3_UNORM_SRGB = 78,
DXGI_FORMAT_BC4_TYPELESS = 79,
DXGI_FORMAT_BC4_UNORM = 80,
DXGI_FORMAT_BC4_SNORM = 81,
DXGI_FORMAT_BC5_TYPELESS = 82,
DXGI_FORMAT_BC5_UNORM = 83,
DXGI_FORMAT_BC5_SNORM = 84,
DXGI_FORMAT_B5G6R5_UNORM = 85,
DXGI_FORMAT_B5G5R5A1_UNORM = 86,
DXGI_FORMAT_B8G8R8A8_UNORM = 87,
DXGI_FORMAT_B8G8R8X8_UNORM = 88,
DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89,
DXGI_FORMAT_B8G8R8A8_TYPELESS = 90,
DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91,
DXGI_FORMAT_B8G8R8X8_TYPELESS = 92,
DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93,
DXGI_FORMAT_BC6H_TYPELESS = 94,
DXGI_FORMAT_BC6H_UF16 = 95,
DXGI_FORMAT_BC6H_SF16 = 96,
DXGI_FORMAT_BC7_TYPELESS = 97,
DXGI_FORMAT_BC7_UNORM = 98,
DXGI_FORMAT_BC7_UNORM_SRGB = 99,
DXGI_FORMAT_AYUV = 100,
DXGI_FORMAT_Y410 = 101,
DXGI_FORMAT_Y416 = 102,
DXGI_FORMAT_NV12 = 103,
DXGI_FORMAT_P010 = 104,
DXGI_FORMAT_P016 = 105,
DXGI_FORMAT_420_OPAQUE = 106,
DXGI_FORMAT_YUY2 = 107,
DXGI_FORMAT_Y210 = 108,
DXGI_FORMAT_Y216 = 109,
DXGI_FORMAT_NV11 = 110,
DXGI_FORMAT_AI44 = 111,
DXGI_FORMAT_IA44 = 112,
DXGI_FORMAT_P8 = 113,
DXGI_FORMAT_A8P8 = 114,
DXGI_FORMAT_B4G4R4A4_UNORM = 115,
DXGI_FORMAT_P208 = 130,
DXGI_FORMAT_V208 = 131,
DXGI_FORMAT_V408 = 132,
DXGI_FORMAT_SAMPLER_FEEDBACK_MIN_MIP_OPAQUE,
DXGI_FORMAT_SAMPLER_FEEDBACK_MIP_REGION_USED_OPAQUE,
DXGI_FORMAT_FORCE_UINT = 0xffffffff
} dxgi_format_t;
typedef enum
{
D3D10_RESOURCE_DIMENSION_UNKNOWN = 0,
D3D10_RESOURCE_DIMENSION_BUFFER = 1,
D3D10_RESOURCE_DIMENSION_TEXTURE1D = 2,
D3D10_RESOURCE_DIMENSION_TEXTURE2D = 3,
D3D10_RESOURCE_DIMENSION_TEXTURE3D = 4
} dds_resource_dimension_t;
typedef struct dds_pf_s
{
uint32_t dwSize;
@@ -96,6 +232,15 @@ typedef struct dds_caps_s
uint32_t dwCaps4; // currently unused
} dds_caps_t;
typedef struct dds_header_dxt10_s
{
dxgi_format_t dxgiFormat;
dds_resource_dimension_t resourceDimension;
uint32_t miscFlag;
uint32_t arraySize;
uint32_t miscFlags2;
} dds_header_dxt10_t;
typedef struct dds_s
{
uint32_t dwIdent; // must matched with DDSHEADER

View File

@@ -71,7 +71,7 @@ static const cubepack_t load_cubemap[] =
};
// soul of ImageLib - table of image format constants
const bpc_desc_t PFDesc[PF_TOTALCOUNT] =
const bpc_desc_t PFDesc[] =
{
{ PF_UNKNOWN, "raw", 0x1908, 0 },
{ PF_INDEXED_24, "pal 24", 0x1908, 1 },
@@ -85,8 +85,6 @@ const bpc_desc_t PFDesc[PF_TOTALCOUNT] =
{ PF_DXT3, "DXT 3", 0x83F2, 4 },
{ PF_DXT5, "DXT 5", 0x83F3, 4 },
{ PF_ATI2, "ATI 2", 0x8837, 4 },
{ PF_RGBA_64, "RGBA 64", 0x1908, 8 },
{ PF_RGB_48, "RGB 48", 0x1908, 6 },
};
void Image_Reset( void )
@@ -568,4 +566,25 @@ void Test_RunImagelib( void )
Z_Free( rgb.buffer );
}
#define IMPLEMENT_IMAGELIB_FUZZ_TARGET( export, target ) \
int EXPORT export( const uint8_t *Data, size_t Size ) \
{ \
rgbdata_t *rgb; \
host.type = HOST_NORMAL; \
Memory_Init(); \
Image_Init(); \
if( target( "#internal", Data, Size )) \
{ \
rgb = ImagePack(); \
FS_FreeImage( rgb ); \
} \
Image_Shutdown(); \
return 0; \
} \
IMPLEMENT_IMAGELIB_FUZZ_TARGET( Fuzz_Image_LoadBMP, Image_LoadBMP )
IMPLEMENT_IMAGELIB_FUZZ_TARGET( Fuzz_Image_LoadPNG, Image_LoadPNG )
IMPLEMENT_IMAGELIB_FUZZ_TARGET( Fuzz_Image_LoadDDS, Image_LoadDDS )
IMPLEMENT_IMAGELIB_FUZZ_TARGET( Fuzz_Image_LoadTGA, Image_LoadTGA )
#endif /* XASH_ENGINE_TESTS */

View File

@@ -40,9 +40,9 @@ qboolean Image_LoadPNG( const char *name, const byte *buffer, fs_offset_t filesi
{
int ret;
short p, a, b, c, pa, pb, pc;
byte *buf_p, *pixbuf, *raw, *prior, *idat_buf = NULL, *uncompressed_buffer = NULL;
byte *buf_p, *pixbuf, *raw, *prior, *idat_buf = NULL, *uncompressed_buffer = NULL, *rowend;
uint chunk_len, crc32, crc32_check, oldsize = 0, newsize = 0, rowsize;
uint uncompressed_size, pixel_size, i, y, filter_type, chunk_sign, channel_size;
uint uncompressed_size, pixel_size, i, y, filter_type, chunk_sign;
qboolean has_iend_chunk = false;
z_stream stream = {0};
png_t png_hdr;
@@ -89,9 +89,9 @@ qboolean Image_LoadPNG( const char *name, const byte *buffer, fs_offset_t filesi
return false;
}
if( png_hdr.ihdr_chunk.bitdepth != 8 && png_hdr.ihdr_chunk.bitdepth != 16 )
if( png_hdr.ihdr_chunk.bitdepth != 8 )
{
Con_DPrintf( S_WARN "Image_LoadPNG: Only 8-bit or 16-bit images is supported (%s)\n", name );
Con_DPrintf( S_WARN "Image_LoadPNG: Only 8-bit images is supported (%s)\n", name );
return false;
}
@@ -228,19 +228,10 @@ qboolean Image_LoadPNG( const char *name, const byte *buffer, fs_offset_t filesi
break;
}
if( png_hdr.ihdr_chunk.bitdepth == 8 )
{
image.type = PF_RGBA_32; // always exctracted to 32-bit buffer
channel_size = 1;
}
else // if( png_hdr.ihdr_chunk.bitdepth == 16 )
{
image.type = PF_RGBA_64;
channel_size = 2;
}
image.type = PF_RGBA_32; // always exctracted to 32-bit buffer
image.width = png_hdr.ihdr_chunk.width;
image.height = png_hdr.ihdr_chunk.height;
image.size = image.height * image.width * channel_size * 4;
image.size = image.height * image.width * 4;
image.flags |= IMAGE_HAS_COLOR;
if( png_hdr.ihdr_chunk.colortype == PNG_CT_RGBA )
@@ -250,7 +241,7 @@ qboolean Image_LoadPNG( const char *name, const byte *buffer, fs_offset_t filesi
rowsize = pixel_size * image.width;
uncompressed_size = image.height * ( rowsize * channel_size + 1 ); // +1 for filter
uncompressed_size = image.height * ( rowsize + 1 ); // +1 for filter
uncompressed_buffer = Mem_Malloc( host.imagepool, uncompressed_size );
stream.next_in = idat_buf;
@@ -288,9 +279,6 @@ qboolean Image_LoadPNG( const char *name, const byte *buffer, fs_offset_t filesi
if( png_hdr.ihdr_chunk.colortype == PNG_CT_RGB )
prior = pixbuf = raw;
rowsize *= channel_size;
pixel_size *= channel_size;
filter_type = *raw++;
// decode adaptive filter
@@ -396,38 +384,19 @@ qboolean Image_LoadPNG( const char *name, const byte *buffer, fs_offset_t filesi
pixbuf = image.rgba;
raw = uncompressed_buffer;
for( y = 0; y < image.height * image.width; y++, raw += pixel_size )
for( y = 0; y < image.height; y++ )
{
*pixbuf++ = raw[0];
*pixbuf++ = raw[1];
*pixbuf++ = raw[2];
if( channel_size == 1 )
rowend = raw + rowsize;
for( ; raw < rowend; raw += pixel_size )
{
*pixbuf++ = 0xFF;
}
else
{
*pixbuf++ = raw[3];
*pixbuf++ = raw[4];
*pixbuf++ = raw[5];
*pixbuf++ = 0xFF;
*pixbuf++ = raw[0];
*pixbuf++ = raw[1];
*pixbuf++ = raw[2];
*pixbuf++ = 0xFF;
}
}
}
#if XASH_LITTLE_ENDIAN
if( channel_size == 2 )
{
pixbuf = image.rgba;
for( y = 0; y < image.height * image.width * 4; y++, pixbuf += 2 )
{
uint16_t val = *(uint16_t*)pixbuf;
*(uint16_t*)pixbuf = ntohs( val );
}
}
#endif /* XASH_LITTLE_ENDIAN */
Mem_Free( uncompressed_buffer );
return true;

View File

@@ -80,15 +80,6 @@ static byte palette_hl[768] =
147,255,247,199,255,255,255,159,91,83
};
static float img_emboss[FILTER_SIZE][FILTER_SIZE] =
{
{-0.7f, -0.7f, -0.7f, -0.7f, 0.0f },
{-0.7f, -0.7f, -0.7f, 0.0f, 0.7f },
{-0.7f, -0.7f, 0.0f, 0.7f, 0.7f },
{-0.7f, 0.0f, 0.7f, 0.7f, 0.7f },
{ 0.0f, 0.7f, 0.7f, 0.7f, 0.7f },
};
/*
=============================================================================
@@ -465,8 +456,8 @@ void Image_PaletteHueReplace( byte *palSrc, int newHue, int start, int end, int
g = palSrc[i*pal_size+1];
b = palSrc[i*pal_size+2];
maxcol = max( max( r, g ), b ) / 255.0f;
mincol = min( min( r, g ), b ) / 255.0f;
maxcol = Q_max( Q_max( r, g ), b ) / 255.0f;
mincol = Q_min( Q_min( r, g ), b ) / 255.0f;
if( maxcol == 0 ) continue;
@@ -1368,107 +1359,7 @@ qboolean Image_RemapInternal( rgbdata_t *pic, int topColor, int bottomColor )
return true;
}
/*
==================
Image_ApplyFilter
Applies a 5 x 5 filtering matrix to the texture, then runs it through a simulated OpenGL texture environment
blend with the original data to derive a new texture. Freaky, funky, and *f--king* *fantastic*. You can do
reasonable enough "fake bumpmapping" with this baby...
Filtering algorithm from http://www.student.kuleuven.ac.be/~m0216922/CG/filtering.html
All credit due
==================
*/
static void Image_ApplyFilter( rgbdata_t *pic, float factor )
{
int i, x, y;
uint *fin, *fout;
size_t size;
// don't waste time
if( factor <= 0.0f ) return;
// first expand the image into 32-bit buffer
pic = Image_DecompressInternal( pic );
factor = bound( 0.0f, factor, 1.0f );
size = image.width * image.height * 4;
image.tempbuffer = Mem_Realloc( host.imagepool, image.tempbuffer, size );
fout = (uint *)image.tempbuffer;
fin = (uint *)pic->buffer;
for( x = 0; x < image.width; x++ )
{
for( y = 0; y < image.height; y++ )
{
vec3_t vout = { 0.0f, 0.0f, 0.0f };
int pos_x, pos_y;
float avg;
for( pos_x = 0; pos_x < FILTER_SIZE; pos_x++ )
{
for( pos_y = 0; pos_y < FILTER_SIZE; pos_y++ )
{
int img_x = (x - (FILTER_SIZE / 2) + pos_x + image.width) % image.width;
int img_y = (y - (FILTER_SIZE / 2) + pos_y + image.height) % image.height;
// casting's a unary operation anyway, so the othermost set of brackets in the left part
// of the rvalue should not be necessary... but i'm paranoid when it comes to C...
vout[0] += ((float)((byte *)&fin[img_y * image.width + img_x])[0]) * img_emboss[pos_x][pos_y];
vout[1] += ((float)((byte *)&fin[img_y * image.width + img_x])[1]) * img_emboss[pos_x][pos_y];
vout[2] += ((float)((byte *)&fin[img_y * image.width + img_x])[2]) * img_emboss[pos_x][pos_y];
}
}
// multiply by factor, add bias, and clamp
for( i = 0; i < 3; i++ )
{
vout[i] *= factor;
vout[i] += 128.0f; // base
vout[i] = bound( 0.0f, vout[i], 255.0f );
}
// NTSC greyscale conversion standard
avg = (vout[0] * 30.0f + vout[1] * 59.0f + vout[2] * 11.0f) / 100.0f;
// divide by 255 so GL operations work as expected
vout[0] = avg / 255.0f;
vout[1] = avg / 255.0f;
vout[2] = avg / 255.0f;
// write to temp - first, write data in (to get the alpha channel quickly and
// easily, which will be left well alone by this particular operation...!)
fout[y * image.width + x] = fin[y * image.width + x];
// now write in each element, applying the blend operator. blend
// operators are based on standard OpenGL TexEnv modes, and the
// formulas are derived from the OpenGL specs (http://www.opengl.org).
for( i = 0; i < 3; i++ )
{
// divide by 255 so GL operations work as expected
float src = ((float)((byte *)&fin[y * image.width + x])[i]) / 255.0f;
float tmp;
// default is GL_BLEND here
// CsS + CdD works out as Src * Dst * 2
tmp = vout[i] * src * 2.0f;
// multiply back by 255 to get the proper byte scale
tmp *= 255.0f;
// bound the temp target again now, cos the operation may have thrown it out
tmp = bound( 0.0f, tmp, 255.0f );
// and copy it in
((byte *)&fout[y * image.width + x])[i] = (byte)tmp;
}
}
}
// copy result back
memcpy( fin, fout, size );
}
qboolean Image_Process( rgbdata_t **pix, int width, int height, uint flags, float bumpscale )
qboolean Image_Process(rgbdata_t **pix, int width, int height, uint flags, float reserved )
{
rgbdata_t *pic = *pix;
qboolean result = true;
@@ -1509,9 +1400,6 @@ qboolean Image_Process( rgbdata_t **pix, int width, int height, uint flags, floa
if( FBitSet( flags, IMAGE_LIGHTGAMMA ))
pic = Image_LightGamma( pic );
if( FBitSet( flags, IMAGE_EMBOSS ))
Image_ApplyFilter( pic, bumpscale );
out = Image_FlipInternal( pic->buffer, &pic->width, &pic->height, pic->type, flags );
if( pic->buffer != out ) memcpy( pic->buffer, image.tempbuffer, pic->size );

View File

@@ -15,8 +15,6 @@ GNU General Public License for more details.
#ifdef SINGLE_BINARY
#include <stdlib.h>
#include <string.h>
#include "build.h"
#include "common.h"
#ifdef XASH_SDLMAIN
@@ -28,62 +26,89 @@ GNU General Public License for more details.
#endif
#if XASH_WIN32
#define XASH_NOCONHOST 1
#include <process.h> // _execve
#else
#include <unistd.h> // execve
#endif
extern char **environ;
static char szGameDir[128]; // safe place to keep gamedir
static int g_iArgc;
static char **g_pszArgv;
#if XASH_WIN32 || XASH_POSIX
#define USE_EXECVE_FOR_CHANGE_GAME 1
#else
#define USE_EXECVE_FOR_CHANGE_GAME 0
#endif
#define E_GAME "XASH3D_GAME" // default env dir to start from
#define GAME_PATH "valve" // default dir to start from
void Launcher_ChangeGame( const char *progname )
{
strncpy( szGameDir, progname, sizeof( szGameDir ) - 1 );
char envstr[256];
#if USE_EXECVE_FOR_CHANGE_GAME
Host_Shutdown();
#if XASH_WIN32
_putenv_s( E_GAME, progname );
_execve( g_pszArgv[0], g_pszArgv, _environ );
#else
snprintf( envstr, sizeof( envstr ), E_GAME "=%s", progname );
putenv( envstr );
execve( g_pszArgv[0], g_pszArgv, environ );
#endif
#else
Q_strncpy( szGameDir, progname, sizeof( szGameDir ) - 1 );
Host_Shutdown( );
exit( Host_Main( g_iArgc, g_pszArgv, szGameDir, 1, &Launcher_ChangeGame ) );
#endif
}
#if XASH_NOCONHOST
#if XASH_WIN32
#include <windows.h>
#include <shellapi.h> // CommandLineToArgvW
int __stdcall WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR cmdLine, int nShow)
{
int szArgc;
char **szArgv;
LPWSTR* lpArgv = CommandLineToArgvW(GetCommandLineW(), &szArgc);
int i = 0;
LPWSTR* lpArgv;
int ret, i;
szArgv = (char**)malloc(szArgc*sizeof(char*));
for (; i < szArgc; ++i)
lpArgv = CommandLineToArgvW( GetCommandLineW(), &szArgc );
szArgv = ( char** )malloc( (szArgc + 1) * sizeof( char* ));
for( i = 0; i < szArgc; ++i )
{
size_t size = wcslen(lpArgv[i]) + 1;
szArgv[i] = (char*)malloc(size);
wcstombs(szArgv[i], lpArgv[i], size);
// just in case, allocate some more memory
szArgv[i] = ( char * )malloc( size * sizeof( wchar_t ));
wcstombs( szArgv[i], lpArgv[i], size );
}
szArgv[i] = NULL;
szArgv[szArgc] = 0;
LocalFree(lpArgv);
LocalFree( lpArgv );
main( szArgc, szArgv );
ret = main( szArgc, szArgv );
for( i = 0; i < szArgc; ++i )
free( szArgv[i] );
free( szArgv );
return ret;
}
#endif
#endif // XASH_WIN32
int main( int argc, char** argv )
{
char gamedir_buf[32] = "";
const char *gamedir = getenv( "XASH3D_GAMEDIR" );
const char *game = getenv( E_GAME );
if( !COM_CheckString( gamedir ) )
{
gamedir = "valve";
}
else
{
strncpy( gamedir_buf, gamedir, 32 );
gamedir = gamedir_buf;
}
if( !game )
game = GAME_PATH;
Q_strncpy( szGameDir, game, sizeof( szGameDir ));
#if XASH_EMSCRIPTEN
#ifdef EMSCRIPTEN_LIB_FS
@@ -110,7 +135,7 @@ int main( int argc, char** argv )
IOS_LaunchDialog();
}
#endif
return Host_Main( g_iArgc, g_pszArgv, gamedir, 0, &Launcher_ChangeGame );
return Host_Main( g_iArgc, g_pszArgv, szGameDir, 0, &Launcher_ChangeGame );
}
#endif

View File

@@ -291,12 +291,12 @@ static char *COM_GetItaniumName( const char * const in_name )
len = len * 10 + ( *f - '0' );
// sane value
len = min( remaining, len );
len = Q_min( remaining, len );
if( len == 0 )
goto invalid_format;
Q_strncpy( symbols[i], f, min( len + 1, sizeof( out_name )));
Q_strncpy( symbols[i], f, Q_min( len + 1, sizeof( out_name )));
f += len;
remaining -= len;
@@ -361,7 +361,7 @@ char **COM_ConvertToLocalPlatform( EFunctionMangleType to, const char *from, siz
if( at ) len = (uint)( at - prev );
else len = (uint)Q_strlen( prev );
Q_strncpy( symbols[i], prev, min( len + 1, sizeof( symbols[i] )));
Q_strncpy( symbols[i], prev, Q_min( len + 1, sizeof( symbols[i] )));
prev = at + 1;
if( !at )

View File

@@ -35,7 +35,11 @@ typedef struct dll_user_s
} dll_user_t;
dll_user_t *FS_FindLibrary( const char *dllname, qboolean directpath );
void *COM_LoadLibrary( const char *dllname, int build_ordinals_table, qboolean directpath );
#define COM_LoadLibrary( dllname, build_ordinals_table, directpath ) \
_COM_LoadLibrary( dllname, build_ordinals_table, directpath, __FILE__, __LINE__ )
void *_COM_LoadLibrary( const char *dllname, int build_ordinals_table, qboolean directpath, const char *name, int line );
void *COM_GetProcAddress( void *hInstance, const char *name );
const char *COM_NameForFunction( void *hInstance, void *function );
void *COM_FunctionFromName_SR( void *hInstance, const char *pName ); // Save/Restore version

View File

@@ -254,6 +254,5 @@ void NET_InitMasters( void )
// keep main master always there
NET_AddMaster( MASTERSERVER_ADR, false );
NET_AddMaster( MASTERSERVER_ADR2, false );
NET_LoadMasters( );
}

View File

@@ -1020,6 +1020,8 @@ Fills in surf->texturemins[] and surf->extents[]
*/
static void Mod_CalcSurfaceExtents( msurface_t *surf )
{
// this place is VERY critical to precision
// keep it as float, don't use double, because it causes issues with lightmap
float mins[2], maxs[2], val;
float lmmins[2], lmmaxs[2];
int bmins[2], bmaxs[2];
@@ -1049,14 +1051,14 @@ static void Mod_CalcSurfaceExtents( msurface_t *surf )
for( j = 0; j < 2; j++ )
{
val = DotProduct( v->position, surf->texinfo->vecs[j] ) + surf->texinfo->vecs[j][3];
val = DotProductPrecise( v->position, surf->texinfo->vecs[j] ) + surf->texinfo->vecs[j][3];
mins[j] = Q_min( val, mins[j] );
maxs[j] = Q_max( val, maxs[j] );
}
for( j = 0; j < 2; j++ )
{
val = DotProduct( v->position, info->lmvecs[j] ) + info->lmvecs[j][3];
val = DotProductPrecise( v->position, info->lmvecs[j] ) + info->lmvecs[j][3];
lmmins[j] = Q_min( val, lmmins[j] );
lmmaxs[j] = Q_max( val, lmmaxs[j] );
}
@@ -2023,7 +2025,7 @@ static void Mod_LoadTextures( dbspmodel_t *bmod )
if( FS_FileExists( texpath, false ))
{
tx->gl_texturenum = ref.dllFuncs.GL_LoadTexture( texpath, NULL, 0, TF_ALLOW_EMBOSS|txFlags );
tx->gl_texturenum = ref.dllFuncs.GL_LoadTexture( texpath, NULL, 0, txFlags );
bmod->wadlist.wadusage[j]++; // this wad are really used
break;
}
@@ -2039,7 +2041,7 @@ static void Mod_LoadTextures( dbspmodel_t *bmod )
if( custom_palette ) size += sizeof( short ) + 768;
Q_snprintf( texname, sizeof( texname ), "#%s:%s.mip", loadstat.name, mt->name );
tx->gl_texturenum = ref.dllFuncs.GL_LoadTexture( texname, (byte *)mt, size, TF_ALLOW_EMBOSS|txFlags );
tx->gl_texturenum = ref.dllFuncs.GL_LoadTexture( texname, (byte *)mt, size, txFlags );
}
// if texture is completely missed
@@ -2734,6 +2736,37 @@ static void Mod_LoadLighting( dbspmodel_t *bmod )
}
}
/*
=================
Mod_LumpLooksLikePlanes
=================
*/
static qboolean Mod_LumpLooksLikePlanes( const byte *in, dlump_t *lump, qboolean fast )
{
int numplanes, i;
const dplane_t *planes;
if( lump->filelen < sizeof( dplane_t ) &&
lump->filelen % sizeof( dplane_t ) != 0 )
return false;
if( fast )
return true;
numplanes = lump->filelen / sizeof( dplane_t );
planes = (const dplane_t*)(in + lump->fileofs);
for( i = 0; i < numplanes; i++ )
{
// planes can only be from 0 to 5: PLANE_X, Y, Z and PLANE_ANYX, Y and Z
if( planes[i].type < 0 || planes[i].type > 5 )
return false;
}
return true;
}
/*
=================
Mod_LoadBmodelLumps
@@ -2780,13 +2813,28 @@ qboolean Mod_LoadBmodelLumps( const byte *mod_base, qboolean isworld )
if( isworld ) world.flags = 0; // clear world settings
bmod->isworld = isworld;
if( header->version == HLBSP_VERSION &&
header->lumps[LUMP_ENTITIES].fileofs <= 1024 &&
(header->lumps[LUMP_ENTITIES].filelen % sizeof( dplane_t )) == 0 )
if( header->version == HLBSP_VERSION )
{
// blue-shift swapped lumps
srclumps[0].lumpnumber = LUMP_PLANES;
srclumps[1].lumpnumber = LUMP_ENTITIES;
// only relevant for half-life maps
if( !Mod_LumpLooksLikePlanes( mod_base, &header->lumps[LUMP_PLANES], false ) &&
Mod_LumpLooksLikePlanes( mod_base, &header->lumps[LUMP_ENTITIES], false ))
{
// blue-shift swapped lumps
srclumps[0].lumpnumber = LUMP_PLANES;
srclumps[1].lumpnumber = LUMP_ENTITIES;
}
else
{
// everything else
srclumps[0].lumpnumber = LUMP_ENTITIES;
srclumps[1].lumpnumber = LUMP_PLANES;
}
}
else
{
// everything else
srclumps[0].lumpnumber = LUMP_ENTITIES;
srclumps[1].lumpnumber = LUMP_PLANES;
}
// loading base lumps
@@ -2893,13 +2941,28 @@ qboolean Mod_TestBmodelLumps( const char *name, const byte *mod_base, qboolean s
break;
}
if( header->version == HLBSP_VERSION &&
header->lumps[LUMP_ENTITIES].fileofs <= 1024 &&
(header->lumps[LUMP_ENTITIES].filelen % sizeof( dplane_t )) == 0 )
if( header->version == HLBSP_VERSION )
{
// blue-shift swapped lumps
srclumps[0].lumpnumber = LUMP_PLANES;
srclumps[1].lumpnumber = LUMP_ENTITIES;
// only relevant for half-life maps
if( Mod_LumpLooksLikePlanes( mod_base, &header->lumps[LUMP_ENTITIES], true ) &&
!Mod_LumpLooksLikePlanes( mod_base, &header->lumps[LUMP_PLANES], true ))
{
// blue-shift swapped lumps
srclumps[0].lumpnumber = LUMP_PLANES;
srclumps[1].lumpnumber = LUMP_ENTITIES;
}
else
{
// everything else
srclumps[0].lumpnumber = LUMP_ENTITIES;
srclumps[1].lumpnumber = LUMP_PLANES;
}
}
else
{
// everything else
srclumps[0].lumpnumber = LUMP_ENTITIES;
srclumps[1].lumpnumber = LUMP_PLANES;
}
// loading base lumps

View File

@@ -980,10 +980,6 @@ qboolean Delta_CompareField( delta_t *pField, void *from, void *to, double timeb
}
else if( pField->flags & DT_INTEGER )
{
#if defined __GNUC__ && __GNUC_MAJOR < 9 && !defined __clang__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wduplicated-branches"
#endif
if( pField->flags & DT_SIGNED )
{
fromF = *(int *)((byte *)from + pField->offset );
@@ -994,9 +990,6 @@ qboolean Delta_CompareField( delta_t *pField, void *from, void *to, double timeb
fromF = *(uint *)((byte *)from + pField->offset );
toF = *(uint *)((byte *)to + pField->offset );
}
#if defined __GNUC__ && __GNUC_MAJOR < 9 && !defined __clang__
#pragma GCC diagnostic pop
#endif
fromF = Delta_ClampIntegerField( pField, fromF, bSigned, pField->bits );
toF = Delta_ClampIntegerField( pField, toF, bSigned, pField->bits );
if( !Q_equal( pField->multiplier, 1.0 ) )
@@ -1121,7 +1114,7 @@ assume from and to is valid
qboolean Delta_WriteField( sizebuf_t *msg, delta_t *pField, void *from, void *to, double timebase )
{
qboolean bSigned = ( pField->flags & DT_SIGNED ) ? true : false;
float flValue, flAngle, flTime;
float flValue, flAngle;
uint iValue;
const char *pStr;
@@ -1161,17 +1154,10 @@ qboolean Delta_WriteField( sizebuf_t *msg, delta_t *pField, void *from, void *to
}
else if( pField->flags & DT_INTEGER )
{
#if defined __GNUC__ && __GNUC_MAJOR < 9 && !defined __clang__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wduplicated-branches"
#endif
if( bSigned )
iValue = *(int32_t *)((int8_t *)to + pField->offset );
else
iValue = *(uint32_t *)((int8_t *)to + pField->offset );
#if defined __GNUC__ && __GNUC_MAJOR < 9 && !defined __clang__
#pragma GCC diagnostic pop
#endif
iValue = Delta_ClampIntegerField( pField, iValue, bSigned, pField->bits );
if( !Q_equal( pField->multiplier, 1.0 ) )
@@ -1218,6 +1204,53 @@ qboolean Delta_WriteField( sizebuf_t *msg, delta_t *pField, void *from, void *to
return true;
}
/*
====================
Delta_CopyField
====================
*/
static void Delta_CopyField( delta_t *pField, void *from, void *to, double timebase )
{
qboolean bSigned = FBitSet( pField->flags, DT_SIGNED );
uint8_t *to_field = (uint8_t *)to + pField->offset;
uint8_t *from_field = (uint8_t *)from + pField->offset;
if( FBitSet( pField->flags, DT_BYTE ))
{
if( bSigned )
*(int8_t *)( to_field ) = *(int8_t *)( from_field );
else
*(uint8_t *)( to_field ) = *(uint8_t *)( from_field );
}
else if( FBitSet( pField->flags, DT_SHORT ))
{
if( bSigned )
*(int16_t *)( to_field ) = *(int16_t *)( from_field );
else
*(uint16_t *)( to_field ) = *(uint16_t *)( from_field );
}
else if( FBitSet( pField->flags, DT_INTEGER ))
{
if( bSigned )
*(int32_t *)( to_field ) = *(int32_t *)( from_field );
else
*(uint32_t *)( to_field ) = *(uint32_t *)( from_field );
}
else if( FBitSet( pField->flags, DT_FLOAT|DT_ANGLE|DT_TIMEWINDOW_8|DT_TIMEWINDOW_BIG ))
{
*(float *)( to_field ) = *(float *)( from_field );
}
else if( FBitSet( pField->flags, DT_STRING ))
{
Q_strncpy( to_field, from_field, pField->size );
}
else
{
Assert( 0 );
}
}
/*
=====================
Delta_ReadField
@@ -1230,30 +1263,24 @@ qboolean Delta_ReadField( sizebuf_t *msg, delta_t *pField, void *from, void *to,
{
qboolean bSigned = ( pField->flags & DT_SIGNED ) ? true : false;
float flValue, flAngle, flTime;
qboolean bChanged;
uint iValue;
const char *pStr;
char *pOut;
bChanged = MSG_ReadOneBit( msg );
if( !MSG_ReadOneBit( msg ) )
{
Delta_CopyField( pField, from, to, timebase );
return false;
}
Assert( pField->multiplier != 0.0f );
if( pField->flags & DT_BYTE )
{
if( bChanged )
{
iValue = MSG_ReadBitLong( msg, pField->bits, bSigned );
if( !Q_equal( pField->multiplier, 1.0 ) )
iValue /= pField->multiplier;
}
else
{
if( bSigned )
iValue = *(int8_t *)((uint8_t *)from + pField->offset );
else
iValue = *(uint8_t *)((uint8_t *)from + pField->offset );
}
iValue = MSG_ReadBitLong( msg, pField->bits, bSigned );
if( !Q_equal( pField->multiplier, 1.0 ) )
iValue /= pField->multiplier;
if( bSigned )
*(int8_t *)((uint8_t *)to + pField->offset ) = iValue;
else
@@ -1261,19 +1288,10 @@ qboolean Delta_ReadField( sizebuf_t *msg, delta_t *pField, void *from, void *to,
}
else if( pField->flags & DT_SHORT )
{
if( bChanged )
{
iValue = MSG_ReadBitLong( msg, pField->bits, bSigned );
if( !Q_equal( pField->multiplier, 1.0 ) )
iValue /= pField->multiplier;
}
else
{
if( bSigned )
iValue = *(int16_t *)((uint8_t *)from + pField->offset );
else
iValue = *(uint16_t *)((uint8_t *)from + pField->offset );
}
iValue = MSG_ReadBitLong( msg, pField->bits, bSigned );
if( !Q_equal( pField->multiplier, 1.0 ) )
iValue /= pField->multiplier;
if( bSigned )
*(int16_t *)((uint8_t *)to + pField->offset ) = iValue;
else
@@ -1281,112 +1299,63 @@ qboolean Delta_ReadField( sizebuf_t *msg, delta_t *pField, void *from, void *to,
}
else if( pField->flags & DT_INTEGER )
{
#if defined __GNUC__ && __GNUC_MAJOR < 9 && !defined __clang__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wduplicated-branches"
#endif
if( bChanged )
{
iValue = MSG_ReadBitLong( msg, pField->bits, bSigned );
if( !Q_equal( pField->multiplier, 1.0 ) )
iValue /= pField->multiplier;
}
else
{
if( bSigned )
iValue = *(int32_t *)((uint8_t *)from + pField->offset );
else
iValue = *(uint32_t *)((uint8_t *)from + pField->offset );
}
iValue = MSG_ReadBitLong( msg, pField->bits, bSigned );
if( !Q_equal( pField->multiplier, 1.0 ) )
iValue /= pField->multiplier;
if( bSigned )
*(int32_t *)((uint8_t *)to + pField->offset ) = iValue;
else
*(uint32_t *)((uint8_t *)to + pField->offset ) = iValue;
#if defined __GNUC__ && __GNUC_MAJOR < 9 && !defined __clang__
#pragma GCC diagnostic pop
#endif
}
else if( pField->flags & DT_FLOAT )
{
if( bChanged )
{
iValue = MSG_ReadBitLong( msg, pField->bits, bSigned );
if( bSigned )
flValue = (int)iValue;
else
flValue = iValue;
if( !Q_equal( pField->multiplier, 1.0 ) )
flValue = flValue / pField->multiplier;
if( !Q_equal( pField->post_multiplier, 1.0 ) )
flValue = flValue * pField->post_multiplier;
}
iValue = MSG_ReadBitLong( msg, pField->bits, bSigned );
if( bSigned )
flValue = (int)iValue;
else
{
flValue = *(float *)((byte *)from + pField->offset );
}
flValue = iValue;
if( !Q_equal( pField->multiplier, 1.0 ) )
flValue = flValue / pField->multiplier;
if( !Q_equal( pField->post_multiplier, 1.0 ) )
flValue = flValue * pField->post_multiplier;
*(float *)((byte *)to + pField->offset ) = flValue;
}
else if( pField->flags & DT_ANGLE )
{
if( bChanged )
{
flAngle = MSG_ReadBitAngle( msg, pField->bits );
}
else
{
flAngle = *(float *)((byte *)from + pField->offset );
}
flAngle = MSG_ReadBitAngle( msg, pField->bits );
*(float *)((byte *)to + pField->offset ) = flAngle;
}
else if( pField->flags & DT_TIMEWINDOW_8 )
{
if( bChanged )
{
bSigned = true; // timewindow is always signed
iValue = MSG_ReadBitLong( msg, pField->bits, bSigned );
flTime = (timebase * 100.0 - iValue) / 100.0;
}
else
{
flTime = *(float *)((byte *)from + pField->offset );
}
bSigned = true; // timewindow is always signed
iValue = MSG_ReadBitLong( msg, pField->bits, bSigned );
flTime = (timebase * 100.0 - (int)iValue) / 100.0;
*(float *)((byte *)to + pField->offset ) = flTime;
}
else if( pField->flags & DT_TIMEWINDOW_BIG )
{
if( bChanged )
{
bSigned = true; // timewindow is always signed
iValue = MSG_ReadBitLong( msg, pField->bits, bSigned );
bSigned = true; // timewindow is always signed
iValue = MSG_ReadBitLong( msg, pField->bits, bSigned );
if( !Q_equal( pField->multiplier, 1.0 ) )
flTime = ( timebase * pField->multiplier - iValue ) / pField->multiplier;
else
flTime = timebase - iValue;
}
if( !Q_equal( pField->multiplier, 1.0 ) )
flTime = ( timebase * pField->multiplier - (int)iValue ) / pField->multiplier;
else
{
flTime = *(float *)((byte *)from + pField->offset );
}
flTime = timebase - (int)iValue;
*(float *)((byte *)to + pField->offset ) = flTime;
}
else if( pField->flags & DT_STRING )
{
if( bChanged )
{
pStr = MSG_ReadString( msg );
}
else
{
pStr = (char *)((byte *)from + pField->offset );
}
pStr = MSG_ReadString( msg );
pOut = (char *)((byte *)to + pField->offset );
Q_strncpy( pOut, pStr, pField->size );
}
return bChanged;
return true;
}
/*
@@ -1636,6 +1605,7 @@ void MSG_ReadClientData( sizebuf_t *msg, clientdata_t *from, clientdata_t *to, d
delta_t *pField;
delta_info_t *dt;
int i;
qboolean noChanges;
dt = Delta_FindStruct( "clientdata_t" );
Assert( dt && dt->bInitialized );
@@ -1643,15 +1613,14 @@ void MSG_ReadClientData( sizebuf_t *msg, clientdata_t *from, clientdata_t *to, d
pField = dt->pFields;
Assert( pField != NULL );
*to = *from;
if( !cls.legacymode && !MSG_ReadOneBit( msg ))
return; // we have no changes
noChanges = !cls.legacymode && !MSG_ReadOneBit( msg );
// process fields
for( i = 0; i < dt->numFields; i++, pField++ )
{
Delta_ReadField( msg, pField, from, to, timebase );
if( noChanges )
Delta_CopyField( pField, from, to, timebase );
else Delta_ReadField( msg, pField, from, to, timebase );
}
#endif
}
@@ -1722,8 +1691,6 @@ void MSG_ReadWeaponData( sizebuf_t *msg, weapon_data_t *from, weapon_data_t *to,
pField = dt->pFields;
Assert( pField != NULL );
*to = *from;
// process fields
for( i = 0; i < dt->numFields; i++, pField++ )
{
@@ -1909,7 +1876,7 @@ qboolean MSG_ReadDeltaEntity( sizebuf_t *msg, entity_state_t *from, entity_state
from = &cl.instanced_baseline[baseline_offset];
}
}
}
}
// g-cont. probably is redundant
*to = *from;

View File

@@ -1382,10 +1382,10 @@ qboolean NET_BufferToBufferDecompress( byte *dest, uint *destLen, byte *source,
/*
====================
NET_Isocket
NET_IPSocket
====================
*/
static int NET_Isocket( const char *net_interface, int port, qboolean multicast )
static int NET_IPSocket( const char *net_interface, int port, qboolean multicast )
{
struct sockaddr_in addr;
int err, net_socket;
@@ -1396,7 +1396,7 @@ static int NET_Isocket( const char *net_interface, int port, qboolean multicast
{
err = WSAGetLastError();
if( err != WSAEAFNOSUPPORT )
Con_DPrintf( S_WARN "NET_UDsocket: port: %d socket: %s\n", port, NET_ErrorString( ));
Con_DPrintf( S_WARN "NET_UDPSocket: port: %d socket: %s\n", port, NET_ErrorString( ));
return INVALID_SOCKET;
}
@@ -1404,7 +1404,7 @@ static int NET_Isocket( const char *net_interface, int port, qboolean multicast
{
struct timeval timeout;
Con_DPrintf( S_WARN "NET_UDsocket: port: %d ioctl FIONBIO: %s\n", port, NET_ErrorString( ));
Con_DPrintf( S_WARN "NET_UDPSocket: port: %d ioctl FIONBIO: %s\n", port, NET_ErrorString( ));
// try timeout instead of NBIO
timeout.tv_sec = timeout.tv_usec = 0;
setsockopt( net_socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));
@@ -1413,14 +1413,14 @@ static int NET_Isocket( const char *net_interface, int port, qboolean multicast
// make it broadcast capable
if( NET_IsSocketError( setsockopt( net_socket, SOL_SOCKET, SO_BROADCAST, (char *)&_true, sizeof( _true ) ) ) )
{
Con_DPrintf( S_WARN "NET_UDsocket: port: %d setsockopt SO_BROADCAST: %s\n", port, NET_ErrorString( ));
Con_DPrintf( S_WARN "NET_UDPSocket: port: %d setsockopt SO_BROADCAST: %s\n", port, NET_ErrorString( ));
}
if( Sys_CheckParm( "-reuse" ) || multicast )
{
if( NET_IsSocketError( setsockopt( net_socket, SOL_SOCKET, SO_REUSEADDR, (const char *)&optval, sizeof( optval )) ) )
{
Con_DPrintf( S_WARN "NET_UDsocket: port: %d setsockopt SO_REUSEADDR: %s\n", port, NET_ErrorString( ));
Con_DPrintf( S_WARN "NET_UDPSocket: port: %d setsockopt SO_REUSEADDR: %s\n", port, NET_ErrorString( ));
closesocket( net_socket );
return INVALID_SOCKET;
}
@@ -1435,7 +1435,7 @@ static int NET_Isocket( const char *net_interface, int port, qboolean multicast
{
err = WSAGetLastError();
if( err != WSAENOPROTOOPT )
Con_Printf( S_WARN "NET_UDsocket: port: %d setsockopt IP_TOS: %s\n", port, NET_ErrorString( ));
Con_Printf( S_WARN "NET_UDPSocket: port: %d setsockopt IP_TOS: %s\n", port, NET_ErrorString( ));
closesocket( net_socket );
return INVALID_SOCKET;
}
@@ -1452,7 +1452,7 @@ static int NET_Isocket( const char *net_interface, int port, qboolean multicast
if( NET_IsSocketError( bind( net_socket, (void *)&addr, sizeof( addr )) ) )
{
Con_DPrintf( S_WARN "NET_UDsocket: port: %d bind: %s\n", port, NET_ErrorString( ));
Con_DPrintf( S_WARN "NET_UDPSocket: port: %d bind: %s\n", port, NET_ErrorString( ));
closesocket( net_socket );
return INVALID_SOCKET;
}
@@ -1461,7 +1461,7 @@ static int NET_Isocket( const char *net_interface, int port, qboolean multicast
{
optval = 1;
if( NET_IsSocketError( setsockopt( net_socket, IPPROTO_IP, IP_MULTICAST_LOOP, (const char *)&optval, sizeof( optval )) ) )
Con_DPrintf( S_WARN "NET_UDsocket: port %d setsockopt IP_MULTICAST_LOOP: %s\n", port, NET_ErrorString( ));
Con_DPrintf( S_WARN "NET_UDPSocket: port %d setsockopt IP_MULTICAST_LOOP: %s\n", port, NET_ErrorString( ));
}
return net_socket;
@@ -1481,7 +1481,7 @@ static void NET_OpenIP( void )
port = net_iphostport->value;
if( !port ) port = net_hostport->value;
if( !port ) port = PORT_SERVER; // forcing to default
net.ip_sockets[NS_SERVER] = NET_Isocket( net_ipname->string, port, false );
net.ip_sockets[NS_SERVER] = NET_IPSocket( net_ipname->string, port, false );
if( !NET_IsSocketValid( net.ip_sockets[NS_SERVER] ) && Host_IsDedicated() )
Host_Error( "Couldn't allocate dedicated server IP port %d.\n", port );
@@ -1496,10 +1496,10 @@ static void NET_OpenIP( void )
port = net_ipclientport->value;
if( !port ) port = net_clientport->value;
if( !port ) port = PORT_ANY; // forcing to default
net.ip_sockets[NS_CLIENT] = NET_Isocket( net_ipname->string, port, false );
net.ip_sockets[NS_CLIENT] = NET_IPSocket( net_ipname->string, port, false );
if( !NET_IsSocketValid( net.ip_sockets[NS_CLIENT] ) )
net.ip_sockets[NS_CLIENT] = NET_Isocket( net_ipname->string, PORT_ANY, false );
net.ip_sockets[NS_CLIENT] = NET_IPSocket( net_ipname->string, PORT_ANY, false );
cl_port = port;
}
}
@@ -1693,15 +1693,15 @@ void NET_Init( void )
if( net.initialized ) return;
net_clockwindow = Cvar_Get( "clockwindow", "0.5", 0, "timewindow to execute client moves" );
net_clockwindow = Cvar_Get( "clockwindow", "0.5", FCVAR_PRIVILEGED, "timewindow to execute client moves" );
net_address = Cvar_Get( "net_address", "0", FCVAR_READ_ONLY, "contain local address of current client" );
net_ipname = Cvar_Get( "ip", "localhost", FCVAR_READ_ONLY, "network ip address" );
net_iphostport = Cvar_Get( "ip_hostport", "0", FCVAR_READ_ONLY, "network ip host port" );
net_hostport = Cvar_Get( "hostport", va( "%i", PORT_SERVER ), FCVAR_READ_ONLY, "network default host port" );
net_ipclientport = Cvar_Get( "ip_clientport", "0", FCVAR_READ_ONLY, "network ip client port" );
net_clientport = Cvar_Get( "clientport", va( "%i", PORT_CLIENT ), FCVAR_READ_ONLY, "network default client port" );
net_fakelag = Cvar_Get( "fakelag", "0", 0, "lag all incoming network data (including loopback) by xxx ms." );
net_fakeloss = Cvar_Get( "fakeloss", "0", 0, "act like we dropped the packet this % of the time." );
net_fakelag = Cvar_Get( "fakelag", "0", FCVAR_PRIVILEGED, "lag all incoming network data (including loopback) by xxx ms." );
net_fakeloss = Cvar_Get( "fakeloss", "0", FCVAR_PRIVILEGED, "act like we dropped the packet this % of the time." );
// prepare some network data
for( i = 0; i < NS_COUNT; i++ )
@@ -2543,10 +2543,10 @@ void HTTP_Init( void )
http.first_file = http.last_file = NULL;
Cmd_AddCommand("http_download", &HTTP_Download_f, "add file to download queue");
Cmd_AddCommand("http_skip", &HTTP_Skip_f, "skip current download server");
Cmd_AddCommand("http_cancel", &HTTP_Cancel_f, "cancel current download");
Cmd_AddCommand("http_clear", &HTTP_Clear_f, "cancel all downloads");
Cmd_AddRestrictedCommand("http_download", &HTTP_Download_f, "add file to download queue");
Cmd_AddRestrictedCommand("http_skip", &HTTP_Skip_f, "skip current download server");
Cmd_AddRestrictedCommand("http_cancel", &HTTP_Cancel_f, "cancel current download");
Cmd_AddRestrictedCommand("http_clear", &HTTP_Clear_f, "cancel all downloads");
Cmd_AddCommand("http_list", &HTTP_List_f, "list all queued downloads");
Cmd_AddCommand("http_addcustomserver", &HTTP_AddCustomServer_f, "add custom fastdl server");
http_useragent = Cvar_Get( "http_useragent", "xash3d", FCVAR_ARCHIVE, "User-Agent string" );

View File

@@ -69,8 +69,7 @@ GNU General Public License for more details.
// bytes will be stripped by the networking channel layer
#define NET_MAX_MESSAGE PAD_NUMBER(( NET_MAX_PAYLOAD + HEADER_BYTES ), 16 )
#define MASTERSERVER_ADR "ms.xash.su:27010"
#define MASTERSERVER_ADR2 "ms2.xash.su:27010"
#define MASTERSERVER_ADR "mentality.rip:27010"
#define MS_SCAN_REQUEST "1\xFF" "0.0.0.0:0\0"
#define PORT_MASTER 27010

View File

@@ -110,13 +110,7 @@ GNU General Public License for more details.
#define MAX_EVENTS (1<<MAX_EVENT_BITS) // 10 bits == 1024 events (the original Half-Life limit)
#define MAX_MODEL_BITS 12 // 12 bits == 4096 models
#define MAX_SUPPORTED_MODELS (1<<MAX_MODEL_BITS)
#ifdef SUPPORT_BSP2_FORMAT
#define MAX_MODELS MAX_SUPPORTED_MODELS // because BSP2 contain too much embedded bsp-models
#else
#define MAX_MODELS 1024 // g-cont. reduce the memory without breaking proto
#endif
#define MAX_MODELS (1<<MAX_MODEL_BITS)
#define MAX_SOUND_BITS 11
#define MAX_SOUNDS (1<<MAX_SOUND_BITS) // 11 bits == 2048 sounds
@@ -187,7 +181,6 @@ GNU General Public License for more details.
#undef MAX_VISIBLE_PACKET
#undef MAX_VISIBLE_PACKET_VIS_BYTES
#undef MAX_EVENTS
#undef MAX_SUPPORTED_MODELS
#undef MAX_MODELS
#undef MAX_SOUNDS
#undef MAX_CUSTOM
@@ -198,17 +191,10 @@ GNU General Public License for more details.
// memory reduced protocol, not for use in multiplayer (but still compatible)
#define MAX_VISIBLE_PACKET 128
#define MAX_VISIBLE_PACKET_VIS_BYTES ((MAX_VISIBLE_PACKET + 7) / 8)
#define MAX_EVENTS 128
#define MAX_SUPPORTED_MODELS 512
#define MAX_MODELS 512
#define MAX_SOUNDS 512
#define MAX_CUSTOM 32
#define MAX_DLIGHTS 16 // dynamic lights (rendered per one frame)
#define MAX_ELIGHTS 32 // entity only point lights
#define MAX_RENDER_DECALS 64 // max rendering decals per a level
@@ -217,20 +203,14 @@ GNU General Public License for more details.
#undef MAX_VISIBLE_PACKET
#undef MAX_VISIBLE_PACKET_VIS_BYTES
#undef MAX_EVENTS
#undef MAX_SUPPORTED_MODELS
#undef MAX_MODELS
#undef MAX_CUSTOM
#undef MAX_RENDER_DECALS
#undef MAX_RESOURCES
#define MAX_VISIBLE_PACKET 256
#define MAX_VISIBLE_PACKET_VIS_BYTES ((MAX_VISIBLE_PACKET + 7) / 8)
#define MAX_EVENTS 128
#define MAX_SUPPORTED_MODELS 1024
#define MAX_MODELS 1024
#define MAX_CUSTOM 512
#define MAX_RENDER_DECALS 128
#define MAX_RESOURCES 1024
@@ -319,11 +299,6 @@ extern const char *clc_strings[clc_lastmsg+1];
#define MAX_LEGACY_ENTITY_BITS 12
#define MAX_LEGACY_WEAPON_BITS 5
#define MAX_LEGACY_MODEL_BITS 11
#if XASH_LOW_MEMORY >= 1
#define MAX_LEGACY_SERVERS 32
#else
#define MAX_LEGACY_SERVERS 256
#endif
#define MAX_LEGACY_TOTAL_CMDS 28 // magic number from old engine's sv_client.c
#endif//NET_PROTOCOL_H

View File

@@ -1247,7 +1247,7 @@ qboolean Sequence_ParseSentenceLine( void )
if( *c )
*c = 0;
strcpy( groupName, fullgroup );
Q_strncpy( groupName, fullgroup, sizeof( groupName ));
len = Sequence_GetLine( data, sizeof( data ) );
lastCharacterPos = len - 1;

View File

@@ -278,3 +278,25 @@ void FS_FreeStream( stream_t *stream )
stream->format->freefunc( stream );
}
#if XASH_ENGINE_TESTS
#define IMPLEMENT_SOUNDLIB_FUZZ_TARGET( export, target ) \
int EXPORT export( const uint8_t *Data, size_t Size ) \
{ \
wavdata_t *wav; \
host.type = HOST_NORMAL; \
Memory_Init(); \
Sound_Init(); \
if( target( "#internal", Data, Size )) \
{ \
wav = SoundPack(); \
FS_FreeSound( wav ); \
} \
Sound_Shutdown(); \
return 0; \
} \
IMPLEMENT_SOUNDLIB_FUZZ_TARGET( Fuzz_Sound_LoadMPG, Sound_LoadMPG )
IMPLEMENT_SOUNDLIB_FUZZ_TARGET( Fuzz_Sound_LoadWAV, Sound_LoadWAV )
#endif

View File

@@ -17,6 +17,8 @@ GNU General Public License for more details.
#if XASH_ANDROID
#include <android/log.h>
#endif
#include <string.h>
#include <errno.h>
#if !XASH_WIN32 && !XASH_MOBILE_PLATFORM
#define XASH_COLORIZE_CONSOLE
@@ -95,6 +97,20 @@ int Sys_LogFileNo( void )
return s_ld.logfileno;
}
static void Sys_FlushStdout( void )
{
// never printing anything to stdout on mobiles
#if !XASH_MOBILE_PLATFORM
fflush( stdout );
#endif
}
static void Sys_FlushLogfile( void )
{
if( s_ld.logfile )
fflush( s_ld.logfile );
}
void Sys_InitLog( void )
{
const char *mode;
@@ -113,11 +129,16 @@ void Sys_InitLog( void )
if( s_ld.log_active )
{
s_ld.logfile = fopen( s_ld.log_path, mode );
if( !s_ld.logfile ) Con_Reportf( S_ERROR "Sys_InitLog: can't create log file %s\n", s_ld.log_path );
fprintf( s_ld.logfile, "=================================================================================\n" );
fprintf( s_ld.logfile, "\t%s (build %i) started at %s\n", s_ld.title, Q_buildnum(), Q_timestamp( TIME_FULL ));
fprintf( s_ld.logfile, "=================================================================================\n" );
if( !s_ld.logfile )
{
Con_Reportf( S_ERROR "Sys_InitLog: can't create log file %s: %s\n", s_ld.log_path, strerror( errno ) );
}
else
{
fprintf( s_ld.logfile, "=================================================================================\n" );
fprintf( s_ld.logfile, "\t%s (build %i) started at %s\n", s_ld.title, Q_buildnum(), Q_timestamp( TIME_FULL ));
fprintf( s_ld.logfile, "=================================================================================\n" );
}
}
}
@@ -140,6 +161,8 @@ void Sys_CloseLog( void )
break;
}
Sys_FlushStdout(); // flush to stdout to ensure all data was written
if( s_ld.logfile )
{
fprintf( s_ld.logfile, "\n");
@@ -153,6 +176,50 @@ void Sys_CloseLog( void )
}
}
static void Sys_PrintColorized( const char *logtime, const char *msg )
{
char colored[4096];
int len = 0;
while( *msg && ( len < 4090 ) )
{
static char q3ToAnsi[ 8 ] =
{
'0', // COLOR_BLACK
'1', // COLOR_RED
'2', // COLOR_GREEN
'3', // COLOR_YELLOW
'4', // COLOR_BLUE
'6', // COLOR_CYAN
'5', // COLOR_MAGENTA
0 // COLOR_WHITE
};
if( IsColorString( msg ) )
{
int color;
msg++;
color = q3ToAnsi[ *msg++ % 8 ];
colored[len++] = '\033';
colored[len++] = '[';
if( color )
{
colored[len++] = '3';
colored[len++] = color;
}
else
colored[len++] = '0';
colored[len++] = 'm';
}
else
colored[len++] = *msg++;
}
colored[len] = 0;
printf( "\033[34m%s\033[0m%s\033[0m", logtime, colored );
}
void Sys_PrintLog( const char *pMsg )
{
time_t crt_time;
@@ -162,6 +229,8 @@ void Sys_PrintLog( const char *pMsg )
time( &crt_time );
crt_tm = localtime( &crt_time );
// platform-specific output
#if XASH_ANDROID && !XASH_DEDICATED
__android_log_print( ANDROID_LOG_DEBUG, "Xash", "%s", pMsg );
#endif
@@ -171,58 +240,17 @@ void Sys_PrintLog( const char *pMsg )
IOS_Log(pMsg);
#endif
if( !lastchar || lastchar == '\n')
strftime( logtime, sizeof( logtime ), "[%H:%M:%S] ", crt_tm ); //short time
// spew to stdout, except mobiles
#if !XASH_MOBILE_PLATFORM
#ifdef XASH_COLORIZE_CONSOLE
{
char colored[4096];
const char *msg = pMsg;
int len = 0;
while( *msg && ( len < 4090 ) )
{
static char q3ToAnsi[ 8 ] =
{
'0', // COLOR_BLACK
'1', // COLOR_RED
'2', // COLOR_GREEN
'3', // COLOR_YELLOW
'4', // COLOR_BLUE
'6', // COLOR_CYAN
'5', // COLOR_MAGENTA
0 // COLOR_WHITE
};
if( IsColorString( msg ) )
{
int color;
msg++;
color = q3ToAnsi[ *msg++ % 8 ];
colored[len++] = '\033';
colored[len++] = '[';
if( color )
{
colored[len++] = '3';
colored[len++] = color;
}
else
colored[len++] = '0';
colored[len++] = 'm';
}
else
colored[len++] = *msg++;
}
colored[len] = 0;
printf( "\033[34m%s\033[0m%s\033[0m", logtime, colored );
}
Sys_PrintColorized( logtime, pMsg );
#else
#if !XASH_ANDROID || XASH_DEDICATED
printf( "%s %s", logtime, pMsg );
fflush( stdout );
#endif
Sys_FlushStdout();
#endif
// save last char to detect when line was not ended
@@ -235,7 +263,7 @@ void Sys_PrintLog( const char *pMsg )
strftime( logtime, sizeof( logtime ), "[%Y:%m:%d|%H:%M:%S]", crt_tm ); //full time
fprintf( s_ld.logfile, "%s %s", logtime, pMsg );
fflush( s_ld.logfile );
Sys_FlushLogfile();
}
/*

View File

@@ -34,6 +34,8 @@ GNU General Public License for more details.
#include "menu_int.h" // _UPDATE_PAGE macro
#include "library.h"
qboolean error_on_exit = false; // arg for exit();
#define DEBUG_BREAK
@@ -81,18 +83,6 @@ char *Sys_GetClipboardData( void )
return data;
}
/*
================
Sys_SetClipboardData
write screenshot into clipboard
================
*/
void Sys_SetClipboardData( const char *buffer, size_t size )
{
Platform_SetClipboardText( buffer, size );
}
#endif // XASH_DEDICATED
/*
@@ -107,7 +97,7 @@ void Sys_Sleep( int msec )
if( !msec )
return;
msec = min( msec, 1000 );
msec = Q_min( msec, 1000 );
Platform_Sleep( msec );
}
@@ -284,7 +274,8 @@ qboolean Sys_LoadLibrary( dll_info_t *dll )
*func->func = NULL;
}
if( !dll->link ) dll->link = LoadLibrary ( dll->name ); // environment pathes
if( !dll->link )
dll->link = COM_LoadLibrary( dll->name, false, true ); // environment pathes
// no DLL found
if( !dll->link )
@@ -319,7 +310,7 @@ void* Sys_GetProcAddress( dll_info_t *dll, const char* name )
if( !dll || !dll->link ) // invalid desc
return NULL;
return (void *)GetProcAddress( dll->link, name );
return (void *)COM_GetProcAddress( dll->link, name );
}
qboolean Sys_FreeLibrary( dll_info_t *dll )
@@ -336,7 +327,7 @@ qboolean Sys_FreeLibrary( dll_info_t *dll )
}
else Con_Reportf( "Sys_FreeLibrary: Unloading %s\n", dll->name );
FreeLibrary( dll->link );
COM_FreeLibrary( dll->link );
dll->link = NULL;
return true;
@@ -353,9 +344,6 @@ void Sys_WaitForQuit( void )
{
#if XASH_WIN32
MSG msg;
Wcon_RegisterHotkeys();
msg.message = 0;
// wait for the user to quit
@@ -531,10 +519,6 @@ void Sys_Print( const char *pMsg )
{
i++; // skip console pseudo graph
}
else if( IsColorString( &msg[i] ))
{
i++; // skip color prefix
}
else
{
if( msg[i] == '\1' || msg[i] == '\2' || msg[i] == '\3' )

View File

@@ -51,7 +51,7 @@ char *Sys_GetClipboardData( void );
const char *Sys_GetCurrentUser( void );
int Sys_CheckParm( const char *parm );
void Sys_Warn( const char *format, ... ) _format( 1 );
void Sys_Error( const char *error, ... ) _format( 1 );
void Sys_Error( const char *error, ... ) _format( 1 ) NORETURN;
qboolean Sys_LoadLibrary( dll_info_t *dll );
void* Sys_GetProcAddress( dll_info_t *dll, const char* name );
qboolean Sys_FreeLibrary( dll_info_t *dll );
@@ -59,7 +59,6 @@ void Sys_ParseCommandLine( int argc, char **argv );
void Sys_MergeCommandLine( void );
void Sys_SetupCrashHandler( void );
void Sys_RestoreCrashHandler( void );
void Sys_SetClipboardData( const char *buffer, size_t size );
#define Sys_GetParmFromCmdLine( parm, out ) _Sys_GetParmFromCmdLine( parm, out, sizeof( out ))
qboolean _Sys_GetParmFromCmdLine( const char *parm, char *out, size_t size );
qboolean Sys_GetIntFromCmdLine( const char *parm, int *out );
@@ -89,10 +88,9 @@ void Wcon_ShowConsole( qboolean show );
void Wcon_CreateConsole( void );
void Wcon_DestroyConsole( void );
void Wcon_DisableInput( void );
void Wcon_Clear( void );
char *Wcon_Input( void );
void Wcon_WinPrint( const char *pMsg );
void Wcon_RegisterHotkeys( void );
void Wcon_SetStatus( const char *pStatus );
#endif
// text messages

View File

@@ -11,19 +11,32 @@ struct tests_stats_s
extern struct tests_stats_s tests_stats;
#define TRUN( x ) Msg( "Running " #x "\n" ); x
#define TRUN( x ) Msg( "Starting " #x "\n" ); \
x; \
Msg( "Finished " #x "\n" )
#define TASSERT( exp ) \
if(!( exp )) \
#define _TASSERT( exp, msg ) \
if( exp ) \
{ \
tests_stats.failed++; \
Msg( S_ERROR "assert failed at %s:%i\n", __FILE__, __LINE__ ); \
msg; \
} \
else tests_stats.passed++;
#define TASSERT( exp ) \
_TASSERT( !(exp), Msg( S_ERROR "assert failed at %s:%i\n", __FILE__, __LINE__ ) )
#define TASSERT_EQi( val1, val2 ) \
_TASSERT( ( val1 ) != ( val2 ), Msg( S_ERROR "assert failed at %s:%i, \"%d\" != \"%d\"\n", __FILE__, __LINE__, #val1, #val2 ))
#define TASSERT_STR( str1, str2 ) \
_TASSERT( Q_strcmp(( str1 ), ( str2 )), Msg( S_ERROR "assert failed at %s:%i, \"%s\" != \"%s\"\n", __FILE__, __LINE__, ( str1 ), ( str2 )))
void Test_RunImagelib( void );
void Test_RunLibCommon( void );
void Test_RunCommon( void );
void Test_RunCmd( void );
void Test_RunCvar( void );
void Test_RunCon( void );
void Test_RunVOX( void );
#endif

39
engine/cursor_type.h Normal file
View File

@@ -0,0 +1,39 @@
/*
cursor_type.h - enumeration of possible mouse cursor types
Copyright (C) 2022 FWGS Team
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.
*/
#pragma once
#ifndef CURSOR_TYPE_H
#define CURSOR_TYPE_H
typedef enum
{
dc_user,
dc_none,
dc_arrow,
dc_ibeam,
dc_hourglass,
dc_crosshair,
dc_up,
dc_sizenwse,
dc_sizenesw,
dc_sizewe,
dc_sizens,
dc_sizeall,
dc_no,
dc_hand,
dc_last
} VGUI_DefaultCursor;
#endif

View File

@@ -278,6 +278,9 @@ typedef struct enginefuncs_s
void (*pfnQueryClientCvarValue)( const edict_t *player, const char *cvarName );
void (*pfnQueryClientCvarValue2)( const edict_t *player, const char *cvarName, int requestID );
int (*pfnCheckParm)( char *parm, char **ppnext );
// added in 8279
edict_t* (*pfnPEntityOfEntIndexAllEntities)( int iEntIndex );
} enginefuncs_t;
// ONLY ADD NEW FUNCTIONS TO THE END OF THIS STRUCT. INTERFACE VERSION IS FROZEN AT 138

35
engine/key_modifiers.h Normal file
View File

@@ -0,0 +1,35 @@
/*
key_modifiers.h - enumeration of possible key modifiers
Copyright (C) 2022 FWGS Team
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.
*/
#pragma once
#ifndef KEY_MODIFIERS_H
#define KEY_MODIFIERS_H
typedef enum
{
KeyModifier_None = 0,
KeyModifier_LeftShift = (1 << 0),
KeyModifier_RightShift = (1 << 1),
KeyModifier_LeftCtrl = (1 << 2),
KeyModifier_RightCtrl = (1 << 3),
KeyModifier_LeftAlt = (1 << 4),
KeyModifier_RightAlt = (1 << 5),
KeyModifier_LeftSuper = (1 << 6),
KeyModifier_RightSuper = (1 << 7),
KeyModifier_NumLock = (1 << 8),
KeyModifier_CapsLock = (1 << 9)
} key_modifier_t;
#endif

View File

@@ -21,9 +21,9 @@
//
#define K_TAB 9
#define K_ENTER 13
#define K_ESCAPE 27
#define K_ESCAPE 27
#define K_SPACE 32
#define K_SCROLLOCK 70
#define K_SCROLLOCK 70
// normal keys should be passed as lowercased ascii
@@ -59,7 +59,7 @@
#define K_KP_UPARROW 161
#define K_KP_PGUP 162
#define K_KP_LEFTARROW 163
#define K_KP_5 164
#define K_KP_5 164
#define K_KP_RIGHTARROW 165
#define K_KP_END 166
#define K_KP_DOWNARROW 167
@@ -71,8 +71,9 @@
#define K_KP_MINUS 173
#define K_KP_PLUS 174
#define K_CAPSLOCK 175
#define K_KP_NUMLOCK 176
#define K_KP_MUL 176
#define K_WIN 177
#define K_KP_NUMLOCK 178
//
// joystick buttons
@@ -143,30 +144,30 @@
#define K_AUX19 225
#define K_DPAD_RIGHT K_AUX19
#define K_AUX20 226
#define K_AUX21 227
#define K_AUX22 228
#define K_AUX23 229
#define K_AUX24 230
#define K_AUX25 231
#define K_AUX26 232
#define K_AUX27 233
#define K_AUX28 234
#define K_AUX29 235
#define K_AUX30 236
#define K_AUX31 237
#define K_AUX32 238
#define K_AUX20 226
#define K_AUX21 227
#define K_AUX22 228
#define K_AUX23 229
#define K_AUX24 230
#define K_AUX25 231
#define K_AUX26 232
#define K_AUX27 233
#define K_AUX28 234
#define K_AUX29 235
#define K_AUX30 236
#define K_AUX31 237
#define K_AUX32 238
#define K_MWHEELDOWN 239
#define K_MWHEELUP 240
#define K_PAUSE 255
#define K_PAUSE 255
//
// mouse buttons generate virtual keys
//
#define K_MOUSE1 241
#define K_MOUSE2 243
#define K_MOUSE3 242
#define K_MOUSE2 242
#define K_MOUSE3 243
#define K_MOUSE4 244
#define K_MOUSE5 245

View File

@@ -53,6 +53,11 @@ typedef struct ui_globalvars_s
struct ref_viewpass_s;
#if __GNUC__ == 3
#undef NORETURN
#define NORETURN
#endif // GCC 3.x have problems with noreturn attribute on function pointer
typedef struct ui_enginefuncs_s
{
// image handlers
@@ -87,10 +92,10 @@ typedef struct ui_enginefuncs_s
const char* (*pfnCmd_Args)( void );
// debug messages (in-menu shows only notify)
void (*Con_Printf)( const char *fmt, ... );
void (*Con_DPrintf)( const char *fmt, ... );
void (*Con_NPrintf)( int pos, const char *fmt, ... );
void (*Con_NXPrintf)( struct con_nprint_s *info, const char *fmt, ... );
void (*Con_Printf)( const char *fmt, ... ) _format( 1 );
void (*Con_DPrintf)( const char *fmt, ... ) _format( 1 );
void (*Con_NPrintf)( int pos, const char *fmt, ... ) _format( 2 );
void (*Con_NXPrintf)( struct con_nprint_s *info, const char *fmt, ... ) _format( 2 );
// sound handlers
void (*pfnPlayLocalSound)( const char *szSound );
@@ -116,7 +121,7 @@ typedef struct ui_enginefuncs_s
int (*CL_CreateVisibleEntity)( int type, struct cl_entity_s *ent );
// misc handlers
void (*pfnHostError)( const char *szFmt, ... );
void (*pfnHostError)( const char *szFmt, ... ) _format( 1 ) NORETURN;
int (*pfnFileExists)( const char *filename, int gamedironly );
void (*pfnGetGameDir)( char *szGetGameDir );
@@ -212,6 +217,8 @@ typedef struct ui_extendedfuncs_s {
double (*pfnDoubleTime)( void );
char *(*pfnParseFile)( char *data, char *buf, const int size, unsigned int flags, int *len );
const char *(*pfnAdrToString)( const struct netadr_s a );
} ui_extendedfuncs_t;
// deprecated export from old engine

View File

@@ -776,17 +776,29 @@ void Platform_ShellExecute( const char *path, const char *parms )
// no need to free jstr
}
void Platform_GetClipboardText( char *buffer, size_t size )
int Platform_GetClipboardText( char *buffer, size_t size )
{
// stub
if( size ) buffer[0] = 0;
return 0;
}
void Platform_SetClipboardText( const char *buffer, size_t size )
void Platform_SetClipboardText( const char *buffer )
{
// stub
}
void Platform_SetCursorType( VGUI_DefaultCursor cursor )
{
// stub
}
key_modifier_t Platform_GetKeyModifiers( void )
{
// stub
return KeyModifier_None;
}
void Platform_PreCreateMove( void )
{
// stub

View File

@@ -34,7 +34,7 @@ void *ANDROID_LoadLibrary( const char *dllname )
if( !libdir[i] )
continue;
Q_snprintf( path, MAX_SYSPATH, "%s/lib%s"POSTFIX"."OS_LIB_EXT, libdir[i], dllname );
Q_snprintf( path, MAX_SYSPATH, "%s/lib%s."OS_LIB_EXT, libdir[i], dllname );
pHandle = dlopen( path, RTLD_LAZY );
if( pHandle )
return pHandle;
@@ -51,7 +51,7 @@ void *ANDROID_LoadLibrary( const char *dllname )
}
else
{
Q_snprintf( path, MAX_SYSPATH, "lib%s"POSTFIX"."OS_LIB_EXT, dllname );
Q_snprintf( path, MAX_SYSPATH, "lib%s."OS_LIB_EXT, dllname );
pHandle = dlopen( path, RTLD_LAZY );
if( pHandle )
return pHandle;

View File

@@ -449,9 +449,9 @@ void Platfrom_MouseMove( float *yaw, float *pitch )
void Evdev_Init( void )
{
Cmd_AddCommand ("evdev_open", Evdev_OpenDevice_f, "Open event device");
Cmd_AddCommand ("evdev_close", Evdev_CloseDevice_f, "Close event device");
Cmd_AddCommand ("evdev_autodetect", Evdev_Autodetect_f, "Automaticly open mouses and keyboards");
Cmd_AddRestrictedCommand ("evdev_open", Evdev_OpenDevice_f, "Open event device");
Cmd_AddRestrictedCommand ("evdev_close", Evdev_CloseDevice_f, "Close event device");
Cmd_AddRestrictedCommand ("evdev_autodetect", Evdev_Autodetect_f, "Automaticly open mouses and keyboards");
#if XASH_INPUT == INPUT_EVDEV
Evdev_Autodetect_f();
#endif

View File

@@ -66,7 +66,7 @@ qboolean SNDDMA_Init( void )
Sys_GetParmFromCmdLine( "-alsadev", device );
Cmd_AddCommand("pcm_pause", SND_Pause_f, "set pcm pause (debug)" );
Cmd_AddRestrictedCommand("pcm_pause", SND_Pause_f, "set pcm pause (debug)" );
if( ( err = snd_pcm_open( &s_alsa.pcm_handle, device, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK ) ) < 0)
{

View File

@@ -20,6 +20,8 @@ GNU General Public License for more details.
#include "common.h"
#include "system.h"
#include "defaults.h"
#include "cursor_type.h"
#include "key_modifiers.h"
/*
==============================================================================
@@ -45,6 +47,12 @@ const char *Android_LoadID( void );
void Android_SaveID( const char *id );
#endif
#if XASH_WIN32
void Platform_UpdateStatusLine( void );
#else
static inline void Platform_UpdateStatusLine( void ) { }
#endif
/*
==============================================================================
@@ -66,6 +74,7 @@ void*Platform_GetNativeObject( const char *name );
int Platform_JoyInit( int numjoy ); // returns number of connected gamepads, negative if error
// Text input
void Platform_EnableTextInput( qboolean enable );
key_modifier_t Platform_GetKeyModifiers( void );
// System events
void Platform_RunEvents( void );
// Mouse
@@ -73,9 +82,10 @@ void Platform_GetMousePos( int *x, int *y );
void Platform_SetMousePos( int x, int y );
void Platform_PreCreateMove( void );
void Platform_MouseMove( float *x, float *y );
void Platform_SetCursorType( VGUI_DefaultCursor type );
// Clipboard
void Platform_GetClipboardText( char *buffer, size_t size );
void Platform_SetClipboardText( const char *buffer, size_t size );
int Platform_GetClipboardText( char *buffer, size_t size );
void Platform_SetClipboardText( const char *buffer );
#if XASH_SDL == 12
#define SDL_SetWindowGrab( wnd, state ) SDL_WM_GrabInput( (state) )

View File

@@ -15,8 +15,7 @@ GNU General Public License for more details.
#define _GNU_SOURCE
#include "platform/platform.h"
#if XASH_LIB == LIB_POSIX
#include <dlfcn.h>
#include "common.h"
#include "library.h"
#include "filesystem.h"
@@ -25,6 +24,127 @@ GNU General Public License for more details.
#include "platform/emscripten/lib_em.h"
#include "platform/apple/lib_ios.h"
#define ENABLE_REFCOUNT_CHECK
#ifdef ENABLE_REFCOUNT_CHECK
struct dll_t
{
void *hInstance;
char name[256];
char file[256];
int line;
int refcount;
struct dll_t *next;
};
struct dll_t *dlls = NULL;
void *DLL_FindInListAndIncrement( const char *name )
{
struct dll_t *dll;
for( dll = dlls; dll; dll = dll->next )
{
if( !Q_strcmp( name, dll->name ))
{
dll->refcount++;
return dll;
}
}
return NULL;
}
void *DLL_AddToList( const char *name, void *hInstance, const char *file, int line )
{
struct dll_t *newdll;
if( !hInstance ) return NULL;
newdll = DLL_FindInListAndIncrement( name );
if( newdll )
return newdll;
newdll = Mem_Malloc( host.mempool, sizeof( *newdll ));
newdll->hInstance = hInstance;
Q_strncpy( newdll->name, name, sizeof( newdll->name ));
Q_strncpy( newdll->file, file, sizeof( newdll->file ));
newdll->line = line;
newdll->refcount = 1;
newdll->next = dlls;
dlls = newdll;
return newdll;
}
void *DLL_Free( void *_dll )
{
struct dll_t *dll = _dll;
void *hinst = dll->hInstance;
dll->refcount--;
if( dll->refcount == 0 )
{
struct dll_t **back, *find;
back = &dlls;
while( 1 )
{
find = *back;
if( !find ) break;
if( find == dll )
{
*back = dll->next;
Mem_Free( dll );
break;
}
back = &find->next;
}
}
return hinst;
}
void *DLL_GetInstance( void *_dll )
{
struct dll_t *dll = _dll;
return dll->hInstance;
}
void DLL_PrintLeaks( void )
{
struct dll_t *dll;
for( dll = dlls; dll; dll = dll->next )
{
Con_Printf( S_ERROR "UNLOADED LIBRARY DETECTED: %s loaded at %s:%i!\n", dll->name, dll->file, dll->line );
}
}
#else
void *DLL_AddToList( const char *name, void *hInstance, const char *file, int line )
{
return hInstance;
}
void DLL_Free( void *_dll )
{
;
}
void *DLL_GetInstance( void *_dll )
{
return _dll;
}
#endif
#ifdef XASH_DLL_LOADER // wine-based dll loader
void * Loader_LoadLibrary (const char *name);
void * Loader_GetProcAddress (void *hndl, const char *name);
@@ -34,25 +154,24 @@ const char * Loader_GetFuncName( void *hndl, void *func);
const char * Loader_GetFuncName_int( void *wm , void *func);
#endif
#ifdef XASH_NO_LIBDL
#ifndef XASH_DLL_LOADER
#error Enable at least one dll backend!!!
#endif // XASH_DLL_LOADER
void *dlsym(void *handle, const char *symbol )
void *dlsym( void *handle, const char *symbol )
{
Con_DPrintf( "dlsym( %p, \"%s\" ): stub\n", handle, symbol );
return NULL;
}
void *dlopen(const char *name, int flag )
void *dlopen( const char *name, int flag )
{
Con_DPrintf( "dlopen( \"%s\", %d ): stub\n", name, flag );
return NULL;
}
int dlclose(void *handle)
int dlclose( void *handle)
{
Con_DPrintf( "dlsym( %p ): stub\n", handle );
return 0;
@@ -75,7 +194,7 @@ qboolean COM_CheckLibraryDirectDependency( const char *name, const char *depname
return true;
}
void *COM_LoadLibrary( const char *dllname, int build_ordinals_table, qboolean directpath )
void *_COM_LoadLibrary( const char *dllname, int build_ordinals_table, qboolean directpath, const char *file, int line )
{
dll_user_t *hInst = NULL;
void *pHandle = NULL;
@@ -96,7 +215,7 @@ void *COM_LoadLibrary( const char *dllname, int build_ordinals_table, qboolean d
#ifdef XASH_DLL_LOADER
if( host.enabledll && ( pHandle = Loader_LoadLibrary(dllname)) )
{
return pHandle;
return DLL_AddToList( dllname, pHandle, file, line );
}
#endif
@@ -105,7 +224,7 @@ void *COM_LoadLibrary( const char *dllname, int build_ordinals_table, qboolean d
{
pHandle = dlopen( dllname, RTLD_LAZY );
if( pHandle )
return pHandle;
return DLL_AddToList( dllname, pHandle, file, line );
COM_PushLibraryError( va( "Failed to find library %s", dllname ));
COM_PushLibraryError( dlerror() );
@@ -152,38 +271,42 @@ void *COM_LoadLibrary( const char *dllname, int build_ordinals_table, qboolean d
Mem_Free( hInst );
return pHandle;
return DLL_AddToList( dllname, pHandle, file, line );
}
void COM_FreeLibrary( void *hInstance )
{
void *hinst = DLL_Free( hInstance );
#ifdef XASH_DLL_LOADER
void *wm;
if( host.enabledll && (wm = Loader_GetDllHandle( hInstance )) )
return Loader_FreeLibrary( hInstance );
if( host.enabledll && (wm = Loader_GetDllHandle( hinst )) )
return Loader_FreeLibrary( hinst );
else
#endif
{
#ifdef Platform_POSIX_FreeLibrary
Platform_POSIX_FreeLibrary( hInstance );
Platform_POSIX_FreeLibrary( hinst );
#else
dlclose( hInstance );
dlclose( hinst );
#endif
}
}
void *COM_GetProcAddress( void *hInstance, const char *name )
{
void *hinst = DLL_GetInstance( hInstance );
#ifdef XASH_DLL_LOADER
void *wm;
if( host.enabledll && (wm = Loader_GetDllHandle( hInstance )) )
return Loader_GetProcAddress(hInstance, name);
if( host.enabledll && ( wm = Loader_GetDllHandle( hinst )))
return Loader_GetProcAddress( hinst, name );
else
#endif
#if Platform_POSIX_GetProcAddress
return Platform_POSIX_GetProcAddress( hInstance, name );
return Platform_POSIX_GetProcAddress( hinst, name );
#else
return dlsym( hInstance, name );
return dlsym( hinst, name );
#endif
}
@@ -217,11 +340,13 @@ static int d_dladdr( void *sym, Dl_info *info )
const char *COM_NameForFunction( void *hInstance, void *function )
{
void *hinst = DLL_GetInstance( hInstance );
#ifdef XASH_DLL_LOADER
void *wm;
if( host.enabledll && (wm = Loader_GetDllHandle( hInstance )) )
if( host.enabledll && ( wm = Loader_GetDllHandle( hinst )))
#error ConvertMangledName
return Loader_GetFuncName_int(wm, function);
return Loader_GetFuncName_int( wm, function );
else
#endif
// NOTE: dladdr() is a glibc extension

View File

@@ -88,6 +88,7 @@ GNU General Public License for more details.
#define SDL_SCANCODE_PRINTSCREEN SDLK_PRINT
#define SDL_SCANCODE_UNKNOWN SDLK_UNKNOWN
#define SDL_GetScancodeName( x ) "unknown"
#define SDL_JoystickID Uint8
#endif
static qboolean SDLash_IsInstanceIDAGameController( SDL_JoystickID joyId )
@@ -121,7 +122,7 @@ static void SDLash_KeyEvent( SDL_KeyboardEvent key )
#endif
qboolean numLock = SDL_GetModState() & KMOD_NUM;
if( SDL_IsTextInputActive() && down )
if( SDL_IsTextInputActive() && down && cls.key_dest != key_game )
{
if( SDL_GetModState() & KMOD_CTRL )
{
@@ -270,30 +271,29 @@ SDLash_MouseEvent
static void SDLash_MouseEvent( SDL_MouseButtonEvent button )
{
int down = button.state != SDL_RELEASED;
qboolean istouch;
uint mstate = 0;
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
istouch = button.which == SDL_TOUCH_MOUSEID;
#else // SDL_VERSION_ATLEAST( 2, 0, 0 )
istouch = false;
#endif // SDL_VERSION_ATLEAST( 2, 0, 0 )
if( button.which == SDL_TOUCH_MOUSEID )
return;
#endif
switch( button.button )
{
case SDL_BUTTON_LEFT:
SDLash_MouseKey( K_MOUSE1, down, istouch );
IN_MouseEvent( 0, down );
break;
case SDL_BUTTON_RIGHT:
SDLash_MouseKey( K_MOUSE2, down, istouch );
IN_MouseEvent( 1, down );
break;
case SDL_BUTTON_MIDDLE:
SDLash_MouseKey( K_MOUSE3, down, istouch );
IN_MouseEvent( 2, down );
break;
case SDL_BUTTON_X1:
SDLash_MouseKey( K_MOUSE4, down, istouch );
IN_MouseEvent( 3, down );
break;
case SDL_BUTTON_X2:
SDLash_MouseKey( K_MOUSE5, down, istouch );
IN_MouseEvent( 4, down );
break;
#if ! SDL_VERSION_ATLEAST( 2, 0, 0 )
case SDL_BUTTON_WHEELUP:
@@ -318,6 +318,7 @@ SDLash_InputEvent
static void SDLash_InputEvent( SDL_TextInputEvent input )
{
char *text;
VGui_ReportTextInput( input.text );
for( text = input.text; *text; text++ )
{
int ch;
@@ -340,7 +341,11 @@ static void SDLash_ActiveEvent( int gain )
if( gain )
{
host.status = HOST_FRAME;
IN_ActivateMouse( true );
if( cls.key_dest == key_game )
{
IN_ActivateMouse( );
}
if( dma.initialized && snd_mute_losefocus.value )
{
SNDDMA_Activate( true );
@@ -360,7 +365,11 @@ static void SDLash_ActiveEvent( int gain )
}
#endif
host.status = HOST_NOFOCUS;
IN_DeactivateMouse();
if( cls.key_dest == key_game )
{
IN_DeactivateMouse();
}
if( dma.initialized && snd_mute_losefocus.value )
{
SNDDMA_Activate( false );
@@ -425,13 +434,10 @@ static void SDLash_EventFilter( SDL_Event *event )
{
/* Mouse events */
case SDL_MOUSEMOTION:
if( !host.mouse_visible
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
&& event->motion.which != SDL_TOUCH_MOUSEID )
#else
)
#endif
IN_MouseEvent();
if( host.mouse_visible )
{
SDL_GetRelativeMouseState( NULL, NULL );
}
break;
case SDL_MOUSEBUTTONUP:

View File

@@ -33,5 +33,11 @@ void VID_SaveWindowSize( int width, int height );
// joystick events
extern SDL_Joystick *g_joy;
//
// in_sdl.c
//
void SDLash_InitCursors( void );
void SDLash_FreeCursors( void );
#endif // XASH_SDL
#endif // KEYWRAPPER_H

View File

@@ -27,6 +27,12 @@ GNU General Public License for more details.
SDL_Joystick *g_joy = NULL;
#if !SDL_VERSION_ATLEAST( 2, 0, 0 )
#define SDL_WarpMouseInWindow( win, x, y ) SDL_WarpMouse( ( x ), ( y ) )
#else
static struct
{
qboolean initialized;
SDL_Cursor *cursors[dc_last];
} cursors;
#endif
/*
@@ -71,19 +77,28 @@ Platform_GetClipobardText
=============
*/
void Platform_GetClipboardText( char *buffer, size_t size )
int Platform_GetClipboardText( char *buffer, size_t size )
{
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
int textLength;
char *sdlbuffer = SDL_GetClipboardText();
if( !sdlbuffer )
return;
return 0;
Q_strncpy( buffer, sdlbuffer, size );
if (buffer && size > 0)
{
textLength = Q_strncpy( buffer, sdlbuffer, size );
}
else {
textLength = Q_strlen( sdlbuffer );
}
SDL_free( sdlbuffer );
return textLength;
#else // SDL_VERSION_ATLEAST( 2, 0, 0 )
buffer[0] = 0;
#endif // SDL_VERSION_ATLEAST( 2, 0, 0 )
return 0;
}
/*
@@ -92,7 +107,7 @@ Platform_SetClipobardText
=============
*/
void Platform_SetClipboardText( const char *buffer, size_t size )
void Platform_SetClipboardText( const char *buffer )
{
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
SDL_SetClipboardText( buffer );
@@ -237,4 +252,143 @@ int Platform_JoyInit( int numjoy )
return SDLash_JoyInit_Old(numjoy);
}
/*
========================
SDLash_InitCursors
========================
*/
void SDLash_InitCursors( void )
{
if( cursors.initialized )
SDLash_FreeCursors();
// load up all default cursors
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
cursors.cursors[dc_none] = NULL;
cursors.cursors[dc_arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
cursors.cursors[dc_ibeam] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM);
cursors.cursors[dc_hourglass] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_WAIT);
cursors.cursors[dc_crosshair] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_CROSSHAIR);
cursors.cursors[dc_up] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
cursors.cursors[dc_sizenwse] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE);
cursors.cursors[dc_sizenesw] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW);
cursors.cursors[dc_sizewe] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE);
cursors.cursors[dc_sizens] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS);
cursors.cursors[dc_sizeall] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL);
cursors.cursors[dc_no] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO);
cursors.cursors[dc_hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND);
#endif
cursors.initialized = true;
}
/*
========================
SDLash_FreeCursors
========================
*/
void SDLash_FreeCursors( void )
{
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
int i = 0;
for( ; i < ARRAYSIZE( cursors.cursors ); i++ )
{
if( cursors.cursors[i] )
SDL_FreeCursor( cursors.cursors[i] );
cursors.cursors[i] = NULL;
}
cursors.initialized = false;
#endif // SDL_VERSION_ATLEAST( 2, 0, 0 )
}
/*
========================
Platform_SetCursorType
========================
*/
void Platform_SetCursorType( VGUI_DefaultCursor type )
{
qboolean visible;
if( !cursors.initialized )
return;
if( cls.key_dest != key_game || cl.paused )
return;
switch( type )
{
case dc_user:
case dc_none:
visible = false;
break;
default:
visible = true;
break;
}
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
if( CVAR_TO_BOOL( touch_emulate ))
return;
if( visible && !host.mouse_visible )
{
SDL_SetCursor( cursors.cursors[type] );
SDL_ShowCursor( true );
Key_EnableTextInput( true, false );
}
else if( !visible && host.mouse_visible )
{
SDL_ShowCursor( false );
Key_EnableTextInput( false, false );
}
host.mouse_visible = visible;
#endif
}
/*
========================
Platform_GetKeyModifiers
========================
*/
key_modifier_t Platform_GetKeyModifiers( void )
{
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
SDL_Keymod modFlags;
key_modifier_t resultFlags;
resultFlags = KeyModifier_None;
modFlags = SDL_GetModState();
if( FBitSet( modFlags, KMOD_LCTRL ))
SetBits( resultFlags, KeyModifier_LeftCtrl );
if( FBitSet( modFlags, KMOD_RCTRL ))
SetBits( resultFlags, KeyModifier_RightCtrl );
if( FBitSet( modFlags, KMOD_RSHIFT ))
SetBits( resultFlags, KeyModifier_RightShift );
if( FBitSet( modFlags, KMOD_LSHIFT ))
SetBits( resultFlags, KeyModifier_LeftShift );
if( FBitSet( modFlags, KMOD_LALT ))
SetBits( resultFlags, KeyModifier_LeftAlt );
if( FBitSet( modFlags, KMOD_RALT ))
SetBits( resultFlags, KeyModifier_RightAlt );
if( FBitSet( modFlags, KMOD_NUM ))
SetBits( resultFlags, KeyModifier_NumLock );
if( FBitSet( modFlags, KMOD_CAPS ))
SetBits( resultFlags, KeyModifier_CapsLock );
if( FBitSet( modFlags, KMOD_RGUI ))
SetBits( resultFlags, KeyModifier_RightSuper );
if( FBitSet( modFlags, KMOD_LGUI ))
SetBits( resultFlags, KeyModifier_LeftSuper );
return resultFlags;
#else
return KeyModifier_None;
#endif
}
#endif // XASH_DEDICATED

View File

@@ -15,6 +15,7 @@ GNU General Public License for more details.
#include <SDL.h>
#include "platform/platform.h"
#include "events.h"
#if XASH_TIMER == TIMER_SDL
double Platform_DoubleTime( void )
@@ -67,11 +68,15 @@ void Platform_Init( void )
#ifdef XASH_WIN32
Wcon_CreateConsole(); // system console used by dedicated server or show fatal errors
#endif
SDLash_InitCursors();
}
void Platform_Shutdown( void )
{
SDLash_FreeCursors();
#ifdef XASH_WIN32
Wcon_DestroyConsole();
#endif
}
}

View File

@@ -574,7 +574,6 @@ static qboolean VID_SetScreenResolution( int width, int height )
SDL_SetWindowBordered( host.hWnd, SDL_FALSE );
//SDL_SetWindowPosition( host.hWnd, 0, 0 );
SDL_SetWindowGrab( host.hWnd, SDL_TRUE );
SDL_SetWindowSize( host.hWnd, got.w, got.h );
VID_SaveWindowSize( got.w, got.h );
@@ -590,7 +589,6 @@ void VID_RestoreScreenResolution( void )
if( !Cvar_VariableInteger("fullscreen") )
{
SDL_SetWindowBordered( host.hWnd, SDL_TRUE );
SDL_SetWindowGrab( host.hWnd, SDL_FALSE );
}
else
{
@@ -662,7 +660,7 @@ qboolean VID_CreateWindow( int width, int height, qboolean fullscreen )
glw_state.safe++;
if( !gl_wgl_msaa_samples->value && glw_state.safe == SAFE_NOMSAA )
if( !gl_msaa_samples->value && glw_state.safe == SAFE_NOMSAA )
glw_state.safe++; // no need to skip msaa, if we already disabled it
GL_SetupAttributes(); // re-choose attributes
@@ -805,7 +803,7 @@ qboolean VID_CreateWindow( int width, int height, qboolean fullscreen )
glw_state.safe++;
if( !gl_wgl_msaa_samples->value && glw_state.safe == SAFE_NOMSAA )
if( !gl_msaa_samples->value && glw_state.safe == SAFE_NOMSAA )
glw_state.safe++; // no need to skip msaa, if we already disabled it
GL_SetupAttributes(); // re-choose attributes

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