Compare commits

...

455 Commits

Author SHA1 Message Date
Andrey Akhmichin
dabed4f9eb utils: mdldec: add separate directories creation for sequences and textures. 2023-12-05 11:18:47 +03:00
Andrey Akhmichin
f9b6389248 utils: mdldec: create full destination path into "Kratisto's mdldec" maner. 2023-12-05 11:18:47 +03:00
Alibek Omarov
9ec1e259b4 engine: platform: sdl: unused variable cleanup 2023-12-05 10:48:47 +03:00
Alibek Omarov
0c2d480d89 engine: client: unused variables cleanup 2023-12-05 10:47:55 +03:00
Alibek Omarov
350d8ccb7b engine: common: cvar: unused variables cleanup 2023-12-05 10:46:26 +03:00
Alibek Omarov
0c512d0431 engine: server: unused variables cleanup 2023-12-05 10:46:03 +03:00
Alibek Omarov
3bf55c9ea4 filesystem: zip: hide CRC checks under common macro 2023-12-04 03:01:11 +03:00
Alibek Omarov
9994c57796 filesystem: fix updating gameinfo.txt from rodir 2023-12-04 03:00:51 +03:00
Alibek Omarov
3f724b6b17 filesystem: remove some really unused variables 2023-12-04 03:00:29 +03:00
Alibek Omarov
255773b4de ref: gl: remove useless calls to glGetString if we're running under GL4ES 2023-12-04 02:53:51 +03:00
Alibek Omarov
5b73a788da ref: gl: disable unused variable warning for GL functions defintions 2023-12-04 02:53:27 +03:00
Alibek Omarov
748b06a00e wscript: warn about unused variables 2023-12-04 02:53:07 +03:00
Alibek Omarov
273bccdc9a engine: nswitch: fix compiling by removing stdc++ from SDL2 dependencies as we link it later (#1519) 2023-12-02 20:25:51 +03:00
Alibek Omarov
f0a2362da3 engine: wscript: another try, link nswitch port using gcc and not g++ 2023-12-02 19:29:30 +03:00
Alibek Omarov
be8ade23e8 engine: wscript: add -nostdlib++ for nswitch so we avoid implicit linking to standard C++ library (we link it explicitly ourselves) 2023-12-02 19:21:44 +03:00
Alibek Omarov
6814908d80 scripts: gha: enable verbose build for nswitch port 2023-12-02 19:08:34 +03:00
Alibek Omarov
08dbfc45d3 ref: gl: refactor getting edge position, texture and lightmap coords 2023-12-02 18:02:18 +03:00
Alibek Omarov
89f9b3df68 public: make simple bbox functions inline 2023-12-02 18:01:57 +03:00
Alibek Omarov
40c9a2fb82 engine: make Mod_SampleSizeForFace accept const surface 2023-12-02 18:01:57 +03:00
Andrey Akhmichin
a34c22fb10 engine: client: add support for "mp3 playfile/loopfile" commands. 2023-12-02 01:10:38 +03:00
Alibek Omarov
e161ff0f7a mainui: update 2023-11-27 19:25:36 +03:00
Alibek Omarov
fee42eab5a mainui: update 2023-11-27 19:05:48 +03:00
Alibek Omarov
2d2e03f235 engine: server: reset edict in ParseSaveTables like GoldSrc does which fixes messed up entities in mods that have advanced save-restore system (thanks to vasiavasiavasia95 for figuring out this bug) 2023-11-27 18:42:50 +03:00
Alibek Omarov
4c3c3529e9 engine: network: rename length variable to something that makes sense. Add usage line to http_addcustomserver 2023-11-26 23:20:46 +03:00
Alibek Omarov
7051b844ff engine: network: set HTTP buffer to 8kb on all systems, without depending on random constant like BUFSIZ 2023-11-26 23:19:49 +03:00
Alibek Omarov
68377435c8 engine: server: remove legacy light -> light_level entity key rewrite 2023-11-26 02:23:52 +03:00
Henry Ford
652b1804a8 wscript: make libdl optional for systems that include it in libc 2023-11-25 14:29:52 +03:00
Henry Ford
e7e1677786 engine: common: comply with C89 in OpenBSD wai_getExecutablePath 2023-11-25 14:29:52 +03:00
Henry Ford
f330aac113 engine: common: dont inlcude ucontext.h on OpenBSD where it doesnt exist 2023-11-25 14:29:52 +03:00
Henry Ford
dbdd330cf7 wscript: try to find alloca in stdlib.h on platforms without alloca.h or malloc.h 2023-11-25 14:29:52 +03:00
Andrey Akhmichin
c448c7b0b1 utils: mdldec: avoid double ".smd" extension output. 2023-11-22 11:05:34 +03:00
Andrey Akhmichin
8d7b9c2f01 utils: mdldec: always write trailing slash for non-empty destination path. 2023-11-22 11:03:28 +03:00
Alibek Omarov
b6a235445a vgui_support: update submodule 2023-11-22 11:02:25 +03:00
Alibek Omarov
9fcd4baa87 engine: client: gameui: expose animated_title and hd_background flags to main menu API 2023-11-22 11:01:18 +03:00
Alibek Omarov
fb0102eb8e filesystem: add support for two new liblist.gam keys: animated_title and hd_background 2023-11-22 11:01:18 +03:00
Alibek Omarov
9c1afaa372 filesystem: fix noskills being written as nomodels in gameinfo.txt 2023-11-22 11:01:18 +03:00
Alibek Omarov
1d1a6badb5 filesystem: VFileSystem009: HL25 compatibility (one single new method) 2023-11-22 11:01:18 +03:00
Andrey Akhmichin
2d41c9cb15 utils: mdldec: texture.c: add Targa image format output support. 2023-11-22 10:56:57 +03:00
Alibek Omarov
722cbe1f02 filesystem: forgot to add defaults.h include 2023-11-20 18:52:05 +03:00
Alibek Omarov
8ac2c241c4 mainui: update 2023-11-20 17:33:40 +03:00
Alibek Omarov
dd11f73951 filesystem: respect DEFAULT_MAX_EDICTS value 2023-11-20 17:32:35 +03:00
Alibek Omarov
a443547d4d common: defaults: add default macro for default gameinfo max_edicts value 2023-11-20 17:32:19 +03:00
Andrey Akhmichin
7a795edeb5 utils: mdldec: better validation checks. 2023-11-20 00:19:14 +03:00
Andrey Akhmichin
a8cbfb8dda Documentation: opensource-mods.md: update link to cs16-client. 2023-11-20 00:15:26 +03:00
SNMetamorph
5216cccef4 engine: server: added singleplayer check for userinfo update 2023-11-20 00:14:30 +03:00
SNMetamorph
a87f399e68 engine: client: revert export for pfnSPR_Load and pfnSPR_Frames functions
This needed for native support GoldSrc Monitor utility.
2023-11-20 00:14:06 +03:00
Andrey Akhmichin
dd310ab851 ci: upgrade freebsd tasks. 2023-11-20 00:13:42 +03:00
Andrey Akhmichin
16cc0ca0fe ref: gl: gl2_shim: replace "malloc.h" header with ALLOCA_H macro. 2023-11-20 00:13:04 +03:00
Alibek Omarov
83d26ad233 engine: server: add sv_allow_autoaim cvar 2023-11-20 00:11:10 +03:00
Alibek Omarov
d1f9a8f2db mainui: updates for HL25 2023-11-19 23:43:46 +03:00
Alibek Omarov
a2e1071808 game_launch: force link libm on Linux to workaround HL25 bug
HL25 doesn't link libm probably because of toolchain updates, where
--Wl,--as-needed became the default.

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

Workaround until Valve fixes it: https://github.com/ValveSoftware/halflife/issues/3492
2023-11-19 23:43:46 +03:00
Alibek Omarov
0aa8a2891c engine: client: add gles3compat to renderers list 2023-11-03 17:03:27 +03:00
Alibek Omarov
c0ceab7513 wscript: enable ref_gles3compat for Android 2023-11-03 17:01:47 +03:00
Velaron
5c90e716cb engine: platform: android: refactoring 2023-11-03 16:40:06 +03:00
Velaron
0073225549 scripts: gha: Android deps and build scripts 2023-11-03 16:36:55 +03:00
Alibek Omarov
d03a64602b wscript: change defaults for Android 2023-11-03 16:34:21 +03:00
Alibek Omarov
d67a4234cc filesystem: android: simplify code, get getAssets method only once, remove unneeded casts and memsets (where Mem_Calloc is used) 2023-11-03 16:29:57 +03:00
Alibek Omarov
0d37244490 filesystem: add missing const to 2nd argument of stringlistappend 2023-11-03 16:23:52 +03:00
Velaron
6426919cb5 filesystem: add Android assets support 2023-11-03 16:23:03 +03:00
Alibek Omarov
0a0d63663a filesystem: link with libandroid 2023-11-03 16:22:59 +03:00
Alibek Omarov
71b06801ef engine: platform: android: remove dead code 2023-11-03 14:48:28 +03:00
Alibek Omarov
cfc7b35927 engine: client: don't leave the user without mouse cursor if they enabled m_ignore 2023-11-03 14:48:28 +03:00
Alibek Omarov
76564958d1 engine: host: hide -nativeegl for Android SDL builds 2023-11-03 14:48:28 +03:00
Alibek Omarov
a464c3dd66 scripts: waifulib: compiler_optimizations: rename release build type to humanrights with kept compatibility 2023-11-02 14:33:00 +03:00
Alibek Omarov
bd969f3594 wscript: fix system opus detection, it didn't compile due to nonnull argument 2023-11-01 01:35:39 +03:00
Alibek Omarov
fb87d7c0b3 readme: wording, add icon, add donate.md link [skip ci] 2023-10-31 21:54:23 +03:00
Alibek Omarov
a69fc87940 Documentation: donate: add sponsorship information 2023-10-31 21:54:23 +03:00
Alibek Omarov
e481e1d73e ref: gl: enable GL waves with r_ripple 2023-10-31 21:52:00 +03:00
Alibek Omarov
6c0eed1b2b ref: gl: allow viewing water textures in their full glory with enabled r_ripple 2 2023-10-31 21:52:00 +03:00
Alibek Omarov
a6c67fdf9f ref: gl: upload only part of texture we're using, i.e. 64x64 for 64x64, 128x128 for 128x128 2023-10-31 21:52:00 +03:00
Alibek Omarov
03f838e37e mainui: update 2023-10-31 21:52:00 +03:00
Alibek Omarov
e21fa4a910 engine: add cvar r_refdll_loaded to indicate currently loaded renderer (for menu options and etc) 2023-10-31 21:52:00 +03:00
Alibek Omarov
46889ed453 ref: gl: libc rand() does better job at randomizing 2023-10-31 21:52:00 +03:00
Alibek Omarov
882fcc152c ref: gl: always scale down texture to 64x64, like sw.dll does 2023-10-31 21:52:00 +03:00
Alibek Omarov
a41902bd46 engine: mod_bmodel: detect water textures by texture name like LoadSurfaces does 2023-10-31 21:52:00 +03:00
Alibek Omarov
a6af32dafd ref: gl: connect ripply water to others parts of renderer (init, reset, animation and rendering) 2023-10-31 21:52:00 +03:00
Alibek Omarov
d6dfb83be7 ref: gl: ripply water implementation (bugfixed version from my Quake-2 patches) 2023-10-31 21:52:00 +03:00
Alibek Omarov
597429cf41 engine, filesystem: unify GetNativeObject between all the APIs. Allow getting filesystem APIs through GetNativeObject 2023-10-31 21:25:11 +03:00
Alibek Omarov
5ea074a1fd engine: fix build issues pointed by @Velaron 2023-10-31 21:01:42 +03:00
Alibek Omarov
29c9393da3 wscript: enable faster builds with gccdeps/msvcdeps 2023-10-31 04:30:27 +03:00
Alibek Omarov
bf6829189e wscript: move XASH_BUILD_COMMIT definition to libpublic, as this is the only place where it's used, for faster builds 2023-10-31 04:30:27 +03:00
Alibek Omarov
a62a9429c9 engine: launcher: remove Windows code from single binary launcher, as Windows completely supports running from external launcher and don't need dedicated builds 2023-10-31 04:30:22 +03:00
mittorn
f2c080e736 gl2shim: fix broken matrix update when fog attribute enabled (32 bit shift overflow) 2023-10-30 22:34:34 +03:00
Alibek Omarov
ea55e78855 ref: _inline -> static 2023-10-29 23:38:43 +03:00
Alibek Omarov
f7c536b81c engine: server: allow loading maps from subdirectories as this is used by some Half-Life mods 2023-10-29 02:44:46 +03:00
Alibek Omarov
6c40104c66 public: better fix for ExtractFilePath 2023-10-28 19:31:17 +03:00
Alibek Omarov
4d7d592918 engine: mod_bmodel: completely get rid of global loadmodel pointer 2023-10-28 16:06:00 +03:00
Alibek Omarov
c5e91f299b engine: mod_studio: reduce dependency on global loadmodel pointer, make it private for brush model loader 2023-10-28 15:38:40 +03:00
Alibek Omarov
cff276db71 engine: client: mod_dbghulls: reduce dependency on global loadmodel pointer 2023-10-28 15:35:20 +03:00
Alibek Omarov
30d1492b93 engine: remove Set/GetCurrentLoadingModel from RefAPI 2023-10-28 15:22:21 +03:00
Alibek Omarov
f07eea5073 engine: server: allow server unloading for Win32 targets until we figure out the issues with MetaMod 2023-10-28 11:14:12 +03:00
Alibek Omarov
fe407fbe00 public: workaround when empty string is passed to COM_ExtractFilePath (should make safe COM_ExtractFilePath) 2023-10-28 11:06:18 +03:00
Alibek Omarov
78bc177e05 engine: server: remove unused host struct field 2023-10-28 11:06:18 +03:00
Alibek Omarov
8fb908e3d4 engine: server: disable SV_UnloadProgs, only call it when shutting down engine 2023-10-28 11:06:18 +03:00
Alibek Omarov
d8b261370a engine: common: do not probe server to collect cvars for game.cfg (CHECK THIS) 2023-10-28 11:06:18 +03:00
Alibek Omarov
a2c9ac5b1f engine: client: disable server DLL probe for GameUI, check it's existence instead 2023-10-28 11:06:18 +03:00
Alibek Omarov
7f9025e178 engine: server: sv_pmove: use model name for physent name to avoid crash when classname isn't initialized yet 2023-10-28 11:04:43 +03:00
Alibek Omarov
8647110a10 Revert "engine: wscript: move libasound uselib under linux condition, as the ALSA interface is only relevant for Linux"
This reverts commit 48e44f0057.
2023-10-28 10:10:03 +03:00
Alibek Omarov
48e44f0057 engine: wscript: move libasound uselib under linux condition, as the ALSA interface is only relevant for Linux 2023-10-27 17:03:04 +03:00
Alibek Omarov
e3934af7d1 wscript: always load cmakelists generation tool 2023-10-27 16:57:22 +03:00
Alibek Omarov
a5ee631191 engine: server: sv_game: disable searching closer to server library memory region for Android 2023-10-27 14:31:16 +03:00
Alibek Omarov
ce39255ef0 engine: host: set rootdir on Android SDL port 2023-10-27 14:25:16 +03:00
Alibek Omarov
5aac5d2a52 filesystem: VFileSystem009: add pathid support to RemoveFile method 2023-10-27 08:02:45 +03:00
Alibek Omarov
061b50404d engine: server: register dummy cvar sv_allow_dlfile for GoldSrc compatibility 2023-10-27 08:02:10 +03:00
Alibek Omarov
279cec5ae9 engine: rename cl/sv_allowdownload for GoldSrc compatibility 2023-10-27 07:25:09 +03:00
Alibek Omarov
83a5648335 filesystem: only allow setting true or false for boolean type keys in gameinfo/liblist.gam 2023-10-27 07:24:42 +03:00
Alibek Omarov
a8fc9a4c5a waf: update to latest waifu 2023-10-27 07:24:18 +03:00
Alibek Omarov
6f6ddbce28 engine: add argument -timedemo that makes engine run timedemo and exit 2023-10-27 03:49:00 +03:00
Alibek Omarov
4cb425d2bb engine: console: do not draw console and do not draw notify in timedemo 2023-10-27 03:47:52 +03:00
mittorn
bf5fd40d64 gl2shim: workaround empty rgb5/rgb8 textures 2023-10-26 23:08:02 +03:00
mittorn
6bc613bdb4 ref_gl: force gles2 on non-nanogl until we support gles1 directly 2023-10-26 23:07:39 +03:00
mittorn
a982562658 ref_gl: Fix missing DebugOutput functions on GLES 2023-10-26 23:07:22 +03:00
Alibek Omarov
96a9172e36 engine: platform: sdl: check that we're handling SDL errors according to it's documentation 2023-10-26 23:06:50 +03:00
Alibek Omarov
34d7664342 ref: gl: disable TGA flip for detail textures, GoldSrc ignores it, so we will too 2023-10-26 05:12:38 +03:00
Alibek Omarov
b0a79df86f ref: change r_traceglow to 0, as GoldSrc does 2023-10-26 04:59:01 +03:00
Alibek Omarov
9e107e900c engine: network: fix async NS resolve
If we're currently running NS resolving thread, any request would block.

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

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

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

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

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

* address spaces-vs-parentheses formatting where noticed

* parenthesize sizeofs

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

* use SetBits() instead of |=

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

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

A proper parser should be reimplemented from ground-up, when we will
start working on CZDS support.
2023-07-26 19:40:03 +03:00
Alibek Omarov
e49848d090 github: bump SDL2 version to 2.28.1 2023-07-23 03:16:03 +03:00
Alibek Omarov
1bfc6e6705 filesystem: try to fix case of library filename in FindLibrary 2023-07-22 07:04:26 +03:00
Alibek Omarov
e7c41759fb Revert "filesystem: allow to reference game libraries in different case"
This reverts commit 43fde38d88.
2023-07-22 06:39:23 +03:00
Alibek Omarov
a07f81820c engine: client: ref_common: fix missing newline in Host_Error 2023-07-22 05:51:18 +03:00
Alibek Omarov
b39378a6da engine: common: fix warning about read-only cvar. In fact, we should force set them. 2023-07-22 05:50:38 +03:00
Alibek Omarov
5c6b9d3235 scripts: flatpak: set correct bindir for flatpak installation 2023-07-22 04:49:48 +03:00
Alibek Omarov
3d49ca25b3 scripts: flatpak: disable LTO for Flatpak for now, it causes linker errors 2023-07-22 00:23:03 +03:00
Alibek Omarov
43fde38d88 filesystem: allow to reference game libraries in different case 2023-07-22 00:19:37 +03:00
Alibek Omarov
6461fa5042 engine: client: make ref params static so client.dll can save address of it and don't trigger ASan 2023-07-17 05:52:45 +03:00
Alibek Omarov
788bc820c8 filesystem: automatically fixup directory name case for base directories 2023-07-17 05:52:06 +03:00
Alibek Omarov
36ff819daf engine: client: fix heap-buffer-overflow in remap when we switch model that have more remap textures than previous 2023-07-17 04:48:02 +03:00
Alibek Omarov
8905883225 utils: xar: add new utility called Xar that helps interacting with Xash3D FWGS archives using filesystem_stdio C API
The utility is not yet finalized, disable from wscript for now
2023-07-05 07:00:39 +03:00
Alibek Omarov
4031f5cb01 public: allow matching anything in matchpattern 2023-07-05 07:00:39 +03:00
Alibek Omarov
cd46ad19a3 filesystem: expose a special flag for archive mounter to skip included WADs 2023-07-05 07:00:39 +03:00
Alibek Omarov
6f7b1695d7 filesystem: expose archive mount generic function for Xar 2023-07-05 07:00:39 +03:00
Alibek Omarov
28a4b51939 Documentation: gameinfo: wording 2023-07-04 03:39:17 +03:00
Alibek Omarov
5e878aae89 mainui: upgrade 2023-07-03 02:25:31 +03:00
Alibek Omarov
7e05562c14 engine: platform: sdl: check SDL version in Platform_Vibrate 2023-07-03 02:18:49 +03:00
Alibek Omarov
777dd3a03c public: add definitions for PowerPC
This doesn't mean we have a port but at least it allows building for ppc64el
2023-07-03 01:40:47 +03:00
Alibek Omarov
9977cb20c0 Documentation: gameinfo: clarify internal_vgui_support is intended to be used only for developers and that it's required for PrimeXT 2023-07-02 08:14:26 +03:00
Alibek Omarov
5661766c79 Documentation: gameinfo: wording 2023-07-02 06:45:29 +03:00
Alibek Omarov
60d65d368a Documentation: add basic document on gameinfo.txt keys and liblist.gam conversion 2023-07-02 06:36:57 +03:00
Alibek Omarov
031594cc99 filesystem: update max_particles limits based on Unkle Mike's latest engine version 2023-07-02 06:36:35 +03:00
Alibek Omarov
d4bf57c7c2 filesystem: delete unused edicts key handler in liblist.gam parsing 2023-07-02 06:36:09 +03:00
Alibek Omarov
8e16c0e410 filesystem: simplify common parsing of type key for liblist.gam and gameinfo.txt 2023-07-02 06:35:34 +03:00
Alibek Omarov
d5f4b409e8 engine: server: sv_save: use new quicksave_aged_count and autosave_aged_count gameinfo.txt keys 2023-07-02 04:53:39 +03:00
Alibek Omarov
88c560aac4 filesystem: add two new gameinfo.txt keys quicksave_aged_count and autosave_aged_count that control the amount of quick/autosaves rotated 2023-07-02 04:53:16 +03:00
Alibek Omarov
c3a6cad0c1 filesystem: do not print error in FS_Delete if file doesn't exist 2023-07-02 04:49:33 +03:00
Alibek Omarov
a862446072 engine: client: restore cl_trace_events from old engine branch 2023-07-02 04:48:43 +03:00
Alibek Omarov
8d04ae8802 engine: client: fix appending extra .dem in record command 2023-07-02 02:44:25 +03:00
Alibek Omarov
0de0615eeb engine: client: implement map CRC32 checking on client side 2023-07-02 01:20:24 +03:00
Alibek Omarov
ea24b5f3ca engine: server: make CRC32_MapFile public 2023-07-02 01:19:38 +03:00
Alibek Omarov
eb7f19d3cf engine: server: properly remove remaining server operator commands 2023-07-02 01:19:21 +03:00
Alibek Omarov
ca134a85ee engine: client: make it more obvious that CL_InitEdicts depends on maxclients value 2023-06-30 02:51:47 +03:00
Alibek Omarov
00765f1ff2 engine: client: cl_parse_48: add a temporary hack to avoid the lag issues after changelevel on legacy servers 2023-06-30 02:35:36 +03:00
Alibek Omarov
013bfe5c34 engine: common: sys_con: always read from stdin when engine is in dedicated mode 2023-06-30 01:44:03 +03:00
Alibek Omarov
5f625bb6e1 wscript: remove option --enable-stdin-input, it's enabled by default in dedicated mode sys_con now 2023-06-30 01:43:26 +03:00
Alibek Omarov
547a862024 engine: client: split protocol 48 support to separate file 2023-06-29 04:09:36 +03:00
Alibek Omarov
6ea8d141d9 engine: common: net_encode: fix usage of new Delta_ClampIntegerField, minor fixes 2023-06-28 14:30:06 +03:00
Alibek Omarov
bdc2390d41 Revert "engine: common: net_encode: rewrite Delta_CompareField to be more efficient"
This reverts commit 82addf11bb.
2023-06-28 14:26:42 +03:00
Alibek Omarov
acc113309c Revert "engine: common: net_encode: fix Delta_CompareField to include integer clamping, in case if no updates happen in significant bits"
This reverts commit 6a7b330463.
2023-06-28 14:26:40 +03:00
Alibek Omarov
5afda72290 engine: common: net_encode: simplify Delta_ClampIntegerField 2023-06-28 05:07:53 +03:00
Alibek Omarov
6a7b330463 engine: common: net_encode: fix Delta_CompareField to include integer clamping, in case if no updates happen in significant bits 2023-06-28 04:47:12 +03:00
Alibek Omarov
f5b9826fd9 engine: common: net_encode: directly access delta description struct than searching for it every time 2023-06-27 19:56:32 +03:00
Alibek Omarov
82addf11bb engine: common: net_encode: rewrite Delta_CompareField to be more efficient 2023-06-27 18:06:24 +03:00
Alibek Omarov
aee5e46516 public: rewrite Q_strncpy with standard C functions, make it inlined to allow compiler remove unneeded checks
So far, passes all tests.
2023-06-27 17:30:09 +03:00
Alibek Omarov
40e248aa63 engine: common: remove unused tentlist_t definition 2023-06-27 17:30:09 +03:00
fgsfds
24ee3ae318 scripts: psvita: bump vitaGL version 2023-06-25 18:15:18 +03:00
fgsfds
f79aaf93f8 ref: gl: psvita: disable NPOT textures, they're broken again 2023-06-25 18:15:18 +03:00
Alibek Omarov
0d89849cab public: move some simple functions to mathlib header. Remove assembler version specific for MSVC6 2023-06-25 13:32:06 +03:00
Alibek Omarov
d962255ebe public: mathlib: remove unused RemapVal, ApproachVal 2023-06-25 13:25:51 +03:00
Alibek Omarov
21b47dff32 ref: gl: static-ize globals and functions in gl_warp 2023-06-25 13:17:46 +03:00
Alibek Omarov
1905782c41 3rdparty: vgui_support: update submodule 2023-06-23 06:10:27 +03:00
Alibek Omarov
b29b3d5859 wscript: clarify that higher versions of opus also accepted in a comment 2023-06-21 13:21:19 +03:00
Alibek Omarov
3533b0d284 wscript: check for opus 1.4, which fixes an assertion in custom modes decoder initialize 2023-06-21 13:19:03 +03:00
Alibek Omarov
7e06d049f5 engine: common: static-ize common.c functions, set GAME_EXPORT to API functions 2023-06-20 14:19:44 +03:00
Alibek Omarov
5a4c443c79 filesystem: fix regression in FS_LoadFile not skipping leading slashes
Earlier it used FS_Open which handles this, but because we don't call
that anymore, just skip it ourselves for compatibility.
2023-06-20 14:11:55 +03:00
Alibek Omarov
4bbd1e59a4 engine: server: static-ize world functions 2023-06-19 07:47:38 +03:00
Alibek Omarov
0809453b2c engine: server: static-ize sv_query functions 2023-06-19 07:39:00 +03:00
Alibek Omarov
8350d81c18 engine: server: static-ize sv_pmove functions 2023-06-19 07:38:18 +03:00
Alibek Omarov
57499dea33 engine: server: static-ize sv_phys functions, set GAME_EXPORT attribute for PhysicAPI functions 2023-06-19 07:32:22 +03:00
Alibek Omarov
6b223f1325 engine: server: static-ize functions in sv_game. Set GAME_EXPORT attribute to server GameAPI functions 2023-06-19 07:11:49 +03:00
Alibek Omarov
03a85e0caa engine: platform: psvita: add unused data to workaround bug in vita-elf-create (thanks @fgsfdsfgs) 2023-06-18 22:49:44 +03:00
Alibek Omarov
01ad3dda2a engine: server: escape rcon arguments before passing it to command buffer, also use more efficient concatenation 2023-06-18 04:44:28 +03:00
Alibek Omarov
2a05624615 engine: server: keep silence in case of unset or invalid rcon password 2023-06-18 04:30:21 +03:00
Alibek Omarov
f3ed9b21c0 scripts: add sample systemd service 2023-06-16 08:47:25 +03:00
Alibek Omarov
16c87ae2c9 engine: platform: reorganize UpdateStatusLine, make it shared but implemented only if platform has SetStatus. Implement SetStatus for systemd/Linux 2023-06-16 08:43:16 +03:00
Alibek Omarov
c16a10e6f3 engine: platform: refactor Platform_Init/Shutdown/GetNativeObject functions. They are now defined in the header, and call platform-specific functios that defined in platform code 2023-06-16 07:32:19 +03:00
Alibek Omarov
c7d748e8df engine: server: add sv_log_outofband cvar that controls whether connectionless packets should be printed or not 2023-06-16 07:19:17 +03:00
Alibek Omarov
0e16110c3a github: use ubuntu-latest for PSVita and NSwitch CI 2023-06-15 19:26:19 +03:00
Alibek Omarov
c966589a50 engine: server: static-ize few game API functions, set GAME_EXPORT attribute 2023-06-15 19:22:13 +03:00
Alibek Omarov
4c02c25506 engine: server: do not assert if SetFatPVS/PAS were called without active player
Fixes issues with POD-Bot based bots.
2023-06-15 19:17:34 +03:00
Alibek Omarov
a4997d0647 engine: server: port old engine's fullupdate ratelimit, but simplify it 2023-06-15 18:09:59 +03:00
Alibek Omarov
243c3cc80f engine: server: port old engine's userinfo penalty 2023-06-15 04:46:22 +03:00
Alibek Omarov
a8dbec56c3 mainui: update 2023-06-14 01:38:41 +03:00
Alibek Omarov
9c62fa901f engine: server: pregenerate CRC table and testpacket data 2023-06-14 00:35:07 +03:00
Alibek Omarov
996897e30e public: use standard uint32_t in place of dword 2023-06-13 06:57:24 +03:00
Alibek Omarov
93ee5b9446 public: crclib: simplify CRC32_ProcessByte 2023-06-13 06:57:24 +03:00
Alibek Omarov
c0c8119040 public: crclib: rework CRC32 code (thanks to @Mr0maks for implementation) 2023-06-13 06:57:24 +03:00
jeefo
61c75b9809 engine: server: log: use S_USAGE in logaddress for consistency with existing code 2023-06-11 16:28:36 +03:00
jeefo
868d10a842 engine: server: log: allow to disable logaddress without turning off logs completely 2023-06-11 16:28:36 +03:00
jeefo
699f3579fe engine: server: log: fix log off command not disabling logging to console (fixes #1340) 2023-06-11 16:28:36 +03:00
jeefo
873ce0ce48 engine: server: query: A2S_PLAYER response should contain bots and normal players 2023-06-11 14:14:59 +03:00
Alibek Omarov
450f77443d engine: client: ignore some out of band packets if we're not connecting to server 2023-06-11 07:06:01 +03:00
Alibek Omarov
278ff22ba9 engine: server: query: use common SV_GetPlayerCount, fix random styling issues 2023-06-10 02:47:52 +03:00
jeefo
d9ef1d4608 server: implement correct answers to TSourceEngineQuery server queries
* count bots as clients as in goldsrc
* handle source-style packets after xash's built-in packets to not interfere with them
2023-06-10 02:06:45 +03:00
Alibek Omarov
58df771c9e filesystem: implement .pk3dir convention 2023-06-08 22:58:24 +03:00
Alibek Omarov
a6ecc778fc filesystem: dir: fix FS_FixFileCase when empty string is passed. Always append slash to searchpath. 2023-06-08 22:58:24 +03:00
Alibek Omarov
37e890f326 filesystem: make fs_searchpaths completely private to the filesystem core 2023-06-08 22:30:45 +03:00
Alibek Omarov
0d6137ee40 filesystem: make generic archive loading functions (with the exception of WADs). Do not alter global searchpath from archives. 2023-06-08 22:14:30 +03:00
Alibek Omarov
653eb00cc6 filesystem: unify prototypes of archive opening functions 2023-06-08 20:02:48 +03:00
Alibek Omarov
b84aba68fa engine: platform: implement generic GetNativeObject for POSIX systems without SDL2 2023-06-07 04:07:53 +03:00
Alibek Omarov
1855fab80b filesystem: fix Platform_GetNativeObject macro definition 2023-06-06 17:46:38 +03:00
Alibek Omarov
23f1c43282 engine: common: net_buffer: use uint32_t in place of dword 2023-06-06 00:28:23 +03:00
Alibek Omarov
a7c76ac0bf engine: common: net_buffer: use stdint.h types in sizebuf_t reading/writing funcs 2023-06-06 00:26:54 +03:00
Alibek Omarov
26959cd280 engine: common: net_encode: use stdint.h types in Delta_CompareField 2023-06-06 00:20:56 +03:00
Alibek Omarov
1fdf6180e6 engine: platform: sdl: merge required SDL2 platform changes for new Android port from @Velaron's tree 2023-06-05 21:51:59 +03:00
Alibek Omarov
d2237fa144 engine: platform: android: merge new SDL2 based Android port from @Velaron's tree 2023-06-05 21:35:58 +03:00
Alibek Omarov
febdfacbd3 wscript: merge CMakeLists generating tool from Velaron's tree 2023-06-05 21:30:07 +03:00
Alibek Omarov
ef663a8790 engine: partially remove legacy Android port, in preparation of new port merge 2023-06-05 20:30:18 +03:00
Alibek Omarov
ba039b8e71 engine: drop XASH_DYNAMIC_DLADDR 2023-06-05 20:30:18 +03:00
Alibek Omarov
02ce80981c filesystem: update optional funcs interface, add platform-specific GetNativeObject call 2023-06-05 20:30:18 +03:00
Alibek Omarov
a40a325d3c 3rdparty: mainui: update 2023-06-03 03:54:49 +03:00
Alibek Omarov
85cc942a3c wscript: fix Sailfish misdetection 2023-06-02 06:35:51 +03:00
Alibek Omarov
a23e17c6d7 engine: platform: sdl: set QtWayland hints 2023-06-02 06:18:47 +03:00
Alibek Omarov
59412f3d92 public: define XASH_MOBILE_PLATFORM by XASH_SAILFISH (defined externally) 2023-06-02 06:18:17 +03:00
Alibek Omarov
0a15cc389d mainui: update 2023-06-02 06:17:14 +03:00
Alibek Omarov
13f8a02cdf wscript: better Sailfish/AuroraOS macros 2023-06-02 06:16:40 +03:00
Alibek Omarov
8caa2d142f scripts: sailfish: initial SailfishOS support 2023-06-02 05:37:13 +03:00
Alibek Omarov
3b8009917a 3rdparty: upgrade GL wrappers submodules 2023-06-02 04:10:24 +03:00
Alibek Omarov
e2e14945e4 contrib: delete outdated files 2023-06-02 00:28:31 +03:00
Alibek Omarov
16595bf2c0 ref: gl: fix r_showhull check 2023-05-29 14:42:16 +03:00
Alibek Omarov
f49a2bc8f3 engine: server: move pfnWriteString character replacement hack to the ALLOC_STRING, the same way as GoldSrc does 2023-05-29 14:40:54 +03:00
Alibek Omarov
d994c6df9a ref: a bit more verbosity if UserTracer color exceed limit 2023-05-27 22:06:33 +03:00
Alibek Omarov
3a57f26351 ref: gl: move ref_gl cvars to static allocation 2023-05-27 21:52:58 +03:00
Alibek Omarov
7fd1534753 engine: common: cvar: remove unused CVAR_TO_BOOL macro 2023-05-27 21:52:58 +03:00
Alibek Omarov
bd52a9ec2d engine: platform: linux: move evdev_keydebug cvar to static allocation 2023-05-27 21:52:58 +03:00
Alibek Omarov
9e0d389d9e engine: server: moved server cvars to static allocation 2023-05-27 21:52:58 +03:00
Alibek Omarov
8680757844 ref: soft: move ref_soft cvars to static allocation, remove dead cvars 2023-05-27 21:52:58 +03:00
Alibek Omarov
95a8d2f51f ref: soft: attempt to fix freeze in decals on software renderer 2023-05-27 21:52:58 +03:00
Alibek Omarov
70b26a13c2 engine: allow ref dlls to use convar_t 2023-05-27 21:52:58 +03:00
Alibek Omarov
6a1f96a2c6 engine: always unlink variables and commands BEFORE all pointers to them would be lost 2023-05-27 21:52:58 +03:00
Alibek Omarov
4ce2475602 engine: common: move network cvars to static allocation 2023-05-27 21:52:58 +03:00
Alibek Omarov
e7ece41ba0 engine: common: move model cvars to static allocation 2023-05-27 21:52:58 +03:00
Alibek Omarov
05579927a5 engine: client: sound: move dsp cvars to static allocation 2023-05-27 21:52:58 +03:00
Alibek Omarov
2f5b359c99 engine: client: move tracer cvars to static allocation 2023-05-27 21:52:58 +03:00
Alibek Omarov
214fc7e827 engine: common: move host cvars to static allocation 2023-05-27 21:52:58 +03:00
Alibek Omarov
df173a83ed engine: client: move touch cvars to static allocation 2023-05-27 21:52:58 +03:00
Alibek Omarov
3918bcd71c engine: client: move console cvars to static allocation 2023-05-27 21:52:58 +03:00
Alibek Omarov
f19ed1c1c2 engine: client: move joystick cvars to static allocation 2023-05-27 21:52:58 +03:00
Alibek Omarov
03ec2f603b engine: client: move netgraph cvars to static allocation 2023-05-27 21:52:58 +03:00
Alibek Omarov
1ee01163b7 engine: client: move scrn cvars to static allocation 2023-05-27 21:52:58 +03:00
Alibek Omarov
b1d60c248d engine: client: move main client cvars to static allocation 2023-05-27 21:52:58 +03:00
Alibek Omarov
d9cbf1fa89 engine: client: move input cvars to static allocation 2023-05-27 21:52:58 +03:00
Alibek Omarov
cd022bdac7 engine: client: move keys cvars to static allocation 2023-05-27 21:52:58 +03:00
Alibek Omarov
5d7d5319fd engine: move ref cvars to static allocation 2023-05-27 21:52:58 +03:00
Alibek Omarov
d4470402ee engine: move vid cvars to static allocation 2023-05-27 21:52:58 +03:00
Alibek Omarov
05560c7607 engine: always read and set vid_fullscreen value directly with it's object 2023-05-27 21:52:58 +03:00
Alibek Omarov
81c752da2b filesystem: wad: static-ize WAD functions 2023-05-27 20:51:00 +03:00
Alibek Omarov
fd2ad447a8 filesystem: zip: static-ize ZIP functions 2023-05-27 20:49:06 +03:00
Alibek Omarov
18d55c1de2 filesystem: zip: adapt to new interface 2023-05-27 20:48:48 +03:00
Alibek Omarov
d0d09c878f filesystem: wad: adapt to new interface 2023-05-27 20:47:49 +03:00
Alibek Omarov
e791d44dd8 filesystem: properly support compressed archives in FS_LoadFile 2023-05-27 20:46:48 +03:00
Alibek Omarov
152f6d154c filesystem: remove unused argument from FS_CheckNastyPath 2023-05-27 20:22:12 +03:00
Alibek Omarov
5627dbbf34 engine: server: greatly simplify pfnWriteString implementation, it shouldn't modify input string 2023-05-27 20:02:09 +03:00
Alibek Omarov
9cd9744407 filesystem: fix Windows build 2023-05-27 19:40:44 +03:00
Alibek Omarov
f13c285287 filesystem: verbose error printing in FS_SetCurrentDirectory, move error reporting from engine 2023-05-26 22:29:34 +03:00
Alibek Omarov
cca7744f1c filesystem: make some calls from API safe to use without initialize 2023-05-26 18:31:00 +03:00
Alibek Omarov
31ae22961b filesystem: add base test case to call ShutdownStdio without calling Init prior 2023-05-26 18:30:13 +03:00
Alibek Omarov
a3603f497d scripts: waifulib: compiler_optimizations: fix -march applying on x86_64 toolchains forced to compile in 32-bit mode 2023-05-24 04:30:28 +03:00
Alibek Omarov
d36cb62a2e mainui: update 2023-05-24 04:25:25 +03:00
Alibek Omarov
2ca6029e03 Revert "github: don't wait for flatpak build finish, it's broken for us anyway"
This reverts commit eb61bcf76a.
2023-05-24 04:24:55 +03:00
Alibek Omarov
dee5cae5f3 scripts: waifulib: compiler_optimizations: set pentium-m minimum cpu requirement for Intel 32-bits, like HLSDK 2023-05-24 04:19:08 +03:00
Alibek Omarov
ef4bc2acf2 scripts: flatpak: try to fix flatpak build on GitHub Actions 2023-05-24 04:18:33 +03:00
Alibek Omarov
eb61bcf76a github: don't wait for flatpak build finish, it's broken for us anyway 2023-05-24 03:52:38 +03:00
Alibek Omarov
cb43df43ef engine: common: cvar: do not check if cvar was registered in DirectSet when it has valid next pointer 2023-05-24 03:51:16 +03:00
Alibek Omarov
356f78ee81 engine: platform: sdl: fix possible buffer overrun in SDL port audio code 2023-05-24 03:49:13 +03:00
Alibek Omarov
275cd73ade engine: server: do not trigger speedhack detection for fakeclients 2023-05-24 00:36:54 +03:00
Velaron
bb1b9dad23 ref: gl: Goldsrc compatible fog implementation 2023-05-20 23:36:04 +03:00
Velaron
e27ac6b092 platform: win32: properly change icon 2023-05-20 23:32:19 +03:00
Alibek Omarov
7333ddc1d9 engine: client: move some RenderAPI GetParm queries to engine 2023-05-19 05:03:25 +03:00
Alibek Omarov
fbd7d8f58a engine: server: use sv_speedhack_kick cvar value as a number of speedhack warns before automatic kick
Thanks to @tyabus for suggestion
2023-05-19 04:49:29 +03:00
Alibek Omarov
3415185dde engine: server: implement simple anti-speedhack 2023-05-19 04:44:42 +03:00
Alibek Omarov
551ea71906 engine: server: make generic function to kick players with a reason 2023-05-19 04:44:42 +03:00
Alibek Omarov
1d965d7543 ref: gl: ignore GenTextures objects that fall into reserved space for skyboxes 2023-05-19 04:37:53 +03:00
Alibek Omarov
1d62df0e2d ref: gl: turn magic skybox numbers into defined macros 2023-05-19 04:36:05 +03:00
Alibek Omarov
b0f52236bc engine: platform: psvita: use _impure_ptr declaration from sys/reent.h 2023-05-17 17:45:17 +03:00
Alibek Omarov
7dcddc559c engine: platform: sdl: set PulseAudio role only on POSIX systems 2023-05-17 17:38:18 +03:00
Alibek Omarov
277bead9b7 ref: remove SetCullState function from StudioAPI. It does nothing on GoldSrc. 2023-05-17 17:23:35 +03:00
Alibek Omarov
d8093ec587 engine: platform: psvita: attempt to fix PSVita builds by exporting _impure_ptr 2023-05-17 17:17:25 +03:00
Alibek Omarov
323626c308 engine: platform: sdl: try to avoid random crash in SDL pulse audio driver 2023-05-17 05:02:12 +03:00
Alibek Omarov
68ff265e8d ref: gl: switch texture object allocation to GenTextures usage
This should fix most overlay programs but I only tested it on MangoHud
2023-05-16 23:47:05 +03:00
Alibek Omarov
a3ab04e0cb ref: gl: track current bound texture index in gl_textures array in separate glState field 2023-05-16 23:44:52 +03:00
Alibek Omarov
7d2bf93c72 engine: client: voice: do not reinitialize voice with same parameters 2023-05-15 17:48:15 +03:00
Alibek Omarov
04107d384e engine: client: fix incorrectly parsed timings for TE_TEXTMESSAGE 2023-05-15 02:11:44 +03:00
Alibek Omarov
3a0f1763fb engine: whereami: update from our downstream fork (only cosmetic changes) 2023-05-15 01:51:14 +03:00
Alibek Omarov
377dd9a255 engine: client: bring back NetAPI infostring options, as they conform to the API definitions 2023-05-14 12:24:40 +03:00
Alibek Omarov
8961e37d7c github: update flatpak-builder action to latest version 2023-05-14 12:10:39 +03:00
Alibek Omarov
de1e53311a engine: client: cl_game: static-ize engine functions in client API 2023-05-14 12:10:14 +03:00
Alibek Omarov
19582cdf11 engine: simplify force version drawing logic 2023-05-14 09:50:17 +03:00
Alibek Omarov
fa0e7e4369 scripts: enable LTO for Linux builds too 2023-05-14 09:49:39 +03:00
Alibek Omarov
2378331e47 wscript: enable -Werror=unsequenced, Clang's analogue of -Werror=sequence-point 2023-05-14 09:39:15 +03:00
Alibek Omarov
5549e7301c scripts: gha: win32: enable LTO by default 2023-05-14 09:36:46 +03:00
Alibek Omarov
5ab7d09a00 scripts: waifulib: compiler_optimizations: allow -fno-semantic-interposition for GCC (less overhead on PIC binaries) 2023-05-14 09:35:00 +03:00
Alibek Omarov
c54e1625d1 scripts: waifulib: compiler_optimizations: fixes for LTO 2023-05-14 09:34:29 +03:00
Alibek Omarov
d0127e5e14 filesystem: fix FS_GetDiskPath, it was broken since implementing caseinsensitive emulation, oops
Anyway, FS_GetFullDiskPath is a proper safe version that lacks this bug
2023-05-14 08:21:17 +03:00
Andrey Akhmichin
0f643f1f87 Documentation: opensource-mods.md: update link to "bubblemod". 2023-05-13 23:19:30 +03:00
Andrey Akhmichin
16eb12b1e0 Documentation: opensource-mods.md: add "HL: Rally". 2023-05-13 23:19:30 +03:00
Alibek Omarov
4856a3c084 Revert "engine: soundlib: wav: attempt to make FindNextChunk more safe"
This reverts commit 78e239d883.
2023-05-05 21:19:58 +03:00
240 changed files with 11152 additions and 9967 deletions

View File

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

View File

@@ -13,6 +13,8 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
include: include:
# Linux build specifically want oldest Ubuntu as possible
# to be crossdistribution compatible, otherwise use ubuntu-latest
- os: ubuntu-20.04 - os: ubuntu-20.04
targetos: linux targetos: linux
targetarch: amd64 targetarch: amd64
@@ -34,10 +36,10 @@ jobs:
# targetos: motomagx # targetos: motomagx
# targetarch: armv6 # targetarch: armv6
- os: ubuntu-20.04 - os: ubuntu-latest
targetos: nswitch targetos: nswitch
targetarch: arm64 targetarch: arm64
- os: ubuntu-20.04 - os: ubuntu-latest
targetos: psvita targetos: psvita
targetarch: armv7hf targetarch: armv7hf
- os: windows-latest - os: windows-latest
@@ -47,7 +49,7 @@ jobs:
targetos: win32 targetos: win32
targetarch: i386 targetarch: i386
env: env:
SDL_VERSION: 2.26.2 SDL_VERSION: 2.28.1
GH_CPU_ARCH: ${{ matrix.targetarch }} GH_CPU_ARCH: ${{ matrix.targetarch }}
ANDROID_SDK_TOOLS_VER: 4333796 ANDROID_SDK_TOOLS_VER: 4333796
steps: steps:
@@ -80,7 +82,7 @@ jobs:
with: with:
submodules: recursive submodules: recursive
- name: Build flatpak (Compat.i386) - name: Build flatpak (Compat.i386)
uses: FWGS/flatpak-github-actions/flatpak-builder@v5 uses: FWGS/flatpak-github-actions/flatpak-builder@v6.1
with: with:
bundle: ${{ matrix.app }}.flatpak bundle: ${{ matrix.app }}.flatpak
manifest-path: scripts/flatpak/${{ matrix.app }}.yml manifest-path: scripts/flatpak/${{ matrix.app }}.yml

4
.gitignore vendored
View File

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

24
Documentation/donate.md Normal file
View File

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

116
Documentation/gameinfo.md Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -57,6 +57,7 @@ typedef uint64_t longtime_t;
#define MAX_USERMSG_LENGTH 2048 // don't modify it's relies on a client-side definitions #define MAX_USERMSG_LENGTH 2048 // don't modify it's relies on a client-side definitions
#define BIT( n ) ( 1U << ( n )) #define BIT( n ) ( 1U << ( n ))
#define BIT64( n ) ( 1ULL << ( n ))
#define GAMMA ( 2.2f ) // Valve Software gamma #define GAMMA ( 2.2f ) // Valve Software gamma
#define INVGAMMA ( 1.0f / 2.2f ) // back to 1.0 #define INVGAMMA ( 1.0f / 2.2f ) // back to 1.0
#define TEXGAMMA ( 0.9f ) // compensate dim textures #define TEXGAMMA ( 0.9f ) // compensate dim textures
@@ -86,16 +87,19 @@ typedef uint64_t longtime_t;
#endif #endif
#define _format(x) __attribute__((format(printf, x, x+1))) #define _format(x) __attribute__((format(printf, x, x+1)))
#define NORETURN __attribute__((noreturn)) #define NORETURN __attribute__((noreturn))
#define NONNULL __attribute__((nonnull))
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
#define EXPORT __declspec( dllexport ) #define EXPORT __declspec( dllexport )
#define GAME_EXPORT #define GAME_EXPORT
#define _format(x) #define _format(x)
#define NORETURN #define NORETURN
#define NONNULL
#else #else
#define EXPORT #define EXPORT
#define GAME_EXPORT #define GAME_EXPORT
#define _format(x) #define _format(x)
#define NORETURN #define NORETURN
#define NONNULL
#endif #endif
#if ( __GNUC__ >= 3 ) #if ( __GNUC__ >= 3 )
@@ -177,6 +181,7 @@ typedef struct dll_info_s
} dll_info_t; } dll_info_t;
typedef void (*setpair_t)( const char *key, const void *value, const void *buffer, void *numpairs ); typedef void (*setpair_t)( const char *key, const void *value, const void *buffer, void *numpairs );
typedef void *(*pfnCreateInterface_t)( const char *, int * );
// config strings are a general means of communication from // config strings are a general means of communication from
// the server to all connected clients. // the server to all connected clients.

View File

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

View File

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

View File

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

View File

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

View File

@@ -85,6 +85,12 @@ void CL_PlayCDTrack_f( void )
paused = false; paused = false;
looped = false; looped = false;
} }
else if( !Q_stricmp( command, "playfile" ))
{
S_StartBackgroundTrack( pszTrack, NULL, 0, true );
paused = false;
looped = false;
}
else if( !Q_stricmp( command, "loop" )) else if( !Q_stricmp( command, "loop" ))
{ {
if( Q_isdigit( pszTrack )) if( Q_isdigit( pszTrack ))
@@ -96,6 +102,12 @@ void CL_PlayCDTrack_f( void )
paused = false; paused = false;
looped = true; looped = true;
} }
else if( !Q_stricmp( command, "loopfile" ))
{
S_StartBackgroundTrack( pszTrack, pszTrack, 0, true );
paused = false;
looped = true;
}
else if( !Q_stricmp( command, "pause" )) else if( !Q_stricmp( command, "pause" ))
{ {
S_StreamSetPause( true ); S_StreamSetPause( true );
@@ -206,7 +218,7 @@ void CL_ScreenShot_f( void )
if( !CL_ScreenshotGetName( i, checkname, sizeof( checkname ))) if( !CL_ScreenshotGetName( i, checkname, sizeof( checkname )))
return; // no namespace return; // no namespace
if( !FS_FileExists( checkname, false )) if( !FS_FileExists( checkname, true ))
break; break;
} }
@@ -246,7 +258,7 @@ void CL_SnapShot_f( void )
if( !CL_SnapshotGetName( i, checkname, sizeof( checkname ))) if( !CL_SnapshotGetName( i, checkname, sizeof( checkname )))
return; // no namespace return; // no namespace
if( !FS_FileExists( checkname, false )) if( !FS_FileExists( checkname, true ))
break; break;
} }

View File

@@ -372,7 +372,7 @@ void CL_WriteDemoHeader( const char *name )
demo.header.id = IDEMOHEADER; demo.header.id = IDEMOHEADER;
demo.header.dem_protocol = DEMO_PROTOCOL; demo.header.dem_protocol = DEMO_PROTOCOL;
demo.header.net_protocol = cls.legacymode ? PROTOCOL_LEGACY_VERSION : PROTOCOL_VERSION; demo.header.net_protocol = cls.legacymode ? PROTOCOL_LEGACY_VERSION : PROTOCOL_VERSION;
demo.header.host_fps = bound( MIN_FPS, host_maxfps->value, MAX_FPS ); demo.header.host_fps = bound( MIN_FPS, host_maxfps.value, MAX_FPS );
Q_strncpy( demo.header.mapname, clgame.mapname, sizeof( demo.header.mapname )); Q_strncpy( demo.header.mapname, clgame.mapname, sizeof( demo.header.mapname ));
Q_strncpy( demo.header.comment, clgame.maptitle, sizeof( demo.header.comment )); Q_strncpy( demo.header.comment, clgame.maptitle, sizeof( demo.header.comment ));
Q_strncpy( demo.header.gamedir, FS_Gamedir(), sizeof( demo.header.gamedir )); Q_strncpy( demo.header.gamedir, FS_Gamedir(), sizeof( demo.header.gamedir ));
@@ -648,11 +648,13 @@ void CL_DemoStartPlayback( int mode )
{ {
if( cls.changedemo ) if( cls.changedemo )
{ {
int maxclients = cl.maxclients;
S_StopAllSounds( true ); S_StopAllSounds( true );
SCR_BeginLoadingPlaque( false ); SCR_BeginLoadingPlaque( false );
CL_ClearState (); CL_ClearState( );
CL_InitEdicts (); // re-arrange edicts CL_InitEdicts( maxclients ); // re-arrange edicts
} }
else else
{ {
@@ -698,7 +700,7 @@ void CL_DemoAborted( void )
cls.demofile = NULL; cls.demofile = NULL;
cls.demonum = -1; cls.demonum = -1;
Cvar_SetValue( "v_dark", 0.0f ); Cvar_DirectSet( &v_dark, "0" );
} }
/* /*
@@ -716,7 +718,7 @@ void CL_DemoCompleted( void )
if( !CL_NextDemo() && !cls.changedemo ) if( !CL_NextDemo() && !cls.changedemo )
UI_SetActiveMenu( true ); UI_SetActiveMenu( true );
Cvar_SetValue( "v_dark", 0.0f ); Cvar_DirectSet( &v_dark, "0" );
} }
/* /*
@@ -1122,7 +1124,10 @@ void CL_FinishTimeDemo( void )
time = host.realtime - cls.td_starttime; time = host.realtime - cls.td_starttime;
if( !time ) time = 1.0; if( !time ) time = 1.0;
Con_Printf( "%i frames %5.3f seconds %5.3f fps\n", frames, time, frames / time ); Con_Printf( "timedemo result: %i frames %5.3f seconds %5.3f fps\n", frames, time, frames / time );
if( Sys_CheckParm( "-timedemo" ))
CL_Quit_f();
} }
/* /*
@@ -1306,7 +1311,7 @@ void CL_CheckStartupDemos( void )
} }
// run demos loop in background mode // run demos loop in background mode
Cvar_SetValue( "v_dark", 1.0f ); Cvar_DirectSet( &v_dark, "1" );
cls.demos_pending = false; cls.demos_pending = false;
cls.demonum = 0; cls.demonum = 0;
CL_NextDemo (); CL_NextDemo ();
@@ -1322,11 +1327,11 @@ static void CL_DemoGetName( int lastnum, char *filename, size_t size )
if( lastnum < 0 || lastnum > 9999 ) if( lastnum < 0 || lastnum > 9999 )
{ {
// bound // bound
Q_strncpy( filename, "demo9999.dem", size ); Q_strncpy( filename, "demo9999", size );
return; return;
} }
Q_snprintf( filename, size, "demo%04d.dem", lastnum ); Q_snprintf( filename, size, "demo%04d", lastnum );
} }
/* /*
@@ -1381,7 +1386,9 @@ void CL_Record_f( void )
for( n = 0; n < 10000; n++ ) for( n = 0; n < 10000; n++ )
{ {
CL_DemoGetName( n, demoname, sizeof( demoname )); CL_DemoGetName( n, demoname, sizeof( demoname ));
if( !FS_FileExists( demoname, true )) Q_snprintf( demopath, sizeof( demopath ), "%s.dem", demoname );
if( !FS_FileExists( demopath, true ))
break; break;
} }
@@ -1468,7 +1475,7 @@ void CL_PlayDemo_f( void )
{ {
int c, neg = false; int c, neg = false;
demo.header.host_fps = host_maxfps->value; demo.header.host_fps = host_maxfps.value;
while(( c = FS_Getc( cls.demofile )) != '\n' ) while(( c = FS_Getc( cls.demofile )) != '\n' )
{ {

View File

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

View File

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

View File

@@ -134,7 +134,7 @@ some ents will be ignore lerping
*/ */
qboolean CL_EntityIgnoreLerp( cl_entity_t *e ) qboolean CL_EntityIgnoreLerp( cl_entity_t *e )
{ {
if( cl_nointerp->value > 0.f ) if( cl_nointerp.value > 0.f )
return true; return true;
if( e->model && e->model->type == mod_alias ) if( e->model && e->model->type == mod_alias )
@@ -464,13 +464,13 @@ int CL_InterpolateModel( cl_entity_t *e )
if( cl.maxclients <= 1 ) if( cl.maxclients <= 1 )
return 1; return 1;
if( e->model->type == mod_brush && !cl_bmodelinterp->value ) if( e->model->type == mod_brush && !cl_bmodelinterp.value )
return 1; return 1;
if( cl.local.moving && cl.local.onground == e->index ) if( cl.local.moving && cl.local.onground == e->index )
return 1; return 1;
t = cl.time - cl_interp->value; t = cl.time - cl_interp.value;
CL_FindInterpolationUpdates( e, t, &ph0, &ph1 ); CL_FindInterpolationUpdates( e, t, &ph0, &ph1 );
if( ph0 == NULL || ph1 == NULL ) if( ph0 == NULL || ph1 == NULL )
@@ -537,7 +537,7 @@ void CL_ComputePlayerOrigin( cl_entity_t *ent )
if( !ent->player ) if( !ent->player )
return; return;
if( cl_nointerp->value > 0.f ) if( cl_nointerp.value > 0.f )
{ {
VectorCopy( ent->curstate.angles, ent->angles ); VectorCopy( ent->curstate.angles, ent->angles );
VectorCopy( ent->curstate.origin, ent->origin ); VectorCopy( ent->curstate.origin, ent->origin );
@@ -555,7 +555,7 @@ void CL_ComputePlayerOrigin( cl_entity_t *ent )
return; return;
} }
targettime = cl.time - cl_interp->value; targettime = cl.time - cl_interp.value;
CL_PureOrigin( ent, targettime, origin, angles ); CL_PureOrigin( ent, targettime, origin, angles );
VectorCopy( angles, ent->angles ); VectorCopy( angles, ent->angles );

View File

@@ -154,7 +154,7 @@ CL_CreatePlaylist
Create a default valve playlist Create a default valve playlist
==================== ====================
*/ */
void CL_CreatePlaylist( const char *filename ) static void CL_CreatePlaylist( const char *filename )
{ {
file_t *f; file_t *f;
@@ -458,7 +458,7 @@ void CL_DrawCenterPrint( void )
if( !clgame.centerPrint.time ) if( !clgame.centerPrint.time )
return; return;
if(( cl.time - clgame.centerPrint.time ) >= scr_centertime->value ) if(( cl.time - clgame.centerPrint.time ) >= scr_centertime.value )
{ {
// time expired // time expired
clgame.centerPrint.time = 0.0f; clgame.centerPrint.time = 0.0f;
@@ -665,12 +665,12 @@ void CL_ParseTextMessage( sizebuf_t *msg )
text->g2 = MSG_ReadByte( msg ); text->g2 = MSG_ReadByte( msg );
text->b2 = MSG_ReadByte( msg ); text->b2 = MSG_ReadByte( msg );
text->a2 = MSG_ReadByte( msg ); text->a2 = MSG_ReadByte( msg );
text->fadein = (float)(MSG_ReadShort( msg ) / 256.0f ); text->fadein = (float)(MSG_ReadWord( msg ) / 256.0f );
text->fadeout = (float)(MSG_ReadShort( msg ) / 256.0f ); text->fadeout = (float)(MSG_ReadWord( msg ) / 256.0f );
text->holdtime = (float)(MSG_ReadShort( msg ) / 256.0f ); text->holdtime = (float)(MSG_ReadWord( msg ) / 256.0f );
if( text->effect == 2 ) if( text->effect == 2 )
text->fxtime = (float)(MSG_ReadShort( msg ) / 256.0f ); text->fxtime = (float)(MSG_ReadWord( msg ) / 256.0f );
else text->fxtime = 0.0f; else text->fxtime = 0.0f;
// to prevent grab too long messages // to prevent grab too long messages
@@ -914,7 +914,7 @@ void CL_DrawCrosshair( void )
int x, y, width, height; int x, y, width, height;
float xscale, yscale; float xscale, yscale;
if( !clgame.ds.pCrosshair || !cl_crosshair->value ) if( !clgame.ds.pCrosshair || !cl_crosshair.value )
return; return;
// any camera on or client is died // any camera on or client is died
@@ -1088,13 +1088,13 @@ void CL_ClearWorld( void )
clgame.numStatics = 0; clgame.numStatics = 0;
} }
void CL_InitEdicts( void ) void CL_InitEdicts( int maxclients )
{ {
Assert( clgame.entities == NULL ); Assert( clgame.entities == NULL );
if( !clgame.mempool ) return; // Host_Error without client if( !clgame.mempool ) return; // Host_Error without client
#if XASH_LOW_MEMORY != 2 #if XASH_LOW_MEMORY != 2
CL_UPDATE_BACKUP = ( cl.maxclients <= 1 ) ? SINGLEPLAYER_BACKUP : MULTIPLAYER_BACKUP; CL_UPDATE_BACKUP = ( maxclients <= 1 ) ? SINGLEPLAYER_BACKUP : MULTIPLAYER_BACKUP;
#endif #endif
cls.num_client_entities = CL_UPDATE_BACKUP * NUM_PACKET_ENTITIES; cls.num_client_entities = CL_UPDATE_BACKUP * NUM_PACKET_ENTITIES;
cls.packet_entities = Mem_Realloc( clgame.mempool, cls.packet_entities, sizeof( entity_state_t ) * cls.num_client_entities ); cls.packet_entities = Mem_Realloc( clgame.mempool, cls.packet_entities, sizeof( entity_state_t ) * cls.num_client_entities );
@@ -1140,7 +1140,7 @@ void CL_ClearEdicts( void )
// in case we stopped with error // in case we stopped with error
clgame.maxEntities = 2; clgame.maxEntities = 2;
CL_InitEdicts(); CL_InitEdicts( cl.maxclients );
} }
/* /*
@@ -1320,6 +1320,7 @@ HSPRITE pfnSPR_LoadExt( const char *szPicName, uint texFlags )
========= =========
pfnSPR_Load pfnSPR_Load
function exported for support GoldSrc Monitor utility
========= =========
*/ */
HSPRITE EXPORT pfnSPR_Load( const char *szPicName ) HSPRITE EXPORT pfnSPR_Load( const char *szPicName )
@@ -1338,7 +1339,7 @@ CL_GetSpritePointer
============= =============
*/ */
const model_t *CL_GetSpritePointer( HSPRITE hSprite ) static const model_t *CL_GetSpritePointer( HSPRITE hSprite )
{ {
model_t *mod; model_t *mod;
int index = hSprite - 1; int index = hSprite - 1;
@@ -1368,6 +1369,7 @@ const model_t *CL_GetSpritePointer( HSPRITE hSprite )
========= =========
pfnSPR_Frames pfnSPR_Frames
function exported for support GoldSrc Monitor utility
========= =========
*/ */
int EXPORT pfnSPR_Frames( HSPRITE hPic ) int EXPORT pfnSPR_Frames( HSPRITE hPic )
@@ -1630,14 +1632,14 @@ get actual screen info
*/ */
int GAME_EXPORT CL_GetScreenInfo( SCREENINFO *pscrinfo ) int GAME_EXPORT CL_GetScreenInfo( SCREENINFO *pscrinfo )
{ {
float scale_factor = hud_scale->value; float scale_factor = hud_scale.value;
if( FBitSet( hud_fontscale->flags, FCVAR_CHANGED )) if( FBitSet( hud_fontscale.flags, FCVAR_CHANGED ))
{ {
CL_FreeFont( &cls.creditsFont ); CL_FreeFont( &cls.creditsFont );
SCR_LoadCreditsFont(); SCR_LoadCreditsFont();
ClearBits( hud_fontscale->flags, FCVAR_CHANGED ); ClearBits( hud_fontscale.flags, FCVAR_CHANGED );
} }
// setup screen info // setup screen info
@@ -1685,6 +1687,22 @@ static void GAME_EXPORT pfnSetCrosshair( HSPRITE hspr, wrect_t rc, int r, int g,
clgame.ds.rcCrosshair = rc; clgame.ds.rcCrosshair = rc;
} }
/*
=============
pfnCvar_RegisterVariable
=============
*/
static cvar_t *GAME_EXPORT pfnCvar_RegisterClientVariable( const char *szName, const char *szValue, int flags )
{
// a1ba: try to mitigate outdated client.dll vulnerabilities
if( !Q_stricmp( szName, "motdfile" ))
flags |= FCVAR_PRIVILEGED;
return (cvar_t *)Cvar_Get( szName, szValue, flags|FCVAR_CLIENTDLL, Cvar_BuildAutoDescription( szName, flags|FCVAR_CLIENTDLL ));
}
/* /*
============= =============
pfnHookUserMsg pfnHookUserMsg
@@ -1889,7 +1907,7 @@ static int GAME_EXPORT pfnDrawCharacter( int x, int y, int number, int r, int g,
rgba_t color = { r, g, b, 255 }; rgba_t color = { r, g, b, 255 };
int flags = FONT_DRAW_HUD; int flags = FONT_DRAW_HUD;
if( hud_utf8->value ) if( hud_utf8.value )
flags |= FONT_DRAW_UTF8; flags |= FONT_DRAW_UTF8;
return CL_DrawCharacter( x, y, number, color, &cls.creditsFont, flags ); return CL_DrawCharacter( x, y, number, color, &cls.creditsFont, flags );
@@ -1904,7 +1922,7 @@ drawing string like a console string
*/ */
int GAME_EXPORT pfnDrawConsoleString( int x, int y, char *string ) int GAME_EXPORT pfnDrawConsoleString( int x, int y, char *string )
{ {
cl_font_t *font = Con_GetFont( con_fontsize->value ); cl_font_t *font = Con_GetFont( con_fontsize.value );
rgba_t color; rgba_t color;
Vector4Copy( clgame.ds.textColor, color ); Vector4Copy( clgame.ds.textColor, color );
Vector4Set( clgame.ds.textColor, 255, 255, 255, 255 ); Vector4Set( clgame.ds.textColor, 255, 255, 255, 255 );
@@ -1937,7 +1955,7 @@ compute string length in screen pixels
*/ */
void GAME_EXPORT pfnDrawConsoleStringLen( const char *pText, int *length, int *height ) void GAME_EXPORT pfnDrawConsoleStringLen( const char *pText, int *length, int *height )
{ {
cl_font_t *font = Con_GetFont( con_fontsize->value ); cl_font_t *font = Con_GetFont( con_fontsize.value );
if( height ) *height = font->charHeight; if( height ) *height = font->charHeight;
CL_DrawStringLen( font, pText, length, NULL, FONT_DRAW_UTF8 | FONT_DRAW_HUD ); CL_DrawStringLen( font, pText, length, NULL, FONT_DRAW_UTF8 | FONT_DRAW_HUD );
@@ -1985,7 +2003,7 @@ static int GAME_EXPORT pfnGetWindowCenterX( void )
{ {
int x = 0; int x = 0;
#if XASH_WIN32 #if XASH_WIN32
if( m_ignore->value ) if( m_ignore.value )
{ {
POINT pos; POINT pos;
GetCursorPos( &pos ); GetCursorPos( &pos );
@@ -2010,7 +2028,7 @@ static int GAME_EXPORT pfnGetWindowCenterY( void )
{ {
int y = 0; int y = 0;
#if XASH_WIN32 #if XASH_WIN32
if( m_ignore->value ) if( m_ignore.value )
{ {
POINT pos; POINT pos;
GetCursorPos( &pos ); GetCursorPos( &pos );
@@ -2122,7 +2140,7 @@ pfnCalcShake
============= =============
*/ */
void GAME_EXPORT pfnCalcShake( void ) static void GAME_EXPORT pfnCalcShake( void )
{ {
screen_shake_t *const shake = &clgame.shake; screen_shake_t *const shake = &clgame.shake;
float frametime, fraction, freq; float frametime, fraction, freq;
@@ -2178,7 +2196,7 @@ pfnApplyShake
============= =============
*/ */
void GAME_EXPORT pfnApplyShake( float *origin, float *angles, float factor ) static void GAME_EXPORT pfnApplyShake( float *origin, float *angles, float factor )
{ {
if( origin ) if( origin )
VectorMA( origin, factor, clgame.shake.applied_offset, origin ); VectorMA( origin, factor, clgame.shake.applied_offset, origin );
@@ -2306,7 +2324,7 @@ pfnPlaySound
============= =============
*/ */
void GAME_EXPORT pfnPlaySound( int ent, float *org, int chan, const char *samp, float vol, float attn, int flags, int pitch ) static void GAME_EXPORT pfnPlaySound( int ent, float *org, int chan, const char *samp, float vol, float attn, int flags, int pitch )
{ {
S_StartSound( org, ent, chan, S_RegisterSound( samp ), vol, attn, pitch, flags ); S_StartSound( org, ent, chan, S_RegisterSound( samp ), vol, attn, pitch, flags );
} }
@@ -2317,7 +2335,7 @@ CL_FindModelIndex
============= =============
*/ */
int GAME_EXPORT CL_FindModelIndex( const char *m ) static int GAME_EXPORT CL_FindModelIndex( const char *m )
{ {
char filepath[MAX_QPATH]; char filepath[MAX_QPATH];
static float lasttimewarn; static float lasttimewarn;
@@ -2354,7 +2372,7 @@ pfnIsLocal
============= =============
*/ */
int GAME_EXPORT pfnIsLocal( int playernum ) static int GAME_EXPORT pfnIsLocal( int playernum )
{ {
if( playernum == cl.playernum ) if( playernum == cl.playernum )
return true; return true;
@@ -2367,7 +2385,7 @@ pfnLocalPlayerDucking
============= =============
*/ */
int GAME_EXPORT pfnLocalPlayerDucking( void ) static int GAME_EXPORT pfnLocalPlayerDucking( void )
{ {
return (cl.local.usehull == 1) ? true : false; return (cl.local.usehull == 1) ? true : false;
} }
@@ -2378,7 +2396,7 @@ pfnLocalPlayerViewheight
============= =============
*/ */
void GAME_EXPORT pfnLocalPlayerViewheight( float *view_ofs ) static void GAME_EXPORT pfnLocalPlayerViewheight( float *view_ofs )
{ {
if( view_ofs ) VectorCopy( cl.viewheight, view_ofs ); if( view_ofs ) VectorCopy( cl.viewheight, view_ofs );
} }
@@ -2389,7 +2407,7 @@ pfnLocalPlayerBounds
============= =============
*/ */
void GAME_EXPORT pfnLocalPlayerBounds( int hull, float *mins, float *maxs ) static void GAME_EXPORT pfnLocalPlayerBounds( int hull, float *mins, float *maxs )
{ {
if( hull >= 0 && hull < 4 ) if( hull >= 0 && hull < 4 )
{ {
@@ -2404,7 +2422,7 @@ pfnIndexFromTrace
============= =============
*/ */
int GAME_EXPORT pfnIndexFromTrace( struct pmtrace_s *pTrace ) static int GAME_EXPORT pfnIndexFromTrace( struct pmtrace_s *pTrace )
{ {
#if 0 // Velaron: breaks compatibility with mods that call the function after CL_PopPMStates #if 0 // Velaron: breaks compatibility with mods that call the function after CL_PopPMStates
if( pTrace->ent >= 0 && pTrace->ent < clgame.pmove->numphysent ) if( pTrace->ent >= 0 && pTrace->ent < clgame.pmove->numphysent )
@@ -2439,7 +2457,7 @@ pfnGetVisent
============= =============
*/ */
physent_t *pfnGetVisent( int idx ) static physent_t *pfnGetVisent( int idx )
{ {
if( idx >= 0 && idx < clgame.pmove->numvisent ) if( idx >= 0 && idx < clgame.pmove->numvisent )
{ {
@@ -2455,7 +2473,7 @@ pfnSetTraceHull
============= =============
*/ */
void GAME_EXPORT CL_SetTraceHull( int hull ) static void GAME_EXPORT CL_SetTraceHull( int hull )
{ {
clgame.pmove->usehull = bound( 0, hull, 3 ); clgame.pmove->usehull = bound( 0, hull, 3 );
} }
@@ -2466,7 +2484,7 @@ pfnPlayerTrace
============= =============
*/ */
void GAME_EXPORT CL_PlayerTrace( float *start, float *end, int traceFlags, int ignore_pe, pmtrace_t *tr ) static void GAME_EXPORT CL_PlayerTrace( float *start, float *end, int traceFlags, int ignore_pe, pmtrace_t *tr )
{ {
if( !tr ) return; if( !tr ) return;
*tr = PM_PlayerTraceExt( clgame.pmove, start, end, traceFlags, clgame.pmove->numphysent, clgame.pmove->physents, ignore_pe, NULL ); *tr = PM_PlayerTraceExt( clgame.pmove, start, end, traceFlags, clgame.pmove->numphysent, clgame.pmove->physents, ignore_pe, NULL );
@@ -2478,7 +2496,7 @@ pfnPlayerTraceExt
============= =============
*/ */
void GAME_EXPORT CL_PlayerTraceExt( float *start, float *end, int traceFlags, int (*pfnIgnore)( physent_t *pe ), pmtrace_t *tr ) static void GAME_EXPORT CL_PlayerTraceExt( float *start, float *end, int traceFlags, int (*pfnIgnore)( physent_t *pe ), pmtrace_t *tr )
{ {
if( !tr ) return; if( !tr ) return;
*tr = PM_PlayerTraceExt( clgame.pmove, start, end, traceFlags, clgame.pmove->numphysent, clgame.pmove->physents, -1, pfnIgnore ); *tr = PM_PlayerTraceExt( clgame.pmove, start, end, traceFlags, clgame.pmove->numphysent, clgame.pmove->physents, -1, pfnIgnore );
@@ -2523,7 +2541,7 @@ pfnStopAllSounds
============= =============
*/ */
void GAME_EXPORT pfnStopAllSounds( int ent, int entchannel ) static void GAME_EXPORT pfnStopAllSounds( int ent, int entchannel )
{ {
S_StopSound( ent, entchannel, NULL ); S_StopSound( ent, entchannel, NULL );
} }
@@ -2548,7 +2566,7 @@ model_t *CL_LoadModel( const char *modelname, int *index )
return CL_ModelHandle( i ); return CL_ModelHandle( i );
} }
int GAME_EXPORT CL_AddEntity( int entityType, cl_entity_t *pEnt ) static int GAME_EXPORT CL_AddEntity( int entityType, cl_entity_t *pEnt )
{ {
if( !pEnt ) return false; if( !pEnt ) return false;
@@ -2565,7 +2583,7 @@ pfnGetGameDirectory
============= =============
*/ */
const char *pfnGetGameDirectory( void ) static const char *pfnGetGameDirectory( void )
{ {
static char szGetGameDir[MAX_SYSPATH]; static char szGetGameDir[MAX_SYSPATH];
@@ -2579,7 +2597,7 @@ Key_LookupBinding
============= =============
*/ */
const char *Key_LookupBinding( const char *pBinding ) static const char *Key_LookupBinding( const char *pBinding )
{ {
return Key_KeynumToString( Key_GetKey( pBinding )); return Key_KeynumToString( Key_GetKey( pBinding ));
} }
@@ -2610,7 +2628,7 @@ pfnGetScreenFade
============= =============
*/ */
void GAME_EXPORT pfnGetScreenFade( struct screenfade_s *fade ) static void GAME_EXPORT pfnGetScreenFade( struct screenfade_s *fade )
{ {
if( fade ) *fade = clgame.fade; if( fade ) *fade = clgame.fade;
} }
@@ -2632,7 +2650,7 @@ pfnLoadMapSprite
============= =============
*/ */
model_t *pfnLoadMapSprite( const char *filename ) static model_t *pfnLoadMapSprite( const char *filename )
{ {
model_t *mod; model_t *mod;
@@ -2650,7 +2668,7 @@ PlayerInfo_ValueForKey
============= =============
*/ */
const char *PlayerInfo_ValueForKey( int playerNum, const char *key ) static const char *PlayerInfo_ValueForKey( int playerNum, const char *key )
{ {
// find the player // find the player
if(( playerNum > cl.maxclients ) || ( playerNum < 1 )) if(( playerNum > cl.maxclients ) || ( playerNum < 1 ))
@@ -2668,7 +2686,7 @@ PlayerInfo_SetValueForKey
============= =============
*/ */
void GAME_EXPORT PlayerInfo_SetValueForKey( const char *key, const char *value ) static void GAME_EXPORT PlayerInfo_SetValueForKey( const char *key, const char *value )
{ {
convar_t *var; convar_t *var;
@@ -2694,7 +2712,7 @@ pfnGetPlayerUniqueID
============= =============
*/ */
qboolean GAME_EXPORT pfnGetPlayerUniqueID( int iPlayer, char playerID[16] ) static qboolean GAME_EXPORT pfnGetPlayerUniqueID( int iPlayer, char playerID[16] )
{ {
if( iPlayer < 1 || iPlayer > cl.maxclients ) if( iPlayer < 1 || iPlayer > cl.maxclients )
return false; return false;
@@ -2714,7 +2732,7 @@ pfnGetTrackerIDForPlayer
obsolete, unused obsolete, unused
============= =============
*/ */
int GAME_EXPORT pfnGetTrackerIDForPlayer( int playerSlot ) static int GAME_EXPORT pfnGetTrackerIDForPlayer( int playerSlot )
{ {
return 0; return 0;
} }
@@ -2726,7 +2744,7 @@ pfnGetPlayerForTrackerID
obsolete, unused obsolete, unused
============= =============
*/ */
int GAME_EXPORT pfnGetPlayerForTrackerID( int trackerID ) static int GAME_EXPORT pfnGetPlayerForTrackerID( int trackerID )
{ {
return 0; return 0;
} }
@@ -2737,7 +2755,7 @@ pfnServerCmdUnreliable
============= =============
*/ */
int GAME_EXPORT pfnServerCmdUnreliable( char *szCmdString ) static int GAME_EXPORT pfnServerCmdUnreliable( char *szCmdString )
{ {
if( !COM_CheckString( szCmdString )) if( !COM_CheckString( szCmdString ))
return 0; return 0;
@@ -2754,7 +2772,7 @@ pfnGetMousePos
============= =============
*/ */
void GAME_EXPORT pfnGetMousePos( struct tagPOINT *ppt ) static void GAME_EXPORT pfnGetMousePos( struct tagPOINT *ppt )
{ {
if( !ppt ) if( !ppt )
return; return;
@@ -2769,7 +2787,7 @@ pfnSetMouseEnable
legacy of dinput code legacy of dinput code
============= =============
*/ */
void GAME_EXPORT pfnSetMouseEnable( qboolean fEnable ) static void GAME_EXPORT pfnSetMouseEnable( qboolean fEnable )
{ {
} }
@@ -2888,7 +2906,7 @@ static int GAME_EXPORT pfnDrawString( int x, int y, const char *str, int r, int
rgba_t color = { r, g, b, 255 }; rgba_t color = { r, g, b, 255 };
int flags = FONT_DRAW_HUD | FONT_DRAW_NOLF; int flags = FONT_DRAW_HUD | FONT_DRAW_NOLF;
if( hud_utf8->value ) if( hud_utf8.value )
SetBits( flags, FONT_DRAW_UTF8 ); SetBits( flags, FONT_DRAW_UTF8 );
return CL_DrawString( x, y, str, color, &cls.creditsFont, flags ); return CL_DrawString( x, y, str, color, &cls.creditsFont, flags );
@@ -2906,7 +2924,7 @@ static int GAME_EXPORT pfnDrawStringReverse( int x, int y, const char *str, int
int flags = FONT_DRAW_HUD | FONT_DRAW_NOLF; int flags = FONT_DRAW_HUD | FONT_DRAW_NOLF;
int width; int width;
if( hud_utf8->value ) if( hud_utf8.value )
SetBits( flags, FONT_DRAW_UTF8 ); SetBits( flags, FONT_DRAW_UTF8 );
CL_DrawStringLen( &cls.creditsFont, str, &width, NULL, flags ); CL_DrawStringLen( &cls.creditsFont, str, &width, NULL, flags );
@@ -2983,7 +3001,7 @@ pfnFillRGBABlend
============= =============
*/ */
void GAME_EXPORT CL_FillRGBABlend( int x, int y, int w, int h, int r, int g, int b, int a ) static void GAME_EXPORT CL_FillRGBABlend( int x, int y, int w, int h, int r, int g, int b, int a )
{ {
float _x = x, _y = y, _w = w, _h = h; float _x = x, _y = y, _w = w, _h = h;
@@ -3045,7 +3063,7 @@ pfnParseFile
handle colon separately handle colon separately
============= =============
*/ */
char *pfnParseFile( char *data, char *token ) static char *pfnParseFile( char *data, char *token )
{ {
return COM_ParseFileSafe( data, token, PFILE_TOKEN_MAX_LENGTH, PFILE_HANDLECOLON, NULL, NULL ); return COM_ParseFileSafe( data, token, PFILE_TOKEN_MAX_LENGTH, PFILE_HANDLECOLON, NULL, NULL );
} }
@@ -3266,7 +3284,7 @@ NetAPI_InitNetworking
================= =================
*/ */
void GAME_EXPORT NetAPI_InitNetworking( void ) static void GAME_EXPORT NetAPI_InitNetworking( void )
{ {
NET_Config( true, false ); // allow remote NET_Config( true, false ); // allow remote
} }
@@ -3277,7 +3295,7 @@ NetAPI_InitNetworking
================= =================
*/ */
void GAME_EXPORT NetAPI_Status( net_status_t *status ) static void GAME_EXPORT NetAPI_Status( net_status_t *status )
{ {
qboolean connected = false; qboolean connected = false;
int packet_loss = 0; int packet_loss = 0;
@@ -3296,7 +3314,7 @@ void GAME_EXPORT NetAPI_Status( net_status_t *status )
status->remote_address = cls.netchan.remote_address; status->remote_address = cls.netchan.remote_address;
status->packet_loss = packet_loss; status->packet_loss = packet_loss;
status->local_address = net_local; status->local_address = net_local;
status->rate = rate->value; status->rate = rate.value;
} }
/* /*
@@ -3305,7 +3323,7 @@ NetAPI_SendRequest
================= =================
*/ */
void GAME_EXPORT NetAPI_SendRequest( int context, int request, int flags, double timeout, netadr_t *remote_address, net_api_response_func_t response ) static void GAME_EXPORT NetAPI_SendRequest( int context, int request, int flags, double timeout, netadr_t *remote_address, net_api_response_func_t response )
{ {
net_request_t *nr = NULL; net_request_t *nr = NULL;
string req; string req;
@@ -3320,6 +3338,9 @@ void GAME_EXPORT NetAPI_SendRequest( int context, int request, int flags, double
if( remote_address->type != NA_IPX && remote_address->type != NA_BROADCAST_IPX ) if( remote_address->type != NA_IPX && remote_address->type != NA_BROADCAST_IPX )
return; // IPX no longer support return; // IPX no longer support
if( request == NETAPI_REQUEST_SERVERLIST )
return; // no support for server list requests
// find a free request // find a free request
for( i = 0; i < MAX_REQUESTS; i++ ) for( i = 0; i < MAX_REQUESTS; i++ )
{ {
@@ -3356,28 +3377,9 @@ void GAME_EXPORT NetAPI_SendRequest( int context, int request, int flags, double
nr->resp.remote_address = *remote_address; nr->resp.remote_address = *remote_address;
nr->flags = flags; nr->flags = flags;
if( request == NETAPI_REQUEST_SERVERLIST )
{
char fullquery[512];
size_t len;
len = CL_BuildMasterServerScanRequest( fullquery, sizeof( fullquery ), false );
// make sure that port is specified
if( !nr->resp.remote_address.port )
nr->resp.remote_address.port = MSG_BigShort( PORT_MASTER );
// grab the list from the master server
NET_SendPacket( NS_CLIENT, len, fullquery, nr->resp.remote_address );
clgame.request_type = NET_REQUEST_CLIENT;
clgame.master_request = nr; // holds the master request unitl the master acking
}
else
{
// local servers request // local servers request
Q_snprintf( req, sizeof( req ), "netinfo %i %i %i", PROTOCOL_VERSION, context, request ); Q_snprintf( req, sizeof( req ), "netinfo %i %i %i", PROTOCOL_VERSION, context, request );
Netchan_OutOfBandPrint( NS_CLIENT, nr->resp.remote_address, "%s", req ); Netchan_OutOfBandPrint( NS_CLIENT, nr->resp.remote_address, "%s", req );
}
} }
/* /*
@@ -3386,7 +3388,7 @@ NetAPI_CancelRequest
================= =================
*/ */
void GAME_EXPORT NetAPI_CancelRequest( int context ) static void GAME_EXPORT NetAPI_CancelRequest( int context )
{ {
net_request_t *nr; net_request_t *nr;
int i; int i;
@@ -3405,13 +3407,6 @@ void GAME_EXPORT NetAPI_CancelRequest( int context )
nr->pfnFunc( &nr->resp ); nr->pfnFunc( &nr->resp );
} }
if( clgame.net_requests[i].resp.type == NETAPI_REQUEST_SERVERLIST && &clgame.net_requests[i] == clgame.master_request )
{
if( clgame.request_type == NET_REQUEST_CLIENT )
clgame.request_type = NET_REQUEST_CANCEL;
clgame.master_request = NULL;
}
memset( &clgame.net_requests[i], 0, sizeof( net_request_t )); memset( &clgame.net_requests[i], 0, sizeof( net_request_t ));
break; break;
} }
@@ -3440,8 +3435,6 @@ void GAME_EXPORT NetAPI_CancelAllRequests( void )
} }
memset( clgame.net_requests, 0, sizeof( clgame.net_requests )); memset( clgame.net_requests, 0, sizeof( clgame.net_requests ));
clgame.request_type = NET_REQUEST_CANCEL;
clgame.master_request = NULL;
} }
/* /*
@@ -3450,7 +3443,7 @@ NetAPI_AdrToString
================= =================
*/ */
const char *NetAPI_AdrToString( netadr_t *a ) static const char *NetAPI_AdrToString( netadr_t *a )
{ {
return NET_AdrToString( *a ); return NET_AdrToString( *a );
} }
@@ -3461,7 +3454,7 @@ NetAPI_CompareAdr
================= =================
*/ */
int GAME_EXPORT NetAPI_CompareAdr( netadr_t *a, netadr_t *b ) static int GAME_EXPORT NetAPI_CompareAdr( netadr_t *a, netadr_t *b )
{ {
return NET_CompareAdr( *a, *b ); return NET_CompareAdr( *a, *b );
} }
@@ -3472,7 +3465,7 @@ NetAPI_StringToAdr
================= =================
*/ */
int GAME_EXPORT NetAPI_StringToAdr( char *s, netadr_t *a ) static int GAME_EXPORT NetAPI_StringToAdr( char *s, netadr_t *a )
{ {
return NET_StringToAdr( s, a ); return NET_StringToAdr( s, a );
} }
@@ -3483,7 +3476,7 @@ NetAPI_ValueForKey
================= =================
*/ */
const char *NetAPI_ValueForKey( const char *s, const char *key ) static const char * GAME_EXPORT NetAPI_ValueForKey( const char *s, const char *key )
{ {
return Info_ValueForKey( s, key ); return Info_ValueForKey( s, key );
} }
@@ -3494,7 +3487,7 @@ NetAPI_RemoveKey
================= =================
*/ */
void GAME_EXPORT NetAPI_RemoveKey( char *s, const char *key ) static void GAME_EXPORT NetAPI_RemoveKey( char *s, const char *key )
{ {
Info_RemoveKey( s, key ); Info_RemoveKey( s, key );
} }
@@ -3505,7 +3498,7 @@ NetAPI_SetValueForKey
================= =================
*/ */
void GAME_EXPORT NetAPI_SetValueForKey( char *s, const char *key, const char *value, int maxsize ) static void GAME_EXPORT NetAPI_SetValueForKey( char *s, const char *key, const char *value, int maxsize )
{ {
if( key[0] == '*' ) return; if( key[0] == '*' ) return;
Info_SetValueForStarKey( s, key, value, maxsize ); Info_SetValueForStarKey( s, key, value, maxsize );
@@ -3525,7 +3518,7 @@ Voice_StartVoiceTweakMode
================= =================
*/ */
int GAME_EXPORT Voice_StartVoiceTweakMode( void ) static int GAME_EXPORT Voice_StartVoiceTweakMode( void )
{ {
return 0; return 0;
} }
@@ -3536,7 +3529,7 @@ Voice_EndVoiceTweakMode
================= =================
*/ */
void GAME_EXPORT Voice_EndVoiceTweakMode( void ) static void GAME_EXPORT Voice_EndVoiceTweakMode( void )
{ {
} }
@@ -3546,7 +3539,7 @@ Voice_SetControlFloat
================= =================
*/ */
void GAME_EXPORT Voice_SetControlFloat( VoiceTweakControl iControl, float value ) static void GAME_EXPORT Voice_SetControlFloat( VoiceTweakControl iControl, float value )
{ {
} }
@@ -3556,7 +3549,7 @@ Voice_GetControlFloat
================= =================
*/ */
float GAME_EXPORT Voice_GetControlFloat( VoiceTweakControl iControl ) static float GAME_EXPORT Voice_GetControlFloat( VoiceTweakControl iControl )
{ {
return 1.0f; return 1.0f;
} }
@@ -3874,13 +3867,13 @@ void CL_UnloadProgs( void )
Cvar_FullSet( "cl_background", "0", FCVAR_READ_ONLY ); Cvar_FullSet( "cl_background", "0", FCVAR_READ_ONLY );
Cvar_FullSet( "host_clientloaded", "0", FCVAR_READ_ONLY ); Cvar_FullSet( "host_clientloaded", "0", FCVAR_READ_ONLY );
Cvar_Unlink( FCVAR_CLIENTDLL );
Cmd_Unlink( CMD_CLIENTDLL );
COM_FreeLibrary( clgame.hInstance ); COM_FreeLibrary( clgame.hInstance );
Mem_FreePool( &cls.mempool ); Mem_FreePool( &cls.mempool );
Mem_FreePool( &clgame.mempool ); Mem_FreePool( &clgame.mempool );
memset( &clgame, 0, sizeof( clgame )); memset( &clgame, 0, sizeof( clgame ));
Cvar_Unlink( FCVAR_CLIENTDLL );
Cmd_Unlink( CMD_CLIENTDLL );
} }
qboolean CL_LoadProgs( const char *name ) qboolean CL_LoadProgs( const char *name )
@@ -4038,7 +4031,7 @@ qboolean CL_LoadProgs( const char *name )
if( !Mobile_Init() ) // Xash3D FWGS extension: mobile interface if( !Mobile_Init() ) // Xash3D FWGS extension: mobile interface
Con_Reportf( S_WARN "CL_LoadProgs: couldn't get mobility API\n" ); Con_Reportf( S_WARN "CL_LoadProgs: couldn't get mobility API\n" );
CL_InitEdicts (); // initailize local player and world CL_InitEdicts( cl.maxclients ); // initailize local player and world
CL_InitClientMove(); // initialize pm_shared CL_InitClientMove(); // initialize pm_shared
// initialize game // initialize game

View File

@@ -414,11 +414,15 @@ static void UI_ConvertGameInfo( GAMEINFO *out, gameinfo_t *in )
out->gamemode = in->gamemode; out->gamemode = in->gamemode;
if( in->nomodels ) if( in->nomodels )
out->flags |= GFL_NOMODELS; SetBits( out->flags, GFL_NOMODELS );
if( in->noskills ) if( in->noskills )
out->flags |= GFL_NOSKILLS; SetBits( out->flags, GFL_NOSKILLS );
if( in->render_picbutton_text ) if( in->render_picbutton_text )
out->flags |= GFL_RENDER_PICBUTTON_TEXT; SetBits( out->flags, GFL_RENDER_PICBUTTON_TEXT );
if( in->hd_background )
SetBits( out->flags, GFL_HD_BACKGROUND );
if( in->animated_title )
SetBits( out->flags, GFL_ANIMATED_TITLE );
} }
/* /*
@@ -642,6 +646,17 @@ static void GAME_EXPORT pfnFillRGBA( int x, int y, int width, int height, int r,
ref.dllFuncs.Color4ub( 255, 255, 255, 255 ); ref.dllFuncs.Color4ub( 255, 255, 255, 255 );
} }
/*
=============
pfnCvar_RegisterVariable
=============
*/
static cvar_t *GAME_EXPORT pfnCvar_RegisterGameUIVariable( const char *szName, const char *szValue, int flags )
{
return (cvar_t *)Cvar_Get( szName, szValue, flags|FCVAR_GAMEUIDLL, Cvar_BuildAutoDescription( szName, flags|FCVAR_GAMEUIDLL ));
}
/* /*
============= =============
pfnClientCmd pfnClientCmd
@@ -971,28 +986,21 @@ pfnCheckGameDll
*/ */
int GAME_EXPORT pfnCheckGameDll( void ) int GAME_EXPORT pfnCheckGameDll( void )
{ {
string dllpath; #ifdef XASH_INTERNAL_GAMELIBS
void *hInst;
#if TARGET_OS_IPHONE
// loading server library drains too many ram
// so 512MB iPod Touch cannot even connect to
// to servers in cstrike
return true; return true;
#endif #else
string dllpath;
if( svgame.hInstance ) if( svgame.hInstance )
return true; return true;
COM_GetCommonLibraryPath( LIBRARY_SERVER, dllpath, sizeof( dllpath )); COM_GetCommonLibraryPath( LIBRARY_SERVER, dllpath, sizeof( dllpath ));
if(( hInst = COM_LoadLibrary( dllpath, true, false )) != NULL ) if( FS_FileExists( dllpath, false ))
{
COM_FreeLibrary( hInst ); // don't increase linker's reference counter
return true; return true;
}
Con_Reportf( S_WARN "Could not load server library: %s\n", COM_GetLibraryError() );
return false; return false;
#endif
} }
/* /*
@@ -1218,12 +1226,12 @@ void UI_UnloadProgs( void )
Cvar_FullSet( "host_gameuiloaded", "0", FCVAR_READ_ONLY ); Cvar_FullSet( "host_gameuiloaded", "0", FCVAR_READ_ONLY );
Cvar_Unlink( FCVAR_GAMEUIDLL );
Cmd_Unlink( CMD_GAMEUIDLL );
COM_FreeLibrary( gameui.hInstance ); COM_FreeLibrary( gameui.hInstance );
Mem_FreePool( &gameui.mempool ); Mem_FreePool( &gameui.mempool );
memset( &gameui, 0, sizeof( gameui )); memset( &gameui, 0, sizeof( gameui ));
Cvar_Unlink( FCVAR_GAMEUIDLL );
Cmd_Unlink( CMD_GAMEUIDLL );
} }
qboolean UI_LoadProgs( void ) qboolean UI_LoadProgs( void )

View File

@@ -23,7 +23,6 @@ GNU General Public License for more details.
#include "library.h" #include "library.h"
#include "vid_common.h" #include "vid_common.h"
#include "pm_local.h" #include "pm_local.h"
#include "sequence.h"
#define MAX_TOTAL_CMDS 32 #define MAX_TOTAL_CMDS 32
#define MAX_CMD_BUFFER 8000 #define MAX_CMD_BUFFER 8000
@@ -35,62 +34,65 @@ GNU General Public License for more details.
CVAR_DEFINE_AUTO( mp_decals, "300", FCVAR_ARCHIVE, "decals limit in multiplayer" ); CVAR_DEFINE_AUTO( mp_decals, "300", FCVAR_ARCHIVE, "decals limit in multiplayer" );
CVAR_DEFINE_AUTO( dev_overview, "0", 0, "draw level in overview-mode" ); CVAR_DEFINE_AUTO( dev_overview, "0", 0, "draw level in overview-mode" );
CVAR_DEFINE_AUTO( cl_resend, "6.0", 0, "time to resend connect" ); CVAR_DEFINE_AUTO( cl_resend, "6.0", 0, "time to resend connect" );
CVAR_DEFINE_AUTO( cl_allow_download, "1", FCVAR_ARCHIVE, "allow to downloading resources from the server" ); CVAR_DEFINE( cl_allow_download, "cl_allowdownload", "1", FCVAR_ARCHIVE, "allow to downloading resources from the server" );
CVAR_DEFINE_AUTO( cl_allow_upload, "1", FCVAR_ARCHIVE, "allow to uploading resources to the server" ); CVAR_DEFINE_AUTO( cl_allow_upload, "1", FCVAR_ARCHIVE, "allow to uploading resources to the server" );
CVAR_DEFINE_AUTO( cl_download_ingame, "1", FCVAR_ARCHIVE, "allow to downloading resources while client is active" ); CVAR_DEFINE_AUTO( cl_download_ingame, "1", FCVAR_ARCHIVE, "allow to downloading resources while client is active" );
CVAR_DEFINE_AUTO( cl_logofile, "lambda", FCVAR_ARCHIVE, "player logo name" ); CVAR_DEFINE_AUTO( cl_logofile, "lambda", FCVAR_ARCHIVE, "player logo name" );
CVAR_DEFINE_AUTO( cl_logocolor, "orange", FCVAR_ARCHIVE, "player logo color" ); CVAR_DEFINE_AUTO( cl_logocolor, "orange", FCVAR_ARCHIVE, "player logo color" );
CVAR_DEFINE_AUTO( cl_logoext, "bmp", FCVAR_ARCHIVE, "temporary cvar to tell engine which logo must be packed" ); CVAR_DEFINE_AUTO( cl_logoext, "bmp", FCVAR_ARCHIVE, "temporary cvar to tell engine which logo must be packed" );
CVAR_DEFINE_AUTO( cl_test_bandwidth, "1", FCVAR_ARCHIVE, "test network bandwith before connection" ); CVAR_DEFINE_AUTO( cl_test_bandwidth, "1", FCVAR_ARCHIVE, "test network bandwith before connection" );
convar_t *rcon_address;
convar_t *cl_timeout;
convar_t *cl_nopred;
convar_t *cl_nodelta;
convar_t *cl_crosshair;
convar_t *cl_cmdbackup;
convar_t *cl_showerror;
convar_t *cl_bmodelinterp;
convar_t *cl_draw_particles;
convar_t *cl_draw_tracers;
convar_t *cl_lightstyle_lerping;
convar_t *cl_idealpitchscale;
convar_t *cl_nosmooth;
convar_t *cl_smoothtime;
convar_t *cl_clockreset;
convar_t *cl_fixtimerate;
convar_t *hud_fontscale;
convar_t *hud_scale;
convar_t *cl_solid_players;
convar_t *cl_draw_beams;
convar_t *cl_updaterate;
convar_t *cl_showevents;
convar_t *cl_cmdrate;
convar_t *cl_interp;
convar_t *cl_nointerp;
convar_t *cl_dlmax;
convar_t *cl_upmax;
convar_t *cl_lw; CVAR_DEFINE( cl_draw_particles, "r_drawparticles", "1", FCVAR_CHEAT, "render particles" );
convar_t *cl_charset; CVAR_DEFINE( cl_draw_tracers, "r_drawtracers", "1", FCVAR_CHEAT, "render tracers" );
convar_t *cl_trace_messages; CVAR_DEFINE( cl_draw_beams, "r_drawbeams", "1", FCVAR_CHEAT, "render beams" );
convar_t *cl_nat;
convar_t *hud_utf8; static CVAR_DEFINE_AUTO( rcon_address, "", FCVAR_PRIVILEGED, "remote control address" );
convar_t *ui_renderworld; CVAR_DEFINE_AUTO( cl_timeout, "60", 0, "connect timeout (in-seconds)" );
CVAR_DEFINE_AUTO( cl_nopred, "0", FCVAR_ARCHIVE|FCVAR_USERINFO, "disable client movement prediction" );
CVAR_DEFINE_AUTO( cl_nodelta, "0", 0, "disable delta-compression for server messages" );
CVAR_DEFINE( cl_crosshair, "crosshair", "1", FCVAR_ARCHIVE, "show weapon chrosshair" );
static CVAR_DEFINE_AUTO( cl_cmdbackup, "10", FCVAR_ARCHIVE, "how many additional history commands are sent" );
CVAR_DEFINE_AUTO( cl_showerror, "0", FCVAR_ARCHIVE, "show prediction error" );
CVAR_DEFINE_AUTO( cl_bmodelinterp, "1", FCVAR_ARCHIVE, "enable bmodel interpolation" );
CVAR_DEFINE_AUTO( cl_lightstyle_lerping, "0", FCVAR_ARCHIVE, "enables animated light lerping (perfomance option)" );
CVAR_DEFINE_AUTO( cl_idealpitchscale, "0.8", 0, "how much to look up/down slopes and stairs when not using freelook" );
CVAR_DEFINE_AUTO( cl_nosmooth, "0", FCVAR_ARCHIVE, "disable smooth up stair climbing" );
CVAR_DEFINE_AUTO( cl_smoothtime, "0.1", FCVAR_ARCHIVE, "time to smooth up" );
CVAR_DEFINE_AUTO( cl_clockreset, "0.1", FCVAR_ARCHIVE, "frametime delta maximum value before reset" );
CVAR_DEFINE_AUTO( cl_fixtimerate, "7.5", FCVAR_ARCHIVE, "time in msec to client clock adjusting" );
CVAR_DEFINE_AUTO( hud_fontscale, "1.0", FCVAR_ARCHIVE|FCVAR_LATCH, "scale hud font texture" );
CVAR_DEFINE_AUTO( hud_scale, "0", FCVAR_ARCHIVE|FCVAR_LATCH, "scale hud at current resolution" );
CVAR_DEFINE_AUTO( cl_solid_players, "1", 0, "Make all players not solid (can't traceline them)" );
CVAR_DEFINE_AUTO( cl_updaterate, "20", FCVAR_USERINFO|FCVAR_ARCHIVE, "refresh rate of server messages" );
CVAR_DEFINE_AUTO( cl_showevents, "0", FCVAR_ARCHIVE, "show events playback" );
CVAR_DEFINE_AUTO( cl_cmdrate, "60", FCVAR_ARCHIVE, "Max number of command packets sent to server per second" );
CVAR_DEFINE( cl_interp, "ex_interp", "0.1", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "Interpolate object positions starting this many seconds in past" );
CVAR_DEFINE_AUTO( cl_nointerp, "0", FCVAR_CLIENTDLL, "disable interpolation of entities and players" );
static CVAR_DEFINE_AUTO( cl_dlmax, "0", FCVAR_USERINFO|FCVAR_ARCHIVE, "max allowed outcoming fragment size" );
static CVAR_DEFINE_AUTO( cl_upmax, "1200", FCVAR_ARCHIVE, "max allowed incoming fragment size" );
CVAR_DEFINE_AUTO( cl_lw, "1", FCVAR_ARCHIVE|FCVAR_USERINFO, "enable client weapon predicting" );
CVAR_DEFINE_AUTO( cl_charset, "utf-8", FCVAR_ARCHIVE, "1-byte charset to use (iconv style)" );
CVAR_DEFINE_AUTO( cl_trace_messages, "0", FCVAR_ARCHIVE|FCVAR_CHEAT, "enable message names tracing (good for developers)");
CVAR_DEFINE_AUTO( cl_trace_events, "0", FCVAR_ARCHIVE|FCVAR_CHEAT, "enable events tracing (good for developers)");
static CVAR_DEFINE_AUTO( cl_nat, "0", 0, "show servers running under NAT" );
CVAR_DEFINE_AUTO( hud_utf8, "0", FCVAR_ARCHIVE, "Use utf-8 encoding for hud text" );
CVAR_DEFINE_AUTO( ui_renderworld, "0", FCVAR_ARCHIVE, "render world when UI is visible" );
// //
// userinfo // userinfo
// //
convar_t *name; static CVAR_DEFINE_AUTO( name, "player", FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_PRINTABLEONLY|FCVAR_FILTERABLE, "player name" );
convar_t *model; static CVAR_DEFINE_AUTO( model, "", FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_FILTERABLE, "player model ('player' is a singleplayer model)" );
convar_t *topcolor; static CVAR_DEFINE_AUTO( topcolor, "0", FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_FILTERABLE, "player top color" );
convar_t *bottomcolor; static CVAR_DEFINE_AUTO( bottomcolor, "0", FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_FILTERABLE, "player bottom color" );
convar_t *rate; CVAR_DEFINE_AUTO( rate, "3500", FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_FILTERABLE, "player network rate" );
client_t cl; client_t cl;
client_static_t cls; client_static_t cls;
clgame_static_t clgame; clgame_static_t clgame;
void CL_InternetServers_f( void ); static void CL_SendMasterServerScanRequest( void );
//====================================================================== //======================================================================
int GAME_EXPORT CL_Active( void ) int GAME_EXPORT CL_Active( void )
@@ -203,7 +205,7 @@ int CL_GetFragmentSize( void *unused, fragsize_t mode )
if( Netchan_IsLocal( &cls.netchan )) if( Netchan_IsLocal( &cls.netchan ))
return FRAGMENT_LOCAL_SIZE; return FRAGMENT_LOCAL_SIZE;
return cl_upmax->value; return cl_upmax.value;
} }
/* /*
@@ -230,9 +232,6 @@ void CL_SignonReply( void )
if( cl.proxy_redirect && !cls.spectator ) if( cl.proxy_redirect && !cls.spectator )
CL_Disconnect(); CL_Disconnect();
cl.proxy_redirect = false; cl.proxy_redirect = false;
if( cls.demoplayback )
Sequence_OnLevelLoad( clgame.mapname );
break; break;
} }
} }
@@ -262,10 +261,10 @@ static float CL_LerpPoint( void )
return 1.0f; return 1.0f;
} }
if( cl_interp->value <= 0.001 ) if( cl_interp.value <= 0.001 )
return 1.0f; return 1.0f;
frac = ( cl.time - cl.mtime[0] ) / cl_interp->value; frac = ( cl.time - cl.mtime[0] ) / cl_interp.value;
return frac; return frac;
} }
@@ -312,13 +311,13 @@ void CL_ComputeClientInterpolationAmount( usercmd_t *cmd )
float max_interp = MAX_EX_INTERP; float max_interp = MAX_EX_INTERP;
float interpolation_time; float interpolation_time;
if( cl_updaterate->value < MIN_UPDATERATE ) if( cl_updaterate.value < MIN_UPDATERATE )
{ {
Con_Printf( "cl_updaterate minimum is %f, resetting to default (20)\n", MIN_UPDATERATE ); Con_Printf( "cl_updaterate minimum is %f, resetting to default (20)\n", MIN_UPDATERATE );
Cvar_Reset( "cl_updaterate" ); Cvar_Reset( "cl_updaterate" );
} }
if( cl_updaterate->value > MAX_UPDATERATE ) if( cl_updaterate.value > MAX_UPDATERATE )
{ {
Con_Printf( "cl_updaterate clamped at maximum (%f)\n", MAX_UPDATERATE ); Con_Printf( "cl_updaterate clamped at maximum (%f)\n", MAX_UPDATERATE );
Cvar_SetValue( "cl_updaterate", MAX_UPDATERATE ); Cvar_SetValue( "cl_updaterate", MAX_UPDATERATE );
@@ -327,15 +326,15 @@ void CL_ComputeClientInterpolationAmount( usercmd_t *cmd )
if( cls.spectator ) if( cls.spectator )
max_interp = 0.2f; max_interp = 0.2f;
min_interp = 1.0f / cl_updaterate->value; min_interp = 1.0f / cl_updaterate.value;
interpolation_time = cl_interp->value * 1000.0; interpolation_time = cl_interp.value * 1000.0;
if( (cl_interp->value + epsilon) < min_interp ) if( (cl_interp.value + epsilon) < min_interp )
{ {
Con_Printf( "ex_interp forced up to %.1f msec\n", min_interp * 1000.f ); Con_Printf( "ex_interp forced up to %.1f msec\n", min_interp * 1000.f );
Cvar_SetValue( "ex_interp", min_interp ); Cvar_SetValue( "ex_interp", min_interp );
} }
else if( (cl_interp->value - epsilon) > max_interp ) else if( (cl_interp.value - epsilon) > max_interp )
{ {
Con_Printf( "ex_interp forced down to %.1f msec\n", max_interp * 1000.f ); Con_Printf( "ex_interp forced down to %.1f msec\n", max_interp * 1000.f );
Cvar_SetValue( "ex_interp", max_interp ); Cvar_SetValue( "ex_interp", max_interp );
@@ -480,7 +479,7 @@ qboolean CL_ProcessShowTexturesCmds( usercmd_t *cmd )
int changed; int changed;
int pressed, released; int pressed, released;
if( !gl_showtextures->value || CL_IsDevOverviewMode( )) if( !r_showtextures.value || CL_IsDevOverviewMode( ))
return false; return false;
changed = (oldbuttons ^ cmd->buttons); changed = (oldbuttons ^ cmd->buttons);
@@ -488,9 +487,9 @@ qboolean CL_ProcessShowTexturesCmds( usercmd_t *cmd )
released = changed & (~cmd->buttons); released = changed & (~cmd->buttons);
if( released & ( IN_RIGHT|IN_MOVERIGHT )) if( released & ( IN_RIGHT|IN_MOVERIGHT ))
Cvar_SetValue( "r_showtextures", gl_showtextures->value + 1 ); Cvar_SetValue( "r_showtextures", r_showtextures.value + 1 );
if( released & ( IN_LEFT|IN_MOVELEFT )) if( released & ( IN_LEFT|IN_MOVELEFT ))
Cvar_SetValue( "r_showtextures", Q_max( 1, gl_showtextures->value - 1 )); Cvar_SetValue( "r_showtextures", Q_max( 1, r_showtextures.value - 1 ));
oldbuttons = cmd->buttons; oldbuttons = cmd->buttons;
return true; return true;
@@ -511,7 +510,7 @@ qboolean CL_ProcessOverviewCmds( usercmd_t *cmd )
float step = (2.0f / size) * host.realframetime; float step = (2.0f / size) * host.realframetime;
float step2 = step * 100.0f * (2.0f / ov->flZoom); float step2 = step * 100.0f * (2.0f / ov->flZoom);
if( !CL_IsDevOverviewMode() || gl_showtextures->value ) if( !CL_IsDevOverviewMode() || r_showtextures.value )
return false; return false;
if( ov->flZoom < 0.0f ) sign = -1; if( ov->flZoom < 0.0f ) sign = -1;
@@ -707,24 +706,24 @@ void CL_WritePacket( void )
MSG_Init( &buf, "ClientData", data, sizeof( data )); MSG_Init( &buf, "ClientData", data, sizeof( data ));
// Determine number of backup commands to send along // Determine number of backup commands to send along
numbackup = bound( 0, cl_cmdbackup->value, cls.legacymode ? MAX_LEGACY_BACKUP_CMDS : MAX_BACKUP_COMMANDS ); numbackup = bound( 0, cl_cmdbackup.value, cls.legacymode ? MAX_LEGACY_BACKUP_CMDS : MAX_BACKUP_COMMANDS );
if( cls.state == ca_connected ) numbackup = 0; if( cls.state == ca_connected ) numbackup = 0;
// clamp cmdrate // clamp cmdrate
if( cl_cmdrate->value < 10.0f ) if( cl_cmdrate.value < 10.0f )
{ {
Cvar_SetValue( "cl_cmdrate", 10.0f ); Cvar_DirectSet( &cl_cmdrate, "10" );
} }
else if( cl_cmdrate->value > 100.0f ) else if( cl_cmdrate.value > 100.0f )
{ {
Cvar_SetValue( "cl_cmdrate", 100.0f ); Cvar_DirectSet( &cl_cmdrate, "100" );
} }
// Check to see if we can actually send this command // Check to see if we can actually send this command
// In single player, send commands as fast as possible // In single player, send commands as fast as possible
// Otherwise, only send when ready and when not choking bandwidth // Otherwise, only send when ready and when not choking bandwidth
if( cl.maxclients == 1 || ( NET_IsLocalAddress( cls.netchan.remote_address ) && !host_limitlocal->value )) if( cl.maxclients == 1 || ( NET_IsLocalAddress( cls.netchan.remote_address ) && !host_limitlocal.value ))
send_command = true; send_command = true;
if(( host.realtime >= cls.nextcmdtime ) && Netchan_CanPacket( &cls.netchan, true )) if(( host.realtime >= cls.nextcmdtime ) && Netchan_CanPacket( &cls.netchan, true ))
@@ -748,20 +747,20 @@ void CL_WritePacket( void )
if(( host.realtime - cls.netchan.last_received ) > CONNECTION_PROBLEM_TIME ) if(( host.realtime - cls.netchan.last_received ) > CONNECTION_PROBLEM_TIME )
{ {
Con_NPrintf( 1, "^3Warning:^1 Connection Problem^7\n" ); Con_NPrintf( 1, "^3Warning:^1 Connection Problem^7\n" );
Con_NPrintf( 2, "^1Auto-disconnect in %.1f seconds^7", cl_timeout->value - ( host.realtime - cls.netchan.last_received )); Con_NPrintf( 2, "^1Auto-disconnect in %.1f seconds^7", cl_timeout.value - ( host.realtime - cls.netchan.last_received ));
cl.validsequence = 0; cl.validsequence = 0;
} }
} }
if( cl_nodelta->value ) if( cl_nodelta.value )
cl.validsequence = 0; cl.validsequence = 0;
if( send_command ) if( send_command )
{ {
int outgoing_sequence; int outgoing_sequence;
if( cl_cmdrate->value > 0 ) // clamped between 10 and 100 fps if( cl_cmdrate.value > 0 ) // clamped between 10 and 100 fps
cls.nextcmdtime = host.realtime + bound( 0.1f, ( 1.0f / cl_cmdrate->value ), 0.01f ); cls.nextcmdtime = host.realtime + bound( 0.1f, ( 1.0f / cl_cmdrate.value ), 0.01f );
else cls.nextcmdtime = host.realtime; // always able to send right away else cls.nextcmdtime = host.realtime; // always able to send right away
if( cls.lastoutgoingcommand == -1 ) if( cls.lastoutgoingcommand == -1 )
@@ -1033,10 +1032,10 @@ void CL_SendConnectPacket( void )
if( cls.legacymode ) if( cls.legacymode )
{ {
// set related userinfo keys // set related userinfo keys
if( cl_dlmax->value >= 40000 || cl_dlmax->value < 100 ) if( cl_dlmax.value >= 40000 || cl_dlmax.value < 100 )
Info_SetValueForKey( cls.userinfo, "cl_maxpacket", "1400", sizeof( cls.userinfo ) ); Info_SetValueForKey( cls.userinfo, "cl_maxpacket", "1400", sizeof( cls.userinfo ) );
else else
Info_SetValueForKey( cls.userinfo, "cl_maxpacket", cl_dlmax->string, sizeof( cls.userinfo ) ); Info_SetValueForKey( cls.userinfo, "cl_maxpacket", cl_dlmax.string, sizeof( cls.userinfo ) );
if( !*Info_ValueForKey( cls.userinfo,"cl_maxpayload") ) if( !*Info_ValueForKey( cls.userinfo,"cl_maxpayload") )
Info_SetValueForKey( cls.userinfo, "cl_maxpayload", "1000", sizeof( cls.userinfo ) ); Info_SetValueForKey( cls.userinfo, "cl_maxpayload", "1000", sizeof( cls.userinfo ) );
@@ -1051,7 +1050,7 @@ void CL_SendConnectPacket( void )
{ {
int extensions = NET_EXT_SPLITSIZE; int extensions = NET_EXT_SPLITSIZE;
if( cl_dlmax->value > FRAGMENT_MAX_SIZE || cl_dlmax->value < FRAGMENT_MIN_SIZE ) if( cl_dlmax.value > FRAGMENT_MAX_SIZE || cl_dlmax.value < FRAGMENT_MIN_SIZE )
Cvar_SetValue( "cl_dlmax", FRAGMENT_DEFAULT_SIZE ); Cvar_SetValue( "cl_dlmax", FRAGMENT_DEFAULT_SIZE );
Info_RemoveKey( cls.userinfo, "cl_maxpacket" ); Info_RemoveKey( cls.userinfo, "cl_maxpacket" );
@@ -1082,7 +1081,7 @@ void CL_CheckForResend( void )
qboolean bandwidthTest; qboolean bandwidthTest;
if( cls.internetservers_wait ) if( cls.internetservers_wait )
CL_InternetServers_f(); CL_SendMasterServerScanRequest();
// if the local server is running and we aren't then connect // if the local server is running and we aren't then connect
if( cls.state == ca_disconnected && SV_Active( )) if( cls.state == ca_disconnected && SV_Active( ))
@@ -1246,7 +1245,7 @@ void CL_Connect_f( void )
// if running a local server, kill it and reissue // if running a local server, kill it and reissue
if( SV_Active( )) Host_ShutdownServer(); if( SV_Active( )) Host_ShutdownServer();
NET_Config( true, !CVAR_TO_BOOL( cl_nat )); // allow remote NET_Config( true, !cl_nat.value ); // allow remote
Con_Printf( "server %s\n", server ); Con_Printf( "server %s\n", server );
CL_Disconnect(); CL_Disconnect();
@@ -1311,13 +1310,13 @@ void CL_Rcon_f( void )
} }
else else
{ {
if( !COM_CheckString( rcon_address->string )) if( !COM_CheckString( rcon_address.string ))
{ {
Con_Printf( "You must either be connected or set the 'rcon_address' cvar to issue rcon commands\n" ); Con_Printf( "You must either be connected or set the 'rcon_address' cvar to issue rcon commands\n" );
return; return;
} }
NET_StringToAdr( rcon_address->string, &to ); NET_StringToAdr( rcon_address.string, &to );
if( to.port == 0 ) to.port = MSG_BigShort( PORT_SERVER ); if( to.port == 0 ) to.port = MSG_BigShort( PORT_SERVER );
} }
@@ -1410,12 +1409,12 @@ int CL_GetSplitSize( void )
if( !(cls.extensions & NET_EXT_SPLITSIZE) ) if( !(cls.extensions & NET_EXT_SPLITSIZE) )
return 1400; return 1400;
splitsize = cl_dlmax->value; splitsize = cl_dlmax.value;
if( splitsize < FRAGMENT_MIN_SIZE || splitsize > FRAGMENT_MAX_SIZE ) if( splitsize < FRAGMENT_MIN_SIZE || splitsize > FRAGMENT_MAX_SIZE )
Cvar_SetValue( "cl_dlmax", FRAGMENT_DEFAULT_SIZE ); Cvar_SetValue( "cl_dlmax", FRAGMENT_DEFAULT_SIZE );
return cl_dlmax->value; return cl_dlmax.value;
} }
/* /*
@@ -1439,7 +1438,7 @@ void CL_Reconnect( qboolean setup_netchan )
{ {
// only enable incoming split for legacy mode // only enable incoming split for legacy mode
cls.netchan.split = true; cls.netchan.split = true;
Con_Reportf( "^2NET_EXT_SPLIT enabled^7 (packet sizes is %d/%d)\n", (int)cl_dlmax->value, 65536 ); Con_Reportf( "^2NET_EXT_SPLIT enabled^7 (packet sizes is %d/%d)\n", (int)cl_dlmax.value, 65536 );
} }
} }
else else
@@ -1448,7 +1447,7 @@ void CL_Reconnect( qboolean setup_netchan )
if( cls.extensions & NET_EXT_SPLITSIZE ) if( cls.extensions & NET_EXT_SPLITSIZE )
{ {
Con_Reportf( "^2NET_EXT_SPLITSIZE enabled^7 (packet size is %d)\n", (int)cl_dlmax->value ); Con_Reportf( "^2NET_EXT_SPLITSIZE enabled^7 (packet size is %d)\n", (int)cl_dlmax.value );
} }
} }
@@ -1556,6 +1555,8 @@ void CL_LocalServers_f( void )
{ {
netadr_t adr; netadr_t adr;
memset( &adr, 0, sizeof( adr ));
Con_Printf( "Scanning for servers on the local network area...\n" ); Con_Printf( "Scanning for servers on the local network area...\n" );
NET_Config( true, true ); // allow remote NET_Config( true, true ); // allow remote
@@ -1573,10 +1574,10 @@ void CL_LocalServers_f( void )
CL_BuildMasterServerScanRequest CL_BuildMasterServerScanRequest
================= =================
*/ */
size_t CL_BuildMasterServerScanRequest( char *buf, size_t size, qboolean nat ) static size_t NONNULL CL_BuildMasterServerScanRequest( char *buf, size_t size, uint32_t *key, qboolean nat, const char *filter )
{ {
size_t remaining; size_t remaining;
char *info; char *info, temp[32];
if( unlikely( size < sizeof( MS_SCAN_REQUEST ))) if( unlikely( size < sizeof( MS_SCAN_REQUEST )))
return 0; return 0;
@@ -1586,15 +1587,34 @@ size_t CL_BuildMasterServerScanRequest( char *buf, size_t size, qboolean nat )
info = buf + sizeof( MS_SCAN_REQUEST ) - 1; info = buf + sizeof( MS_SCAN_REQUEST ) - 1;
remaining = size - sizeof( MS_SCAN_REQUEST ); remaining = size - sizeof( MS_SCAN_REQUEST );
info[0] = 0; Q_strncpy( info, filter, remaining );
*key = COM_RandomLong( 0, 0x7FFFFFFF );
#ifndef XASH_ALL_SERVERS
Info_SetValueForKey( info, "gamedir", GI->gamefolder, remaining ); Info_SetValueForKey( info, "gamedir", GI->gamefolder, remaining );
#endif
Info_SetValueForKey( info, "clver", XASH_VERSION, remaining ); // let master know about client version Info_SetValueForKey( info, "clver", XASH_VERSION, remaining ); // let master know about client version
Info_SetValueForKey( info, "nat", nat ? "1" : "0", remaining ); Info_SetValueForKey( info, "nat", nat ? "1" : "0", remaining );
Q_snprintf( temp, sizeof( temp ), "%x", *key );
Info_SetValueForKey( info, "key", temp, remaining );
return sizeof( MS_SCAN_REQUEST ) + Q_strlen( info ); return sizeof( MS_SCAN_REQUEST ) + Q_strlen( info );
} }
/*
=================
CL_SendMasterServerScanRequest
=================
*/
static void CL_SendMasterServerScanRequest( void )
{
cls.internetservers_wait = NET_SendToMasters( NS_CLIENT,
cls.internetservers_query_len, cls.internetservers_query );
cls.internetservers_pending = true;
}
/* /*
================= =================
CL_InternetServers_f CL_InternetServers_f
@@ -1602,26 +1622,24 @@ CL_InternetServers_f
*/ */
void CL_InternetServers_f( void ) void CL_InternetServers_f( void )
{ {
char fullquery[512]; qboolean nat = cl_nat.value != 0.0f;
size_t len; uint32_t key;
qboolean nat = cl_nat->value != 0.0f;
len = CL_BuildMasterServerScanRequest( fullquery, sizeof( fullquery ), nat ); if( Cmd_Argc( ) > 2 || ( Cmd_Argc( ) == 2 && !Info_IsValid( Cmd_Argv( 1 ))))
{
Con_Printf( S_USAGE "internetservers [filter]\n" );
return;
}
cls.internetservers_query_len = CL_BuildMasterServerScanRequest(
cls.internetservers_query, sizeof( cls.internetservers_query ),
&cls.internetservers_key, nat, Cmd_Argv( 1 ));
Con_Printf( "Scanning for servers on the internet area...\n" ); Con_Printf( "Scanning for servers on the internet area...\n" );
NET_Config( true, true ); // allow remote NET_Config( true, true ); // allow remote
cls.internetservers_wait = NET_SendToMasters( NS_CLIENT, len, fullquery ); CL_SendMasterServerScanRequest();
cls.internetservers_pending = true;
if( !cls.internetservers_wait )
{
// now we clearing the vgui request
if( clgame.master_request != NULL )
memset( clgame.master_request, 0, sizeof( net_request_t ));
clgame.request_type = NET_REQUEST_GAMEUI;
}
} }
/* /*
@@ -1990,6 +2008,11 @@ void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
int realsize; int realsize;
dword crcValue2 = 0; dword crcValue2 = 0;
// this message only used during connection
// it doesn't make sense after client_connect
if( cls.state != ca_connecting )
return;
if( !CL_IsFromConnectingServer( from )) if( !CL_IsFromConnectingServer( from ))
return; return;
@@ -2053,6 +2076,11 @@ void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
} }
else if( !Q_strcmp( c, "challenge" )) else if( !Q_strcmp( c, "challenge" ))
{ {
// this message only used during connection
// it doesn't make sense after client_connect
if( cls.state != ca_connecting )
return;
if( !CL_IsFromConnectingServer( from )) if( !CL_IsFromConnectingServer( from ))
return; return;
@@ -2071,6 +2099,11 @@ void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
} }
else if( !Q_strcmp( c, "disconnect" )) else if( !Q_strcmp( c, "disconnect" ))
{ {
// this message only used during connection
// it doesn't make sense after client_connect
if( cls.state != ca_connecting )
return;
if( !CL_IsFromConnectingServer( from )) if( !CL_IsFromConnectingServer( from ))
return; return;
@@ -2134,6 +2167,25 @@ void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
return; return;
} }
// check the extra header
if( MSG_ReadByte( msg ) == 0x7f )
{
uint32_t key = MSG_ReadDword( msg );
if( cls.internetservers_key != key )
{
Con_Printf( S_WARN "unexpected server list packet from %s (invalid key)\n", NET_AdrToString( from ));
return;
}
MSG_ReadByte( msg ); // reserved byte
}
else
{
Con_Printf( S_WARN "invalid server list packet from %s (missing extra header)\n", NET_AdrToString( from ));
return;
}
// serverlist got from masterserver // serverlist got from masterserver
while( MSG_GetNumBitsLeft( msg ) > 8 ) while( MSG_GetNumBitsLeft( msg ) > 8 )
{ {
@@ -2143,59 +2195,11 @@ void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
// list is ends here // list is ends here
if( !servadr.port ) if( !servadr.port )
{
if( clgame.request_type == NET_REQUEST_CLIENT && clgame.master_request != NULL )
{
net_request_t *nr = clgame.master_request;
net_adrlist_t *list, **prev;
// setup the answer
nr->resp.remote_address = from;
nr->resp.error = NET_SUCCESS;
nr->resp.ping = host.realtime - nr->timesend;
if( nr->timeout <= host.realtime )
SetBits( nr->resp.error, NET_ERROR_TIMEOUT );
Con_Printf( "serverlist call: %s\n", NET_AdrToString( from ));
nr->pfnFunc( &nr->resp );
// throw the list, now it will be stored in user area
prev = (net_adrlist_t**)&nr->resp.response;
while( 1 )
{
list = *prev;
if( !list ) break;
// throw out any variables the game created
*prev = list->next;
Mem_Free( list );
}
memset( nr, 0, sizeof( *nr )); // done
clgame.request_type = NET_REQUEST_CANCEL;
clgame.master_request = NULL;
}
break; break;
}
if( clgame.request_type == NET_REQUEST_CLIENT && clgame.master_request != NULL )
{
net_request_t *nr = clgame.master_request;
net_adrlist_t *list;
// adding addresses into list
list = Z_Malloc( sizeof( *list ));
list->remote_address = servadr;
list->next = nr->resp.response;
nr->resp.response = list;
}
else if( clgame.request_type == NET_REQUEST_GAMEUI )
{
NET_Config( true, false ); // allow remote NET_Config( true, false ); // allow remote
Netchan_OutOfBandPrint( NS_CLIENT, servadr, "info %i", PROTOCOL_VERSION ); Netchan_OutOfBandPrint( NS_CLIENT, servadr, "info %i", PROTOCOL_VERSION );
} }
}
if( cls.internetservers_pending ) if( cls.internetservers_pending )
{ {
@@ -2243,10 +2247,13 @@ void CL_ReadNetMessage( void )
while( CL_GetMessage( net_message_buffer, &curSize )) while( CL_GetMessage( net_message_buffer, &curSize ))
{ {
if( cls.legacymode && *((int *)&net_message_buffer) == 0xFFFFFFFE ) const int split_header = LittleLong( 0xFFFFFFFE );
if( cls.legacymode && !memcmp( &split_header, net_message_buffer, sizeof( split_header )))
{
// Will rewrite existing packet by merged // Will rewrite existing packet by merged
if( !NetSplit_GetLong( &cls.netchan.netsplit, &net_from, net_message_buffer, &curSize ) ) if( !NetSplit_GetLong( &cls.netchan.netsplit, &net_from, net_message_buffer, &curSize ) )
continue; continue;
}
MSG_Init( &net_message, "ServerData", net_message_buffer, curSize ); MSG_Init( &net_message, "ServerData", net_message_buffer, curSize );
@@ -2323,7 +2330,7 @@ void CL_ReadPackets( void )
// decide the simulation time // decide the simulation time
cl.oldtime = cl.time; cl.oldtime = cl.time;
if( cls.demoplayback != DEMO_XASH3D && !cl.paused ) if( !cl.paused )
cl.time += host.frametime; cl.time += host.frametime;
// demo time // demo time
@@ -2365,7 +2372,7 @@ void CL_ReadPackets( void )
// check timeout // check timeout
if( cls.state >= ca_connected && cls.state != ca_cinematic && !cls.demoplayback ) if( cls.state >= ca_connected && cls.state != ca_cinematic && !cls.demoplayback )
{ {
if( host.realtime - cls.netchan.last_received > cl_timeout->value ) if( host.realtime - cls.netchan.last_received > cl_timeout.value )
{ {
Con_Printf( "\nServer connection timed out.\n" ); Con_Printf( "\nServer connection timed out.\n" );
CL_Disconnect(); CL_Disconnect();
@@ -2859,55 +2866,57 @@ void CL_InitLocal( void )
VGui_RegisterCvars(); VGui_RegisterCvars();
// register our variables // register our variables
cl_crosshair = Cvar_Get( "crosshair", "1", FCVAR_ARCHIVE, "show weapon chrosshair" ); Cvar_RegisterVariable( &cl_crosshair );
cl_nodelta = Cvar_Get ("cl_nodelta", "0", 0, "disable delta-compression for server messages" ); Cvar_RegisterVariable( &cl_nodelta );
cl_idealpitchscale = Cvar_Get( "cl_idealpitchscale", "0.8", 0, "how much to look up/down slopes and stairs when not using freelook" ); Cvar_RegisterVariable( &cl_idealpitchscale );
cl_solid_players = Cvar_Get( "cl_solid_players", "1", 0, "Make all players not solid (can't traceline them)" ); Cvar_RegisterVariable( &cl_solid_players );
cl_interp = Cvar_Get( "ex_interp", "0.1", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "Interpolate object positions starting this many seconds in past" ); Cvar_RegisterVariable( &cl_interp );
cl_timeout = Cvar_Get( "cl_timeout", "60", 0, "connect timeout (in-seconds)" ); Cvar_RegisterVariable( &cl_timeout );
cl_charset = Cvar_Get( "cl_charset", "utf-8", FCVAR_ARCHIVE, "1-byte charset to use (iconv style)" ); Cvar_RegisterVariable( &cl_charset );
hud_utf8 = Cvar_Get( "hud_utf8", "0", FCVAR_ARCHIVE, "Use utf-8 encoding for hud text" ); Cvar_RegisterVariable( &hud_utf8 );
rcon_address = Cvar_Get( "rcon_address", "", FCVAR_PRIVILEGED, "remote control address" ); Cvar_RegisterVariable( &rcon_address );
cl_trace_messages = Cvar_Get( "cl_trace_messages", "0", FCVAR_ARCHIVE|FCVAR_CHEAT, "enable message names tracing (good for developers)"); Cvar_RegisterVariable( &cl_trace_messages );
Cvar_RegisterVariable( &cl_trace_events );
// userinfo // userinfo
cl_nopred = Cvar_Get( "cl_nopred", "0", FCVAR_ARCHIVE|FCVAR_USERINFO, "disable client movement prediction" ); Cvar_RegisterVariable( &cl_nopred );
name = Cvar_Get( "name", Sys_GetCurrentUser(), FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_PRINTABLEONLY, "player name" ); Cvar_RegisterVariable( &name );
model = Cvar_Get( "model", "", FCVAR_USERINFO|FCVAR_ARCHIVE, "player model ('player' is a singleplayer model)" ); Cvar_DirectSet( &name, Sys_GetCurrentUser( ));
cl_updaterate = Cvar_Get( "cl_updaterate", "20", FCVAR_USERINFO|FCVAR_ARCHIVE, "refresh rate of server messages" ); Cvar_RegisterVariable( &model );
cl_dlmax = Cvar_Get( "cl_dlmax", "0", FCVAR_USERINFO|FCVAR_ARCHIVE, "max allowed outcoming fragment size" ); Cvar_RegisterVariable( &cl_updaterate );
cl_upmax = Cvar_Get( "cl_upmax", "1200", FCVAR_ARCHIVE, "max allowed incoming fragment size" ); Cvar_RegisterVariable( &cl_dlmax );
cl_nat = Cvar_Get( "cl_nat", "0", 0, "show servers running under NAT" ); Cvar_RegisterVariable( &cl_upmax );
rate = Cvar_Get( "rate", "3500", FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_FILTERABLE, "player network rate" ); Cvar_RegisterVariable( &cl_nat );
topcolor = Cvar_Get( "topcolor", "0", FCVAR_USERINFO|FCVAR_ARCHIVE, "player top color" ); Cvar_RegisterVariable( &rate );
bottomcolor = Cvar_Get( "bottomcolor", "0", FCVAR_USERINFO|FCVAR_ARCHIVE, "player bottom color" ); Cvar_RegisterVariable( &topcolor );
cl_lw = Cvar_Get( "cl_lw", "1", FCVAR_ARCHIVE|FCVAR_USERINFO, "enable client weapon predicting" ); Cvar_RegisterVariable( &bottomcolor );
Cvar_RegisterVariable( &cl_lw );
Cvar_Get( "cl_lc", "1", FCVAR_ARCHIVE|FCVAR_USERINFO, "enable lag compensation" ); Cvar_Get( "cl_lc", "1", FCVAR_ARCHIVE|FCVAR_USERINFO, "enable lag compensation" );
Cvar_Get( "password", "", FCVAR_USERINFO, "server password" ); Cvar_Get( "password", "", FCVAR_USERINFO, "server password" );
Cvar_Get( "team", "", FCVAR_USERINFO, "player team" ); Cvar_Get( "team", "", FCVAR_USERINFO, "player team" );
Cvar_Get( "skin", "", FCVAR_USERINFO, "player skin" ); Cvar_Get( "skin", "", FCVAR_USERINFO, "player skin" );
cl_nosmooth = Cvar_Get( "cl_nosmooth", "0", FCVAR_ARCHIVE, "disable smooth up stair climbing" ); Cvar_RegisterVariable( &cl_nosmooth );
cl_nointerp = Cvar_Get( "cl_nointerp", "0", FCVAR_CLIENTDLL, "disable interpolation of entities and players" ); Cvar_RegisterVariable( &cl_nointerp );
cl_smoothtime = Cvar_Get( "cl_smoothtime", "0.1", FCVAR_ARCHIVE, "time to smooth up" ); Cvar_RegisterVariable( &cl_smoothtime );
cl_cmdbackup = Cvar_Get( "cl_cmdbackup", "10", FCVAR_ARCHIVE, "how many additional history commands are sent" ); Cvar_RegisterVariable( &cl_cmdbackup );
cl_cmdrate = Cvar_Get( "cl_cmdrate", "60", FCVAR_ARCHIVE, "Max number of command packets sent to server per second" ); Cvar_RegisterVariable( &cl_cmdrate );
cl_draw_particles = Cvar_Get( "r_drawparticles", "1", FCVAR_CHEAT, "render particles" ); Cvar_RegisterVariable( &cl_draw_particles );
cl_draw_tracers = Cvar_Get( "r_drawtracers", "1", FCVAR_CHEAT, "render tracers" ); Cvar_RegisterVariable( &cl_draw_tracers );
cl_draw_beams = Cvar_Get( "r_drawbeams", "1", FCVAR_CHEAT, "render beams" ); Cvar_RegisterVariable( &cl_draw_beams );
cl_lightstyle_lerping = Cvar_Get( "cl_lightstyle_lerping", "0", FCVAR_ARCHIVE, "enables animated light lerping (perfomance option)" ); Cvar_RegisterVariable( &cl_lightstyle_lerping );
cl_showerror = Cvar_Get( "cl_showerror", "0", FCVAR_ARCHIVE, "show prediction error" ); Cvar_RegisterVariable( &cl_showerror );
cl_bmodelinterp = Cvar_Get( "cl_bmodelinterp", "1", FCVAR_ARCHIVE, "enable bmodel interpolation" ); Cvar_RegisterVariable( &cl_bmodelinterp );
cl_clockreset = Cvar_Get( "cl_clockreset", "0.1", FCVAR_ARCHIVE, "frametime delta maximum value before reset" ); Cvar_RegisterVariable( &cl_clockreset );
cl_fixtimerate = Cvar_Get( "cl_fixtimerate", "7.5", FCVAR_ARCHIVE, "time in msec to client clock adjusting" ); Cvar_RegisterVariable( &cl_fixtimerate );
hud_fontscale = Cvar_Get( "hud_fontscale", "1.0", FCVAR_ARCHIVE|FCVAR_LATCH, "scale hud font texture" ); Cvar_RegisterVariable( &hud_fontscale );
hud_scale = Cvar_Get( "hud_scale", "0", FCVAR_ARCHIVE|FCVAR_LATCH, "scale hud at current resolution" ); Cvar_RegisterVariable( &hud_scale );
Cvar_Get( "cl_background", "0", FCVAR_READ_ONLY, "indicate what background map is running" ); Cvar_Get( "cl_background", "0", FCVAR_READ_ONLY, "indicate what background map is running" );
cl_showevents = Cvar_Get( "cl_showevents", "0", FCVAR_ARCHIVE, "show events playback" ); Cvar_RegisterVariable( &cl_showevents );
Cvar_Get( "lastdemo", "", FCVAR_ARCHIVE, "last played demo" ); Cvar_Get( "lastdemo", "", FCVAR_ARCHIVE, "last played demo" );
ui_renderworld = Cvar_Get( "ui_renderworld", "0", FCVAR_ARCHIVE, "render world when UI is visible" ); Cvar_RegisterVariable( &ui_renderworld );
// these two added to shut up CS 1.5 about 'unknown' commands // these two added to shut up CS 1.5 about 'unknown' commands
Cvar_Get( "lightgamma", "1", FCVAR_ARCHIVE, "ambient lighting level (legacy, unused)" ); Cvar_Get( "lightgamma", "1", FCVAR_ARCHIVE, "ambient lighting level (legacy, unused)" );
@@ -2987,10 +2996,10 @@ to smooth lag effect
*/ */
void CL_AdjustClock( void ) void CL_AdjustClock( void )
{ {
if( cl.timedelta == 0.0f || !cl_fixtimerate->value ) if( cl.timedelta == 0.0f || !cl_fixtimerate.value )
return; return;
if( cl_fixtimerate->value < 0.0f ) if( cl_fixtimerate.value < 0.0f )
Cvar_SetValue( "cl_fixtimerate", 7.5f ); Cvar_SetValue( "cl_fixtimerate", 7.5f );
if( fabs( cl.timedelta ) >= 0.001f ) if( fabs( cl.timedelta ) >= 0.001f )
@@ -3000,7 +3009,7 @@ void CL_AdjustClock( void )
msec = ( cl.timedelta * 1000.0 ); msec = ( cl.timedelta * 1000.0 );
sign = ( msec < 0 ) ? 1.0 : -1.0; sign = ( msec < 0 ) ? 1.0 : -1.0;
msec = Q_min( cl_fixtimerate->value, fabs( msec )); msec = Q_min( cl_fixtimerate.value, fabs( msec ));
adjust = sign * ( msec / 1000.0 ); adjust = sign * ( msec / 1000.0 );
if( fabs( adjust ) < fabs( cl.timedelta )) if( fabs( adjust ) < fabs( cl.timedelta ))
@@ -3118,7 +3127,6 @@ void CL_Init( void )
VID_Init(); // init video VID_Init(); // init video
S_Init(); // init sound S_Init(); // init sound
Voice_Init( VOICE_DEFAULT_CODEC, 3 ); // init voice Voice_Init( VOICE_DEFAULT_CODEC, 3 ); // init voice
Sequence_Init();
// unreliable buffer. unsed for unreliable commands and voice stream // unreliable buffer. unsed for unreliable commands and voice stream
MSG_Init( &cls.datagram, "cls.datagram", cls.datagram_buf, sizeof( cls.datagram_buf )); MSG_Init( &cls.datagram, "cls.datagram", cls.datagram_buf, sizeof( cls.datagram_buf ));

View File

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

View File

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

View File

@@ -21,6 +21,7 @@ GNU General Public License for more details.
#include "shake.h" #include "shake.h"
#include "hltv.h" #include "hltv.h"
#include "input.h" #include "input.h"
#include "server.h"
#if XASH_LOW_MEMORY != 2 #if XASH_LOW_MEMORY != 2
int CL_UPDATE_BACKUP = SINGLEPLAYER_BACKUP; int CL_UPDATE_BACKUP = SINGLEPLAYER_BACKUP;
#endif #endif
@@ -196,7 +197,7 @@ void CL_ParseServerTime( sizebuf_t *msg )
dt = cl.time - cl.mtime[0]; dt = cl.time - cl.mtime[0];
if( fabs( dt ) > cl_clockreset->value ) // 0.1 by default if( fabs( dt ) > cl_clockreset.value ) // 0.1 by default
{ {
cl.time = cl.mtime[0]; cl.time = cl.mtime[0];
cl.timedelta = 0.0f; cl.timedelta = 0.0f;
@@ -848,8 +849,10 @@ CL_ParseServerData
void CL_ParseServerData( sizebuf_t *msg, qboolean legacy ) void CL_ParseServerData( sizebuf_t *msg, qboolean legacy )
{ {
char gamefolder[MAX_QPATH]; char gamefolder[MAX_QPATH];
string mapfile;
qboolean background; qboolean background;
int i; int i;
uint32_t mapCRC;
HPAK_CheckSize( CUSTOM_RES_PATH ); HPAK_CheckSize( CUSTOM_RES_PATH );
@@ -912,6 +915,18 @@ void CL_ParseServerData( sizebuf_t *msg, qboolean legacy )
} }
} }
Q_snprintf( mapfile, sizeof( mapfile ), "maps/%s.bsp", clgame.mapname );
if( CRC32_MapFile( &mapCRC, mapfile, cl.maxclients > 1 ))
{
// validate map checksum
if( mapCRC != cl.checksum )
{
Con_Printf( S_ERROR "Your map [%s] differs from the server's.\n", clgame.mapname );
CL_Disconnect_f(); // for local game, call EndGame
Host_AbortCurrentFrame(); // to avoid svc_bad
}
}
if( clgame.maxModels > MAX_MODELS ) if( clgame.maxModels > MAX_MODELS )
Con_Printf( S_WARN "server model limit is above client model limit %i > %i\n", clgame.maxModels, MAX_MODELS ); Con_Printf( S_WARN "server model limit is above client model limit %i > %i\n", clgame.maxModels, MAX_MODELS );
@@ -931,10 +946,10 @@ void CL_ParseServerData( sizebuf_t *msg, qboolean legacy )
// loading user settings // loading user settings
CSCR_LoadDefaultCVars( "user.scr" ); CSCR_LoadDefaultCVars( "user.scr" );
if( r_decals->value > mp_decals.value ) if( r_decals.value > mp_decals.value )
Cvar_SetValue( "r_decals", mp_decals.value ); Cvar_DirectSet( &r_decals, mp_decals.string );
} }
else Cvar_Reset( "r_decals" ); else Cvar_DirectSet( &r_decals, NULL );
// set the background state // set the background state
if( cls.demoplayback && ( cls.demonum != -1 )) if( cls.demoplayback && ( cls.demonum != -1 ))
@@ -966,7 +981,7 @@ void CL_ParseServerData( sizebuf_t *msg, qboolean legacy )
Q_strncpy( gameui.globals->maptitle, clgame.maptitle, sizeof( gameui.globals->maptitle )); Q_strncpy( gameui.globals->maptitle, clgame.maptitle, sizeof( gameui.globals->maptitle ));
if( !cls.changelevel && !cls.changedemo ) if( !cls.changelevel && !cls.changedemo )
CL_InitEdicts (); // re-arrange edicts CL_InitEdicts( cl.maxclients ); // re-arrange edicts
// get splash name // get splash name
if( cls.demoplayback && ( cls.demonum != -1 )) if( cls.demoplayback && ( cls.demonum != -1 ))
@@ -974,9 +989,9 @@ void CL_ParseServerData( sizebuf_t *msg, qboolean legacy )
else Cvar_Set( "cl_levelshot_name", va( "levelshots/%s_%s", clgame.mapname, refState.wideScreen ? "16x9" : "4x3" )); else Cvar_Set( "cl_levelshot_name", va( "levelshots/%s_%s", clgame.mapname, refState.wideScreen ? "16x9" : "4x3" ));
Cvar_SetValue( "scr_loading", 0.0f ); // reset progress bar Cvar_SetValue( "scr_loading", 0.0f ); // reset progress bar
if(( cl_allow_levelshots->value && !cls.changelevel ) || cl.background ) if(( cl_allow_levelshots.value && !cls.changelevel ) || cl.background )
{ {
if( !FS_FileExists( va( "%s.bmp", cl_levelshot_name->string ), true )) if( !FS_FileExists( va( "%s.bmp", cl_levelshot_name.string ), true ))
Cvar_Set( "cl_levelshot_name", "*black" ); // render a black screen Cvar_Set( "cl_levelshot_name", "*black" ); // render a black screen
cls.scrshot_request = scrshot_plaque; // request levelshot even if exist (check filetime) cls.scrshot_request = scrshot_plaque; // request levelshot even if exist (check filetime)
} }
@@ -1240,7 +1255,7 @@ CL_ParseSetAngle
set the view angle to this absolute value set the view angle to this absolute value
================ ================
*/ */
static void CL_ParseSetAngle( sizebuf_t *msg ) void CL_ParseSetAngle( sizebuf_t *msg )
{ {
MSG_ReadVec3Angles( msg, cl.viewangles ); MSG_ReadVec3Angles( msg, cl.viewangles );
} }
@@ -1519,7 +1534,8 @@ void CL_SendConsistencyInfo( sizebuf_t *msg )
{ {
case force_exactfile: case force_exactfile:
MD5_HashFile( md5, filename, NULL ); MD5_HashFile( md5, filename, NULL );
pc->value = *(int *)md5; memcpy( &pc->value, md5, sizeof( pc->value ));
LittleLongSW( pc->value );
if( user_changed_diskfile ) if( user_changed_diskfile )
MSG_WriteUBitLong( msg, 0, 32 ); MSG_WriteUBitLong( msg, 0, 32 );
@@ -1550,7 +1566,7 @@ CL_StartDark
*/ */
static void CL_StartDark( void ) static void CL_StartDark( void )
{ {
if( Cvar_VariableValue( "v_dark" )) if( v_dark.value )
{ {
screenfade_t *sf = &clgame.fade; screenfade_t *sf = &clgame.fade;
float fadetime = 5.0f; float fadetime = 5.0f;
@@ -1575,7 +1591,7 @@ static void CL_StartDark( void )
sf->fadeReset += cl.time; sf->fadeReset += cl.time;
sf->fadeEnd += sf->fadeReset; sf->fadeEnd += sf->fadeReset;
Cvar_SetValue( "v_dark", 0.0f ); Cvar_DirectSet( &v_dark, "0" );
} }
} }
@@ -2153,7 +2169,7 @@ void CL_ParseUserMessage( sizebuf_t *msg, int svc_num )
// parse user message into buffer // parse user message into buffer
MSG_ReadBytes( msg, pbuf, iSize ); MSG_ReadBytes( msg, pbuf, iSize );
if( cl_trace_messages->value ) if( cl_trace_messages.value )
{ {
Con_Reportf( "^3USERMSG %s SIZE %i SVC_NUM %i\n", Con_Reportf( "^3USERMSG %s SIZE %i SVC_NUM %i\n",
clgame.msg[i].name, iSize, clgame.msg[i].number ); clgame.msg[i].name, iSize, clgame.msg[i].number );
@@ -2260,6 +2276,8 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
old_background = cl.background; old_background = cl.background;
if( MSG_ReadOneBit( msg )) if( MSG_ReadOneBit( msg ))
{ {
int maxclients = cl.maxclients;
cls.changelevel = true; cls.changelevel = true;
S_StopAllSounds( true ); S_StopAllSounds( true );
@@ -2271,8 +2289,8 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
cls.changedemo = true; cls.changedemo = true;
} }
CL_ClearState (); CL_ClearState();
CL_InitEdicts (); // re-arrange edicts CL_InitEdicts( maxclients ); // re-arrange edicts
} }
else Con_Printf( "Server disconnected, reconnecting\n" ); else Con_Printf( "Server disconnected, reconnecting\n" );
@@ -2491,666 +2509,3 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
} }
} }
} }
/*
==================
CL_ParseStaticEntity
static client entity
==================
*/
void CL_LegacyParseStaticEntity( sizebuf_t *msg )
{
int i;
entity_state_t state;
cl_entity_t *ent;
memset( &state, 0, sizeof( state ));
state.modelindex = MSG_ReadShort( msg );
state.sequence = MSG_ReadByte( msg );
state.frame = MSG_ReadByte( msg );
state.colormap = MSG_ReadWord( msg );
state.skin = MSG_ReadByte( msg );
for( i = 0; i < 3; i++ )
{
state.origin[i] = MSG_ReadCoord( msg );
state.angles[i] = MSG_ReadBitAngle( msg, 16 );
}
state.rendermode = MSG_ReadByte( msg );
if( state.rendermode != kRenderNormal )
{
state.renderamt = MSG_ReadByte( msg );
state.rendercolor.r = MSG_ReadByte( msg );
state.rendercolor.g = MSG_ReadByte( msg );
state.rendercolor.b = MSG_ReadByte( msg );
state.renderfx = MSG_ReadByte( msg );
}
i = clgame.numStatics;
if( i >= MAX_STATIC_ENTITIES )
{
Con_Printf( S_ERROR "MAX_STATIC_ENTITIES limit exceeded!\n" );
return;
}
ent = &clgame.static_entities[i];
clgame.numStatics++;
// all states are same
ent->baseline = ent->curstate = ent->prevstate = state;
ent->index = 0; // static entities doesn't has the numbers
// statics may be respawned in game e.g. for demo recording
if( cls.state == ca_connected || cls.state == ca_validate )
ent->trivial_accept = INVALID_HANDLE;
// setup the new static entity
VectorCopy( ent->curstate.origin, ent->origin );
VectorCopy( ent->curstate.angles, ent->angles );
ent->model = CL_ModelHandle( state.modelindex );
ent->curstate.framerate = 1.0f;
CL_ResetLatchedVars( ent, true );
if( ent->curstate.rendermode == kRenderNormal && ent->model != NULL )
{
// auto 'solid' faces
if( FBitSet( ent->model->flags, MODEL_TRANSPARENT ) && Host_IsQuakeCompatible( ))
{
ent->curstate.rendermode = kRenderTransAlpha;
ent->curstate.renderamt = 255;
}
}
R_AddEfrags( ent ); // add link
}
void CL_LegacyParseSoundPacket( sizebuf_t *msg, qboolean is_ambient )
{
vec3_t pos;
int chan, sound;
float volume, attn;
int flags, pitch, entnum;
sound_t handle = 0;
flags = MSG_ReadWord( msg );
if( flags & SND_LEGACY_LARGE_INDEX )
{
sound = MSG_ReadWord( msg );
flags &= ~SND_LEGACY_LARGE_INDEX;
}
else
sound = MSG_ReadByte( msg );
chan = MSG_ReadByte( msg );
if( FBitSet( flags, SND_VOLUME ))
volume = (float)MSG_ReadByte( msg ) / 255.0f;
else volume = VOL_NORM;
if( FBitSet( flags, SND_ATTENUATION ))
attn = (float)MSG_ReadByte( msg ) / 64.0f;
else attn = ATTN_NONE;
if( FBitSet( flags, SND_PITCH ))
pitch = MSG_ReadByte( msg );
else pitch = PITCH_NORM;
// entity reletive
entnum = MSG_ReadWord( msg );
// positioned in space
MSG_ReadVec3Coord( msg, pos );
if( FBitSet( flags, SND_SENTENCE ))
{
char sentenceName[32];
//if( FBitSet( flags, SND_SEQUENCE ))
//Q_snprintf( sentenceName, sizeof( sentenceName ), "!#%i", sound + MAX_SOUNDS );
//else
Q_snprintf( sentenceName, sizeof( sentenceName ), "!%i", sound );
handle = S_RegisterSound( sentenceName );
}
else handle = cl.sound_index[sound]; // see precached sound
if( !cl.audio_prepped )
return; // too early
// g-cont. sound and ambient sound have only difference with channel
if( is_ambient )
{
S_AmbientSound( pos, entnum, handle, volume, attn, pitch, flags );
}
else
{
S_StartSound( pos, entnum, chan, handle, volume, attn, pitch, flags );
}
}
/*
================
CL_PrecacheSound
prceache sound from server
================
*/
void CL_LegacyPrecacheSound( sizebuf_t *msg )
{
int soundIndex;
soundIndex = MSG_ReadUBitLong( msg, MAX_SOUND_BITS );
if( soundIndex < 0 || soundIndex >= MAX_SOUNDS )
Host_Error( "CL_PrecacheSound: bad soundindex %i\n", soundIndex );
Q_strncpy( cl.sound_precache[soundIndex], MSG_ReadString( msg ), sizeof( cl.sound_precache[0] ));
// when we loading map all resources is precached sequentially
//if( !cl.audio_prepped ) return;
cl.sound_index[soundIndex] = S_RegisterSound( cl.sound_precache[soundIndex] );
}
void CL_LegacyPrecacheModel( sizebuf_t *msg )
{
int modelIndex;
string model;
modelIndex = MSG_ReadUBitLong( msg, MAX_LEGACY_MODEL_BITS );
if( modelIndex < 0 || modelIndex >= MAX_MODELS )
Host_Error( "CL_PrecacheModel: bad modelindex %i\n", modelIndex );
Q_strncpy( model, MSG_ReadString( msg ), MAX_STRING );
//Q_strncpy( cl.model_precache[modelIndex], BF_ReadString( msg ), sizeof( cl.model_precache[0] ));
// when we loading map all resources is precached sequentially
//if( !cl.video_prepped ) return;
if( modelIndex == 1 && !cl.worldmodel )
{
CL_ClearWorld ();
cl.models[modelIndex] = cl.worldmodel = Mod_LoadWorld( model, true );
return;
}
//Mod_RegisterModel( cl.model_precache[modelIndex], modelIndex );
cl.models[modelIndex] = Mod_ForName( model, false, false );
cl.nummodels = Q_max( cl.nummodels, modelIndex );
}
void CL_LegacyPrecacheEvent( sizebuf_t *msg )
{
int eventIndex;
eventIndex = MSG_ReadUBitLong( msg, MAX_EVENT_BITS );
if( eventIndex < 0 || eventIndex >= MAX_EVENTS )
Host_Error( "CL_PrecacheEvent: bad eventindex %i\n", eventIndex );
Q_strncpy( cl.event_precache[eventIndex], MSG_ReadString( msg ), sizeof( cl.event_precache[0] ));
// can be set now
CL_SetEventIndex( cl.event_precache[eventIndex], eventIndex );
}
#if XASH_LOW_MEMORY == 0
#define MAX_LEGACY_RESOURCES 2048
#elif XASH_LOW_MEMORY == 2
#define MAX_LEGACY_RESOURCES 1
#elif XASH_LOW_MEMORY == 1
#define MAX_LEGACY_RESOURCES 512
#endif
/*
==============
CL_ParseResourceList
==============
*/
void CL_LegacyParseResourceList( sizebuf_t *msg )
{
int i = 0;
static struct
{
int rescount;
int restype[MAX_LEGACY_RESOURCES];
char resnames[MAX_LEGACY_RESOURCES][MAX_QPATH];
} reslist;
memset( &reslist, 0, sizeof( reslist ));
reslist.rescount = MSG_ReadWord( msg ) - 1;
if( reslist.rescount > MAX_LEGACY_RESOURCES )
Host_Error("MAX_RESOURCES reached\n");
for( i = 0; i < reslist.rescount; i++ )
{
reslist.restype[i] = MSG_ReadWord( msg );
Q_strncpy( reslist.resnames[i], MSG_ReadString( msg ), MAX_QPATH );
}
if( CL_IsPlaybackDemo() )
{
return;
}
HTTP_ResetProcessState();
host.downloadcount = 0;
for( i = 0; i < reslist.rescount; i++ )
{
char soundpath[MAX_VA_STRING];
const char *path;
if( reslist.restype[i] == t_sound )
{
Q_snprintf( soundpath, sizeof( soundpath ), DEFAULT_SOUNDPATH "%s", reslist.resnames[i] );
path = soundpath;
}
else path = reslist.resnames[i];
if( FS_FileExists( path, false ))
continue; // already exists
host.downloadcount++;
HTTP_AddDownload( path, -1, true );
}
if( !host.downloadcount )
{
MSG_WriteByte( &cls.netchan.message, clc_stringcmd );
MSG_WriteString( &cls.netchan.message, "continueloading" );
}
}
/*
=====================
CL_ParseLegacyServerMessage
dispatch messages
=====================
*/
void CL_ParseLegacyServerMessage( sizebuf_t *msg, qboolean normal_message )
{
size_t bufStart, playerbytes;
int cmd, param1, param2;
int old_background;
const char *s;
cls.starting_count = MSG_GetNumBytesRead( msg ); // updates each frame
CL_Parse_Debug( true ); // begin parsing
if( normal_message )
{
// assume no entity/player update this packet
if( cls.state == ca_active )
{
cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].valid = false;
cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].choked = false;
}
else
{
CL_ResetFrame( &cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK] );
}
}
// parse the message
while( 1 )
{
if( MSG_CheckOverflow( msg ))
{
Host_Error( "CL_ParseServerMessage: overflow!\n" );
return;
}
// mark start position
bufStart = MSG_GetNumBytesRead( msg );
// end of message (align bits)
if( MSG_GetNumBitsLeft( msg ) < 8 )
break;
cmd = MSG_ReadServerCmd( msg );
// record command for debugging spew on parse problem
CL_Parse_RecordCommand( cmd, bufStart );
// other commands
switch( cmd )
{
case svc_bad:
Host_Error( "svc_bad\n" );
break;
case svc_nop:
// this does nothing
break;
case svc_disconnect:
CL_Drop ();
Host_AbortCurrentFrame ();
break;
case svc_legacy_event:
CL_ParseEvent( msg );
cl.frames[cl.parsecountmod].graphdata.event += MSG_GetNumBytesRead( msg ) - bufStart;
break;
case svc_legacy_changing:
old_background = cl.background;
if( MSG_ReadOneBit( msg ))
{
cls.changelevel = true;
S_StopAllSounds( true );
Con_Printf( "Server changing, reconnecting\n" );
if( cls.demoplayback )
{
SCR_BeginLoadingPlaque( cl.background );
cls.changedemo = true;
}
CL_ClearState ();
CL_InitEdicts (); // re-arrange edicts
}
else Con_Printf( "Server disconnected, reconnecting\n" );
if( cls.demoplayback )
{
cl.background = (cls.demonum != -1) ? true : false;
cls.state = ca_connected;
}
else
{
// g-cont. local client skip the challenge
if( SV_Active( ))
cls.state = ca_disconnected;
else cls.state = ca_connecting;
cl.background = old_background;
cls.connect_time = MAX_HEARTBEAT;
cls.connect_retry = 0;
}
break;
case svc_setview:
CL_ParseViewEntity( msg );
break;
case svc_sound:
CL_LegacyParseSoundPacket( msg, false );
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
break;
case svc_legacy_ambientsound:
CL_LegacyParseSoundPacket( msg, true );
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
break;
case svc_time:
CL_ParseServerTime( msg );
break;
case svc_print:
Con_Printf( "%s", MSG_ReadString( msg ));
break;
case svc_stufftext:
s = MSG_ReadString( msg );
#ifdef HACKS_RELATED_HLMODS
// disable Cry Of Fear antisave protection
if( !Q_strnicmp( s, "disconnect", 10 ) && cls.signon != SIGNONS )
break; // too early
#endif
Con_Reportf( "Stufftext: %s", s );
Cbuf_AddFilteredText( s );
break;
case svc_setangle:
CL_ParseSetAngle( msg );
break;
case svc_serverdata:
Cbuf_Execute(); // make sure any stuffed commands are done
CL_ParseServerData( msg, true );
break;
case svc_lightstyle:
CL_ParseLightStyle( msg );
break;
case svc_updateuserinfo:
CL_UpdateUserinfo( msg, true );
break;
case svc_deltatable:
Delta_ParseTableField( msg );
break;
case svc_clientdata:
CL_ParseClientData( msg );
cl.frames[cl.parsecountmod].graphdata.client += MSG_GetNumBytesRead( msg ) - bufStart;
break;
case svc_resource:
CL_ParseResource( msg );
break;
case svc_pings:
CL_UpdateUserPings( msg );
break;
case svc_particle:
CL_ParseParticles( msg );
break;
case svc_restoresound:
CL_ParseRestoreSoundPacket( msg );
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
break;
case svc_spawnstatic:
CL_LegacyParseStaticEntity( msg );
break;
case svc_event_reliable:
CL_ParseReliableEvent( msg );
cl.frames[cl.parsecountmod].graphdata.event += MSG_GetNumBytesRead( msg ) - bufStart;
break;
case svc_spawnbaseline:
CL_ParseBaseline( msg, true );
break;
case svc_temp_entity:
CL_ParseTempEntity( msg );
cl.frames[cl.parsecountmod].graphdata.tentities += MSG_GetNumBytesRead( msg ) - bufStart;
break;
case svc_setpause:
cl.paused = ( MSG_ReadOneBit( msg ) != 0 );
break;
case svc_signonnum:
CL_ParseSignon( msg );
break;
case svc_centerprint:
CL_CenterPrint( MSG_ReadString( msg ), 0.25f );
break;
case svc_intermission:
cl.intermission = 1;
break;
case svc_legacy_modelindex:
CL_LegacyPrecacheModel( msg );
break;
case svc_legacy_soundindex:
CL_LegacyPrecacheSound( msg );
break;
case svc_cdtrack:
param1 = MSG_ReadByte( msg );
param1 = bound( 1, param1, MAX_CDTRACKS ); // tracknum
param2 = MSG_ReadByte( msg );
param2 = bound( 1, param2, MAX_CDTRACKS ); // loopnum
S_StartBackgroundTrack( clgame.cdtracks[param1-1], clgame.cdtracks[param2-1], 0, false );
break;
case svc_restore:
CL_ParseRestore( msg );
break;
case svc_legacy_eventindex:
CL_LegacyPrecacheEvent(msg);
break;
case svc_weaponanim:
param1 = MSG_ReadByte( msg ); // iAnim
param2 = MSG_ReadByte( msg ); // body
CL_WeaponAnim( param1, param2 );
break;
case svc_bspdecal:
CL_ParseStaticDecal( msg );
break;
case svc_roomtype:
param1 = MSG_ReadShort( msg );
Cvar_SetValue( "room_type", param1 );
break;
case svc_addangle:
CL_ParseAddAngle( msg );
break;
case svc_usermessage:
CL_RegisterUserMessage( msg );
break;
case svc_packetentities:
playerbytes = CL_ParsePacketEntities( msg, false );
cl.frames[cl.parsecountmod].graphdata.players += playerbytes;
cl.frames[cl.parsecountmod].graphdata.entities += MSG_GetNumBytesRead( msg ) - bufStart - playerbytes;
break;
case svc_deltapacketentities:
playerbytes = CL_ParsePacketEntities( msg, true );
cl.frames[cl.parsecountmod].graphdata.players += playerbytes;
cl.frames[cl.parsecountmod].graphdata.entities += MSG_GetNumBytesRead( msg ) - bufStart - playerbytes;
break;
case svc_legacy_chokecount:
{
int i, j;
i = MSG_ReadByte( msg );
j = cls.netchan.incoming_acknowledged - 1;
for( ; i > 0 && j > cls.netchan.outgoing_sequence - CL_UPDATE_BACKUP; j-- )
{
if( cl.frames[j & CL_UPDATE_MASK].receivedtime != -3.0 )
{
cl.frames[j & CL_UPDATE_MASK].choked = true;
cl.frames[j & CL_UPDATE_MASK].receivedtime = -2.0;
i--;
}
}
break;
}
//cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].choked = true;
//cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].receivedtime = -2.0;
break;
case svc_resourcelist:
CL_LegacyParseResourceList( msg );
break;
case svc_deltamovevars:
CL_ParseMovevars( msg );
break;
case svc_resourcerequest:
CL_ParseResourceRequest( msg );
break;
case svc_customization:
CL_ParseCustomization( msg );
break;
case svc_crosshairangle:
CL_ParseCrosshairAngle( msg );
break;
case svc_soundfade:
CL_ParseSoundFade( msg );
break;
case svc_filetxferfailed:
CL_ParseFileTransferFailed( msg );
break;
case svc_hltv:
CL_ParseHLTV( msg );
break;
case svc_director:
CL_ParseDirector( msg );
break;
case svc_resourcelocation:
CL_ParseResLocation( msg );
break;
case svc_querycvarvalue:
CL_ParseCvarValue( msg, false );
break;
case svc_querycvarvalue2:
CL_ParseCvarValue( msg, true );
break;
default:
CL_ParseUserMessage( msg, cmd );
cl.frames[cl.parsecountmod].graphdata.usr += MSG_GetNumBytesRead( msg ) - bufStart;
break;
}
}
cl.frames[cl.parsecountmod].graphdata.msgbytes += MSG_GetNumBytesRead( msg ) - cls.starting_count;
CL_Parse_Debug( false ); // done
// we don't know if it is ok to save a demo message until
// after we have parsed the frame
if( !cls.demoplayback )
{
if( cls.demorecording && !cls.demowaiting )
{
CL_WriteDemoMessage( false, cls.starting_count, msg );
}
else if( cls.state != ca_active )
{
CL_WriteDemoMessage( true, cls.starting_count, msg );
}
}
}
void CL_LegacyPrecache_f( void )
{
int spawncount, i;
model_t *mod;
if( !cls.legacymode )
return;
spawncount = Q_atoi( Cmd_Argv( 1 ));
Con_Printf( "Setting up renderer...\n" );
// load tempent sprites (glowshell, muzzleflashes etc)
CL_LoadClientSprites ();
// invalidate all decal indexes
memset( cl.decal_index, 0, sizeof( cl.decal_index ));
cl.video_prepped = true;
cl.audio_prepped = true;
if( clgame.entities )
clgame.entities->model = cl.worldmodel;
// update the ref state.
R_UpdateRefState ();
// tell rendering system we have a new set of models.
ref.dllFuncs.R_NewMap ();
CL_SetupOverviewParams();
// release unused SpriteTextures
for( i = 1, mod = clgame.sprites; i < MAX_CLIENT_SPRITES; i++, mod++ )
{
if( mod->needload == NL_UNREFERENCED && COM_CheckString( mod->name ))
Mod_FreeModel( mod );
}
// Mod_FreeUnused ();
if( host_developer.value <= DEV_NONE )
Con_ClearNotify(); // clear any lines of console text
// done with all resources, issue prespawn command.
// Include server count in case server disconnects and changes level during d/l
MSG_BeginClientCmd( &cls.netchan.message, clc_stringcmd );
MSG_WriteStringf( &cls.netchan.message, "begin %i", spawncount );
cls.signon = SIGNONS;
}
void CL_LegacyUpdateInfo( void )
{
if( !cls.legacymode )
return;
if( cls.state != ca_active )
return;
MSG_BeginClientCmd( &cls.netchan.message, clc_legacy_userinfo );
MSG_WriteString( &cls.netchan.message, cls.userinfo );
}
qboolean CL_LegacyMode( void )
{
return cls.legacymode;
}

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

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

View File

@@ -86,7 +86,7 @@ CL_IsPredicted
*/ */
qboolean CL_IsPredicted( void ) qboolean CL_IsPredicted( void )
{ {
if( cl_nopred->value || cl.intermission ) if( cl_nopred.value || cl.intermission )
return false; return false;
// never predict the quake demos // never predict the quake demos
@@ -183,7 +183,7 @@ void CL_SetIdealPitch( void )
} }
if( steps < 2 ) return; if( steps < 2 ) return;
cl.local.idealpitch = -dir * cl_idealpitchscale->value; cl.local.idealpitch = -dir * cl_idealpitchscale.value;
} }
/* /*
@@ -234,7 +234,7 @@ void CL_CheckPredictionError( void )
// save the prediction error for interpolation // save the prediction error for interpolation
if( dist > MAX_PREDICTION_ERROR ) if( dist > MAX_PREDICTION_ERROR )
{ {
if( cl_showerror->value && host_developer.value ) if( cl_showerror.value && host_developer.value )
Con_NPrintf( 10 + ( ++pos & 3 ), "^3player teleported:^7 %.3f units\n", dist ); Con_NPrintf( 10 + ( ++pos & 3 ), "^3player teleported:^7 %.3f units\n", dist );
// a teleport or something or gamepaused // a teleport or something or gamepaused
@@ -242,7 +242,7 @@ void CL_CheckPredictionError( void )
} }
else else
{ {
if( cl_showerror->value && dist > MIN_PREDICTION_EPSILON && host_developer.value ) if( cl_showerror.value && dist > MIN_PREDICTION_EPSILON && host_developer.value )
Con_NPrintf( 10 + ( ++pos & 3 ), "^1prediction error:^7 %.3f units\n", dist ); Con_NPrintf( 10 + ( ++pos & 3 ), "^1prediction error:^7 %.3f units\n", dist );
VectorCopy( cl.frames[cmd].playerstate[cl.playernum].origin, cl.local.predicted_origins[frame] ); VectorCopy( cl.frames[cmd].playerstate[cl.playernum].origin, cl.local.predicted_origins[frame] );
@@ -253,7 +253,7 @@ void CL_CheckPredictionError( void )
// GoldSrc checks for singleplayer // GoldSrc checks for singleplayer
// we would check for local server // we would check for local server
if( dist > MIN_CORRECTION_DISTANCE && !SV_Active() ) if( dist > MIN_CORRECTION_DISTANCE && !SV_Active() )
cls.correction_time = cl_smoothtime->value; cls.correction_time = cl_smoothtime.value;
} }
} }
@@ -533,7 +533,7 @@ void GAME_EXPORT CL_SetSolidPlayers( int playernum )
physent_t *pe; physent_t *pe;
int i; int i;
if( !cl_solid_players->value ) if( !cl_solid_players.value )
return; return;
for( i = 0; i < MAX_CLIENTS; i++ ) for( i = 0; i < MAX_CLIENTS; i++ )
@@ -1105,7 +1105,7 @@ void CL_PredictMovement( qboolean repredicting )
cl.local.onground = frame->playerstate[cl.playernum].onground; cl.local.onground = frame->playerstate[cl.playernum].onground;
else cl.local.onground = -1; else cl.local.onground = -1;
if( !repredicting || !CVAR_TO_BOOL( cl_lw )) if( !repredicting || !cl_lw.value )
cl.local.viewmodel = to->client.viewmodel; cl.local.viewmodel = to->client.viewmodel;
cl.local.repredicting = false; cl.local.repredicting = false;
cl.local.moving = false; cl.local.moving = false;
@@ -1137,7 +1137,7 @@ void CL_PredictMovement( qboolean repredicting )
cl.local.waterlevel = to->client.waterlevel; cl.local.waterlevel = to->client.waterlevel;
cl.local.usehull = to->playerstate.usehull; cl.local.usehull = to->playerstate.usehull;
if( !repredicting || !CVAR_TO_BOOL( cl_lw )) if( !repredicting || !cl_lw.value )
cl.local.viewmodel = to->client.viewmodel; cl.local.viewmodel = to->client.viewmodel;
if( FBitSet( to->client.flags, FL_ONGROUND )) if( FBitSet( to->client.flags, FL_ONGROUND ))
@@ -1167,7 +1167,7 @@ void CL_PredictMovement( qboolean repredicting )
cl.local.moving = false; cl.local.moving = false;
} }
if( cls.correction_time > 0 && !cl_nosmooth->value && cl_smoothtime->value ) if( cls.correction_time > 0 && !cl_nosmooth.value && cl_smoothtime.value )
{ {
vec3_t delta; vec3_t delta;
float frac; float frac;
@@ -1177,14 +1177,14 @@ void CL_PredictMovement( qboolean repredicting )
cls.correction_time -= host.frametime; cls.correction_time -= host.frametime;
// Make sure smoothtime is postive // Make sure smoothtime is postive
if( cl_smoothtime->value <= 0.0f ) if( cl_smoothtime.value <= 0.0f )
Cvar_DirectSet( cl_smoothtime, "0.1" ); Cvar_DirectSet( &cl_smoothtime, "0.1" );
// Clamp from 0 to cl_smoothtime.value // Clamp from 0 to cl_smoothtime.value
cls.correction_time = bound( 0.0, cls.correction_time, cl_smoothtime->value ); cls.correction_time = bound( 0.0, cls.correction_time, cl_smoothtime.value );
// Compute backward interpolation fraction along full correction // Compute backward interpolation fraction along full correction
frac = 1.0f - cls.correction_time / cl_smoothtime->value; frac = 1.0f - cls.correction_time / cl_smoothtime.value;
// Determine how much error we still have to make up for // Determine how much error we still have to make up for
VectorSubtract( cl.simorg, cl.local.lastorigin, delta ); VectorSubtract( cl.simorg, cl.local.lastorigin, delta );

View File

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

View File

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

View File

@@ -164,6 +164,14 @@ intptr_t CL_RenderGetParm( const int parm, const int arg, const qboolean checkRe
return (intptr_t)world.deluxedata; return (intptr_t)world.deluxedata;
case PARM_SHADOWDATA: case PARM_SHADOWDATA:
return (intptr_t)world.shadowdata; return (intptr_t)world.shadowdata;
case PARM_FULLSCREEN:
return refState.fullScreen;
case PARM_WIDESCREEN:
return refState.wideScreen;
case PARM_SCREEN_WIDTH:
return refState.width;
case PARM_SCREEN_HEIGHT:
return refState.height;
default: default:
// indicates call from client.dll // indicates call from client.dll
if( checkRef ) if( checkRef )

View File

@@ -20,18 +20,18 @@ GNU General Public License for more details.
#include "input.h" #include "input.h"
#include "library.h" #include "library.h"
convar_t *scr_centertime; CVAR_DEFINE_AUTO( scr_centertime, "2.5", 0, "centerprint hold time" );
convar_t *scr_loading; CVAR_DEFINE_AUTO( scr_loading, "0", 0, "loading bar progress" );
convar_t *scr_download; CVAR_DEFINE_AUTO( scr_download, "-1", 0, "downloading bar progress" );
convar_t *scr_viewsize; CVAR_DEFINE( scr_viewsize, "viewsize", "120", FCVAR_ARCHIVE, "screen size (quake only)" );
convar_t *cl_testlights; CVAR_DEFINE_AUTO( cl_testlights, "0", 0, "test dynamic lights" );
convar_t *cl_allow_levelshots; CVAR_DEFINE( cl_allow_levelshots, "allow_levelshots", "0", FCVAR_ARCHIVE, "allow engine to use indivdual levelshots instead of 'loading' image" );
convar_t *cl_levelshot_name; CVAR_DEFINE_AUTO( cl_levelshot_name, "*black", 0, "contains path to current levelshot" );
static convar_t *cl_envshot_size; static CVAR_DEFINE_AUTO( cl_envshot_size, "256", FCVAR_ARCHIVE, "envshot size of cube side" );
convar_t *v_dark; CVAR_DEFINE_AUTO( v_dark, "0", 0, "starts level from dark screen" );
static convar_t *net_speeds; static CVAR_DEFINE_AUTO( net_speeds, "0", FCVAR_ARCHIVE, "show network packets" );
static convar_t *cl_showfps; static CVAR_DEFINE_AUTO( cl_showfps, "0", FCVAR_ARCHIVE, "show client fps" );
static convar_t *cl_showpos; static CVAR_DEFINE_AUTO( cl_showpos, "0", FCVAR_ARCHIVE, "show local player position and velocity" );
typedef struct typedef struct
{ {
@@ -59,7 +59,7 @@ void SCR_DrawFPS( int height )
char fpsstring[64]; char fpsstring[64];
int offset; int offset;
if( cls.state != ca_active || !cl_showfps->value || cl.background ) if( cls.state != ca_active || !cl_showfps.value || cl.background )
return; return;
switch( cls.scrshot_action ) switch( cls.scrshot_action )
@@ -95,7 +95,7 @@ void SCR_DrawFPS( int height )
if( curfps < minfps ) minfps = curfps; if( curfps < minfps ) minfps = curfps;
if( curfps > maxfps ) maxfps = curfps; if( curfps > maxfps ) maxfps = curfps;
if( cl_showfps->value == 2 ) if( cl_showfps.value == 2 )
Q_snprintf( fpsstring, sizeof( fpsstring ), "fps: ^1%4i min, ^3%4i cur, ^2%4i max", minfps, curfps, maxfps ); Q_snprintf( fpsstring, sizeof( fpsstring ), "fps: ^1%4i min, ^3%4i cur, ^2%4i max", minfps, curfps, maxfps );
else Q_snprintf( fpsstring, sizeof( fpsstring ), "%4i fps", curfps ); else Q_snprintf( fpsstring, sizeof( fpsstring ), "%4i fps", curfps );
MakeRGBA( color, 255, 255, 255, 255 ); MakeRGBA( color, 255, 255, 255, 255 );
@@ -119,7 +119,7 @@ void SCR_DrawPos( void )
cl_entity_t *ent; cl_entity_t *ent;
rgba_t color; rgba_t color;
if( cls.state != ca_active || !cl_showpos->value || cl.background ) if( cls.state != ca_active || !cl_showpos.value || cl.background )
return; return;
ent = CL_GetLocalPlayer(); ent = CL_GetLocalPlayer();
@@ -164,7 +164,7 @@ void SCR_NetSpeeds( void )
if( !host.allow_console ) if( !host.allow_console )
return; return;
if( !net_speeds->value || cls.state != ca_active ) if( !net_speeds.value || cls.state != ca_active )
return; return;
// prevent to get too big values at max // prevent to get too big values at max
@@ -290,7 +290,7 @@ void SCR_MakeScreenShot( void )
if( cls.envshot_viewsize > 0 ) if( cls.envshot_viewsize > 0 )
viewsize = cls.envshot_viewsize; viewsize = cls.envshot_viewsize;
else viewsize = cl_envshot_size->value; else viewsize = cl_envshot_size.value;
switch( cls.scrshot_action ) switch( cls.scrshot_action )
{ {
@@ -344,9 +344,9 @@ SCR_DrawPlaque
*/ */
void SCR_DrawPlaque( void ) void SCR_DrawPlaque( void )
{ {
if(( cl_allow_levelshots->value && !cls.changelevel ) || cl.background ) if(( cl_allow_levelshots.value && !cls.changelevel ) || cl.background )
{ {
int levelshot = ref.dllFuncs.GL_LoadTexture( cl_levelshot_name->string, NULL, 0, TF_IMAGE ); int levelshot = ref.dllFuncs.GL_LoadTexture( cl_levelshot_name.string, NULL, 0, TF_IMAGE );
ref.dllFuncs.GL_SetRenderMode( kRenderNormal ); ref.dllFuncs.GL_SetRenderMode( kRenderNormal );
ref.dllFuncs.R_DrawStretchPic( 0, 0, refState.width, refState.height, 0, 0, 1, 1, levelshot ); ref.dllFuncs.R_DrawStretchPic( 0, 0, refState.width, refState.height, 0, 0, 1, 1, levelshot );
if( !cl.background ) CL_DrawHUD( CL_LOADING ); if( !cl.background ) CL_DrawHUD( CL_LOADING );
@@ -366,7 +366,7 @@ void SCR_BeginLoadingPlaque( qboolean is_background )
cl.video_prepped = false; cl.video_prepped = false;
if( !Host_IsDedicated() ) if( !Host_IsDedicated() )
oldclear = gl_clear->value; oldclear = gl_clear.value;
if( CL_IsInMenu( ) && !cls.changedemo && !is_background ) if( CL_IsInMenu( ) && !cls.changedemo && !is_background )
{ {
@@ -382,7 +382,7 @@ void SCR_BeginLoadingPlaque( qboolean is_background )
return; return;
if( !Host_IsDedicated() ) if( !Host_IsDedicated() )
gl_clear->value = 0.0f; gl_clear.value = 0.0f;
if( is_background ) IN_MouseSavePos( ); if( is_background ) IN_MouseSavePos( );
cls.draw_changelevel = !is_background; cls.draw_changelevel = !is_background;
@@ -391,7 +391,7 @@ void SCR_BeginLoadingPlaque( qboolean is_background )
cl.background = is_background; // set right state before svc_serverdata is came cl.background = is_background; // set right state before svc_serverdata is came
if( !Host_IsDedicated() ) if( !Host_IsDedicated() )
gl_clear->value = oldclear; gl_clear.value = oldclear;
// SNDDMA_LockSound(); // SNDDMA_LockSound();
} }
@@ -442,7 +442,7 @@ void SCR_TileClear( void )
int i, top, bottom, left, right; int i, top, bottom, left, right;
dirty_t clear; dirty_t clear;
if( scr_viewsize->value >= 120 ) if( scr_viewsize.value >= 120 )
return; // full screen rendering return; // full screen rendering
// erase rect will be the union of the past three frames // erase rect will be the union of the past three frames
@@ -558,7 +558,7 @@ void SCR_LoadCreditsFont( void )
{ {
cl_font_t *const font = &cls.creditsFont; cl_font_t *const font = &cls.creditsFont;
qboolean success = false; qboolean success = false;
float scale = hud_fontscale->value; float scale = hud_fontscale.value;
dword crc = 0; dword crc = 0;
// replace default gfx.wad textures by current charset's font // replace default gfx.wad textures by current charset's font
@@ -652,13 +652,13 @@ void SCR_RegisterTextures( void )
if( FS_FileExists( "gfx/lambda.lmp", false )) if( FS_FileExists( "gfx/lambda.lmp", false ))
{ {
if( cl_allow_levelshots->value ) if( cl_allow_levelshots.value )
cls.loadingBar = ref.dllFuncs.GL_LoadTexture( "gfx/lambda.lmp", NULL, 0, TF_IMAGE|TF_LUMINANCE ); cls.loadingBar = ref.dllFuncs.GL_LoadTexture( "gfx/lambda.lmp", NULL, 0, TF_IMAGE|TF_LUMINANCE );
else cls.loadingBar = ref.dllFuncs.GL_LoadTexture( "gfx/lambda.lmp", NULL, 0, TF_IMAGE ); else cls.loadingBar = ref.dllFuncs.GL_LoadTexture( "gfx/lambda.lmp", NULL, 0, TF_IMAGE );
} }
else if( FS_FileExists( "gfx/loading.lmp", false )) else if( FS_FileExists( "gfx/loading.lmp", false ))
{ {
if( cl_allow_levelshots->value ) if( cl_allow_levelshots.value )
cls.loadingBar = ref.dllFuncs.GL_LoadTexture( "gfx/loading.lmp", NULL, 0, TF_IMAGE|TF_LUMINANCE ); cls.loadingBar = ref.dllFuncs.GL_LoadTexture( "gfx/loading.lmp", NULL, 0, TF_IMAGE|TF_LUMINANCE );
else cls.loadingBar = ref.dllFuncs.GL_LoadTexture( "gfx/loading.lmp", NULL, 0, TF_IMAGE ); else cls.loadingBar = ref.dllFuncs.GL_LoadTexture( "gfx/loading.lmp", NULL, 0, TF_IMAGE );
} }
@@ -675,7 +675,7 @@ Keybinding command
*/ */
void SCR_SizeUp_f( void ) void SCR_SizeUp_f( void )
{ {
Cvar_SetValue( "viewsize", Q_min( scr_viewsize->value + 10, 120 )); Cvar_SetValue( "viewsize", Q_min( scr_viewsize.value + 10, 120 ));
} }
@@ -688,7 +688,7 @@ Keybinding command
*/ */
void SCR_SizeDown_f( void ) void SCR_SizeDown_f( void )
{ {
Cvar_SetValue( "viewsize", Q_max( scr_viewsize->value - 10, 30 )); Cvar_SetValue( "viewsize", Q_max( scr_viewsize.value - 10, 30 ));
} }
/* /*
@@ -726,6 +726,7 @@ void SCR_VidInit( void )
// restart console size // restart console size
Con_VidInit (); Con_VidInit ();
Touch_NotifyResize();
} }
/* /*
@@ -737,18 +738,18 @@ void SCR_Init( void )
{ {
if( scr_init ) return; if( scr_init ) return;
scr_centertime = Cvar_Get( "scr_centertime", "2.5", 0, "centerprint hold time" ); Cvar_RegisterVariable( &scr_centertime );
cl_levelshot_name = Cvar_Get( "cl_levelshot_name", "*black", 0, "contains path to current levelshot" ); Cvar_RegisterVariable( &cl_levelshot_name );
cl_allow_levelshots = Cvar_Get( "allow_levelshots", "0", FCVAR_ARCHIVE, "allow engine to use indivdual levelshots instead of 'loading' image" ); Cvar_RegisterVariable( &cl_allow_levelshots );
scr_loading = Cvar_Get( "scr_loading", "0", 0, "loading bar progress" ); Cvar_RegisterVariable( &scr_loading );
scr_download = Cvar_Get( "scr_download", "-1", 0, "downloading bar progress" ); Cvar_RegisterVariable( &scr_download );
cl_testlights = Cvar_Get( "cl_testlights", "0", 0, "test dynamic lights" ); Cvar_RegisterVariable( &cl_testlights );
cl_envshot_size = Cvar_Get( "cl_envshot_size", "256", FCVAR_ARCHIVE, "envshot size of cube side" ); Cvar_RegisterVariable( &cl_envshot_size );
v_dark = Cvar_Get( "v_dark", "0", 0, "starts level from dark screen" ); Cvar_RegisterVariable( &v_dark );
scr_viewsize = Cvar_Get( "viewsize", "120", FCVAR_ARCHIVE, "screen size" ); Cvar_RegisterVariable( &scr_viewsize );
net_speeds = Cvar_Get( "net_speeds", "0", FCVAR_ARCHIVE, "show network packets" ); Cvar_RegisterVariable( &net_speeds );
cl_showfps = Cvar_Get( "cl_showfps", "0", FCVAR_ARCHIVE, "show client fps" ); Cvar_RegisterVariable( &cl_showfps );
cl_showpos = Cvar_Get( "cl_showpos", "0", FCVAR_ARCHIVE, "show local player position and velocity" ); Cvar_RegisterVariable( &cl_showpos );
// register our commands // register our commands
Cmd_AddCommand( "skyname", CL_SetSky_f, "set new skybox by basename" ); Cmd_AddCommand( "skyname", CL_SetSky_f, "set new skybox by basename" );

View File

@@ -2629,7 +2629,7 @@ void CL_UpdateFlashlight( cl_entity_t *ent )
vec3_t forward, view_ofs; vec3_t forward, view_ofs;
vec3_t vecSrc, vecEnd; vec3_t vecSrc, vecEnd;
float falloff; float falloff;
pmtrace_t *trace; pmtrace_t trace;
cl_entity_t *hit; cl_entity_t *hit;
dlight_t *dl; dlight_t *dl;
@@ -2660,28 +2660,26 @@ void CL_UpdateFlashlight( cl_entity_t *ent )
VectorAdd( ent->origin, view_ofs, vecSrc ); VectorAdd( ent->origin, view_ofs, vecSrc );
VectorMA( vecSrc, FLASHLIGHT_DISTANCE, forward, vecEnd ); VectorMA( vecSrc, FLASHLIGHT_DISTANCE, forward, vecEnd );
trace = CL_VisTraceLine( vecSrc, vecEnd, PM_STUDIO_BOX ); trace = CL_TraceLine( vecSrc, vecEnd, PM_STUDIO_BOX );
// update flashlight endpos // update flashlight endpos
dl = CL_AllocDlight( ent->index ); dl = CL_AllocDlight( ent->index );
#if 1 #if 1
hit = CL_GetEntityByIndex( clgame.pmove->visents[trace->ent].info ); hit = CL_GetEntityByIndex( clgame.pmove->visents[trace.ent].info );
if( hit && hit->model && ( hit->model->type == mod_alias || hit->model->type == mod_studio )) if( hit && hit->model && ( hit->model->type == mod_alias || hit->model->type == mod_studio ))
VectorCopy( hit->origin, dl->origin ); VectorCopy( hit->origin, dl->origin );
else VectorCopy( trace->endpos, dl->origin ); else VectorCopy( trace.endpos, dl->origin );
#else #else
VectorCopy( trace->endpos, dl->origin ); VectorCopy( trace->endpos, dl->origin );
#endif #endif
// compute falloff // compute falloff
falloff = trace->fraction * FLASHLIGHT_DISTANCE; falloff = trace.fraction * FLASHLIGHT_DISTANCE;
if( falloff < 500.0f ) falloff = 1.0f; if( falloff < 500.0f ) falloff = 1.0f;
else falloff = 500.0f / falloff; else falloff = 500.0f / falloff;
falloff *= falloff; falloff *= falloff;
// apply brigthness to dlight // apply brigthness to dlight
dl->color.r = bound( 0, falloff * 255, 255 ); dl->color.r = dl->color.g = dl->color.b = bound( 0, falloff * 255, 255 );
dl->color.g = bound( 0, falloff * 255, 255 );
dl->color.b = bound( 0, falloff * 255, 255 );
dl->die = cl.time + 0.01f; // die on next frame dl->die = cl.time + 0.01f; // die on next frame
dl->radius = 80; dl->radius = 80;
} }
@@ -2843,10 +2841,10 @@ void CL_TestLights( void )
float f, r; float f, r;
dlight_t *dl; dlight_t *dl;
if( !CVAR_TO_BOOL( cl_testlights )) if( !cl_testlights.value )
return; return;
numLights = bound( 1, cl_testlights->value, MAX_DLIGHTS ); numLights = bound( 1, cl_testlights.value, MAX_DLIGHTS );
AngleVectors( cl.viewangles, forward, right, NULL ); AngleVectors( cl.viewangles, forward, right, NULL );
for( i = 0; i < numLights; i++ ) for( i = 0; i < numLights; i++ )

View File

@@ -202,7 +202,6 @@ SCR_PlayCinematic
*/ */
qboolean SCR_PlayCinematic( const char *arg ) qboolean SCR_PlayCinematic( const char *arg )
{ {
string path;
const char *fullpath; const char *fullpath;
fullpath = FS_GetDiskPath( arg, false ); fullpath = FS_GetDiskPath( arg, false );

View File

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

View File

@@ -423,13 +423,6 @@ typedef struct
float applied_angle; float applied_angle;
} screen_shake_t; } screen_shake_t;
typedef enum
{
NET_REQUEST_CANCEL = 0, // request was cancelled for some reasons
NET_REQUEST_GAMEUI, // called from GameUI
NET_REQUEST_CLIENT, // called from Client
} net_request_type_t;
typedef struct typedef struct
{ {
net_response_t resp; net_response_t resp;
@@ -491,9 +484,7 @@ typedef struct
client_textmessage_t *titles; // title messages, not network messages client_textmessage_t *titles; // title messages, not network messages
int numTitles; int numTitles;
net_request_type_t request_type; // filter the requests
net_request_t net_requests[MAX_REQUESTS]; // no reason to keep more net_request_t net_requests[MAX_REQUESTS]; // no reason to keep more
net_request_t *master_request; // queued master request
efrag_t *free_efrags; // linked efrags efrag_t *free_efrags; // linked efrags
cl_entity_t viewent; // viewmodel cl_entity_t viewent; // viewmodel
@@ -627,7 +618,10 @@ typedef struct
file_t *demofile; file_t *demofile;
file_t *demoheader; // contain demo startup info in case we record a demo on this level file_t *demoheader; // contain demo startup info in case we record a demo on this level
qboolean internetservers_wait; // internetservers is waiting for dns request qboolean internetservers_wait; // internetservers is waiting for dns request
qboolean internetservers_pending; // internetservers is waiting for dns request qboolean internetservers_pending; // if true, clean master server pings
uint32_t internetservers_key; // compare key to validate master server reply
char internetservers_query[512]; // cached query
uint32_t internetservers_query_len;
// legacy mode support // legacy mode support
qboolean legacymode; // one-way 48 protocol compatibility qboolean legacymode; // one-way 48 protocol compatibility
@@ -659,46 +653,47 @@ extern convar_t cl_logocolor;
extern convar_t cl_allow_download; extern convar_t cl_allow_download;
extern convar_t cl_allow_upload; extern convar_t cl_allow_upload;
extern convar_t cl_download_ingame; extern convar_t cl_download_ingame;
extern convar_t *cl_nopred; extern convar_t cl_nopred;
extern convar_t *cl_timeout; extern convar_t cl_timeout;
extern convar_t *cl_nodelta; extern convar_t cl_nodelta;
extern convar_t *cl_interp; extern convar_t cl_interp;
extern convar_t *cl_nointerp; extern convar_t cl_nointerp;
extern convar_t *cl_showerror; extern convar_t cl_showerror;
extern convar_t *cl_nosmooth; extern convar_t cl_nosmooth;
extern convar_t *cl_smoothtime; extern convar_t cl_smoothtime;
extern convar_t *cl_crosshair; extern convar_t cl_crosshair;
extern convar_t *cl_testlights; extern convar_t cl_testlights;
extern convar_t *cl_cmdrate; extern convar_t cl_cmdrate;
extern convar_t *cl_updaterate; extern convar_t cl_updaterate;
extern convar_t *cl_solid_players; extern convar_t cl_solid_players;
extern convar_t *cl_idealpitchscale; extern convar_t cl_idealpitchscale;
extern convar_t *cl_allow_levelshots; extern convar_t cl_allow_levelshots;
extern convar_t *cl_lightstyle_lerping; extern convar_t cl_lightstyle_lerping;
extern convar_t *cl_draw_particles; extern convar_t cl_draw_particles;
extern convar_t *cl_draw_tracers; extern convar_t cl_draw_tracers;
extern convar_t *cl_levelshot_name; extern convar_t cl_levelshot_name;
extern convar_t *cl_draw_beams; extern convar_t cl_draw_beams;
extern convar_t *cl_clockreset; extern convar_t cl_clockreset;
extern convar_t *cl_fixtimerate; extern convar_t cl_fixtimerate;
extern convar_t *hud_fontscale; extern convar_t hud_fontscale;
extern convar_t *hud_scale; extern convar_t hud_scale;
extern convar_t *gl_showtextures; extern convar_t r_showtextures;
extern convar_t *cl_bmodelinterp; extern convar_t cl_bmodelinterp;
extern convar_t *cl_lw; // local weapons extern convar_t cl_lw; // local weapons
extern convar_t *cl_charset; extern convar_t cl_charset;
extern convar_t *cl_trace_messages; extern convar_t cl_trace_messages;
extern convar_t *hud_utf8; extern convar_t cl_trace_events;
extern convar_t *cl_showevents; extern convar_t hud_utf8;
extern convar_t *scr_centertime; extern convar_t cl_showevents;
extern convar_t *scr_viewsize; extern convar_t scr_centertime;
extern convar_t *scr_loading; extern convar_t scr_viewsize;
extern convar_t *v_dark; // start from dark extern convar_t scr_loading;
extern convar_t *net_graph; extern convar_t v_dark; // start from dark
extern convar_t *rate; extern convar_t net_graph;
extern convar_t *m_ignore; extern convar_t rate;
extern convar_t *r_showtree; extern convar_t m_ignore;
extern convar_t *ui_renderworld; extern convar_t r_showtree;
extern convar_t ui_renderworld;
//============================================================================= //=============================================================================
@@ -764,7 +759,6 @@ int CL_IsDevOverviewMode( void );
void CL_PingServers_f( void ); void CL_PingServers_f( void );
void CL_SignonReply( void ); void CL_SignonReply( void );
void CL_ClearState( void ); void CL_ClearState( void );
size_t CL_BuildMasterServerScanRequest( char *buf, size_t size, qboolean nat );
// //
// cl_demo.c // cl_demo.c
@@ -830,7 +824,7 @@ void CL_LinkUserMessage( char *pszName, const int svc_num, int iSize );
void CL_ParseFinaleCutscene( sizebuf_t *msg, int level ); void CL_ParseFinaleCutscene( sizebuf_t *msg, int level );
void CL_ParseTextMessage( sizebuf_t *msg ); void CL_ParseTextMessage( sizebuf_t *msg );
void CL_DrawHUD( int state ); void CL_DrawHUD( int state );
void CL_InitEdicts( void ); void CL_InitEdicts( int maxclients );
void CL_FreeEdicts( void ); void CL_FreeEdicts( void );
void CL_ClearWorld( void ); void CL_ClearWorld( void );
void CL_DrawCenterPrint( void ); void CL_DrawCenterPrint( void );
@@ -838,29 +832,21 @@ void CL_ClearSpriteTextures( void );
void CL_CenterPrint( const char *text, float y ); void CL_CenterPrint( const char *text, float y );
void CL_TextMessageParse( byte *pMemFile, int fileSize ); void CL_TextMessageParse( byte *pMemFile, int fileSize );
client_textmessage_t *CL_TextMessageGet( const char *pName ); client_textmessage_t *CL_TextMessageGet( const char *pName );
int pfnDecalIndexFromName( const char *szDecalName );
int pfnIndexFromTrace( struct pmtrace_s *pTrace );
model_t *CL_ModelHandle( int modelindex ); model_t *CL_ModelHandle( int modelindex );
void NetAPI_CancelAllRequests( void ); void NetAPI_CancelAllRequests( void );
int CL_FindModelIndex( const char *m );
cl_entity_t *CL_GetLocalPlayer( void ); cl_entity_t *CL_GetLocalPlayer( void );
model_t *CL_LoadClientSprite( const char *filename ); model_t *CL_LoadClientSprite( const char *filename );
model_t *CL_LoadModel( const char *modelname, int *index ); model_t *CL_LoadModel( const char *modelname, int *index );
HSPRITE EXPORT pfnSPR_Load( const char *szPicName );
HSPRITE pfnSPR_LoadExt( const char *szPicName, uint texFlags ); HSPRITE pfnSPR_LoadExt( const char *szPicName, uint texFlags );
void SPR_AdjustSize( float *x, float *y, float *w, float *h ); void SPR_AdjustSize( float *x, float *y, float *w, float *h );
void SPR_AdjustTexCoords( float width, float height, float *s1, float *t1, float *s2, float *t2 ); void SPR_AdjustTexCoords( float width, float height, float *s1, float *t1, float *s2, float *t2 );
int CL_GetScreenInfo( SCREENINFO *pscrinfo ); int CL_GetScreenInfo( SCREENINFO *pscrinfo );
void CL_FillRGBA( int x, int y, int width, int height, int r, int g, int b, int a ); void CL_FillRGBA( int x, int y, int width, int height, int r, int g, int b, int a );
void CL_PlayerTrace( float *start, float *end, int traceFlags, int ignore_pe, pmtrace_t *tr );
void CL_PlayerTraceExt( float *start, float *end, int traceFlags, int (*pfnIgnore)( physent_t *pe ), pmtrace_t *tr );
pmtrace_t *PM_CL_TraceLine( float *start, float *end, int flags, int usehull, int ignore_pe ); pmtrace_t *PM_CL_TraceLine( float *start, float *end, int flags, int usehull, int ignore_pe );
const char *PM_CL_TraceTexture( int ground, float *vstart, float *vend ); const char *PM_CL_TraceTexture( int ground, float *vstart, float *vend );
int PM_CL_PointContents( const float *p, int *truecontents ); int PM_CL_PointContents( const float *p, int *truecontents );
void CL_SetTraceHull( int hull );
void CL_GetMousePosition( int *mx, int *my ); // TODO: move to input void CL_GetMousePosition( int *mx, int *my ); // TODO: move to input
cl_entity_t* CL_GetViewModel( void ); cl_entity_t* CL_GetViewModel( void );
void pfnGetScreenFade( struct screenfade_s *fade );
physent_t *pfnGetPhysent( int idx ); physent_t *pfnGetPhysent( int idx );
struct msurface_s *pfnTraceSurface( int ground, float *vstart, float *vend ); struct msurface_s *pfnTraceSurface( int ground, float *vstart, float *vend );
movevars_t *pfnGetMoveVars( void ); movevars_t *pfnGetMoveVars( void );
@@ -886,10 +872,32 @@ _inline cl_entity_t *CL_EDICT_NUM( int n )
// //
// cl_parse.c // cl_parse.c
// //
void CL_ParseSetAngle( sizebuf_t *msg );
void CL_ParseServerData( sizebuf_t *msg, qboolean legacy );
void CL_ParseLightStyle( sizebuf_t *msg );
void CL_UpdateUserinfo( sizebuf_t *msg, qboolean legacy );
void CL_ParseResource( sizebuf_t *msg );
void CL_ParseClientData( sizebuf_t *msg );
void CL_UpdateUserPings( sizebuf_t *msg );
void CL_ParseParticles( sizebuf_t *msg );
void CL_ParseRestoreSoundPacket( sizebuf_t *msg );
void CL_ParseBaseline( sizebuf_t *msg, qboolean legacy );
void CL_ParseSignon( sizebuf_t *msg );
void CL_ParseRestore( sizebuf_t *msg );
void CL_ParseStaticDecal( sizebuf_t *msg );
void CL_ParseAddAngle( sizebuf_t *msg );
void CL_RegisterUserMessage( sizebuf_t *msg );
void CL_ParseMovevars( sizebuf_t *msg );
void CL_ParseResourceRequest( sizebuf_t *msg );
void CL_ParseCustomization( sizebuf_t *msg );
void CL_ParseCrosshairAngle( sizebuf_t *msg );
void CL_ParseSoundFade( sizebuf_t *msg );
void CL_ParseFileTransferFailed( sizebuf_t *msg );
void CL_ParseHLTV( sizebuf_t *msg );
void CL_ParseDirector( sizebuf_t *msg );
void CL_ParseResLocation( sizebuf_t *msg );
void CL_ParseCvarValue( sizebuf_t *msg, const qboolean ext );
void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message ); void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message );
void CL_ParseLegacyServerMessage( sizebuf_t *msg, qboolean normal_message );
void CL_LegacyPrecache_f( void );
void CL_ParseTempEntity( sizebuf_t *msg ); void CL_ParseTempEntity( sizebuf_t *msg );
qboolean CL_DispatchUserMessage( const char *pszName, int iSize, void *pbuf ); qboolean CL_DispatchUserMessage( const char *pszName, int iSize, void *pbuf );
qboolean CL_RequestMissingResources( void ); qboolean CL_RequestMissingResources( void );
@@ -897,6 +905,12 @@ void CL_RegisterResources ( sizebuf_t *msg );
void CL_ParseViewEntity( sizebuf_t *msg ); void CL_ParseViewEntity( sizebuf_t *msg );
void CL_ParseServerTime( sizebuf_t *msg ); void CL_ParseServerTime( sizebuf_t *msg );
//
// cl_parse_48.c
//
void CL_ParseLegacyServerMessage( sizebuf_t *msg, qboolean normal_message );
void CL_LegacyPrecache_f( void );
// //
// cl_scrn.c // cl_scrn.c
// //
@@ -1005,7 +1019,6 @@ void R_AddEfrags( cl_entity_t *ent );
// cl_tent.c // cl_tent.c
// //
struct particle_s; struct particle_s;
int CL_AddEntity( int entityType, cl_entity_t *pEnt );
void CL_WeaponAnim( int iAnim, int body ); void CL_WeaponAnim( int iAnim, int body );
void CL_ClearEffects( void ); void CL_ClearEffects( void );
void CL_ClearEfrags( void ); void CL_ClearEfrags( void );
@@ -1039,7 +1052,7 @@ void CL_RunLightStyles( void );
// //
// console.c // console.c
// //
extern convar_t *con_fontsize; extern convar_t con_fontsize;
int Con_Visible( void ); int Con_Visible( void );
qboolean Con_FixedFont( void ); qboolean Con_FixedFont( void );
void Con_VidInit( void ); void Con_VidInit( void );

View File

@@ -22,13 +22,14 @@ GNU General Public License for more details.
#include "wadfile.h" #include "wadfile.h"
#include "input.h" #include "input.h"
convar_t *con_notifytime; static CVAR_DEFINE_AUTO( scr_conspeed, "600", FCVAR_ARCHIVE, "console moving speed" );
convar_t *scr_conspeed; static CVAR_DEFINE_AUTO( con_notifytime, "3", FCVAR_ARCHIVE, "notify time to live" );
convar_t *con_fontsize; CVAR_DEFINE_AUTO( con_fontsize, "1", FCVAR_ARCHIVE, "console font number (0, 1 or 2)" );
convar_t *con_charset; static CVAR_DEFINE_AUTO( con_charset, "cp1251", FCVAR_ARCHIVE, "console font charset (only cp1251 supported now)" );
convar_t *con_fontscale; static CVAR_DEFINE_AUTO( con_fontscale, "1.0", FCVAR_ARCHIVE, "scale font texture" );
convar_t *con_fontnum; static CVAR_DEFINE_AUTO( con_fontnum, "-1", FCVAR_ARCHIVE, "console font number (0, 1 or 2), -1 for autoselect" );
convar_t *con_color; static CVAR_DEFINE_AUTO( con_color, "240 180 24", FCVAR_ARCHIVE, "set a custom console color" );
static int g_codepage = 0; static int g_codepage = 0;
static qboolean g_utf8 = false; static qboolean g_utf8 = false;
@@ -162,14 +163,13 @@ Con_SetColor
*/ */
static void Con_SetColor( void ) static void Con_SetColor( void )
{ {
vec3_t color;
int r, g, b; int r, g, b;
int num; int num;
if( !FBitSet( con_color->flags, FCVAR_CHANGED )) if( !FBitSet( con_color.flags, FCVAR_CHANGED ))
return; return;
num = sscanf( con_color->string, "%i %i %i", &r, &g, &b ); num = sscanf( con_color.string, "%i %i %i", &r, &g, &b );
switch( num ) switch( num )
{ {
@@ -180,11 +180,11 @@ static void Con_SetColor( void )
Con_DefaultColor( r, g, b ); Con_DefaultColor( r, g, b );
break; break;
default: default:
Cvar_DirectSet( con_color, con_color->def_string ); Cvar_DirectSet( &con_color, con_color.def_string );
break; break;
} }
ClearBits( con_color->flags, FCVAR_CHANGED ); ClearBits( con_color.flags, FCVAR_CHANGED );
} }
/* /*
@@ -538,7 +538,7 @@ INTERNAL RESOURCE
static void Con_LoadConsoleFont( int fontNumber, cl_font_t *font ) static void Con_LoadConsoleFont( int fontNumber, cl_font_t *font )
{ {
qboolean success = false; qboolean success = false;
float scale = con_fontscale->value; float scale = con_fontscale.value;
if( font->valid ) if( font->valid )
return; // already loaded return; // already loaded
@@ -593,8 +593,8 @@ static void Con_LoadConchars( void )
Con_LoadConsoleFont( i, con.chars + i ); Con_LoadConsoleFont( i, con.chars + i );
// select properly fontsize // select properly fontsize
if( con_fontnum->value >= 0 && con_fontnum->value <= CON_NUMFONTS - 1 ) if( con_fontnum.value >= 0 && con_fontnum.value <= CON_NUMFONTS - 1 )
fontSize = con_fontnum->value; fontSize = con_fontnum.value;
else if( refState.width <= 640 ) else if( refState.width <= 640 )
fontSize = 0; fontSize = 0;
else if( refState.width >= 1280 ) else if( refState.width >= 1280 )
@@ -808,7 +808,7 @@ compute string width and height in screen pixels
*/ */
void GAME_EXPORT Con_DrawStringLen( const char *pText, int *length, int *height ) void GAME_EXPORT Con_DrawStringLen( const char *pText, int *length, int *height )
{ {
return CL_DrawStringLen( con.curFont, pText, length, height, FONT_DRAW_UTF8 ); CL_DrawStringLen( con.curFont, pText, length, height, FONT_DRAW_UTF8 );
} }
/* /*
@@ -830,19 +830,17 @@ Con_Init
*/ */
void Con_Init( void ) void Con_Init( void )
{ {
int i;
if( host.type == HOST_DEDICATED ) if( host.type == HOST_DEDICATED )
return; // dedicated server already have console return; // dedicated server already have console
// must be init before startup video subsystem // must be init before startup video subsystem
scr_conspeed = Cvar_Get( "scr_conspeed", "600", FCVAR_ARCHIVE, "console moving speed" ); Cvar_RegisterVariable( &scr_conspeed );
con_notifytime = Cvar_Get( "con_notifytime", "3", FCVAR_ARCHIVE, "notify time to live" ); Cvar_RegisterVariable( &con_notifytime );
con_fontsize = Cvar_Get( "con_fontsize", "1", FCVAR_ARCHIVE, "console font number (0, 1 or 2)" ); Cvar_RegisterVariable( &con_fontsize );
con_charset = Cvar_Get( "con_charset", "cp1251", FCVAR_ARCHIVE, "console font charset (only cp1251 supported now)" ); Cvar_RegisterVariable( &con_charset );
con_fontscale = Cvar_Get( "con_fontscale", "1.0", FCVAR_ARCHIVE, "scale font texture" ); Cvar_RegisterVariable( &con_fontscale );
con_fontnum = Cvar_Get( "con_fontnum", "-1", FCVAR_ARCHIVE, "console font number (0, 1 or 2), -1 for autoselect" ); Cvar_RegisterVariable( &con_fontnum );
con_color = Cvar_Get( "con_color", "240 180 24", FCVAR_ARCHIVE, "set a custom console color" ); Cvar_RegisterVariable( &con_color );
// init the console buffer // init the console buffer
con.bufsize = CON_TEXTSIZE; con.bufsize = CON_TEXTSIZE;
@@ -1754,11 +1752,15 @@ void Con_DrawDebug( void )
string dlstring; string dlstring;
int x, y; int x, y;
if( scr_download->value != -1.0f ) if( scr_download.value != -1.0f )
{ {
int length;
Q_snprintf( dlstring, sizeof( dlstring ), "Downloading [%d remaining]: ^2%s^7 %5.1f%% time %.f secs", Q_snprintf( dlstring, sizeof( dlstring ), "Downloading [%d remaining]: ^2%s^7 %5.1f%% time %.f secs",
host.downloadcount, host.downloadfile, scr_download->value, Sys_DoubleTime() - timeStart ); host.downloadcount, host.downloadfile, scr_download.value, Sys_DoubleTime() - timeStart );
x = refState.width - 500;
Con_DrawStringLen( dlstring, &length, NULL );
length = Q_max( length, 500 );
x = refState.width - length * 1.05f;
y = con.curFont->charHeight * 1.05f; y = con.curFont->charHeight * 1.05f;
Con_DrawString( x, y, dlstring, g_color_table[7] ); Con_DrawString( x, y, dlstring, g_color_table[7] );
} }
@@ -1799,7 +1801,7 @@ void Con_DrawNotify( void )
{ {
con_lineinfo_t *l = &CON_LINES( i ); con_lineinfo_t *l = &CON_LINES( i );
if( l->addtime < ( time - con_notifytime->value )) if( l->addtime < ( time - con_notifytime.value ))
continue; continue;
Con_DrawString( x, y, l->start, g_color_table[7] ); Con_DrawString( x, y, l->start, g_color_table[7] );
@@ -1981,7 +1983,7 @@ void Con_DrawConsole( void )
if( cls.state == ca_connecting || cls.state == ca_connected ) if( cls.state == ca_connecting || cls.state == ca_connected )
{ {
if( !cl_allow_levelshots->value ) if( !cl_allow_levelshots.value && !cls.timedemo )
{ {
if(( Cvar_VariableInteger( "cl_background" ) || Cvar_VariableInteger( "sv_background" )) && cls.key_dest != key_console ) if(( Cvar_VariableInteger( "cl_background" ) || Cvar_VariableInteger( "sv_background" )) && cls.key_dest != key_console )
con.vislines = con.showlines = 0; con.vislines = con.showlines = 0;
@@ -1991,7 +1993,7 @@ void Con_DrawConsole( void )
{ {
con.showlines = 0; con.showlines = 0;
if( host_developer.value >= DEV_EXTENDED ) if( host_developer.value >= DEV_EXTENDED && !cls.timedemo )
Con_DrawNotify(); // draw notify lines Con_DrawNotify(); // draw notify lines
} }
} }
@@ -2023,7 +2025,7 @@ void Con_DrawConsole( void )
{ {
if( con.vislines ) if( con.vislines )
Con_DrawSolidConsole( con.vislines ); Con_DrawSolidConsole( con.vislines );
else if( cls.state == ca_active && ( cls.key_dest == key_game || cls.key_dest == key_message )) else if( cls.state == ca_active && ( cls.key_dest == key_game || cls.key_dest == key_message ) && !cls.timedemo )
Con_DrawNotify(); // draw notify lines Con_DrawNotify(); // draw notify lines
} }
break; break;
@@ -2056,16 +2058,13 @@ void Con_DrawVersion( void )
break; break;
} }
if( !host.force_draw_version )
{
if(( cls.key_dest != key_menu && !draw_version ) || CL_IsDevOverviewMode() == 2 || net_graph->value )
return;
}
if( host.force_draw_version_time > host.realtime ) if( host.force_draw_version_time > host.realtime )
host.force_draw_version = false; draw_version = true;
if( host.force_draw_version || draw_version ) if(( cls.key_dest != key_menu && !draw_version ) || CL_IsDevOverviewMode() == 2 || net_graph.value )
return;
if( draw_version )
Q_snprintf( curbuild, MAX_STRING, XASH_ENGINE_NAME " v%i/" XASH_VERSION " (%s-%s build %i)", PROTOCOL_VERSION, Q_buildos(), Q_buildarch(), Q_buildnum( )); Q_snprintf( curbuild, MAX_STRING, XASH_ENGINE_NAME " v%i/" XASH_VERSION " (%s-%s build %i)", PROTOCOL_VERSION, Q_buildos(), Q_buildarch(), Q_buildnum( ));
else Q_snprintf( curbuild, MAX_STRING, "v%i/" XASH_VERSION " (%s-%s build %i)", PROTOCOL_VERSION, Q_buildos(), Q_buildarch(), Q_buildnum( )); else Q_snprintf( curbuild, MAX_STRING, "v%i/" XASH_VERSION " (%s-%s build %i)", PROTOCOL_VERSION, Q_buildos(), Q_buildarch(), Q_buildnum( ));
@@ -2098,7 +2097,7 @@ void Con_RunConsole( void )
} }
else con.showlines = 0; // none visible else con.showlines = 0; // none visible
lines_per_frame = fabs( scr_conspeed->value ) * host.realframetime; lines_per_frame = fabs( scr_conspeed.value ) * host.realframetime;
if( con.showlines < con.vislines ) if( con.showlines < con.vislines )
{ {
@@ -2113,35 +2112,35 @@ void Con_RunConsole( void )
con.vislines = con.showlines; con.vislines = con.showlines;
} }
if( FBitSet( con_charset->flags, FCVAR_CHANGED ) || if( FBitSet( con_charset.flags, FCVAR_CHANGED ) ||
FBitSet( con_fontscale->flags, FCVAR_CHANGED ) || FBitSet( con_fontscale.flags, FCVAR_CHANGED ) ||
FBitSet( con_fontnum->flags, FCVAR_CHANGED ) || FBitSet( con_fontnum.flags, FCVAR_CHANGED ) ||
FBitSet( cl_charset->flags, FCVAR_CHANGED )) FBitSet( cl_charset.flags, FCVAR_CHANGED ))
{ {
// update codepage parameters // update codepage parameters
if( !Q_stricmp( con_charset->string, "cp1251" )) if( !Q_stricmp( con_charset.string, "cp1251" ))
{ {
g_codepage = 1251; g_codepage = 1251;
} }
else if( !Q_stricmp( con_charset->string, "cp1252" )) else if( !Q_stricmp( con_charset.string, "cp1252" ))
{ {
g_codepage = 1252; g_codepage = 1252;
} }
else else
{ {
Con_Printf( S_WARN "Unknown charset %s, defaulting to cp1252", con_charset->string ); Con_Printf( S_WARN "Unknown charset %s, defaulting to cp1252", con_charset.string );
Cvar_DirectSet( con_charset, "cp1252" ); Cvar_DirectSet( &con_charset, "cp1252" );
g_codepage = 1252; g_codepage = 1252;
} }
g_utf8 = !Q_stricmp( cl_charset->string, "utf-8" ); g_utf8 = !Q_stricmp( cl_charset.string, "utf-8" );
Con_InvalidateFonts(); Con_InvalidateFonts();
Con_LoadConchars(); Con_LoadConchars();
ClearBits( con_charset->flags, FCVAR_CHANGED ); ClearBits( con_charset.flags, FCVAR_CHANGED );
ClearBits( con_fontnum->flags, FCVAR_CHANGED ); ClearBits( con_fontnum.flags, FCVAR_CHANGED );
ClearBits( con_fontscale->flags, FCVAR_CHANGED ); ClearBits( con_fontscale.flags, FCVAR_CHANGED );
ClearBits( cl_charset->flags, FCVAR_CHANGED ); ClearBits( cl_charset.flags, FCVAR_CHANGED );
} }
} }

View File

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

View File

@@ -132,6 +132,8 @@ static struct touch_s
int whitetexture; int whitetexture;
int joytexture; // touch indicator int joytexture; // touch indicator
qboolean configchanged; qboolean configchanged;
float actual_aspect_ratio; // maximum aspect ratio from launch, or aspect ratio when entering editor
float config_aspect_ratio; // aspect ratio set by command from config or after entering editor
} touch; } touch;
// private to the engine flags // private to the engine flags
@@ -140,28 +142,27 @@ static struct touch_s
touchdefaultbutton_t g_DefaultButtons[256]; touchdefaultbutton_t g_DefaultButtons[256];
int g_LastDefaultButton; int g_LastDefaultButton;
convar_t *touch_pitch; static CVAR_DEFINE_AUTO( touch_in_menu, "0", FCVAR_FILTERABLE, "draw touch in menu (for internal use only)" );
convar_t *touch_yaw; static CVAR_DEFINE_AUTO( touch_forwardzone, "0.06", FCVAR_FILTERABLE, "forward touch zone" );
convar_t *touch_forwardzone; static CVAR_DEFINE_AUTO( touch_sidezone, "0.06", FCVAR_FILTERABLE, "side touch zone" );
convar_t *touch_sidezone; static CVAR_DEFINE_AUTO( touch_pitch, "90", FCVAR_FILTERABLE, "touch pitch sensitivity" );
convar_t *touch_nonlinear_look; static CVAR_DEFINE_AUTO( touch_yaw, "120", FCVAR_FILTERABLE, "touch yaw sensitivity" );
convar_t *touch_pow_mult; static CVAR_DEFINE_AUTO( touch_nonlinear_look, "0", FCVAR_FILTERABLE, "enable nonlinear touch look" );
convar_t *touch_pow_factor; static CVAR_DEFINE_AUTO( touch_pow_factor, "1.3", FCVAR_FILTERABLE, "set > 1 to enable" );
convar_t *touch_exp_mult; static CVAR_DEFINE_AUTO( touch_pow_mult, "400.0", FCVAR_FILTERABLE, "power multiplier, usually 200-1000" );
convar_t *touch_grid_enable; static CVAR_DEFINE_AUTO( touch_exp_mult, "0", FCVAR_FILTERABLE, "exponent multiplier, usually 20-200, 0 to disable" );
convar_t *touch_grid_count; static CVAR_DEFINE_AUTO( touch_grid_count, "50", FCVAR_FILTERABLE, "touch grid count" );
convar_t *touch_config_file; static CVAR_DEFINE_AUTO( touch_grid_enable, "1", FCVAR_FILTERABLE, "enable touch grid" );
convar_t *touch_in_menu; static CVAR_DEFINE_AUTO( touch_config_file, "touch.cfg", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "current touch profile file" );
convar_t *touch_joy_radius; static CVAR_DEFINE_AUTO( touch_precise_amount, "0.5", FCVAR_FILTERABLE, "sensitivity multiplier for precise-look" );
convar_t *touch_dpad_radius; static CVAR_DEFINE_AUTO( touch_highlight_r, "1.0", 0, "highlight r color" );
convar_t *touch_move_indicator; static CVAR_DEFINE_AUTO( touch_highlight_g, "1.0", 0, "highlight g color" );
convar_t *touch_highlight_r; static CVAR_DEFINE_AUTO( touch_highlight_b, "1.0", 0, "highlight b color" );
convar_t *touch_highlight_g; static CVAR_DEFINE_AUTO( touch_highlight_a, "1.0", 0, "highlight alpha" );
convar_t *touch_highlight_b; static CVAR_DEFINE_AUTO( touch_dpad_radius, "1.0", FCVAR_FILTERABLE, "dpad radius multiplier" );
convar_t *touch_highlight_a; static CVAR_DEFINE_AUTO( touch_joy_radius, "1.0", FCVAR_FILTERABLE, "joy radius multiplier" );
convar_t *touch_precise_amount; static CVAR_DEFINE_AUTO( touch_move_indicator, "0.0", FCVAR_FILTERABLE, "indicate move events (0 to disable)" );
convar_t *touch_joy_texture; static CVAR_DEFINE_AUTO( touch_joy_texture, "touch_default/joy", FCVAR_FILTERABLE, "texture for move indicator");
CVAR_DEFINE_AUTO( touch_enable, DEFAULT_TOUCH_ENABLE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enable touch controls" ); CVAR_DEFINE_AUTO( touch_enable, DEFAULT_TOUCH_ENABLE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enable touch controls" );
CVAR_DEFINE_AUTO( touch_emulate, "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "emulate touch with mouse" ); CVAR_DEFINE_AUTO( touch_emulate, "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "emulate touch with mouse" );
@@ -169,13 +170,42 @@ CVAR_DEFINE_AUTO( touch_emulate, "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "emulate
#define B(x) (button->x) #define B(x) (button->x)
#define SCR_W ((float)refState.width) #define SCR_W ((float)refState.width)
#define SCR_H ((float)refState.height) #define SCR_H ((float)refState.height)
#define TO_SCRN_Y(x) (refState.height * (x)) #define TO_SCRN_Y(x) (refState.width * (x) * Touch_AspectRatio())
#define TO_SCRN_X(x) (refState.width * (x)) #define TO_SCRN_X(x) (refState.width * (x))
static void IN_TouchCheckCoords( float *x1, float *y1, float *x2, float *y2 ); static void IN_TouchCheckCoords( float *x1, float *y1, float *x2, float *y2 );
static void IN_TouchEditClear( void ); static void IN_TouchEditClear( void );
static void Touch_InitConfig( void ); static void Touch_InitConfig( void );
void Touch_NotifyResize( void )
{
if( refState.width && refState.height && ( !touch.configchanged || !touch.actual_aspect_ratio ))
{
float aspect_ratio = SCR_H/SCR_W;
if( aspect_ratio < 0.99 && aspect_ratio > touch.actual_aspect_ratio )
touch.actual_aspect_ratio = aspect_ratio;
}
}
static inline float Touch_AspectRatio( void )
{
if( touch.config_aspect_ratio )
return touch.config_aspect_ratio;
else if( touch.actual_aspect_ratio )
return touch.actual_aspect_ratio;
else if( refState.width && refState.height )
return SCR_H/SCR_W;
else
return 9.0f / 16.0f;
}
static void Touch_ConfigAspectRatio_f( void )
{
touch.config_aspect_ratio = Q_atof( Cmd_Argv( 1 ));
}
/* /*
========================== ==========================
Touch_ExportButtonToConfig Touch_ExportButtonToConfig
@@ -207,7 +237,7 @@ static inline int Touch_ExportButtonToConfig( file_t *f, touch_button_t *button,
if( keepAspect ) if( keepAspect )
{ {
float aspect = ( B(y2) - B(y1) ) / ( ( B(x2) - B(x1) ) /(SCR_H/SCR_W) ); float aspect = ( B(y2) - B(y1) ) / ( ( B(x2) - B(x1) ) /(Touch_AspectRatio()) );
FS_Printf( f, " %f\n", aspect ); FS_Printf( f, " %f\n", aspect );
} }
else FS_Printf( f, "\n" ); else FS_Printf( f, "\n" );
@@ -242,36 +272,38 @@ qboolean Touch_DumpConfig( const char *name, const char *profilename )
FS_Printf( f, "\ntouch_config_file \"%s\"\n", profilename ); FS_Printf( f, "\ntouch_config_file \"%s\"\n", profilename );
FS_Printf( f, "\n// touch cvars\n" ); FS_Printf( f, "\n// touch cvars\n" );
FS_Printf( f, "\n// sensitivity settings\n" ); FS_Printf( f, "\n// sensitivity settings\n" );
FS_Printf( f, "touch_pitch \"%f\"\n", touch_pitch->value ); FS_Printf( f, "touch_pitch \"%f\"\n", touch_pitch.value );
FS_Printf( f, "touch_yaw \"%f\"\n", touch_yaw->value ); FS_Printf( f, "touch_yaw \"%f\"\n", touch_yaw.value );
FS_Printf( f, "touch_forwardzone \"%f\"\n", touch_forwardzone->value ); FS_Printf( f, "touch_forwardzone \"%f\"\n", touch_forwardzone.value );
FS_Printf( f, "touch_sidezone \"%f\"\n", touch_sidezone->value ); FS_Printf( f, "touch_sidezone \"%f\"\n", touch_sidezone.value );
FS_Printf( f, "touch_nonlinear_look \"%d\"\n", CVAR_TO_BOOL(touch_nonlinear_look)); FS_Printf( f, "touch_nonlinear_look \"%d\"\n", touch_nonlinear_look.value ? 1 : 0 );
FS_Printf( f, "touch_pow_factor \"%f\"\n", touch_pow_factor->value ); FS_Printf( f, "touch_pow_factor \"%f\"\n", touch_pow_factor.value );
FS_Printf( f, "touch_pow_mult \"%f\"\n", touch_pow_mult->value ); FS_Printf( f, "touch_pow_mult \"%f\"\n", touch_pow_mult.value );
FS_Printf( f, "touch_exp_mult \"%f\"\n", touch_exp_mult->value ); FS_Printf( f, "touch_exp_mult \"%f\"\n", touch_exp_mult.value );
FS_Printf( f, "\n// grid settings\n" ); FS_Printf( f, "\n// grid settings\n" );
FS_Printf( f, "touch_grid_count \"%d\"\n", (int)touch_grid_count->value ); FS_Printf( f, "touch_grid_count \"%d\"\n", (int)touch_grid_count.value );
FS_Printf( f, "touch_grid_enable \"%d\"\n", CVAR_TO_BOOL(touch_grid_enable)); FS_Printf( f, "touch_grid_enable \"%d\"\n", touch_grid_enable.value ? 1 : 0 );
FS_Printf( f, "\n// global overstroke (width, r, g, b, a)\n" ); FS_Printf( f, "\n// global overstroke (width, r, g, b, a)\n" );
FS_Printf( f, "touch_set_stroke %d %d %d %d %d\n", touch.swidth, touch.scolor[0], touch.scolor[1], touch.scolor[2], touch.scolor[3] ); FS_Printf( f, "touch_set_stroke %d %d %d %d %d\n", touch.swidth, touch.scolor[0], touch.scolor[1], touch.scolor[2], touch.scolor[3] );
FS_Printf( f, "\n// highlight when pressed\n" ); FS_Printf( f, "\n// highlight when pressed\n" );
FS_Printf( f, "touch_highlight_r \"%f\"\n", touch_highlight_r->value ); FS_Printf( f, "touch_highlight_r \"%f\"\n", touch_highlight_r.value );
FS_Printf( f, "touch_highlight_g \"%f\"\n", touch_highlight_g->value ); FS_Printf( f, "touch_highlight_g \"%f\"\n", touch_highlight_g.value );
FS_Printf( f, "touch_highlight_b \"%f\"\n", touch_highlight_b->value ); FS_Printf( f, "touch_highlight_b \"%f\"\n", touch_highlight_b.value );
FS_Printf( f, "touch_highlight_a \"%f\"\n", touch_highlight_a->value ); FS_Printf( f, "touch_highlight_a \"%f\"\n", touch_highlight_a.value );
FS_Printf( f, "\n// _joy and _dpad options\n" ); FS_Printf( f, "\n// _joy and _dpad options\n" );
FS_Printf( f, "touch_dpad_radius \"%f\"\n", touch_dpad_radius->value ); FS_Printf( f, "touch_dpad_radius \"%f\"\n", touch_dpad_radius.value );
FS_Printf( f, "touch_joy_radius \"%f\"\n", touch_joy_radius->value ); FS_Printf( f, "touch_joy_radius \"%f\"\n", touch_joy_radius.value );
FS_Printf( f, "\n// how much slowdown when Precise Look button pressed\n" ); FS_Printf( f, "\n// how much slowdown when Precise Look button pressed\n" );
FS_Printf( f, "touch_precise_amount \"%f\"\n", touch_precise_amount->value ); FS_Printf( f, "touch_precise_amount \"%f\"\n", touch_precise_amount.value );
FS_Printf( f, "\n// enable/disable move indicator\n" ); FS_Printf( f, "\n// enable/disable move indicator\n" );
FS_Printf( f, "touch_move_indicator \"%f\"\n", touch_move_indicator->value ); FS_Printf( f, "touch_move_indicator \"%f\"\n", touch_move_indicator.value );
FS_Printf( f, "\n// reset menu state when execing config\n" ); FS_Printf( f, "\n// reset menu state when execing config\n" );
FS_Printf( f, "touch_setclientonly 0\n" ); FS_Printf( f, "touch_setclientonly 0\n" );
FS_Printf( f, "\n// touch buttons\n" ); FS_Printf( f, "\n// touch buttons\n" );
FS_Printf( f, "touch_removeall\n" ); FS_Printf( f, "touch_removeall\n" );
FS_Printf( f, "touch_aspectratio %f\n", Touch_AspectRatio());
for( button = touch.list_user.first; button; button = button->next ) for( button = touch.list_user.first; button; button = button->next )
{ {
@@ -301,18 +333,18 @@ void Touch_WriteConfig( void )
if( Sys_CheckParm( "-nowriteconfig" ) || !touch.configchanged || !touch.config_loaded ) if( Sys_CheckParm( "-nowriteconfig" ) || !touch.configchanged || !touch.config_loaded )
return; return;
Con_DPrintf( "Touch_WriteConfig(): %s\n", touch_config_file->string ); Con_DPrintf( "Touch_WriteConfig(): %s\n", touch_config_file.string );
Q_snprintf( newconfigfile, sizeof( newconfigfile ), "%s.new", touch_config_file->string ); Q_snprintf( newconfigfile, sizeof( newconfigfile ), "%s.new", touch_config_file.string );
Q_snprintf( oldconfigfile, sizeof( oldconfigfile ), "%s.bak", touch_config_file->string ); Q_snprintf( oldconfigfile, sizeof( oldconfigfile ), "%s.bak", touch_config_file.string );
if( Touch_DumpConfig( newconfigfile, touch_config_file->string )) if( Touch_DumpConfig( newconfigfile, touch_config_file.string ))
{ {
FS_Delete( oldconfigfile ); FS_Delete( oldconfigfile );
FS_Rename( touch_config_file->string, oldconfigfile ); FS_Rename( touch_config_file.string, oldconfigfile );
FS_Delete( touch_config_file->string ); FS_Delete( touch_config_file.string );
FS_Rename( newconfigfile, touch_config_file->string ); FS_Rename( newconfigfile, touch_config_file.string );
} }
} }
@@ -377,7 +409,7 @@ static void Touch_GenerateCode_f( void )
if( FBitSet( flags, TOUCH_FL_DEF_HIDE )) if( FBitSet( flags, TOUCH_FL_DEF_HIDE ))
SetBits( flags, TOUCH_FL_HIDE ); SetBits( flags, TOUCH_FL_HIDE );
aspect = ( B(y2) - B(y1) ) / ( ( B(x2) - B(x1) ) /(SCR_H/SCR_W) ); aspect = ( B(y2) - B(y1) ) / ( ( B(x2) - B(x1) ) /(Touch_AspectRatio()) );
if( memcmp( &c, &B(color), sizeof( rgba_t ) ) ) if( memcmp( &c, &B(color), sizeof( rgba_t ) ) )
{ {
Con_Printf( "unsigned char color[] = { %d, %d, %d, %d };\n", B(color[0]), B(color[1]), B(color[2]), B(color[3]) ); Con_Printf( "unsigned char color[] = { %d, %d, %d, %d };\n", B(color[0]), B(color[1]), B(color[2]), B(color[3]) );
@@ -393,7 +425,7 @@ static void Touch_RoundAll_f( void )
{ {
touch_button_t *button; touch_button_t *button;
if( !touch_grid_enable->value ) if( !touch_grid_enable.value )
return; return;
for( button = touch.list_user.first; button; button = button->next ) for( button = touch.list_user.first; button; button = button->next )
@@ -550,6 +582,7 @@ static void Touch_RemoveAll_f( void )
{ {
IN_TouchEditClear(); IN_TouchEditClear();
Touch_ClearList( &touch.list_user ); Touch_ClearList( &touch.list_user );
touch.config_aspect_ratio = 0.0f;
} }
static void Touch_SetColor( touchbuttonlist_t *list, const char *name, byte *color ) static void Touch_SetColor( touchbuttonlist_t *list, const char *name, byte *color )
@@ -727,6 +760,8 @@ static void Touch_SetCommand_f( void )
Con_Printf( S_USAGE "touch_setcommand <name> <command>\n" ); Con_Printf( S_USAGE "touch_setcommand <name> <command>\n" );
} }
static void Touch_LoadDefaults_f( void );
static void Touch_ReloadConfig_f( void ) static void Touch_ReloadConfig_f( void )
{ {
touch.state = state_none; touch.state = state_none;
@@ -736,8 +771,15 @@ static void Touch_ReloadConfig_f( void )
touch.selection->finger = -1; touch.selection->finger = -1;
touch.edit = touch.selection = NULL; touch.edit = touch.selection = NULL;
touch.resize_finger = touch.move_finger = touch.look_finger = touch.wheel_finger = -1; touch.resize_finger = touch.move_finger = touch.look_finger = touch.wheel_finger = -1;
if( FS_FileExists( touch_config_file.string, true ) )
Cbuf_AddTextf( "exec %s\n", touch_config_file->string ); {
Cbuf_AddTextf( "exec \"%s\"\n", touch_config_file.string );
}
else
{
Touch_LoadDefaults_f();
touch.configchanged = true;
}
} }
static touch_button_t *Touch_AddButton( touchbuttonlist_t *list, static touch_button_t *Touch_AddButton( touchbuttonlist_t *list,
@@ -785,7 +827,7 @@ void Touch_AddClientButton( const char *name, const char *texture, const char *c
IN_TouchCheckCoords( &x1, &y1, &x2, &y2 ); IN_TouchCheckCoords( &x1, &y1, &x2, &y2 );
if( round == round_aspect ) if( round == round_aspect )
{ {
y2 = y1 + ( x2 - x1 ) * (SCR_W/SCR_H) * aspect; y2 = y1 + ( x2 - x1 ) / (Touch_AspectRatio()) * aspect;
} }
button = Touch_AddButton( &touch.list_user, name, texture, command, x1, y1, x2, y2, color, true ); button = Touch_AddButton( &touch.list_user, name, texture, command, x1, y1, x2, y2, color, true );
button->flags |= flags | TOUCH_FL_CLIENT | TOUCH_FL_NOEDIT; button->flags |= flags | TOUCH_FL_CLIENT | TOUCH_FL_NOEDIT;
@@ -810,7 +852,7 @@ static void Touch_LoadDefaults_f( void )
if( g_DefaultButtons[i].texturefile[0] == '#' ) if( g_DefaultButtons[i].texturefile[0] == '#' )
y2 = y1 + ( (float)clgame.scrInfo.iCharHeight / (float)clgame.scrInfo.iHeight ) * g_DefaultButtons[i].aspect + touch.swidth*2/SCR_H; y2 = y1 + ( (float)clgame.scrInfo.iCharHeight / (float)clgame.scrInfo.iHeight ) * g_DefaultButtons[i].aspect + touch.swidth*2/SCR_H;
else else
y2 = y1 + ( x2 - x1 ) * (SCR_W/SCR_H) * g_DefaultButtons[i].aspect; y2 = y1 + (( x2 - x1 ) / Touch_AspectRatio()) * g_DefaultButtons[i].aspect;
} }
IN_TouchCheckCoords( &x1, &y1, &x2, &y2 ); IN_TouchCheckCoords( &x1, &y1, &x2, &y2 );
@@ -818,6 +860,7 @@ static void Touch_LoadDefaults_f( void )
button->flags |= g_DefaultButtons[i].flags; button->flags |= g_DefaultButtons[i].flags;
button->aspect = g_DefaultButtons[i].aspect; button->aspect = g_DefaultButtons[i].aspect;
} }
touch.configchanged = true;
} }
// Add default button from client // Add default button from client
@@ -910,7 +953,7 @@ static void Touch_AddButton_f( void )
if( aspect ) if( aspect )
{ {
if( B( texturefile )[0] != '#' ) if( B( texturefile )[0] != '#' )
B( y2 ) = B( y1 ) + ( B( x2 ) - B( x1 )) * ( SCR_W / SCR_H ) * aspect; B( y2 ) = B( y1 ) + (( B( x2 ) - B( x1 )) / Touch_AspectRatio() ) * aspect;
B( aspect ) = aspect; B( aspect ) = aspect;
} }
} }
@@ -918,11 +961,39 @@ static void Touch_AddButton_f( void )
static void Touch_EnableEdit_f( void ) static void Touch_EnableEdit_f( void )
{ {
touch_button_t *button;
float current_ratio = SCR_H/SCR_W;
if( touch.state == state_none ) if( touch.state == state_none )
touch.state = state_edit; touch.state = state_edit;
touch.resize_finger = touch.move_finger = touch.look_finger = touch.wheel_finger = -1; touch.resize_finger = touch.move_finger = touch.look_finger = touch.wheel_finger = -1;
touch.move_button = NULL; touch.move_button = NULL;
touch.configchanged = true; touch.configchanged = true;
/* try determine the best ratio
* User enters editor. Window now have correct size. Need to fix aspect ratio in some cases */
// Case A: no config was loaded, touch was generated with lower height, but window was resized higher, reset it to actual size
if( touch.actual_aspect_ratio > current_ratio )
touch.actual_aspect_ratio = current_ratio;
if( !touch.config_aspect_ratio )
touch.config_aspect_ratio = touch.actual_aspect_ratio;
// Case B: config was loaded, but window may be resized later, so keep y coordinate as is
touch.actual_aspect_ratio = current_ratio;
// convert coordinates to actual aspect ratio after it was updated
if( touch.config_aspect_ratio != touch.actual_aspect_ratio )
{
for( button = touch.list_user.first; button; button = button->next )
{
B(y1) /= touch.actual_aspect_ratio / touch.config_aspect_ratio;
B(y2) /= touch.actual_aspect_ratio / touch.config_aspect_ratio;
// clamp positions to make buttons visible by user
if( B(y2) > 1.0f )
{
B(y1) -= B(y2) - 1.0f;
B(y2) -= B(y2) - 1.0f;
}
}
touch.config_aspect_ratio = touch.actual_aspect_ratio;
}
} }
static void Touch_DisableEdit_f( void ) static void Touch_DisableEdit_f( void )
@@ -935,7 +1006,7 @@ static void Touch_DisableEdit_f( void )
touch.edit = touch.selection = NULL; touch.edit = touch.selection = NULL;
touch.resize_finger = touch.move_finger = touch.look_finger = touch.wheel_finger = -1; touch.resize_finger = touch.move_finger = touch.look_finger = touch.wheel_finger = -1;
if( CVAR_TO_BOOL( touch_in_menu )) if( touch_in_menu.value )
{ {
Cvar_Set( "touch_in_menu", "0" ); Cvar_Set( "touch_in_menu", "0" );
} }
@@ -957,7 +1028,7 @@ static void Touch_DeleteProfile_f( void )
static void Touch_InitEditor( void ) static void Touch_InitEditor( void )
{ {
float x = 0.1f * (SCR_H/SCR_W); float x = 0.1f * (Touch_AspectRatio());
float y = 0.05f; float y = 0.05f;
touch_button_t *temp; touch_button_t *temp;
rgba_t color; rgba_t color;
@@ -1052,33 +1123,34 @@ void Touch_Init( void )
Cmd_AddRestrictedCommand( "touch_generate_code", Touch_GenerateCode_f, "create code sample for mobility API" ); Cmd_AddRestrictedCommand( "touch_generate_code", Touch_GenerateCode_f, "create code sample for mobility API" );
Cmd_AddCommand( "touch_fade", Touch_Fade_f, "start fade animation for selected buttons" ); Cmd_AddCommand( "touch_fade", Touch_Fade_f, "start fade animation for selected buttons" );
Cmd_AddRestrictedCommand( "touch_toggleselection", Touch_ToggleSelection_f, "toggle vidibility on selected button in editor" ); Cmd_AddRestrictedCommand( "touch_toggleselection", Touch_ToggleSelection_f, "toggle vidibility on selected button in editor" );
Cmd_AddRestrictedCommand( "touch_aspectratio", Touch_ConfigAspectRatio_f, "set current aspect ratio" );
// not saved, just runtime state for scripting // not saved, just runtime state for scripting
touch_in_menu = Cvar_Get( "touch_in_menu", "0", FCVAR_FILTERABLE, "draw touch in menu (for internal use only)" ); Cvar_RegisterVariable( &touch_in_menu );
// sensitivity configuration // sensitivity configuration
touch_forwardzone = Cvar_Get( "touch_forwardzone", "0.06", FCVAR_FILTERABLE, "forward touch zone" ); Cvar_RegisterVariable( &touch_forwardzone );
touch_sidezone = Cvar_Get( "touch_sidezone", "0.06", FCVAR_FILTERABLE, "side touch zone" ); Cvar_RegisterVariable( &touch_sidezone );
touch_pitch = Cvar_Get( "touch_pitch", "90", FCVAR_FILTERABLE, "touch pitch sensitivity" ); Cvar_RegisterVariable( &touch_pitch );
touch_yaw = Cvar_Get( "touch_yaw", "120", FCVAR_FILTERABLE, "touch yaw sensitivity" ); Cvar_RegisterVariable( &touch_yaw );
touch_nonlinear_look = Cvar_Get( "touch_nonlinear_look", "0", FCVAR_FILTERABLE, "enable nonlinear touch look" ); Cvar_RegisterVariable( &touch_nonlinear_look );
touch_pow_factor = Cvar_Get( "touch_pow_factor", "1.3", FCVAR_FILTERABLE, "set > 1 to enable" ); Cvar_RegisterVariable( &touch_pow_factor );
touch_pow_mult = Cvar_Get( "touch_pow_mult", "400.0", FCVAR_FILTERABLE, "power multiplier, usually 200-1000" ); Cvar_RegisterVariable( &touch_pow_mult );
touch_exp_mult = Cvar_Get( "touch_exp_mult", "0", FCVAR_FILTERABLE, "exponent multiplier, usually 20-200, 0 to disable" ); Cvar_RegisterVariable( &touch_exp_mult );
// touch.cfg // touch.cfg
touch_grid_count = Cvar_Get( "touch_grid_count", "50", FCVAR_FILTERABLE, "touch grid count" ); Cvar_RegisterVariable( &touch_grid_count );
touch_grid_enable = Cvar_Get( "touch_grid_enable", "1", FCVAR_FILTERABLE, "enable touch grid" ); Cvar_RegisterVariable( &touch_grid_enable );
touch_config_file = Cvar_Get( "touch_config_file", "touch.cfg", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "current touch profile file" ); Cvar_RegisterVariable( &touch_config_file );
touch_precise_amount = Cvar_Get( "touch_precise_amount", "0.5", FCVAR_FILTERABLE, "sensitivity multiplier for precise-look" ); Cvar_RegisterVariable( &touch_precise_amount );
touch_highlight_r = Cvar_Get( "touch_highlight_r", "1.0", 0, "highlight r color" ); Cvar_RegisterVariable( &touch_highlight_r );
touch_highlight_g = Cvar_Get( "touch_highlight_g", "1.0", 0, "highlight g color" ); Cvar_RegisterVariable( &touch_highlight_g );
touch_highlight_b = Cvar_Get( "touch_highlight_b", "1.0", 0, "highlight b color" ); Cvar_RegisterVariable( &touch_highlight_b );
touch_highlight_a = Cvar_Get( "touch_highlight_a", "1.0", 0, "highlight alpha" ); Cvar_RegisterVariable( &touch_highlight_a );
touch_dpad_radius = Cvar_Get( "touch_dpad_radius", "1.0", FCVAR_FILTERABLE, "dpad radius multiplier" ); Cvar_RegisterVariable( &touch_dpad_radius );
touch_joy_radius = Cvar_Get( "touch_joy_radius", "1.0", FCVAR_FILTERABLE, "joy radius multiplier" ); Cvar_RegisterVariable( &touch_joy_radius );
touch_move_indicator = Cvar_Get( "touch_move_indicator", "0.0", FCVAR_FILTERABLE, "indicate move events (0 to disable)" ); Cvar_RegisterVariable( &touch_move_indicator );
touch_joy_texture = Cvar_Get( "touch_joy_texture", "touch_default/joy", FCVAR_FILTERABLE, "texture for move indicator"); Cvar_RegisterVariable( &touch_joy_texture );
// input devices cvar // input devices cvar
Cvar_RegisterVariable( &touch_enable ); Cvar_RegisterVariable( &touch_enable );
@@ -1088,7 +1160,7 @@ void Touch_Init( void )
#if SDL_VERSION_ATLEAST( 2, 0, 10 ) #if SDL_VERSION_ATLEAST( 2, 0, 10 )
SDL_SetHint( SDL_HINT_MOUSE_TOUCH_EVENTS, "0" ); SDL_SetHint( SDL_HINT_MOUSE_TOUCH_EVENTS, "0" );
SDL_SetHint( SDL_HINT_TOUCH_MOUSE_EVENTS, "0" ); SDL_SetHint( SDL_HINT_TOUCH_MOUSE_EVENTS, "0" );
#else #elif defined(SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH)
SDL_SetHint( SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH, "1" ); SDL_SetHint( SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH, "1" );
#endif #endif
@@ -1109,9 +1181,9 @@ static void Touch_InitConfig( void )
/// TODO: hud font /// TODO: hud font
//pfnGetScreenInfo( NULL ); //HACK: update hud screen parameters like iHeight //pfnGetScreenInfo( NULL ); //HACK: update hud screen parameters like iHeight
if( FS_FileExists( touch_config_file->string, true ) ) if( FS_FileExists( touch_config_file.string, true ) )
{ {
Cbuf_AddTextf( "exec \"%s\"\n", touch_config_file->string ); Cbuf_AddTextf( "exec \"%s\"\n", touch_config_file.string );
Cbuf_Execute(); Cbuf_Execute();
} }
else else
@@ -1120,7 +1192,7 @@ static void Touch_InitConfig( void )
} }
Touch_InitEditor(); Touch_InitEditor();
touch.joytexture = ref.dllFuncs.GL_LoadTexture( touch_joy_texture->string, NULL, 0, TF_NOMIPMAP ); touch.joytexture = ref.dllFuncs.GL_LoadTexture( touch_joy_texture.string, NULL, 0, TF_NOMIPMAP );
touch.whitetexture = R_GetBuiltinTexture( REF_WHITE_TEXTURE ); touch.whitetexture = R_GetBuiltinTexture( REF_WHITE_TEXTURE );
touch.configchanged = false; touch.configchanged = false;
touch.config_loaded = true; touch.config_loaded = true;
@@ -1170,10 +1242,10 @@ static void Touch_DrawTexture ( float x1, float y1, float x2, float y2, int text
0, 0, 1, 1, texture ); 0, 0, 1, 1, texture );
} }
#define GRID_COUNT_X ((int)touch_grid_count->value) #define GRID_COUNT_X ((int)touch_grid_count.value)
#define GRID_COUNT_Y (((int)touch_grid_count->value) * SCR_H / SCR_W) #define GRID_COUNT_Y (((int)touch_grid_count.value) * Touch_AspectRatio())
#define GRID_X (1.0f/GRID_COUNT_X) #define GRID_X (1.0f/GRID_COUNT_X)
#define GRID_Y (SCR_W/SCR_H/GRID_COUNT_X) #define GRID_Y (1.0f/Touch_AspectRatio()/GRID_COUNT_X)
#define GRID_ROUND_X(x) ((float)round( x * GRID_COUNT_X ) / GRID_COUNT_X) #define GRID_ROUND_X(x) ((float)round( x * GRID_COUNT_X ) / GRID_COUNT_X)
#define GRID_ROUND_Y(x) ((float)round( x * GRID_COUNT_Y ) / GRID_COUNT_Y) #define GRID_ROUND_Y(x) ((float)round( x * GRID_COUNT_Y ) / GRID_COUNT_Y)
@@ -1192,7 +1264,7 @@ static void IN_TouchCheckCoords( float *x1, float *y1, float *x2, float *y2 )
*y1 -= *y2 - 1, *y2 = 1; *y1 -= *y2 - 1, *y2 = 1;
if( *x2 > 1 ) if( *x2 > 1 )
*x1 -= *x2 - 1, *x2 = 1; *x1 -= *x2 - 1, *x2 = 1;
if( CVAR_TO_BOOL( touch_grid_enable )) if( touch_grid_enable.value )
{ {
*x1 = GRID_ROUND_X( *x1 ); *x1 = GRID_ROUND_X( *x1 );
*x2 = GRID_ROUND_X( *x2 ); *x2 = GRID_ROUND_X( *x2 );
@@ -1251,7 +1323,7 @@ static float Touch_DrawText( float x1, float y1, float x2, float y2, const char
{ {
while( *s && ( *s != '\n' ) && ( *s != ';' ) && ( x1 < maxx ) ) while( *s && ( *s != '\n' ) && ( *s != ';' ) && ( x1 < maxx ) )
x1 += Touch_DrawCharacter( x1, y1, *s++, size ); x1 += Touch_DrawCharacter( x1, y1, *s++, size );
y1 += cls.creditsFont.charHeight / 1024.f * size / SCR_H * SCR_W; y1 += cls.creditsFont.charHeight / 1024.f * size / Touch_AspectRatio();
if( y1 >= maxy ) if( y1 >= maxy )
break; break;
@@ -1288,10 +1360,10 @@ static void Touch_DrawButtons( touchbuttonlist_t *list )
if( ( B( finger ) != -1 ) && !FBitSet( B( flags ), TOUCH_FL_CLIENT ) ) if( ( B( finger ) != -1 ) && !FBitSet( B( flags ), TOUCH_FL_CLIENT ) )
{ {
color[0] = bound( 0,(float) color[0] * touch_highlight_r->value, 255 ); color[0] = bound( 0,(float) color[0] * touch_highlight_r.value, 255 );
color[1] = bound( 0,(float) color[1] * touch_highlight_g->value, 255 ); color[1] = bound( 0,(float) color[1] * touch_highlight_g.value, 255 );
color[2] = bound( 0,(float) color[2] * touch_highlight_b->value, 255 ); color[2] = bound( 0,(float) color[2] * touch_highlight_b.value, 255 );
color[3] = bound( 0,(float) color[3] * touch_highlight_a->value, 255 ); color[3] = bound( 0,(float) color[3] * touch_highlight_a.value, 255 );
} }
color[3] *= B( fade ); color[3] *= B( fade );
@@ -1358,17 +1430,18 @@ void Touch_Draw( void )
if( !touch.initialized || ( !touch_enable.value && !touch.clientonly )) if( !touch.initialized || ( !touch_enable.value && !touch.clientonly ))
return; return;
if( cls.key_dest != key_game && !touch_in_menu.value )
return;
Touch_InitConfig(); Touch_InitConfig();
if( cls.key_dest != key_game && !CVAR_TO_BOOL(touch_in_menu) )
return;
ref.dllFuncs.GL_SetRenderMode( kRenderTransTexture ); ref.dllFuncs.GL_SetRenderMode( kRenderTransTexture );
if( touch.state >= state_edit && CVAR_TO_BOOL(touch_grid_enable) ) if( touch.state >= state_edit && touch_grid_enable.value )
{ {
float x; float x;
if( CVAR_TO_BOOL(touch_in_menu) ) if( touch_in_menu.value )
Touch_DrawTexture( 0, 0, 1, 1, touch.whitetexture, 32, 32, 32, 255 ); Touch_DrawTexture( 0, 0, 1, 1, touch.whitetexture, 32, 32, 32, 255 );
else else
Touch_DrawTexture( 0, 0, 1, 1, touch.whitetexture, 0, 0, 0, 112 ); Touch_DrawTexture( 0, 0, 1, 1, touch.whitetexture, 0, 0, 0, 112 );
@@ -1429,19 +1502,19 @@ void Touch_Draw( void )
ref.dllFuncs.Color4ub( 255, 255, 255, 255 ); ref.dllFuncs.Color4ub( 255, 255, 255, 255 );
if( ( touch.move_finger != -1 ) && touch.move_button && touch_move_indicator->value ) if( ( touch.move_finger != -1 ) && touch.move_button && touch_move_indicator.value )
{ {
float width; float width;
float height; float height;
if( FBitSet( touch_joy_texture->flags, FCVAR_CHANGED ) ) if( FBitSet( touch_joy_texture.flags, FCVAR_CHANGED ) )
{ {
ClearBits( touch_joy_texture->flags, FCVAR_CHANGED ); ClearBits( touch_joy_texture.flags, FCVAR_CHANGED );
touch.joytexture = ref.dllFuncs.GL_LoadTexture( touch_joy_texture->string, NULL, 0, TF_NOMIPMAP ); touch.joytexture = ref.dllFuncs.GL_LoadTexture( touch_joy_texture.string, NULL, 0, TF_NOMIPMAP );
} }
if( touch.move_button->type == touch_move ) if( touch.move_button->type == touch_move )
{ {
width = touch_sidezone->value; width = touch_sidezone.value;
height = touch_forwardzone->value; height = touch_forwardzone.value;
} }
else else
{ {
@@ -1449,13 +1522,13 @@ void Touch_Draw( void )
height = (touch.move_button->y2 - touch.move_button->y1)/2; height = (touch.move_button->y2 - touch.move_button->y1)/2;
} }
ref.dllFuncs.Color4ub( 255, 255, 255, 128 ); ref.dllFuncs.Color4ub( 255, 255, 255, 128 );
ref.dllFuncs.R_DrawStretchPic( TO_SCRN_X( touch.move_start_x - GRID_X * touch_move_indicator->value ), ref.dllFuncs.R_DrawStretchPic( TO_SCRN_X( touch.move_start_x - GRID_X * touch_move_indicator.value ),
TO_SCRN_Y( touch.move_start_y - GRID_Y * touch_move_indicator->value ), TO_SCRN_Y( touch.move_start_y - GRID_Y * touch_move_indicator.value ),
TO_SCRN_X( GRID_X * 2 * touch_move_indicator->value ), TO_SCRN_Y( GRID_Y * 2 * touch_move_indicator->value ), 0, 0, 1, 1, touch.joytexture ); TO_SCRN_X( GRID_X * 2 * touch_move_indicator.value ), TO_SCRN_Y( GRID_Y * 2 * touch_move_indicator.value ), 0, 0, 1, 1, touch.joytexture );
ref.dllFuncs.Color4ub( 255, 255, 255, 255 ); ref.dllFuncs.Color4ub( 255, 255, 255, 255 );
ref.dllFuncs.R_DrawStretchPic( TO_SCRN_X( touch.move_start_x + touch.side * width - GRID_X * touch_move_indicator->value ), ref.dllFuncs.R_DrawStretchPic( TO_SCRN_X( touch.move_start_x + touch.side * width - GRID_X * touch_move_indicator.value ),
TO_SCRN_Y( touch.move_start_y - touch.forward * height - GRID_Y * touch_move_indicator->value ), TO_SCRN_Y( touch.move_start_y - touch.forward * height - GRID_Y * touch_move_indicator.value ),
TO_SCRN_X( GRID_X * 2 * touch_move_indicator->value ), TO_SCRN_Y( GRID_Y * 2 * touch_move_indicator->value ), 0, 0, 1, 1, touch.joytexture ); TO_SCRN_X( GRID_X * 2 * touch_move_indicator.value ), TO_SCRN_Y( GRID_Y * 2 * touch_move_indicator.value ), 0, 0, 1, 1, touch.joytexture );
} }
@@ -1564,28 +1637,28 @@ static void Touch_Motion( touchEventType type, int fingerID, float x, float y, f
if( fingerID == touch.move_finger ) if( fingerID == touch.move_finger )
{ {
// check bounds // check bounds
if( touch_forwardzone->value <= 0 ) if( touch_forwardzone.value <= 0 )
Cvar_SetValue( "touch_forwardzone", 0.5 ); Cvar_SetValue( "touch_forwardzone", 0.5 );
if( touch_sidezone->value <= 0 ) if( touch_sidezone.value <= 0 )
Cvar_SetValue( "touch_sidezone", 0.3 ); Cvar_SetValue( "touch_sidezone", 0.3 );
if( !touch.move_button || touch.move_button->type == touch_move ) if( !touch.move_button || touch.move_button->type == touch_move )
{ {
// move relative to touch start // move relative to touch start
touch.forward = ( touch.move_start_y - y ) / touch_forwardzone->value; touch.forward = ( touch.move_start_y - y ) / touch_forwardzone.value;
touch.side = ( x - touch.move_start_x ) / touch_sidezone->value; touch.side = ( x - touch.move_start_x ) / touch_sidezone.value;
} }
else if( touch.move_button->type == touch_joy ) else if( touch.move_button->type == touch_joy )
{ {
// move relative to joy center // move relative to joy center
touch.forward = ( ( touch.move_button->y2 + touch.move_button->y1 ) - y * 2 ) / ( touch.move_button->y2 - touch.move_button->y1 ) * touch_joy_radius->value; touch.forward = ( ( touch.move_button->y2 + touch.move_button->y1 ) - y * 2 ) / ( touch.move_button->y2 - touch.move_button->y1 ) * touch_joy_radius.value;
touch.side = ( x * 2 - ( touch.move_button->x2 + touch.move_button->x1 ) ) / ( touch.move_button->x2 - touch.move_button->x1 ) * touch_joy_radius->value; touch.side = ( x * 2 - ( touch.move_button->x2 + touch.move_button->x1 ) ) / ( touch.move_button->x2 - touch.move_button->x1 ) * touch_joy_radius.value;
} }
else if( touch.move_button->type == touch_dpad ) else if( touch.move_button->type == touch_dpad )
{ {
// like joy, but without acceleration. useful for bhop // like joy, but without acceleration. useful for bhop
touch.forward = round( ( (touch.move_button->y2 + touch.move_button->y1) - y * 2 ) / ( touch.move_button->y2 - touch.move_button->y1 ) * touch_dpad_radius->value ); touch.forward = round( ( (touch.move_button->y2 + touch.move_button->y1) - y * 2 ) / ( touch.move_button->y2 - touch.move_button->y1 ) * touch_dpad_radius.value );
touch.side = round( ( x * 2 - (touch.move_button->x2 + touch.move_button->x1) ) / ( touch.move_button->x2 - touch.move_button->x1 ) * touch_dpad_radius->value ); touch.side = round( ( x * 2 - (touch.move_button->x2 + touch.move_button->x1) ) / ( touch.move_button->x2 - touch.move_button->x1 ) * touch_dpad_radius.value );
} }
touch.forward = bound( -1, touch.forward, 1 ); touch.forward = bound( -1, touch.forward, 1 );
@@ -1596,9 +1669,9 @@ static void Touch_Motion( touchEventType type, int fingerID, float x, float y, f
if( fingerID == touch.look_finger ) if( fingerID == touch.look_finger )
{ {
if( touch.precision ) if( touch.precision )
dx *= touch_precise_amount->value, dy *= touch_precise_amount->value; dx *= touch_precise_amount.value, dy *= touch_precise_amount.value;
if( CVAR_TO_BOOL(touch_nonlinear_look) ) if( touch_nonlinear_look.value )
{ {
float dabs, dcos, dsin; float dabs, dcos, dsin;
@@ -1611,11 +1684,11 @@ static void Touch_Motion( touchEventType type, int fingerID, float x, float y, f
dcos = dx / dabs; dcos = dx / dabs;
dsin = dy / dabs; dsin = dy / dabs;
if( touch_exp_mult->value > 1 ) if( touch_exp_mult.value > 1 )
dabs = ( exp( dabs * touch_exp_mult->value ) - 1 ) / touch_exp_mult->value; dabs = ( exp( dabs * touch_exp_mult.value ) - 1 ) / touch_exp_mult.value;
if( touch_pow_mult->value > 1 && touch_pow_factor->value > 1 ) if( touch_pow_mult.value > 1 && touch_pow_factor.value > 1 )
dabs = pow( dabs * touch_pow_mult->value, touch_pow_factor->value ) / touch_pow_mult->value; dabs = pow( dabs * touch_pow_mult.value, touch_pow_factor.value ) / touch_pow_mult.value;
dx = dabs * dcos; dx = dabs * dcos;
dy = dabs * dsin; dy = dabs * dsin;
@@ -1626,7 +1699,7 @@ static void Touch_Motion( touchEventType type, int fingerID, float x, float y, f
return; return;
// accumulate // accumulate
touch.yaw -= dx * touch_yaw->value, touch.pitch += dy * touch_pitch->value; touch.yaw -= dx * touch_yaw.value, touch.pitch += dy * touch_pitch.value;
} }
} }
@@ -1949,8 +2022,10 @@ static int Touch_ControlsEvent( touchEventType type, int fingerID, float x, floa
int IN_TouchEvent( touchEventType type, int fingerID, float x, float y, float dx, float dy ) int IN_TouchEvent( touchEventType type, int fingerID, float x, float y, float dx, float dy )
{ {
y *= SCR_H/SCR_W/Touch_AspectRatio();
// Con_Printf("%f %f\n", TO_SCRN_X(x), TO_SCRN_Y(y));
// simulate menu mouse click // simulate menu mouse click
if( cls.key_dest != key_game && !CVAR_TO_BOOL( touch_in_menu )) if( cls.key_dest != key_game && !touch_in_menu.value )
{ {
touch.move_finger = touch.resize_finger = touch.look_finger = -1; touch.move_finger = touch.resize_finger = touch.look_finger = -1;
// Hack for keyboard, hope it help // Hack for keyboard, hope it help

View File

@@ -36,16 +36,15 @@ static struct inputstate_s
float lastpitch, lastyaw; float lastpitch, lastyaw;
} inputstate; } inputstate;
extern convar_t *vid_fullscreen; CVAR_DEFINE_AUTO( m_pitch, "0.022", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "mouse pitch value" );
convar_t *m_pitch; CVAR_DEFINE_AUTO( m_yaw, "0.022", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "mouse yaw value" );
convar_t *m_yaw; CVAR_DEFINE_AUTO( m_ignore, DEFAULT_M_IGNORE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "ignore mouse events" );
static CVAR_DEFINE_AUTO( look_filter, "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "filter look events making it smoother" );
static CVAR_DEFINE_AUTO( m_rawinput, "1", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enable mouse raw input" );
convar_t *m_ignore; static CVAR_DEFINE_AUTO( cl_forwardspeed, "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL | FCVAR_FILTERABLE, "Default forward move speed" );
convar_t *cl_forwardspeed; static CVAR_DEFINE_AUTO( cl_backspeed, "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL | FCVAR_FILTERABLE, "Default back move speed" );
convar_t *cl_sidespeed; static CVAR_DEFINE_AUTO( cl_sidespeed, "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL | FCVAR_FILTERABLE, "Default side move speed" );
convar_t *cl_backspeed;
convar_t *look_filter;
convar_t *m_rawinput;
/* /*
================ ================
@@ -58,7 +57,7 @@ uint IN_CollectInputDevices( void )
{ {
uint ret = 0; uint ret = 0;
if( !m_ignore->value ) // no way to check is mouse connected, so use cvar only if( !m_ignore.value ) // no way to check is mouse connected, so use cvar only
ret |= INPUT_DEVICE_MOUSE; ret |= INPUT_DEVICE_MOUSE;
if( touch_enable.value ) if( touch_enable.value )
@@ -86,18 +85,18 @@ player is connected to the server
*/ */
void IN_LockInputDevices( qboolean lock ) void IN_LockInputDevices( qboolean lock )
{ {
extern convar_t *joy_enable; // private to input system extern convar_t joy_enable; // private to input system
if( lock ) if( lock )
{ {
SetBits( m_ignore->flags, FCVAR_READ_ONLY ); SetBits( m_ignore.flags, FCVAR_READ_ONLY );
SetBits( joy_enable->flags, FCVAR_READ_ONLY ); SetBits( joy_enable.flags, FCVAR_READ_ONLY );
SetBits( touch_enable.flags, FCVAR_READ_ONLY ); SetBits( touch_enable.flags, FCVAR_READ_ONLY );
} }
else else
{ {
ClearBits( m_ignore->flags, FCVAR_READ_ONLY ); ClearBits( m_ignore.flags, FCVAR_READ_ONLY );
ClearBits( joy_enable->flags, FCVAR_READ_ONLY ); ClearBits( joy_enable.flags, FCVAR_READ_ONLY );
ClearBits( touch_enable.flags, FCVAR_READ_ONLY ); ClearBits( touch_enable.flags, FCVAR_READ_ONLY );
} }
} }
@@ -110,12 +109,12 @@ IN_StartupMouse
*/ */
void IN_StartupMouse( void ) void IN_StartupMouse( void )
{ {
m_ignore = Cvar_Get( "m_ignore", DEFAULT_M_IGNORE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "ignore mouse events" ); Cvar_RegisterVariable( &m_ignore );
m_pitch = Cvar_Get( "m_pitch", "0.022", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "mouse pitch value" ); Cvar_RegisterVariable( &m_pitch );
m_yaw = Cvar_Get( "m_yaw", "0.022", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "mouse yaw value" ); Cvar_RegisterVariable( &m_yaw );
look_filter = Cvar_Get( "look_filter", "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "filter look events making it smoother" ); Cvar_RegisterVariable( &look_filter );
m_rawinput = Cvar_Get( "m_rawinput", "1", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enable mouse raw input" ); Cvar_RegisterVariable( &m_rawinput );
// You can use -nomouse argument to prevent using mouse from client // You can use -nomouse argument to prevent using mouse from client
// -noenginemouse will disable all mouse input // -noenginemouse will disable all mouse input
@@ -180,9 +179,6 @@ void IN_ToggleClientMouse( int newstate, int oldstate )
{ {
Platform_SetCursorType( dc_arrow ); Platform_SetCursorType( dc_arrow );
#if XASH_ANDROID
Android_ShowMouse( true );
#endif
#if XASH_USE_EVDEV #if XASH_USE_EVDEV
Evdev_SetGrab( false ); Evdev_SetGrab( false );
#endif #endif
@@ -191,14 +187,15 @@ void IN_ToggleClientMouse( int newstate, int oldstate )
{ {
Platform_SetCursorType( dc_none ); Platform_SetCursorType( dc_none );
#if XASH_ANDROID
Android_ShowMouse( false );
#endif
#if XASH_USE_EVDEV #if XASH_USE_EVDEV
Evdev_SetGrab( true ); Evdev_SetGrab( true );
#endif #endif
} }
// don't leave the user without cursor if they enabled m_ignore
if( m_ignore.value )
return;
if( oldstate == key_game ) if( oldstate == key_game )
{ {
IN_DeactivateMouse(); IN_DeactivateMouse();
@@ -214,11 +211,14 @@ void IN_CheckMouseState( qboolean active )
static qboolean s_bRawInput, s_bMouseGrab; static qboolean s_bRawInput, s_bMouseGrab;
#if XASH_WIN32 #if XASH_WIN32
qboolean useRawInput = ( CVAR_TO_BOOL( m_rawinput ) && clgame.client_dll_uses_sdl ) || clgame.dllFuncs.pfnLookEvent != NULL; qboolean useRawInput = ( m_rawinput.value && clgame.client_dll_uses_sdl ) || clgame.dllFuncs.pfnLookEvent != NULL;
#else #else
qboolean useRawInput = true; // always use SDL code qboolean useRawInput = true; // always use SDL code
#endif #endif
if( m_ignore.value )
return;
if( active && useRawInput && !host.mouse_visible && cls.state == ca_active ) if( active && useRawInput && !host.mouse_visible && cls.state == ca_active )
{ {
if( !s_bRawInput ) if( !s_bRawInput )
@@ -414,9 +414,9 @@ IN_Init
*/ */
void IN_Init( void ) void IN_Init( void )
{ {
cl_forwardspeed = Cvar_Get( "cl_forwardspeed", "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL | FCVAR_FILTERABLE, "Default forward move speed" ); Cvar_RegisterVariable( &cl_forwardspeed );
cl_backspeed = Cvar_Get( "cl_backspeed", "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL | FCVAR_FILTERABLE, "Default back move speed" ); Cvar_RegisterVariable( &cl_backspeed );
cl_sidespeed = Cvar_Get( "cl_sidespeed", "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL | FCVAR_FILTERABLE, "Default side move speed" ); Cvar_RegisterVariable( &cl_sidespeed );
if( !Host_IsDedicated() ) if( !Host_IsDedicated() )
{ {
@@ -453,8 +453,8 @@ static void IN_JoyAppendMove( usercmd_t *cmd, float forwardmove, float sidemove
{ {
static uint moveflags = T | S; static uint moveflags = T | S;
if( forwardmove ) cmd->forwardmove = forwardmove * cl_forwardspeed->value; if( forwardmove ) cmd->forwardmove = forwardmove * cl_forwardspeed.value;
if( sidemove ) cmd->sidemove = sidemove * cl_sidespeed->value; if( sidemove ) cmd->sidemove = sidemove * cl_sidespeed.value;
if( forwardmove ) if( forwardmove )
{ {
@@ -529,8 +529,8 @@ static void IN_CollectInput( float *forward, float *side, float *pitch, float *y
{ {
float x, y; float x, y;
Platform_MouseMove( &x, &y ); Platform_MouseMove( &x, &y );
*pitch += y * m_pitch->value; *pitch += y * m_pitch.value;
*yaw -= x * m_yaw->value; *yaw -= x * m_yaw.value;
#if XASH_USE_EVDEV #if XASH_USE_EVDEV
IN_EvdevMove( yaw, pitch ); IN_EvdevMove( yaw, pitch );
@@ -540,7 +540,7 @@ static void IN_CollectInput( float *forward, float *side, float *pitch, float *y
Joy_FinalizeMove( forward, side, yaw, pitch ); Joy_FinalizeMove( forward, side, yaw, pitch );
Touch_GetMove( forward, side, yaw, pitch ); Touch_GetMove( forward, side, yaw, pitch );
if( look_filter->value ) if( look_filter.value )
{ {
*pitch = ( inputstate.lastpitch + *pitch ) / 2; *pitch = ( inputstate.lastpitch + *pitch ) / 2;
*yaw = ( inputstate.lastyaw + *yaw ) / 2; *yaw = ( inputstate.lastyaw + *yaw ) / 2;
@@ -598,7 +598,7 @@ void IN_Commands( void )
{ {
float forward = 0, side = 0, pitch = 0, yaw = 0; float forward = 0, side = 0, pitch = 0, yaw = 0;
IN_CollectInput( &forward, &side, &pitch, &yaw, in_mouseinitialized && !CVAR_TO_BOOL( m_ignore ) ); IN_CollectInput( &forward, &side, &pitch, &yaw, in_mouseinitialized && !m_ignore.value );
if( cls.key_dest == key_game ) if( cls.key_dest == key_game )
{ {

View File

@@ -46,8 +46,8 @@ uint IN_CollectInputDevices( void );
void IN_LockInputDevices( qboolean lock ); void IN_LockInputDevices( qboolean lock );
void IN_EngineAppendMove( float frametime, void *cmd, qboolean active ); void IN_EngineAppendMove( float frametime, void *cmd, qboolean active );
extern convar_t *m_yaw; extern convar_t m_yaw;
extern convar_t *m_pitch; extern convar_t m_pitch;
// //
// in_touch.c // in_touch.c
// //
@@ -75,6 +75,7 @@ void Touch_ResetDefaultButtons( void );
int IN_TouchEvent( touchEventType type, int fingerID, float x, float y, float dx, float dy ); int IN_TouchEvent( touchEventType type, int fingerID, float x, float y, float dx, float dy );
void Touch_KeyEvent( int key, int down ); void Touch_KeyEvent( int key, int down );
qboolean Touch_WantVisibleCursor( void ); qboolean Touch_WantVisibleCursor( void );
void Touch_NotifyResize( void );
// //
// in_joy.c // in_joy.c

View File

@@ -144,8 +144,8 @@ keyname_t keynames[] =
static void OSK_EnableTextInput( qboolean enable, qboolean force ); static void OSK_EnableTextInput( qboolean enable, qboolean force );
static qboolean OSK_KeyEvent( int key, int down ); static qboolean OSK_KeyEvent( int key, int down );
static convar_t *osk_enable; static CVAR_DEFINE_AUTO( osk_enable, "0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "enable built-in on-screen keyboard" );
static convar_t *key_rotate; static CVAR_DEFINE_AUTO( key_rotate, "0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "rotate arrow keys (0-3)" );
/* /*
=================== ===================
@@ -513,8 +513,8 @@ void Key_Init( void )
// setup default binding. "unbindall" from config.cfg will be reset it // setup default binding. "unbindall" from config.cfg will be reset it
for( kn = keynames; kn->name; kn++ ) Key_SetBinding( kn->keynum, kn->binding ); for( kn = keynames; kn->name; kn++ ) Key_SetBinding( kn->keynum, kn->binding );
osk_enable = Cvar_Get( "osk_enable", "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enable built-in on-screen keyboard" ); Cvar_RegisterVariable( &osk_enable );
key_rotate = Cvar_Get( "key_rotate", "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "rotate arrow keys (0-3)" ); Cvar_RegisterVariable( &key_rotate );
} }
@@ -590,7 +590,7 @@ static qboolean Key_IsAllowedAutoRepeat( int key )
static int Key_Rotate( int key ) static int Key_Rotate( int key )
{ {
if( key_rotate->value == 1.0f ) // CW if( key_rotate.value == 1.0f ) // CW
{ {
if( key == K_UPARROW ) if( key == K_UPARROW )
key = K_LEFTARROW; key = K_LEFTARROW;
@@ -602,7 +602,7 @@ static int Key_Rotate( int key )
key = K_RIGHTARROW; key = K_RIGHTARROW;
} }
else if( key_rotate->value == 3.0f ) // CCW else if( key_rotate.value == 3.0f ) // CCW
{ {
if( key == K_UPARROW ) if( key == K_UPARROW )
key = K_RIGHTARROW; key = K_RIGHTARROW;
@@ -614,7 +614,7 @@ static int Key_Rotate( int key )
key = K_LEFTARROW; key = K_LEFTARROW;
} }
else if( key_rotate->value == 2.0f ) else if( key_rotate.value == 2.0f )
{ {
if( key == K_UPARROW ) if( key == K_UPARROW )
key = K_DOWNARROW; key = K_DOWNARROW;
@@ -719,10 +719,10 @@ void GAME_EXPORT Key_Event( int key, int down )
switch( cls.key_dest ) switch( cls.key_dest )
{ {
case key_game: case key_game:
if( CVAR_TO_BOOL( gl_showtextures )) if( r_showtextures.value )
{ {
// close texture atlas // close texture atlas
Cvar_SetValue( "r_showtextures", 0.0f ); Cvar_DirectSet( &r_showtextures, "0" );
return; return;
} }
else if( host.mouse_visible && cls.state != ca_cinematic ) else if( host.mouse_visible && cls.state != ca_cinematic )
@@ -797,7 +797,7 @@ Key_EnableTextInput
*/ */
void Key_EnableTextInput( qboolean enable, qboolean force ) void Key_EnableTextInput( qboolean enable, qboolean force )
{ {
if( CVAR_TO_BOOL( osk_enable ) ) if( osk_enable.value )
{ {
OSK_EnableTextInput( enable, force ); OSK_EnableTextInput( enable, force );
return; return;
@@ -995,7 +995,7 @@ struct osk_s
static qboolean OSK_KeyEvent( int key, int down ) static qboolean OSK_KeyEvent( int key, int down )
{ {
if( !osk.enable || !CVAR_TO_BOOL( osk_enable ) ) if( !osk.enable || !osk_enable.value )
return false; return false;
if( osk.sending ) if( osk.sending )
@@ -1055,7 +1055,7 @@ static qboolean OSK_KeyEvent( int key, int down )
break; break;
} }
if( !Q_stricmp( cl_charset->string, "utf-8" ) ) if( !Q_stricmp( cl_charset.string, "utf-8" ) )
ch = (unsigned char)osk.curbutton.val; ch = (unsigned char)osk.curbutton.val;
else else
ch = Con_UtfProcessCharForce( (unsigned char)osk.curbutton.val ); ch = Con_UtfProcessCharForce( (unsigned char)osk.curbutton.val );
@@ -1190,7 +1190,7 @@ void OSK_Draw( void )
float x, y; float x, y;
int i, j; int i, j;
if( !osk.enable || !CVAR_TO_BOOL(osk_enable) || !osk.curbutton.val ) if( !osk.enable || !osk_enable.value || !osk.curbutton.val )
return; return;
// draw keyboard // draw keyboard

View File

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

View File

@@ -8,14 +8,15 @@
struct ref_state_s ref; struct ref_state_s ref;
ref_globals_t refState; ref_globals_t refState;
convar_t *gl_vsync; CVAR_DEFINE_AUTO( gl_vsync, "0", FCVAR_ARCHIVE, "enable vertical syncronization" );
convar_t *gl_showtextures; CVAR_DEFINE_AUTO( r_showtextures, "0", FCVAR_CHEAT, "show all uploaded textures" );
convar_t *r_decals; CVAR_DEFINE_AUTO( r_adjust_fov, "1", FCVAR_ARCHIVE, "making FOV adjustment for wide-screens" );
convar_t *r_adjust_fov; CVAR_DEFINE_AUTO( r_decals, "4096", FCVAR_ARCHIVE, "sets the maximum number of decals" );
convar_t *r_showtree; CVAR_DEFINE_AUTO( gl_msaa_samples, "0", FCVAR_GLCONFIG, "samples number for multisample anti-aliasing" );
convar_t *gl_msaa_samples; CVAR_DEFINE_AUTO( gl_clear, "0", FCVAR_ARCHIVE, "clearing screen after each frame" );
convar_t *gl_clear; CVAR_DEFINE_AUTO( r_showtree, "0", FCVAR_ARCHIVE, "build the graph of visible BSP tree" );
convar_t *r_refdll; static CVAR_DEFINE_AUTO( r_refdll, "", FCVAR_RENDERINFO, "choose renderer implementation, if supported" );
static CVAR_DEFINE_AUTO( r_refdll_loaded, "", FCVAR_READ_ONLY, "currently loaded renderer" );
void R_GetTextureParms( int *w, int *h, int texnum ) void R_GetTextureParms( int *w, int *h, int texnum )
{ {
@@ -98,16 +99,6 @@ static void *pfnMod_Extradata( int type, model_t *m )
return NULL; return NULL;
} }
static model_t *pfnMod_GetCurrentLoadingModel( void )
{
return loadmodel;
}
static void pfnMod_SetCurrentLoadingModel( model_t *m )
{
loadmodel = m;
}
static void pfnGetPredictedOrigin( vec3_t v ) static void pfnGetPredictedOrigin( vec3_t v )
{ {
VectorCopy( cl.simorg, v ); VectorCopy( cl.simorg, v );
@@ -231,7 +222,7 @@ static ref_api_t gEngfuncs =
Cvar_VariableString, Cvar_VariableString,
Cvar_SetValue, Cvar_SetValue,
Cvar_Set, Cvar_Set,
(void*)Cvar_RegisterVariable, Cvar_RegisterVariable,
Cvar_FullSet, Cvar_FullSet,
Cmd_AddRefCommand, Cmd_AddRefCommand,
@@ -282,8 +273,6 @@ static ref_api_t gEngfuncs =
Mod_ForName, Mod_ForName,
pfnMod_Extradata, pfnMod_Extradata,
CL_ModelHandle, CL_ModelHandle,
pfnMod_GetCurrentLoadingModel,
pfnMod_SetCurrentLoadingModel,
CL_GetRemapInfoForEntity, CL_GetRemapInfoForEntity,
CL_AllocRemapInfo, CL_AllocRemapInfo,
@@ -379,14 +368,14 @@ static void R_UnloadProgs( void )
Cvar_FullSet( "host_refloaded", "0", FCVAR_READ_ONLY ); Cvar_FullSet( "host_refloaded", "0", FCVAR_READ_ONLY );
Cvar_Unlink( FCVAR_RENDERINFO | FCVAR_GLCONFIG );
Cmd_Unlink( CMD_REFDLL );
COM_FreeLibrary( ref.hInstance ); COM_FreeLibrary( ref.hInstance );
ref.hInstance = NULL; ref.hInstance = NULL;
memset( &refState, 0, sizeof( refState )); memset( &refState, 0, sizeof( refState ));
memset( &ref.dllFuncs, 0, sizeof( ref.dllFuncs )); memset( &ref.dllFuncs, 0, sizeof( ref.dllFuncs ));
Cvar_Unlink( FCVAR_RENDERINFO | FCVAR_GLCONFIG );
Cmd_Unlink( CMD_REFDLL );
} }
static void CL_FillTriAPIFromRef( triangleapi_t *dst, const ref_interface_t *src ) static void CL_FillTriAPIFromRef( triangleapi_t *dst, const ref_interface_t *src )
@@ -531,6 +520,7 @@ static qboolean R_LoadRenderer( const char *refopt )
return false; return false;
} }
Cvar_FullSet( "r_refdll_loaded", refopt, FCVAR_READ_ONLY );
Con_Reportf( "Renderer %s initialized\n", refdll ); Con_Reportf( "Renderer %s initialized\n", refdll );
return true; return true;
@@ -549,21 +539,17 @@ static void SetWidthAndHeightFromCommandLine( void )
return; return;
} }
R_SaveVideoMode( width, height, width, height ); R_SaveVideoMode( width, height, width, height, false );
} }
static void SetFullscreenModeFromCommandLine( void ) static void SetFullscreenModeFromCommandLine( void )
{ {
#if !XASH_MOBILE_PLATFORM if( Sys_CheckParm( "-borderless" ))
if( Sys_CheckParm( "-fullscreen" )) Cvar_DirectSet( &vid_fullscreen, "2" );
{ else if( Sys_CheckParm( "-fullscreen" ))
Cvar_Set( "fullscreen", "1" ); Cvar_DirectSet( &vid_fullscreen, "1" );
}
else if( Sys_CheckParm( "-windowed" )) else if( Sys_CheckParm( "-windowed" ))
{ Cvar_DirectSet( &vid_fullscreen, "0" );
Cvar_Set( "fullscreen", "0" );
}
#endif
} }
static void R_CollectRendererNames( void ) static void R_CollectRendererNames( void )
@@ -583,6 +569,9 @@ static void R_CollectRendererNames( void )
#if XASH_REF_GL4ES_ENABLED #if XASH_REF_GL4ES_ENABLED
"gl4es", "gl4es",
#endif #endif
#if XASH_REF_GLES3COMPAT_ENABLED
"gles3compat",
#endif
#if XASH_REF_SOFT_ENABLED #if XASH_REF_SOFT_ENABLED
"soft", "soft",
#endif #endif
@@ -603,6 +592,9 @@ static void R_CollectRendererNames( void )
#if XASH_REF_GL4ES_ENABLED #if XASH_REF_GL4ES_ENABLED
"GL4ES", "GL4ES",
#endif #endif
#if XASH_REF_GLES3COMPAT_ENABLED
"GLES3 (gl2_shim)"
#endif
#if XASH_REF_SOFT_ENABLED #if XASH_REF_SOFT_ENABLED
"Software", "Software",
#endif #endif
@@ -618,14 +610,15 @@ qboolean R_Init( void )
qboolean success = false; qboolean success = false;
string requested; string requested;
gl_vsync = Cvar_Get( "gl_vsync", "0", FCVAR_ARCHIVE, "enable vertical syncronization" ); Cvar_RegisterVariable( &gl_vsync );
gl_showtextures = Cvar_Get( "r_showtextures", "0", FCVAR_CHEAT, "show all uploaded textures" ); Cvar_RegisterVariable( &r_showtextures );
r_adjust_fov = Cvar_Get( "r_adjust_fov", "1", FCVAR_ARCHIVE, "making FOV adjustment for wide-screens" ); Cvar_RegisterVariable( &r_adjust_fov );
r_decals = Cvar_Get( "r_decals", "4096", FCVAR_ARCHIVE, "sets the maximum number of decals" ); Cvar_RegisterVariable( &r_decals );
gl_msaa_samples = Cvar_Get( "gl_msaa_samples", "0", FCVAR_GLCONFIG, "samples number for multisample anti-aliasing" ); Cvar_RegisterVariable( &gl_msaa_samples );
gl_clear = Cvar_Get( "gl_clear", "0", FCVAR_ARCHIVE, "clearing screen after each frame" ); Cvar_RegisterVariable( &gl_clear );
r_showtree = Cvar_Get( "r_showtree", "0", FCVAR_ARCHIVE, "build the graph of visible BSP tree" ); Cvar_RegisterVariable( &r_showtree );
r_refdll = Cvar_Get( "r_refdll", "", FCVAR_RENDERINFO, "choose renderer implementation, if supported" ); Cvar_RegisterVariable( &r_refdll );
Cvar_RegisterVariable( &r_refdll_loaded );
// cvars that are expected to exist // cvars that are expected to exist
Cvar_Get( "r_speeds", "0", FCVAR_ARCHIVE, "shows renderer speeds" ); Cvar_Get( "r_speeds", "0", FCVAR_ARCHIVE, "shows renderer speeds" );
@@ -669,9 +662,9 @@ qboolean R_Init( void )
if( !success && Sys_GetParmFromCmdLine( "-ref", requested )) if( !success && Sys_GetParmFromCmdLine( "-ref", requested ))
success = R_LoadRenderer( requested ); success = R_LoadRenderer( requested );
if( !success && COM_CheckString( r_refdll->string )) if( !success && COM_CheckString( r_refdll.string ))
{ {
Q_strncpy( requested, r_refdll->string, sizeof( requested )); Q_strncpy( requested, r_refdll.string, sizeof( requested ));
success = R_LoadRenderer( requested ); success = R_LoadRenderer( requested );
} }
@@ -691,7 +684,7 @@ qboolean R_Init( void )
if( !success ) if( !success )
{ {
Host_Error( "Can't initialize any renderer. Check your video drivers!" ); Host_Error( "Can't initialize any renderer. Check your video drivers!\n" );
return false; return false;
} }

View File

@@ -46,9 +46,9 @@ void R_GetTextureParms( int *w, int *h, int texnum );
void GL_RenderFrame( const struct ref_viewpass_s *rvp ); void GL_RenderFrame( const struct ref_viewpass_s *rvp );
// common engine and renderer cvars // common engine and renderer cvars
extern convar_t *r_decals; extern convar_t r_decals;
extern convar_t *r_adjust_fov; extern convar_t r_adjust_fov;
extern convar_t *gl_clear; extern convar_t gl_clear;
qboolean R_Init( void ); qboolean R_Init( void );
void R_Shutdown( void ); void R_Shutdown( void );

View File

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

View File

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

View File

@@ -219,7 +219,6 @@ extern dma_t dma;
extern convar_t s_musicvolume; extern convar_t s_musicvolume;
extern convar_t s_lerping; extern convar_t s_lerping;
extern convar_t *dsp_off;
extern convar_t s_test; // cvar to testify new effects extern convar_t s_test; // cvar to testify new effects
extern convar_t s_samplecount; extern convar_t s_samplecount;
extern convar_t snd_mute_losefocus; extern convar_t snd_mute_losefocus;

View File

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

View File

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

View File

@@ -600,7 +600,9 @@ qboolean Voice_Init( const char *pszCodecName, int quality )
} }
// reinitialize only if codec parameters are different // reinitialize only if codec parameters are different
if( Q_strcmp( voice.codec, pszCodecName ) && voice.quality != quality ) if( !Q_strcmp( voice.codec, pszCodecName ) && voice.quality == quality )
return true;
Voice_Shutdown(); Voice_Shutdown();
voice.autogain.block_size = 128; voice.autogain.block_size = 128;

View File

@@ -547,7 +547,7 @@ int GAME_EXPORT Cmd_Argc( void )
Cmd_Argv Cmd_Argv
============ ============
*/ */
const char *Cmd_Argv( int arg ) const char *GAME_EXPORT Cmd_Argv( int arg )
{ {
if((uint)arg >= cmd_argc ) if((uint)arg >= cmd_argc )
return ""; return "";
@@ -559,7 +559,7 @@ const char *Cmd_Argv( int arg )
Cmd_Args Cmd_Args
============ ============
*/ */
const char *Cmd_Args( void ) const char *GAME_EXPORT Cmd_Args( void )
{ {
return cmd_args; return cmd_args;
} }
@@ -996,7 +996,7 @@ static void Cmd_ExecuteStringWithPrivilegeCheck( const char *text, qboolean isPr
cmd_condlevel = 0; cmd_condlevel = 0;
// cvar value substitution // cvar value substitution
if( CVAR_TO_BOOL( cmd_scripting ) && isPrivileged ) if( cmd_scripting.value && isPrivileged )
{ {
while( *text ) while( *text )
{ {
@@ -1357,7 +1357,7 @@ inserts escape sequences
void Cmd_Escape( char *newCommand, const char *oldCommand, int len ) void Cmd_Escape( char *newCommand, const char *oldCommand, int len )
{ {
int c; int c;
int scripting = CVAR_TO_BOOL( cmd_scripting ); int scripting = cmd_scripting.value;
while( (c = *oldCommand++) && len > 1 ) while( (c = *oldCommand++) && len > 1 )
{ {

View File

@@ -22,7 +22,6 @@ GNU General Public License for more details.
#include "const.h" #include "const.h"
#include "client.h" #include "client.h"
#include "library.h" #include "library.h"
#include "sequence.h"
static const char *file_exts[] = static const char *file_exts[] =
{ {
@@ -104,7 +103,7 @@ static float fran1( void )
return temp; return temp;
} }
void COM_SetRandomSeed( int lSeed ) void GAME_EXPORT COM_SetRandomSeed( int lSeed )
{ {
if( lSeed ) idum = lSeed; if( lSeed ) idum = lSeed;
else idum = -time( NULL ); else idum = -time( NULL );
@@ -267,7 +266,7 @@ static void LZSS_BuildHash( lzss_state_t *state, const byte *source )
list->start = node; list->start = node;
} }
byte *LZSS_CompressNoAlloc( lzss_state_t *state, byte *pInput, int input_length, byte *pOutputBuf, uint *pOutputSize ) static byte *LZSS_CompressNoAlloc( lzss_state_t *state, byte *pInput, int input_length, byte *pOutputBuf, uint *pOutputSize )
{ {
byte *pStart = pOutputBuf; // allocate the output buffer, compressed buffer is expected to be less, caller will free byte *pStart = pOutputBuf; // allocate the output buffer, compressed buffer is expected to be less, caller will free
byte *pEnd = pStart + input_length - sizeof( lzss_header_t ) - 8; // prevent compression failure byte *pEnd = pStart + input_length - sizeof( lzss_header_t ) - 8; // prevent compression failure
@@ -613,7 +612,7 @@ COM_Nibble
Returns the 4 bit nibble for a hex character Returns the 4 bit nibble for a hex character
================== ==================
*/ */
byte COM_Nibble( char c ) static byte COM_Nibble( char c )
{ {
if(( c >= '0' ) && ( c <= '9' )) if(( c >= '0' ) && ( c <= '9' ))
{ {
@@ -661,7 +660,7 @@ COM_MemFgets
============= =============
*/ */
char *COM_MemFgets( byte *pMemFile, int fileSize, int *filePos, char *pBuffer, int bufferSize ) char *GAME_EXPORT COM_MemFgets( byte *pMemFile, int fileSize, int *filePos, char *pBuffer, int bufferSize )
{ {
int i, last, stop; int i, last, stop;
@@ -715,7 +714,7 @@ Cache_Check
consistency check consistency check
==================== ====================
*/ */
void *Cache_Check( poolhandle_t mempool, cache_user_t *c ) void *GAME_EXPORT Cache_Check( poolhandle_t mempool, cache_user_t *c )
{ {
if( !c->data ) if( !c->data )
return NULL; return NULL;
@@ -732,7 +731,7 @@ COM_LoadFileForMe
============= =============
*/ */
byte* GAME_EXPORT COM_LoadFileForMe( const char *filename, int *pLength ) byte *GAME_EXPORT COM_LoadFileForMe( const char *filename, int *pLength )
{ {
string name; string name;
byte *file, *pfile; byte *file, *pfile;
@@ -772,7 +771,7 @@ COM_LoadFile
============= =============
*/ */
byte *COM_LoadFile( const char *filename, int usehunk, int *pLength ) byte *GAME_EXPORT COM_LoadFile( const char *filename, int usehunk, int *pLength )
{ {
return COM_LoadFileForMe( filename, pLength ); return COM_LoadFileForMe( filename, pLength );
} }
@@ -858,59 +857,6 @@ void GAME_EXPORT pfnGetModelBounds( model_t *mod, float *mins, float *maxs )
} }
} }
/*
=============
pfnCvar_RegisterServerVariable
standard path to register game variable
=============
*/
void GAME_EXPORT pfnCvar_RegisterServerVariable( cvar_t *variable )
{
if( variable != NULL )
SetBits( variable->flags, FCVAR_EXTDLL );
Cvar_RegisterVariable( (convar_t *)variable );
}
/*
=============
pfnCvar_RegisterEngineVariable
use with precaution: this cvar will NOT unlinked
after game.dll is unloaded
=============
*/
void GAME_EXPORT pfnCvar_RegisterEngineVariable( cvar_t *variable )
{
Cvar_RegisterVariable( (convar_t *)variable );
}
/*
=============
pfnCvar_RegisterVariable
=============
*/
cvar_t *pfnCvar_RegisterClientVariable( const char *szName, const char *szValue, int flags )
{
// a1ba: try to mitigate outdated client.dll vulnerabilities
if( !Q_stricmp( szName, "motdfile" ))
flags |= FCVAR_PRIVILEGED;
return (cvar_t *)Cvar_Get( szName, szValue, flags|FCVAR_CLIENTDLL, Cvar_BuildAutoDescription( szName, flags|FCVAR_CLIENTDLL ));
}
/*
=============
pfnCvar_RegisterVariable
=============
*/
cvar_t *pfnCvar_RegisterGameUIVariable( const char *szName, const char *szValue, int flags )
{
return (cvar_t *)Cvar_Get( szName, szValue, flags|FCVAR_GAMEUIDLL, Cvar_BuildAutoDescription( szName, flags|FCVAR_GAMEUIDLL ));
}
/* /*
============= =============
pfnCVarGetPointer pfnCVarGetPointer
@@ -918,7 +864,7 @@ pfnCVarGetPointer
can return NULL can return NULL
============= =============
*/ */
cvar_t *pfnCVarGetPointer( const char *szVarName ) cvar_t *GAME_EXPORT pfnCVarGetPointer( const char *szVarName )
{ {
return (cvar_t *)Cvar_FindVar( szVarName ); return (cvar_t *)Cvar_FindVar( szVarName );
} }
@@ -1100,7 +1046,7 @@ void *GAME_EXPORT pfnSequenceGet( const char *fileName, const char *entryName )
{ {
Msg( "Sequence_Get: file %s, entry %s\n", fileName, entryName ); Msg( "Sequence_Get: file %s, entry %s\n", fileName, entryName );
return Sequence_Get( fileName, entryName ); return NULL;
} }
/* /*
@@ -1114,7 +1060,7 @@ void *GAME_EXPORT pfnSequencePickSentence( const char *groupName, int pickMethod
{ {
Msg( "Sequence_PickSentence: group %s, pickMethod %i\n", groupName, pickMethod ); Msg( "Sequence_PickSentence: group %s, pickMethod %i\n", groupName, pickMethod );
return Sequence_PickSentence( groupName, pickMethod, picked ); return NULL;
} }
@@ -1125,30 +1071,7 @@ pfnIsCareerMatch
used by CS:CZ (client stub) used by CS:CZ (client stub)
============= =============
*/ */
int GAME_EXPORT GAME_EXPORT pfnIsCareerMatch( void ) int GAME_EXPORT pfnIsCareerMatch( void )
{
return 0;
}
/*
=============
pfnRegisterTutorMessageShown
only exists in PlayStation version
=============
*/
void GAME_EXPORT pfnRegisterTutorMessageShown( int mid )
{
}
/*
=============
pfnGetTimesTutorMessageShown
only exists in PlayStation version
=============
*/
int GAME_EXPORT pfnGetTimesTutorMessageShown( int mid )
{ {
return 0; return 0;
} }

View File

@@ -144,7 +144,7 @@ typedef enum
#define GameState (&host.game) #define GameState (&host.game)
#define FORCE_DRAW_VERSION_TIME 5.0f // draw version for 5 seconds #define FORCE_DRAW_VERSION_TIME 5.0 // draw version for 5 seconds
#ifdef _DEBUG #ifdef _DEBUG
void DBG_AssertFunction( qboolean fExpr, const char* szExpr, const char* szFile, int szLine, const char* szMessage ); void DBG_AssertFunction( qboolean fExpr, const char* szExpr, const char* szFile, int szLine, const char* szMessage );
@@ -153,16 +153,14 @@ void DBG_AssertFunction( qboolean fExpr, const char* szExpr, const char* szFile,
#define Assert( f ) #define Assert( f )
#endif #endif
extern convar_t *gl_vsync; extern convar_t gl_vsync;
extern convar_t *scr_loading; extern convar_t scr_loading;
extern convar_t *scr_download; extern convar_t scr_download;
extern convar_t *cmd_scripting; extern convar_t cmd_scripting;
extern convar_t *sv_maxclients; extern convar_t cl_allow_levelshots;
extern convar_t *cl_allow_levelshots;
extern convar_t host_developer; extern convar_t host_developer;
extern convar_t *host_limitlocal; extern convar_t host_limitlocal;
extern convar_t *host_framerate; extern convar_t host_maxfps;
extern convar_t *host_maxfps;
extern convar_t sys_timescale; extern convar_t sys_timescale;
extern convar_t cl_filterstuffcmd; extern convar_t cl_filterstuffcmd;
extern convar_t rcon_password; extern convar_t rcon_password;
@@ -273,40 +271,6 @@ typedef struct
double forcedEnd; double forcedEnd;
} soundlist_t; } soundlist_t;
typedef struct
{
char model[MAX_QPATH]; // curstate.modelindex = SV_ModelIndex
vec3_t tentOffset; // if attached, client origin + tentOffset = tent origin.
short clientIndex;
float fadeSpeed;
float bounceFactor;
byte hitSound;
qboolean high_priority;
float x, y, z;
int flags;
float time;
// base state
vec3_t velocity; // baseline.origin
vec3_t avelocity; // baseline.angles
int fadeamount; // baseline.renderamt
float sparklife; // baseline.framerate
float thinkTime; // baseline.scale
// current state
vec3_t origin; // entity.origin
vec3_t angles; // entity.angles
float renderamt; // curstate.renderamt
color24 rendercolor; // curstate.rendercolor
int rendermode; // curstate.rendermode
int renderfx; // curstate.renderfx
float framerate; // curstate.framerate
float frame; // curstate.frame
byte body; // curstate.body
byte skin; // curstate.skin
float scale; // curstate.scale
} tentlist_t;
typedef enum bugcomp_e typedef enum bugcomp_e
{ {
// default mode, we assume that user dlls are not relying on engine bugs // default mode, we assume that user dlls are not relying on engine bugs
@@ -360,8 +324,7 @@ typedef struct host_parm_s
qboolean change_game; // initialize when game is changed qboolean change_game; // initialize when game is changed
qboolean mouse_visible; // vgui override cursor control (never change outside Platform_SetCursorType!) qboolean mouse_visible; // vgui override cursor control (never change outside Platform_SetCursorType!)
qboolean shutdown_issued; // engine is shutting down qboolean shutdown_issued; // engine is shutting down
qboolean force_draw_version; // used when fraps is loaded double force_draw_version_time;
float force_draw_version_time;
qboolean apply_game_config; // when true apply only to game cvars and ignore all other commands qboolean apply_game_config; // when true apply only to game cvars and ignore all other commands
qboolean apply_opengl_config;// when true apply only to opengl cvars and ignore all other commands qboolean apply_opengl_config;// when true apply only to opengl cvars and ignore all other commands
qboolean config_executed; // a bit who indicated was config.cfg already executed e.g. from valve.rc qboolean config_executed; // a bit who indicated was config.cfg already executed e.g. from valve.rc
@@ -418,6 +381,7 @@ typedef void (*xcommand_t)( void );
qboolean FS_LoadProgs( void ); qboolean FS_LoadProgs( void );
void FS_Init( void ); void FS_Init( void );
void FS_Shutdown( void ); void FS_Shutdown( void );
void *FS_GetNativeObject( const char *obj );
// //
// cmd.c // cmd.c
@@ -629,10 +593,6 @@ qboolean SV_Active( void );
============================================================== ==============================================================
*/ */
void pfnCvar_RegisterServerVariable( cvar_t *variable );
void pfnCvar_RegisterEngineVariable( cvar_t *variable );
cvar_t *pfnCvar_RegisterClientVariable( const char *szName, const char *szValue, int flags );
cvar_t *pfnCvar_RegisterGameUIVariable( const char *szName, const char *szValue, int flags );
char *COM_MemFgets( byte *pMemFile, int fileSize, int *filePos, char *pBuffer, int bufferSize ); char *COM_MemFgets( byte *pMemFile, int fileSize, int *filePos, char *pBuffer, int bufferSize );
void COM_HexConvert( const char *pszInput, int nInputLength, byte *pOutput ); void COM_HexConvert( const char *pszInput, int nInputLength, byte *pOutput );
int COM_SaveFile( const char *filename, const void *data, int len ); int COM_SaveFile( const char *filename, const void *data, int len );
@@ -649,7 +609,6 @@ void pfnGetModelBounds( model_t *mod, float *mins, float *maxs );
void pfnCVarDirectSet( cvar_t *var, const char *szValue ); void pfnCVarDirectSet( cvar_t *var, const char *szValue );
int COM_CheckParm( char *parm, char **ppnext ); int COM_CheckParm( char *parm, char **ppnext );
void pfnGetGameDir( char *szGetGameDir ); void pfnGetGameDir( char *szGetGameDir );
int pfnDecalIndex( const char *m );
int pfnGetModelType( model_t *mod ); int pfnGetModelType( model_t *mod );
int pfnIsMapValid( char *filename ); int pfnIsMapValid( char *filename );
void Con_Reportf( const char *szFmt, ... ) _format( 1 ); void Con_Reportf( const char *szFmt, ... ) _format( 1 );
@@ -669,8 +628,6 @@ void *pfnSequencePickSentence( const char *groupName, int pickMethod, int *picke
int pfnIsCareerMatch( void ); int pfnIsCareerMatch( void );
// Decay engfuncs (stubs) // Decay engfuncs (stubs)
int pfnGetTimesTutorMessageShown( int mid );
void pfnRegisterTutorMessageShown( int mid );
void pfnConstructTutorMessageDecayBuffer( int *buffer, int buflen ); void pfnConstructTutorMessageDecayBuffer( int *buffer, int buflen );
void pfnProcessTutorMessageDecayBuffer( int *buffer, int bufferLength ); void pfnProcessTutorMessageDecayBuffer( int *buffer, int bufferLength );
void pfnResetTutorMessageDecayData( void ); void pfnResetTutorMessageDecayData( void );
@@ -755,7 +712,6 @@ struct cmd_s *Cmd_GetNextFunctionHandle( struct cmd_s *cmd );
struct cmdalias_s *Cmd_AliasGetList( void ); struct cmdalias_s *Cmd_AliasGetList( void );
const char *Cmd_GetName( struct cmd_s *cmd ); const char *Cmd_GetName( struct cmd_s *cmd );
void SV_StartSound( edict_t *ent, int chan, const char *sample, float vol, float attn, int flags, int pitch ); void SV_StartSound( edict_t *ent, int chan, const char *sample, float vol, float attn, int flags, int pitch );
void SV_StartMusic( const char *curtrack, const char *looptrack, int position );
void SV_CreateDecal( sizebuf_t *msg, const float *origin, int decalIndex, int entityIndex, int modelIndex, int flags, float scale ); void SV_CreateDecal( sizebuf_t *msg, const float *origin, int decalIndex, int entityIndex, int modelIndex, int flags, float scale );
void Log_Printf( const char *fmt, ... ) _format( 1 ); void Log_Printf( const char *fmt, ... ) _format( 1 );
void SV_BroadcastCommand( const char *fmt, ... ) _format( 1 ); void SV_BroadcastCommand( const char *fmt, ... ) _format( 1 );
@@ -792,8 +748,6 @@ void SV_ShutdownGame( void );
void SV_ExecLoadLevel( void ); void SV_ExecLoadLevel( void );
void SV_ExecLoadGame( void ); void SV_ExecLoadGame( void );
void SV_ExecChangeLevel( void ); void SV_ExecChangeLevel( void );
void SV_InitGameProgs( void );
void SV_FreeGameProgs( void );
void CL_WriteMessageHistory( void ); void CL_WriteMessageHistory( void );
void CL_SendCmd( void ); void CL_SendCmd( void );
void CL_Disconnect( void ); void CL_Disconnect( void );

View File

@@ -18,7 +18,7 @@ GNU General Public License for more details.
#include "const.h" #include "const.h"
#include "kbutton.h" #include "kbutton.h"
extern convar_t *con_gamemaps; extern convar_t con_gamemaps;
#define CON_MAXCMDS 4096 // auto-complete intermediate list #define CON_MAXCMDS 4096 // auto-complete intermediate list
@@ -76,7 +76,7 @@ int Cmd_ListMaps( search_t *t, char *lastmapname, size_t len )
compiler[0] = '\0'; compiler[0] = '\0';
generator[0] = '\0'; generator[0] = '\0';
f = FS_Open( t->filenames[i], "rb", con_gamemaps->value ); f = FS_Open( t->filenames[i], "rb", con_gamemaps.value );
if( f ) if( f )
{ {
@@ -190,7 +190,7 @@ qboolean Cmd_GetMapList( const char *s, char *completedname, int length )
string matchbuf; string matchbuf;
int i, nummaps; int i, nummaps;
t = FS_Search( va( "maps/%s*.bsp", s ), true, con_gamemaps->value ); t = FS_Search( va( "maps/%s*.bsp", s ), true, con_gamemaps.value );
if( !t ) return false; if( !t ) return false;
COM_FileBase( t->filenames[0], matchbuf, sizeof( matchbuf )); COM_FileBase( t->filenames[0], matchbuf, sizeof( matchbuf ));
@@ -1428,8 +1428,6 @@ void GAME_EXPORT Host_WriteServerConfig( const char *name )
Q_snprintf( newconfigfile, MAX_STRING, "%s.new", name ); Q_snprintf( newconfigfile, MAX_STRING, "%s.new", name );
SV_InitGameProgs(); // collect user variables
// FIXME: move this out until menu parser is done // FIXME: move this out until menu parser is done
CSCR_LoadDefaultCVars( "settings.scr" ); CSCR_LoadDefaultCVars( "settings.scr" );
@@ -1446,8 +1444,6 @@ void GAME_EXPORT Host_WriteServerConfig( const char *name )
Host_FinalizeConfig( f, name ); Host_FinalizeConfig( f, name );
} }
else Con_DPrintf( S_ERROR "Couldn't write %s.\n", name ); else Con_DPrintf( S_ERROR "Couldn't write %s.\n", name );
SV_FreeGameProgs(); // release progs with all variables
} }
/* /*

View File

@@ -320,7 +320,9 @@ void Sys_RestoreCrashHandler( void )
#elif XASH_FREEBSD || XASH_NETBSD || XASH_OPENBSD || XASH_ANDROID || XASH_LINUX #elif XASH_FREEBSD || XASH_NETBSD || XASH_OPENBSD || XASH_ANDROID || XASH_LINUX
// Posix signal handler // Posix signal handler
#ifndef XASH_OPENBSD
#include <ucontext.h> #include <ucontext.h>
#endif
#include <signal.h> #include <signal.h>
#include <sys/mman.h> #include <sys/mman.h>
#include "library.h" #include "library.h"
@@ -334,24 +336,6 @@ void Sys_RestoreCrashHandler( void )
static struct sigaction oldFilter; static struct sigaction oldFilter;
#ifdef XASH_DYNAMIC_DLADDR
static int d_dladdr( void *sym, Dl_info *info )
{
static int (*dladdr_real) ( void *sym, Dl_info *info );
if( !dladdr_real )
dladdr_real = dlsym( (void*)(size_t)(-1), "dladdr" );
memset( info, 0, sizeof( *info ) );
if( !dladdr_real )
return -1;
return dladdr_real( sym, info );
}
#define dladdr d_dladdr
#endif
static int Sys_PrintFrame( char *buf, int len, int i, void *addr ) static int Sys_PrintFrame( char *buf, int len, int i, void *addr )
{ {
Dl_info dlinfo; Dl_info dlinfo;
@@ -406,9 +390,9 @@ static void Sys_Crash( int signal, siginfo_t *si, void *context)
bp = (void**)ucontext->uc_mcontext.mc_ebp; bp = (void**)ucontext->uc_mcontext.mc_ebp;
sp = (void**)ucontext->uc_mcontext.mc_esp; sp = (void**)ucontext->uc_mcontext.mc_esp;
#elif XASH_NETBSD #elif XASH_NETBSD
pc = (void*)ucontext->uc_mcontext.__gregs[REG_EIP]; pc = (void*)ucontext->uc_mcontext.__gregs[_REG_EIP];
bp = (void**)ucontext->uc_mcontext.__gregs[REG_EBP]; bp = (void**)ucontext->uc_mcontext.__gregs[_REG_EBP];
sp = (void**)ucontext->uc_mcontext.__gregs[REG_ESP]; sp = (void**)ucontext->uc_mcontext.__gregs[_REG_ESP];
#elif XASH_OPENBSD #elif XASH_OPENBSD
pc = (void*)ucontext->sc_eip; pc = (void*)ucontext->sc_eip;
bp = (void**)ucontext->sc_ebp; bp = (void**)ucontext->sc_ebp;

View File

@@ -19,7 +19,7 @@ GNU General Public License for more details.
#include "eiface.h" // ARRAYSIZE #include "eiface.h" // ARRAYSIZE
convar_t *cvar_vars = NULL; // head of list convar_t *cvar_vars = NULL; // head of list
convar_t *cmd_scripting; CVAR_DEFINE_AUTO( cmd_scripting, "0", FCVAR_ARCHIVE|FCVAR_PRIVILEGED, "enable simple condition checking and variable operations" );
#ifdef HACKS_RELATED_HLMODS #ifdef HACKS_RELATED_HLMODS
typedef struct cvar_filter_quirks_s typedef struct cvar_filter_quirks_s
@@ -211,7 +211,7 @@ const char *Cvar_ValidateString( convar_t *var, const char *value )
int len = 0; int len = 0;
// step through the string, only copying back in characters that are printable // step through the string, only copying back in characters that are printable
while( *pszValue && len < MAX_STRING ) while( *pszValue && len < ( MAX_STRING - 1 ))
{ {
if( ((byte)*pszValue) < 32 ) if( ((byte)*pszValue) < 32 )
{ {
@@ -681,18 +681,18 @@ void Cvar_DirectSet( convar_t *var, const char *value )
{ {
const char *pszValue; const char *pszValue;
if( !var ) return; // ??? if( unlikely( !var )) return; // ???
// lookup for registration // lookup for registration
if( CVAR_CHECK_SENTINEL( var ) || ( var->next == NULL && !FBitSet( var->flags, FCVAR_EXTENDED|FCVAR_ALLOCATED ))) if( unlikely( CVAR_CHECK_SENTINEL( var ) || ( var->next == NULL && !FBitSet( var->flags, FCVAR_EXTENDED|FCVAR_ALLOCATED ))))
{ {
// need to registering cvar fisrt // need to registering cvar fisrt
Cvar_RegisterVariable( var ); // ok, register it Cvar_RegisterVariable( var ); // ok, register it
}
// lookup for registration again // lookup for registration again
if( var != Cvar_FindVar( var->name )) if( var != Cvar_FindVar( var->name ))
return; // how this possible? return; // how this possible?
}
if( FBitSet( var->flags, FCVAR_READ_ONLY )) if( FBitSet( var->flags, FCVAR_READ_ONLY ))
{ {
@@ -1136,8 +1136,6 @@ As Cvar_Set, but also flags it as glconfig
*/ */
void Cvar_SetGL_f( void ) void Cvar_SetGL_f( void )
{ {
convar_t *var;
if( Cmd_Argc() != 3 ) if( Cmd_Argc() != 3 )
{ {
Con_Printf( S_USAGE "setgl <variable> <value>\n" ); Con_Printf( S_USAGE "setgl <variable> <value>\n" );
@@ -1240,7 +1238,7 @@ void Cvar_Init( void )
{ {
cvar_vars = NULL; cvar_vars = NULL;
cvar_active_filter_quirks = NULL; cvar_active_filter_quirks = NULL;
cmd_scripting = Cvar_Get( "cmd_scripting", "0", FCVAR_ARCHIVE|FCVAR_PRIVILEGED, "enable simple condition checking and variable operations" ); Cvar_RegisterVariable( &cmd_scripting );
Cvar_RegisterVariable( &host_developer ); // early registering for dev Cvar_RegisterVariable( &host_developer ); // early registering for dev
Cvar_RegisterVariable( &cl_filterstuffcmd ); Cvar_RegisterVariable( &cl_filterstuffcmd );
Cmd_AddRestrictedCommand( "setgl", Cvar_SetGL_f, "change the value of a opengl variable" ); // OBSOLETE Cmd_AddRestrictedCommand( "setgl", Cvar_SetGL_f, "change the value of a opengl variable" ); // OBSOLETE

View File

@@ -56,8 +56,7 @@ typedef struct convar_s
#define CVAR_DEFINE_AUTO( cv, cvstr, cvflags, cvdesc ) \ #define CVAR_DEFINE_AUTO( cv, cvstr, cvflags, cvdesc ) \
CVAR_DEFINE( cv, #cv, cvstr, cvflags, cvdesc ) CVAR_DEFINE( cv, #cv, cvstr, cvflags, cvdesc )
#define CVAR_TO_BOOL( x ) ((x) && ((x)->value != 0.0f) ? true : false ) #ifndef REF_DLL
cvar_t *Cvar_GetList( void ); cvar_t *Cvar_GetList( void );
#define Cvar_FindVar( name ) Cvar_FindVarExt( name, 0 ) #define Cvar_FindVar( name ) Cvar_FindVarExt( name, 0 )
convar_t *Cvar_FindVarExt( const char *var_name, int ignore_group ); convar_t *Cvar_FindVarExt( const char *var_name, int ignore_group );
@@ -81,5 +80,6 @@ qboolean Cvar_CommandWithPrivilegeCheck( convar_t *v, qboolean isPrivileged );
void Cvar_Init( void ); void Cvar_Init( void );
void Cvar_PostFSInit( void ); void Cvar_PostFSInit( void );
void Cvar_Unlink( int group ); void Cvar_Unlink( int group );
#endif // REF_DLL
#endif//CVAR_H #endif//CVAR_H

View File

@@ -218,11 +218,6 @@ void GAME_EXPORT Con_NXPrintf( struct con_nprint_s *info, const char *fmt, ...
} }
const byte *GL_TextureData( unsigned int texnum )
{
return NULL;
}
void SCR_CheckStartupVids( void ) void SCR_CheckStartupVids( void )
{ {

View File

@@ -18,12 +18,22 @@ GNU General Public License for more details.
#include "common.h" #include "common.h"
#include "library.h" #include "library.h"
#include "platform/platform.h"
fs_api_t g_fsapi; fs_api_t g_fsapi;
fs_globals_t *FI; fs_globals_t *FI;
static pfnCreateInterface_t fs_pfnCreateInterface;
static HINSTANCE fs_hInstance; static HINSTANCE fs_hInstance;
void *FS_GetNativeObject( const char *obj )
{
if( fs_pfnCreateInterface )
return fs_pfnCreateInterface( obj, NULL );
return NULL;
}
static void FS_Rescan_f( void ) static void FS_Rescan_f( void )
{ {
FS_Rescan(); FS_Rescan();
@@ -51,6 +61,8 @@ static fs_interface_t fs_memfuncs =
_Mem_Alloc, _Mem_Alloc,
_Mem_Realloc, _Mem_Realloc,
_Mem_Free, _Mem_Free,
Sys_GetNativeObject,
}; };
static void FS_UnloadProgs( void ) static void FS_UnloadProgs( void )
@@ -95,6 +107,13 @@ qboolean FS_LoadProgs( void )
return false; return false;
} }
if( !( fs_pfnCreateInterface = (pfnCreateInterface_t)COM_GetProcAddress( fs_hInstance, "CreateInterface" )))
{
FS_UnloadProgs();
Host_Error( "FS_LoadProgs: can't find CreateInterface entry point in %s\n", name );
return false;
}
Con_DPrintf( "FS_LoadProgs: filesystem_stdio successfully loaded\n" ); Con_DPrintf( "FS_LoadProgs: filesystem_stdio successfully loaded\n" );
return true; return true;

View File

@@ -33,6 +33,7 @@ GNU General Public License for more details.
#include "common.h" #include "common.h"
#include "base_cmd.h" #include "base_cmd.h"
#include "client.h" #include "client.h"
#include "server.h"
#include "netchan.h" #include "netchan.h"
#include "protocol.h" #include "protocol.h"
#include "mod_local.h" #include "mod_local.h"
@@ -54,15 +55,14 @@ CVAR_DEFINE( host_developer, "developer", "0", FCVAR_FILTERABLE, "engine is in d
CVAR_DEFINE_AUTO( sys_timescale, "1.0", FCVAR_CHEAT|FCVAR_FILTERABLE, "scale frame time" ); 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" ); CVAR_DEFINE_AUTO( sys_ticrate, "100", 0, "framerate in dedicated mode" );
convar_t *host_serverstate; static CVAR_DEFINE_AUTO( host_serverstate, "0", FCVAR_READ_ONLY, "displays current server state" );
convar_t *host_gameloaded; static CVAR_DEFINE_AUTO( host_gameloaded, "0", FCVAR_READ_ONLY, "inidcates a loaded game.dll" );
convar_t *host_clientloaded; static CVAR_DEFINE_AUTO( host_clientloaded, "0", FCVAR_READ_ONLY, "inidcates a loaded client.dll" );
convar_t *host_limitlocal; CVAR_DEFINE_AUTO( host_limitlocal, "0", 0, "apply cl_cmdrate and rate to loopback connection" );
convar_t *host_maxfps; CVAR_DEFINE( host_maxfps, "fps_max", "72", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "host fps upper limit" );
convar_t *host_framerate; static CVAR_DEFINE_AUTO( host_framerate, "0", FCVAR_FILTERABLE, "locks frame timing to this value in seconds" );
convar_t *host_sleeptime; static CVAR_DEFINE( host_sleeptime, "sleeptime", "1", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "milliseconds to sleep for each frame. higher values reduce fps accuracy" );
convar_t *con_gamemaps; CVAR_DEFINE( con_gamemaps, "con_mapfilter", "1", FCVAR_ARCHIVE, "when true show only maps in game folder" );
convar_t *build, *ver;
void Sys_PrintUsage( void ) void Sys_PrintUsage( void )
{ {
@@ -116,6 +116,7 @@ void Sys_PrintUsage( void )
O("-oldfont ", "enable unused Quake font in Half-Life") O("-oldfont ", "enable unused Quake font in Half-Life")
O("-width <n> ", "set window width") O("-width <n> ", "set window width")
O("-height <n> ", "set window height") O("-height <n> ", "set window height")
O("-borderless ", "run engine in fullscreen borderless mode")
O("-fullscreen ", "run engine in fullscreen mode") O("-fullscreen ", "run engine in fullscreen mode")
O("-windowed ", "run engine in windowed mode") O("-windowed ", "run engine in windowed mode")
O("-ref <name> ", "use selected renderer dll") O("-ref <name> ", "use selected renderer dll")
@@ -127,6 +128,7 @@ void Sys_PrintUsage( void )
O("-noenginejoy ", "disable engine builtin joystick support") O("-noenginejoy ", "disable engine builtin joystick support")
O("-noenginemouse ", "disable engine builtin mouse support") O("-noenginemouse ", "disable engine builtin mouse support")
O("-nosound ", "disable sound output") O("-nosound ", "disable sound output")
O("-timedemo ", "run timedemo and exit")
#endif #endif
"\nPlatform-specific options:\n" "\nPlatform-specific options:\n"
@@ -137,7 +139,7 @@ void Sys_PrintUsage( void )
O("-sdl_joy_old_api ","use SDL legacy joystick API") O("-sdl_joy_old_api ","use SDL legacy joystick API")
O("-sdl_renderer <n>","use alternative SDL_Renderer for software") O("-sdl_renderer <n>","use alternative SDL_Renderer for software")
#endif // XASH_SDL #endif // XASH_SDL
#if XASH_ANDROID #if XASH_ANDROID && !XASH_SDL
O("-nativeegl ","use native egl implementation. Use if screen does not update or black") O("-nativeegl ","use native egl implementation. Use if screen does not update or black")
#endif // XASH_ANDROID #endif // XASH_ANDROID
#if XASH_DOS #if XASH_DOS
@@ -278,27 +280,27 @@ static int Host_CalcSleep( void )
#ifndef XASH_DEDICATED #ifndef XASH_DEDICATED
// never sleep in timedemo for benchmarking purposes // never sleep in timedemo for benchmarking purposes
// also don't sleep with vsync for less lag // also don't sleep with vsync for less lag
if( CL_IsTimeDemo( ) || CVAR_TO_BOOL( gl_vsync )) if( CL_IsTimeDemo( ) || gl_vsync.value )
return 0; return 0;
#endif #endif
if( Host_IsDedicated() ) if( Host_IsDedicated() )
{ {
// let the dedicated server some sleep // let the dedicated server some sleep
return host_sleeptime->value; return host_sleeptime.value;
} }
switch( host.status ) switch( host.status )
{ {
case HOST_NOFOCUS: case HOST_NOFOCUS:
if( SV_Active() && CL_IsInGame()) if( SV_Active() && CL_IsInGame())
return host_sleeptime->value; return host_sleeptime.value;
// fallthrough // fallthrough
case HOST_SLEEP: case HOST_SLEEP:
return 20; return 20;
} }
return host_sleeptime->value; return host_sleeptime.value;
} }
void Host_NewInstance( const char *name, const char *finalmsg ) void Host_NewInstance( const char *name, const char *finalmsg )
@@ -599,14 +601,14 @@ double Host_CalcFPS( void )
} }
else if( Host_IsLocalGame( )) else if( Host_IsLocalGame( ))
{ {
if( !CVAR_TO_BOOL( gl_vsync )) if( !gl_vsync.value )
fps = host_maxfps->value; fps = host_maxfps.value;
} }
else else
{ {
if( !CVAR_TO_BOOL( gl_vsync )) if( !gl_vsync.value )
{ {
fps = host_maxfps->value; fps = host_maxfps.value;
if( fps == 0.0 ) fps = MAX_FPS; if( fps == 0.0 ) fps = MAX_FPS;
fps = bound( MIN_FPS, fps, MAX_FPS ); fps = bound( MIN_FPS, fps, MAX_FPS );
} }
@@ -681,8 +683,8 @@ qboolean Host_FilterTime( float time )
oldtime = host.realtime; oldtime = host.realtime;
// NOTE: allow only in singleplayer while demos are not active // NOTE: allow only in singleplayer while demos are not active
if( host_framerate->value > 0.0f && Host_IsLocalGame() && !CL_IsPlaybackDemo() && !CL_IsRecordDemo( )) if( host_framerate.value > 0.0f && Host_IsLocalGame() && !CL_IsPlaybackDemo() && !CL_IsRecordDemo( ))
host.frametime = bound( MIN_FRAMETIME, host_framerate->value * scale, MAX_FRAMETIME ); host.frametime = bound( MIN_FRAMETIME, host_framerate.value * scale, MAX_FRAMETIME );
else host.frametime = bound( MIN_FRAMETIME, host.frametime, MAX_FRAMETIME ); else host.frametime = bound( MIN_FRAMETIME, host.frametime, MAX_FRAMETIME );
return true; return true;
@@ -1016,21 +1018,31 @@ void Host_InitCommon( int argc, char **argv, const char *progname, qboolean bCha
else else
{ {
#if TARGET_OS_IOS #if TARGET_OS_IOS
const char *IOS_GetDocsDir(); Q_strncpy( host.rootdir, IOS_GetDocsDir(), sizeof( host.rootdir ));
Q_strncpy( host.rootdir, IOS_GetDocsDir(), sizeof(host.rootdir) ); #elif XASH_ANDROID && XASH_SDL
Q_strncpy( host.rootdir, SDL_AndroidGetExternalStoragePath(), sizeof( host.rootdir ));
#elif XASH_PSVITA #elif XASH_PSVITA
if ( !PSVita_GetBasePath( host.rootdir, sizeof( host.rootdir ) ) ) if ( !PSVita_GetBasePath( host.rootdir, sizeof( host.rootdir )))
{ {
Sys_Error( "couldn't find xash3d data directory" ); Sys_Error( "couldn't find xash3d data directory" );
host.rootdir[0] = 0; host.rootdir[0] = 0;
} }
#elif (XASH_SDL == 2) && !XASH_NSWITCH // GetBasePath not impl'd in switch-sdl2 #elif (XASH_SDL == 2) && !XASH_NSWITCH // GetBasePath not impl'd in switch-sdl2
char *szBasePath; char *szBasePath = SDL_GetBasePath();
if( szBasePath )
if( !( szBasePath = SDL_GetBasePath() ) ) {
Sys_Error( "couldn't determine current directory: %s", SDL_GetError() );
Q_strncpy( host.rootdir, szBasePath, sizeof( host.rootdir )); Q_strncpy( host.rootdir, szBasePath, sizeof( host.rootdir ));
SDL_free( szBasePath ); SDL_free( szBasePath );
}
else
{
#if XASH_POSIX || XASH_WIN32
if( !getcwd( host.rootdir, sizeof( host.rootdir )))
Sys_Error( "couldn't determine current directory: %s, getcwd: %s", SDL_GetError(), strerror( errno ));
#else
Sys_Error( "couldn't determine current directory: %s", SDL_GetError() );
#endif
}
#else #else
if( !getcwd( host.rootdir, sizeof( host.rootdir ))) if( !getcwd( host.rootdir, sizeof( host.rootdir )))
{ {
@@ -1077,10 +1089,9 @@ void Host_InitCommon( int argc, char **argv, const char *progname, qboolean bCha
FS_LoadProgs(); FS_LoadProgs();
if( FS_SetCurrentDirectory( host.rootdir ) != 0 ) // TODO: this function will cause engine to stop in case of fail
Con_Reportf( "%s is working directory now\n", host.rootdir ); // when it will have an option to return string error, restore Sys_Error
else FS_SetCurrentDirectory( host.rootdir );
Sys_Error( "Changing working directory to %s failed.\n", host.rootdir );
FS_Init(); FS_Init();
@@ -1150,6 +1161,7 @@ Host_Main
int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGame, pfnChangeGame func ) int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGame, pfnChangeGame func )
{ {
static double oldtime, newtime; static double oldtime, newtime;
string demoname;
host.starttime = Sys_DoubleTime(); host.starttime = Sys_DoubleTime();
@@ -1165,18 +1177,18 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
Cmd_AddRestrictedCommand ( "crash", Host_Crash_f, "a way to force a bus error for development reasons"); 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" ); Cvar_RegisterVariable( &host_serverstate );
host_maxfps = Cvar_Get( "fps_max", "72", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "host fps upper limit" ); Cvar_RegisterVariable( &host_maxfps );
host_framerate = Cvar_Get( "host_framerate", "0", FCVAR_FILTERABLE, "locks frame timing to this value in seconds" ); Cvar_RegisterVariable( &host_framerate );
host_sleeptime = Cvar_Get( "sleeptime", "1", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "milliseconds to sleep for each frame. higher values reduce fps accuracy" ); Cvar_RegisterVariable( &host_sleeptime );
host_gameloaded = Cvar_Get( "host_gameloaded", "0", FCVAR_READ_ONLY, "inidcates a loaded game.dll" ); Cvar_RegisterVariable( &host_gameloaded );
host_clientloaded = Cvar_Get( "host_clientloaded", "0", FCVAR_READ_ONLY, "inidcates a loaded client.dll" ); Cvar_RegisterVariable( &host_clientloaded );
host_limitlocal = Cvar_Get( "host_limitlocal", "0", 0, "apply cl_cmdrate and rate to loopback connection" ); Cvar_RegisterVariable( &host_limitlocal );
con_gamemaps = Cvar_Get( "con_mapfilter", "1", FCVAR_ARCHIVE, "when true show only maps in game folder" ); Cvar_RegisterVariable( &con_gamemaps );
Cvar_RegisterVariable( &sys_timescale ); Cvar_RegisterVariable( &sys_timescale );
build = Cvar_Getf( "buildnum", FCVAR_READ_ONLY, "returns a current build number", "%i", Q_buildnum_compat()); Cvar_Getf( "buildnum", FCVAR_READ_ONLY, "returns a current build number", "%i", Q_buildnum_compat());
ver = Cvar_Getf( "ver", FCVAR_READ_ONLY, "shows an engine version", "%i/%s (hw build %i)", PROTOCOL_VERSION, XASH_COMPAT_VERSION, Q_buildnum_compat()); Cvar_Getf( "ver", FCVAR_READ_ONLY, "shows an engine version", "%i/%s (hw build %i)", PROTOCOL_VERSION, XASH_COMPAT_VERSION, Q_buildnum_compat());
Cvar_Getf( "host_ver", FCVAR_READ_ONLY, "detailed info about this build", "%i " XASH_VERSION " %s %s %s", Q_buildnum(), Q_buildos(), Q_buildarch(), Q_buildcommit()); Cvar_Getf( "host_ver", FCVAR_READ_ONLY, "detailed info about this build", "%i " XASH_VERSION " %s %s %s", Q_buildnum(), Q_buildos(), Q_buildarch(), Q_buildcommit());
Cvar_Getf( "host_lowmemorymode", FCVAR_READ_ONLY, "indicates if engine compiled for low RAM consumption (0 - normal, 1 - low engine limits, 2 - low protocol limits)", "%i", XASH_LOW_MEMORY ); Cvar_Getf( "host_lowmemorymode", FCVAR_READ_ONLY, "indicates if engine compiled for low RAM consumption (0 - normal, 1 - low engine limits, 2 - low protocol limits)", "%i", XASH_LOW_MEMORY );
@@ -1246,6 +1258,9 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
Cbuf_ExecStuffCmds(); // execute stuffcmds (commandline) Cbuf_ExecStuffCmds(); // execute stuffcmds (commandline)
SCR_CheckStartupVids(); // must be last SCR_CheckStartupVids(); // must be last
if( Sys_GetParmFromCmdLine( "-timedemo", demoname ))
Cbuf_AddTextf( "timedemo %s\n", demoname );
oldtime = Sys_DoubleTime() - 0.1; oldtime = Sys_DoubleTime() - 0.1;
if( Host_IsDedicated( )) if( Host_IsDedicated( ))
@@ -1294,6 +1309,7 @@ void EXPORT Host_Shutdown( void )
#endif #endif
SV_Shutdown( "Server shutdown\n" ); SV_Shutdown( "Server shutdown\n" );
SV_UnloadProgs();
SV_ShutdownFilter(); SV_ShutdownFilter();
CL_Shutdown(); CL_Shutdown();

View File

@@ -142,6 +142,7 @@ void Image_CopyPalette32bit( void );
void Image_SetPixelFormat( void ); void Image_SetPixelFormat( void );
void Image_GetPaletteQ1( void ); void Image_GetPaletteQ1( void );
void Image_GetPaletteHL( void ); void Image_GetPaletteHL( void );
size_t Image_ComputeSize( int type, int width, int height, int depth );
// //
// formats load // formats load
@@ -156,6 +157,7 @@ qboolean Image_LoadDDS( const char *name, const byte *buffer, fs_offset_t filesi
qboolean Image_LoadFNT( const char *name, const byte *buffer, fs_offset_t filesize ); qboolean Image_LoadFNT( const char *name, const byte *buffer, fs_offset_t filesize );
qboolean Image_LoadLMP( const char *name, const byte *buffer, fs_offset_t filesize ); qboolean Image_LoadLMP( const char *name, const byte *buffer, fs_offset_t filesize );
qboolean Image_LoadPAL( const char *name, const byte *buffer, fs_offset_t filesize ); qboolean Image_LoadPAL( const char *name, const byte *buffer, fs_offset_t filesize );
qboolean Image_LoadKTX2( const char *name, const byte *buffer, fs_offset_t filesize );
// //
// formats save // formats save

View File

@@ -104,6 +104,13 @@ void Image_DXTGetPixelFormat( dds_t *hdr, dds_header_dxt10_t *headerExt )
{ {
switch( headerExt->dxgiFormat ) switch( headerExt->dxgiFormat )
{ {
case DXGI_FORMAT_BC4_TYPELESS:
case DXGI_FORMAT_BC4_UNORM:
image.type = PF_BC4_UNSIGNED;
break;
case DXGI_FORMAT_BC4_SNORM:
image.type = PF_BC4_SIGNED;
break;
case DXGI_FORMAT_BC6H_SF16: case DXGI_FORMAT_BC6H_SF16:
image.type = PF_BC6H_SIGNED; image.type = PF_BC6H_SIGNED;
break; break;
@@ -112,9 +119,20 @@ void Image_DXTGetPixelFormat( dds_t *hdr, dds_header_dxt10_t *headerExt )
image.type = PF_BC6H_UNSIGNED; image.type = PF_BC6H_UNSIGNED;
break; break;
case DXGI_FORMAT_BC7_UNORM: case DXGI_FORMAT_BC7_UNORM:
case DXGI_FORMAT_BC7_UNORM_SRGB:
case DXGI_FORMAT_BC7_TYPELESS: case DXGI_FORMAT_BC7_TYPELESS:
image.type = PF_BC7; image.type = PF_BC7_UNORM;
break;
case DXGI_FORMAT_BC7_UNORM_SRGB:
image.type = PF_BC7_SRGB;
break;
case DXGI_FORMAT_BC5_TYPELESS:
image.type = PF_ATI2;
break;
case DXGI_FORMAT_BC5_UNORM:
image.type = PF_BC5_UNSIGNED;
break;
case DXGI_FORMAT_BC5_SNORM:
image.type = PF_BC5_SIGNED;
break; break;
default: default:
image.type = PF_UNKNOWN; image.type = PF_UNKNOWN;
@@ -143,6 +161,15 @@ void Image_DXTGetPixelFormat( dds_t *hdr, dds_header_dxt10_t *headerExt )
case TYPE_ATI2: case TYPE_ATI2:
image.type = PF_ATI2; image.type = PF_ATI2;
break; break;
case TYPE_BC5S:
image.type = PF_BC5_SIGNED;
break;
case TYPE_BC4S:
image.type = PF_BC4_SIGNED;
break;
case TYPE_BC4U:
image.type = PF_BC4_UNSIGNED;
break;
default: default:
image.type = PF_UNKNOWN; // assume error image.type = PF_UNKNOWN; // assume error
break; break;
@@ -188,27 +215,6 @@ void Image_DXTGetPixelFormat( dds_t *hdr, dds_header_dxt10_t *headerExt )
image.num_mips = hdr->dwMipMapCount; // get actual mip count image.num_mips = hdr->dwMipMapCount; // get actual mip count
} }
size_t Image_DXTGetLinearSize( int type, int width, int height, int depth )
{
switch( type )
{
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:
case PF_RGB_24: return (width * height * depth * 3);
case PF_BGRA_32:
case PF_RGBA_32: return (width * height * depth * 4);
}
return 0;
}
size_t Image_DXTCalcMipmapSize( dds_t *hdr ) size_t Image_DXTCalcMipmapSize( dds_t *hdr )
{ {
size_t buffsize = 0; size_t buffsize = 0;
@@ -219,7 +225,7 @@ size_t Image_DXTCalcMipmapSize( dds_t *hdr )
{ {
width = Q_max( 1, ( hdr->dwWidth >> i )); width = Q_max( 1, ( hdr->dwWidth >> i ));
height = Q_max( 1, ( hdr->dwHeight >> i )); height = Q_max( 1, ( hdr->dwHeight >> i ));
buffsize += Image_DXTGetLinearSize( image.type, width, height, image.depth ); buffsize += Image_ComputeSize( image.type, width, height, image.depth );
} }
return buffsize; return buffsize;
@@ -255,7 +261,7 @@ uint Image_DXTCalcSize( const char *name, dds_t *hdr, size_t filesize )
if( filesize != buffsize ) // main check if( filesize != buffsize ) // main check
{ {
Con_DPrintf( S_WARN "Image_LoadDDS: (%s) probably corrupted (%i should be %lu)\n", name, buffsize, filesize ); Con_DPrintf( S_WARN "Image_LoadDDS: (%s) probably corrupted (%zu should be %lu)\n", name, buffsize, filesize );
if( buffsize > filesize ) if( buffsize > filesize )
return false; return false;
} }
@@ -268,7 +274,7 @@ void Image_DXTAdjustVolume( dds_t *hdr )
if( hdr->dwDepth <= 1 ) if( hdr->dwDepth <= 1 )
return; return;
hdr->dwLinearSize = Image_DXTGetLinearSize( image.type, hdr->dwWidth, hdr->dwHeight, hdr->dwDepth ); hdr->dwLinearSize = Image_ComputeSize( image.type, hdr->dwWidth, hdr->dwHeight, hdr->dwDepth );
hdr->dwFlags |= DDS_LINEARSIZE; hdr->dwFlags |= DDS_LINEARSIZE;
} }
@@ -323,7 +329,7 @@ qboolean Image_LoadDDS( const char *name, const byte *buffer, fs_offset_t filesi
Image_DXTGetPixelFormat( &header, &header2 ); // and image type too :) Image_DXTGetPixelFormat( &header, &header2 ); // and image type too :)
Image_DXTAdjustVolume( &header ); Image_DXTAdjustVolume( &header );
if( !Image_CheckFlag( IL_DDS_HARDWARE ) && ImageDXT( image.type )) if( !Image_CheckFlag( IL_DDS_HARDWARE ) && ImageCompressed( image.type ))
return false; // silently rejected return false; // silently rejected
if( image.type == PF_UNKNOWN ) if( image.type == PF_UNKNOWN )
@@ -356,8 +362,10 @@ qboolean Image_LoadDDS( const char *name, const byte *buffer, fs_offset_t filesi
SetBits( image.flags, IMAGE_HAS_ALPHA ); SetBits( image.flags, IMAGE_HAS_ALPHA );
else if( image.type == PF_DXT5 && Image_CheckDXT5Alpha( &header, fin )) else if( image.type == PF_DXT5 && Image_CheckDXT5Alpha( &header, fin ))
SetBits( image.flags, IMAGE_HAS_ALPHA ); SetBits( image.flags, IMAGE_HAS_ALPHA );
else if ( image.type == PF_BC7 ) else if( image.type == PF_BC5_SIGNED || image.type == PF_BC5_UNSIGNED )
SetBits(image.flags, IMAGE_HAS_ALPHA); SetBits( image.flags, IMAGE_HAS_ALPHA );
else if( image.type == PF_BC7_UNORM || image.type == PF_BC7_SRGB )
SetBits( image.flags, IMAGE_HAS_ALPHA );
if( !FBitSet( header.dsPixelFormat.dwFlags, DDS_LUMINANCE )) if( !FBitSet( header.dsPixelFormat.dwFlags, DDS_LUMINANCE ))
SetBits( image.flags, IMAGE_HAS_COLOR ); SetBits( image.flags, IMAGE_HAS_COLOR );
break; break;

View File

@@ -32,6 +32,9 @@ GNU General Public License for more details.
#define TYPE_DX10 (('0'<<24)+('1'<<16)+('X'<<8)+'D') // little-endian "DX10" #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_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_ATI2 (('2'<<24)+('I'<<16)+('T'<<8)+'A') // little-endian "ATI2"
#define TYPE_BC5S (('S'<<24)+('5'<<16)+('C'<<8)+'B') // little-endian "BC5S"
#define TYPE_BC4S (('S'<<24)+('4'<<16)+('C'<<8)+'B') // little-endian "BC4S"
#define TYPE_BC4U (('U'<<24)+('4'<<16)+('C'<<8)+'B') // little-endian "BC4U"
#define TYPE_RXGB (('B'<<24)+('G'<<16)+('X'<<8)+'R') // little-endian "RXGB" doom3 normalmaps #define TYPE_RXGB (('B'<<24)+('G'<<16)+('X'<<8)+'R') // little-endian "RXGB" doom3 normalmaps
#define TYPE_$ (('\0'<<24)+('\0'<<16)+('\0'<<8)+'$') // little-endian "$" #define TYPE_$ (('\0'<<24)+('\0'<<16)+('\0'<<8)+'$') // little-endian "$"
#define TYPE_o (('\0'<<24)+('\0'<<16)+('\0'<<8)+'o') // little-endian "o" #define TYPE_o (('\0'<<24)+('\0'<<16)+('\0'<<8)+'o') // little-endian "o"

View File

@@ -0,0 +1,204 @@
/*
img_ktx2.c - ktx2 format load
Copyright (C) 2023 Provod
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 "imagelib.h"
#include "xash3d_mathlib.h"
#include "img_ktx2.h"
static void Image_KTX2Format( uint32_t ktx2_format )
{
switch( ktx2_format )
{
case KTX2_FORMAT_BC4_UNORM_BLOCK:
image.type = PF_BC4_UNSIGNED;
// 1 component for ref_gl
break;
case KTX2_FORMAT_BC4_SNORM_BLOCK:
image.type = PF_BC4_SIGNED;
// 1 component for ref_gl
break;
case KTX2_FORMAT_BC5_UNORM_BLOCK:
image.type = PF_BC5_UNSIGNED;
// 2 components for ref_gl
SetBits( image.flags, IMAGE_HAS_ALPHA );
break;
case KTX2_FORMAT_BC5_SNORM_BLOCK:
image.type = PF_BC5_SIGNED;
// 2 components for ref_gl
SetBits( image.flags, IMAGE_HAS_ALPHA );
break;
case KTX2_FORMAT_BC6H_UFLOAT_BLOCK:
image.type = PF_BC6H_UNSIGNED;
// 3 components for ref_gl
SetBits( image.flags, IMAGE_HAS_COLOR );
break;
case KTX2_FORMAT_BC6H_SFLOAT_BLOCK:
image.type = PF_BC6H_SIGNED;
// 3 components for ref_gl
SetBits( image.flags, IMAGE_HAS_COLOR );
break;
case KTX2_FORMAT_BC7_UNORM_BLOCK:
image.type = PF_BC7_UNORM;
// 4 components for ref_gl
SetBits( image.flags, IMAGE_HAS_COLOR | IMAGE_HAS_ALPHA );
break;
case KTX2_FORMAT_BC7_SRGB_BLOCK:
image.type = PF_BC7_SRGB;
// 4 components for ref_gl
SetBits( image.flags, IMAGE_HAS_COLOR | IMAGE_HAS_ALPHA );
break;
default:
image.type = PF_UNKNOWN;
break;
}
}
static qboolean Image_KTX2Parse( const ktx2_header_t *header, const byte *buffer, fs_offset_t filesize )
{
ktx2_index_t index;
size_t total_size = 0;
size_t max_offset = 0;
const byte *const levels_begin = buffer + KTX2_LEVELS_OFFSET;
// Sets image.type and image.flags
Image_KTX2Format( header->vkFormat );
if( image.type == PF_UNKNOWN )
{
Con_DPrintf( S_ERROR "%s: unsupported KTX2 format %d\n", __FUNCTION__, header->vkFormat );
return false;
}
if( !Image_CheckFlag( IL_DDS_HARDWARE ) && ImageCompressed( image.type ))
{
Con_DPrintf( S_WARN "%s: has compressed format, but support is not advertized\n", __FUNCTION__ );
return false;
}
if( header->pixelDepth > 1 )
{
Con_DPrintf( S_ERROR "%s: unsupported KTX2 pixelDepth %d\n", __FUNCTION__, header->pixelDepth );
return false;
}
if( header->faceCount > 1 )
{
Con_DPrintf( S_ERROR "%s: unsupported KTX2 faceCount %d\n", __FUNCTION__, header->faceCount );
return false;
}
if( header->layerCount > 1 )
{
Con_DPrintf( S_ERROR "%s: unsupported KTX2 layerCount %d\n", __FUNCTION__, header->layerCount );
return false;
}
if( header->supercompressionScheme != 0 )
{
Con_DPrintf( S_ERROR "%s: unsupported KTX2 supercompressionScheme %d\n", __FUNCTION__, header->supercompressionScheme );
return false;
}
if( header->levelCount * sizeof( ktx2_level_t ) + KTX2_LEVELS_OFFSET > filesize )
{
Con_DPrintf( S_ERROR "%s: file abruptly ends\n", __FUNCTION__ );
return false;
}
memcpy( &index, buffer + KTX2_IDENTIFIER_SIZE + sizeof( ktx2_header_t ), sizeof( index ));
for( int mip = 0; mip < header->levelCount; ++mip )
{
const uint32_t width = Q_max( 1, ( header->pixelWidth >> mip ));
const uint32_t height = Q_max( 1, ( header->pixelHeight >> mip ));
const uint32_t mip_size = Image_ComputeSize( image.type, width, height, image.depth );
ktx2_level_t level;
memcpy( &level, levels_begin + mip * sizeof( level ), sizeof( level ));
if( mip_size != level.byteLength )
{
Con_DPrintf( S_ERROR "%s: mip=%d size mismatch read=%d, but computed=%d\n",
__FUNCTION__, mip, (int)level.byteLength, mip_size );
return false;
}
total_size += level.byteLength;
max_offset = Q_max( max_offset, level.byteLength + level.byteOffset );
}
if( max_offset > filesize )
return false;
image.size = total_size;
image.num_mips = header->levelCount;
image.rgba = Mem_Malloc( host.imagepool, image.size );
memcpy( image.rgba, buffer, image.size );
for( int mip = 0, cursor = 0; mip < header->levelCount; ++mip )
{
ktx2_level_t level;
memcpy( &level, levels_begin + mip * sizeof( level ), sizeof( level ));
memcpy( image.rgba + cursor, buffer + level.byteOffset, level.byteLength );
cursor += level.byteLength;
}
return true;
}
qboolean Image_LoadKTX2( const char *name, const byte *buffer, fs_offset_t filesize )
{
ktx2_header_t header;
if( filesize < KTX2_MINIMAL_HEADER_SIZE )
return false;
if( memcmp( buffer, KTX2_IDENTIFIER, KTX2_IDENTIFIER_SIZE ) != 0 )
{
Con_DPrintf( S_ERROR "%s: (%s) has invalid identifier\n", __FUNCTION__, name );
return false;
}
memcpy( &header, buffer + KTX2_IDENTIFIER_SIZE, sizeof( header ));
image.width = header.pixelWidth;
image.height = header.pixelHeight;
image.depth = Q_max( 1, header.pixelDepth );
image.num_mips = 1;
ClearBits( image.flags, IMAGE_HAS_COLOR | IMAGE_HAS_ALPHA | IMAGE_HAS_LUMA );
if( !Image_KTX2Parse( &header, buffer, filesize ))
{
if( !Image_CheckFlag( IL_KTX2_RAW ))
return false;
// If KTX2 to imagelib conversion failed, try passing the file as raw data.
// This is useful for ref_vk which can directly support hundreds of formats which we don't convert to pixformat_t here
Con_DPrintf( S_WARN "%s: (%s) could not be converted to supported imagelib format, passing as raw KTX2 data\n", __FUNCTION__, name );
// This is a catch-all for ref_vk, which can do this format directly and natively
image.type = PF_KTX2_RAW;
image.size = filesize;
//image.encode = TODO custom encode type?
image.rgba = Mem_Malloc( host.imagepool, image.size );
memcpy( image.rgba, buffer, image.size );
}
return true;
}

View File

@@ -0,0 +1,79 @@
/*
img_ktx2.h - ktx2 format reference
Copyright (C) 2023 Provod
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.
*/
#ifndef IMG_KTX2_H
#define IMG_KTX2_H
#include <stdint.h>
#define KTX2_IDENTIFIER_SIZE 12
#define KTX2_IDENTIFIER "\xABKTX 20\xBB\r\n\x1A\n"
/*
static const char k_ktx2_identifier[KTX2_IDENTIFIER_SIZE] =
{
'\xAB', 'K', 'T', 'X', ' ', '2', '0', '\xBB', '\r', '\n', '\x1A', '\n'
};
*/
typedef struct
{
uint32_t vkFormat;
uint32_t typeSize;
uint32_t pixelWidth;
uint32_t pixelHeight;
uint32_t pixelDepth;
uint32_t layerCount;
uint32_t faceCount;
uint32_t levelCount;
uint32_t supercompressionScheme;
} ktx2_header_t;
typedef struct
{
uint32_t dfdByteOffset;
uint32_t dfdByteLength;
uint32_t kvdByteOffset;
uint32_t kvdByteLength;
uint64_t sgdByteOffset;
uint64_t sgdByteLength;
} ktx2_index_t;
typedef struct
{
uint64_t byteOffset;
uint64_t byteLength;
uint64_t uncompressedByteLength;
} ktx2_level_t;
#define KTX2_LEVELS_OFFSET ( KTX2_IDENTIFIER_SIZE + sizeof( ktx2_header_t ) + sizeof( ktx2_index_t ))
#define KTX2_MINIMAL_HEADER_SIZE ( KTX2_LEVELS_OFFSET + sizeof( ktx2_level_t ))
// These have the same values as enum VkFormat in vulkan_core.h
// There are hundreds of formats which can be contained in KTX2.
// Below are listed the ones which are supported here. This list can be extended.
typedef enum
{
KTX2_FORMAT_BC4_UNORM_BLOCK = 139,
KTX2_FORMAT_BC4_SNORM_BLOCK = 140,
KTX2_FORMAT_BC5_UNORM_BLOCK = 141,
KTX2_FORMAT_BC5_SNORM_BLOCK = 142,
KTX2_FORMAT_BC6H_UFLOAT_BLOCK = 143,
KTX2_FORMAT_BC6H_SFLOAT_BLOCK = 144,
KTX2_FORMAT_BC7_UNORM_BLOCK = 145,
KTX2_FORMAT_BC7_SRGB_BLOCK = 146,
} ktx2_format_t;
#endif // IMG_KTX2_H

View File

@@ -105,6 +105,7 @@ static const loadpixformat_t load_game[] =
{ "%s%s.%s", "lmp", Image_LoadLMP, IL_HINT_NO }, // hl menu images (cached.wad etc) { "%s%s.%s", "lmp", Image_LoadLMP, IL_HINT_NO }, // hl menu images (cached.wad etc)
{ "%s%s.%s", "fnt", Image_LoadFNT, IL_HINT_HL }, // hl console font (fonts.wad etc) { "%s%s.%s", "fnt", Image_LoadFNT, IL_HINT_HL }, // hl console font (fonts.wad etc)
{ "%s%s.%s", "pal", Image_LoadPAL, IL_HINT_NO }, // install studio\sprite palette { "%s%s.%s", "pal", Image_LoadPAL, IL_HINT_NO }, // install studio\sprite palette
{ "%s%s.%s", "ktx2", Image_LoadKTX2, IL_HINT_NO }, // ktx2 for world and studio models
{ NULL, NULL, NULL, IL_HINT_NO } { NULL, NULL, NULL, IL_HINT_NO }
}; };
@@ -283,8 +284,10 @@ int Image_ComparePalette( const byte *pal )
void Image_SetPalette( const byte *pal, uint *d_table ) void Image_SetPalette( const byte *pal, uint *d_table )
{ {
byte rgba[4]; byte rgba[4];
uint uirgba; // TODO: palette looks byte-swapped on big-endian
int i; int i;
// setup palette // setup palette
switch( image.d_rendermode ) switch( image.d_rendermode )
{ {
@@ -295,7 +298,8 @@ void Image_SetPalette( const byte *pal, uint *d_table )
rgba[1] = pal[i*3+1]; rgba[1] = pal[i*3+1];
rgba[2] = pal[i*3+2]; rgba[2] = pal[i*3+2];
rgba[3] = 0xFF; rgba[3] = 0xFF;
d_table[i] = *(uint *)rgba; memcpy( &uirgba, rgba, sizeof( uirgba ));
d_table[i] = uirgba;
} }
break; break;
case LUMP_GRADIENT: case LUMP_GRADIENT:
@@ -305,7 +309,8 @@ void Image_SetPalette( const byte *pal, uint *d_table )
rgba[1] = pal[766]; rgba[1] = pal[766];
rgba[2] = pal[767]; rgba[2] = pal[767];
rgba[3] = i; rgba[3] = i;
d_table[i] = *(uint *)rgba; memcpy( &uirgba, rgba, sizeof( uirgba ));
d_table[i] = uirgba;
} }
break; break;
case LUMP_MASKED: case LUMP_MASKED:
@@ -315,7 +320,8 @@ void Image_SetPalette( const byte *pal, uint *d_table )
rgba[1] = pal[i*3+1]; rgba[1] = pal[i*3+1];
rgba[2] = pal[i*3+2]; rgba[2] = pal[i*3+2];
rgba[3] = 0xFF; rgba[3] = 0xFF;
d_table[i] = *(uint *)rgba; memcpy( &uirgba, rgba, sizeof( uirgba ));
d_table[i] = uirgba;
} }
d_table[255] = 0; d_table[255] = 0;
break; break;
@@ -326,7 +332,8 @@ void Image_SetPalette( const byte *pal, uint *d_table )
rgba[1] = pal[i*4+1]; rgba[1] = pal[i*4+1];
rgba[2] = pal[i*4+2]; rgba[2] = pal[i*4+2];
rgba[3] = pal[i*4+3]; rgba[3] = pal[i*4+3];
d_table[i] = *(uint *)rgba; memcpy( &uirgba, rgba, sizeof( uirgba ));
d_table[i] = uirgba;
} }
break; break;
} }
@@ -1446,3 +1453,36 @@ qboolean Image_Process(rgbdata_t **pix, int width, int height, uint flags, float
return result; return result;
} }
// This codebase has too many copies of this function:
// - ref_gl has one
// - ref_vk has one
// - ref_soft has one
// - many more places probably have one too
// TODO figure out how to make it available for ref_*
size_t Image_ComputeSize( int type, int width, int height, int depth )
{
switch( type )
{
case PF_DXT1:
case PF_BC4_SIGNED:
case PF_BC4_UNSIGNED:
return ((( width + 3 ) / 4 ) * (( height + 3 ) / 4 ) * depth * 8 );
case PF_DXT3:
case PF_DXT5:
case PF_ATI2:
case PF_BC5_UNSIGNED:
case PF_BC5_SIGNED:
case PF_BC6H_SIGNED:
case PF_BC6H_UNSIGNED:
case PF_BC7_UNORM:
case PF_BC7_SRGB: return ((( width + 3 ) / 4 ) * (( height + 3 ) / 4 ) * depth * 16 );
case PF_LUMINANCE: return ( width * height * depth );
case PF_BGR_24:
case PF_RGB_24: return ( width * height * depth * 3 );
case PF_BGRA_32:
case PF_RGBA_32: return ( width * height * depth * 4 );
}
return 0;
}

View File

@@ -189,7 +189,7 @@ Searches the string for the given
key and returns the associated value, or an empty string. key and returns the associated value, or an empty string.
=============== ===============
*/ */
const char *Info_ValueForKey( const char *s, const char *key ) const char *GAME_EXPORT Info_ValueForKey( const char *s, const char *key )
{ {
char pkey[MAX_KV_SIZE]; char pkey[MAX_KV_SIZE];
static char value[4][MAX_KV_SIZE]; // use two buffers so compares work without stomping on each other static char value[4][MAX_KV_SIZE]; // use two buffers so compares work without stomping on each other

View File

@@ -177,7 +177,9 @@ bool ParseIPv6Addr( const char *pszText, unsigned char *pOutIP, int *pOutPort, u
{ {
// Next thing must be a quad, or end of input. Is it a quad? // Next thing must be a quad, or end of input. Is it a quad?
int quadDigit = ParseIPv6Addr_HexDigitVal( *s ); int quadDigit = ParseIPv6Addr_HexDigitVal( *s );
const char *pszStartQuad;
int quad; int quad;
if ( quadDigit < 0 ) if ( quadDigit < 0 )
{ {
if ( bQuadMustFollow ) if ( bQuadMustFollow )
@@ -189,6 +191,7 @@ bool ParseIPv6Addr( const char *pszText, unsigned char *pOutIP, int *pOutPort, u
if ( d >= pEndIP ) if ( d >= pEndIP )
return false; return false;
pszStartQuad = s;
++s; ++s;
quad = quadDigit; quad = quadDigit;
@@ -214,6 +217,60 @@ bool ParseIPv6Addr( const char *pszText, unsigned char *pOutIP, int *pOutPort, u
} }
} }
// Check if we hit a period, which would happen if we
// have an IPv4 dotted decimal. For example, "::ffff:192.168.1.210"
if ( *s == '.' )
{
// Make sure we would have room to store four more bytes.
unsigned char *pEndDottedDecimal = d+4;
if ( pEndDottedDecimal > pEndIP )
return false;
// Parse 4 octets
s = pszStartQuad;
for (;;)
{
// Parse 1-3 decimal digits
int octet = ParseIPv6Addr_DecimalDigitVal( *s );
int dig;
if ( octet < 0 )
return false;
++s;
dig = ParseIPv6Addr_DecimalDigitVal( *s );
if ( dig >= 0 )
{
++s;
octet = octet*10 + dig;
dig = ParseIPv6Addr_DecimalDigitVal( *s );
if ( dig >= 0 )
{
++s;
octet = octet*10 + dig;
// Make sure value is in range.
if ( octet > 255 )
return false;
}
}
*(d++) = (unsigned char)octet;
// All done?
if ( d >= pEndDottedDecimal )
break;
// Next thing must be dot dot separator
if ( *s != '.' )
return false;
// Eat dot
++s;
}
break;
}
// Stash it in the next slot, ignoring for now the issue // Stash it in the next slot, ignoring for now the issue
// of compressed zeros // of compressed zeros
*(d++) = (unsigned char)( quad >> 8 ); *(d++) = (unsigned char)( quad >> 8 );

View File

@@ -25,8 +25,10 @@ extern "C" {
extern void IPv6IPToString( char *pszOutText, const unsigned char *ip ); extern void IPv6IPToString( char *pszOutText, const unsigned char *ip );
/// Format IPv6 IP and port to string. This uses the recommended /// Format IPv6 IP and port to string. This uses the recommended
/// bracket notation, eg [1234::1]:12345. Your buffer must be /// bracket notation, eg [1234::1]:12345. Your buffer MUST be
/// at least k_ncchMaxIPV6AddrStringWithPort bytes. /// at least k_ncchMaxIPV6AddrStringWithPort bytes.
///
/// If the scope is zero, it is not printed.
extern void IPv6AddrToString( char *pszOutText, const unsigned char *ip, uint16_t port, uint32_t scope ); extern void IPv6AddrToString( char *pszOutText, const unsigned char *ip, uint16_t port, uint32_t scope );
/// Parse IPv6 address string. Returns true if parsed OK. Returns false /// Parse IPv6 address string. Returns true if parsed OK. Returns false
@@ -41,7 +43,7 @@ extern void IPv6AddrToString( char *pszOutText, const unsigned char *ip, uint16_
/// ///
/// Leading and trailing whitespace is OK around the entire string, /// Leading and trailing whitespace is OK around the entire string,
/// but not internal whitespace. The different methods for separating the /// but not internal whitespace. The different methods for separating the
/// port in RFC5952 are supported section 6, except the ambiguous case /// port in RFC5952 section 6 are supported, except the ambiguous case
/// of a colon to separate the port, when the IP contains a double-colon. /// of a colon to separate the port, when the IP contains a double-colon.
/// Brackets around an IP are OK, even if there is no port. /// Brackets around an IP are OK, even if there is no port.
/// ///

View File

@@ -23,15 +23,6 @@ GNU General Public License for more details.
#if XASH_EMSCRIPTEN #if XASH_EMSCRIPTEN
#include <emscripten.h> #include <emscripten.h>
#elif XASH_WIN32
extern "C"
{
// Enable NVIDIA High Performance Graphics while using Integrated Graphics.
__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
// Enable AMD High Performance Graphics while using Integrated Graphics.
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
}
#endif #endif
#define E_GAME "XASH3D_GAME" // default env dir to start from #define E_GAME "XASH3D_GAME" // default env dir to start from
@@ -39,6 +30,10 @@ __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
#define XASH_GAMEDIR "valve" #define XASH_GAMEDIR "valve"
#endif #endif
#if XASH_WIN32
#error "Single-binary or dedicated builds aren't supported for Windows!"
#endif
static char szGameDir[128]; // safe place to keep gamedir static char szGameDir[128]; // safe place to keep gamedir
static int szArgc; static int szArgc;
static char **szArgv; static char **szArgv;
@@ -47,7 +42,7 @@ static void Sys_ChangeGame( const char *progname )
{ {
// a1ba: may never be called within engine // a1ba: may never be called within engine
// if platform supports execv() function // if platform supports execv() function
Q_strncpy( szGameDir, progname, sizeof( szGameDir ) - 1 ); Q_strncpy( szGameDir, progname, sizeof( szGameDir ));
Host_Shutdown( ); Host_Shutdown( );
exit( Host_Main( szArgc, szArgv, szGameDir, 1, &Sys_ChangeGame ) ); exit( Host_Main( szArgc, szArgv, szGameDir, 1, &Sys_ChangeGame ) );
} }
@@ -88,7 +83,6 @@ _inline int Sys_Start( void )
return ret; return ret;
} }
#if !XASH_WIN32
int main( int argc, char **argv ) int main( int argc, char **argv )
{ {
#if XASH_PSVITA #if XASH_PSVITA
@@ -100,36 +94,4 @@ int main( int argc, char **argv )
#endif // XASH_PSVITA #endif // XASH_PSVITA
return Sys_Start(); return Sys_Start();
} }
#else #endif // SINGLE_BINARY
int __stdcall WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR cmdLine, int nShow)
{
LPWSTR* lpArgv;
int ret, 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;
// just in case, allocate some more memory
szArgv[i] = ( char * )malloc( size * sizeof( wchar_t ));
wcstombs( szArgv[i], lpArgv[i], size );
}
szArgv[szArgc] = 0;
LocalFree( lpArgv );
ret = Sys_Start();
for( ; i < szArgc; ++i )
free( szArgv[i] );
free( szArgv );
return ret;
}
#endif // XASH_WIN32
#endif

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -118,10 +118,9 @@ typedef struct world_static_s
#ifndef REF_DLL #ifndef REF_DLL
extern world_static_t world; extern world_static_t world;
extern poolhandle_t com_studiocache; extern poolhandle_t com_studiocache;
extern model_t *loadmodel; extern convar_t mod_studiocache;
extern convar_t *mod_studiocache; extern convar_t r_wadtextures;
extern convar_t *r_wadtextures; extern convar_t r_showhull;
extern convar_t *r_showhull;
// //
// model.c // model.c
@@ -156,7 +155,7 @@ int Mod_CheckLump( const char *filename, const int lump, int *lumpsize );
int Mod_ReadLump( const char *filename, const int lump, void **lumpdata, int *lumpsize ); int Mod_ReadLump( const char *filename, const int lump, void **lumpdata, int *lumpsize );
int Mod_SaveLump( const char *filename, const int lump, void *lumpdata, int lumpsize ); int Mod_SaveLump( const char *filename, const int lump, void *lumpdata, int lumpsize );
mleaf_t *Mod_PointInLeaf( const vec3_t p, mnode_t *node ); mleaf_t *Mod_PointInLeaf( const vec3_t p, mnode_t *node );
int Mod_SampleSizeForFace( msurface_t *surf ); int Mod_SampleSizeForFace( const msurface_t *surf );
byte *Mod_GetPVSForPoint( const vec3_t p ); byte *Mod_GetPVSForPoint( const vec3_t p );
void Mod_UnloadBrushModel( model_t *mod ); void Mod_UnloadBrushModel( model_t *mod );
void Mod_PrintWorldStats_f( void ); void Mod_PrintWorldStats_f( void );
@@ -164,7 +163,7 @@ void Mod_PrintWorldStats_f( void );
// //
// mod_dbghulls.c // mod_dbghulls.c
// //
void Mod_InitDebugHulls( void ); void Mod_InitDebugHulls( model_t *mod );
void Mod_CreatePolygonsForHull( int hullnum ); void Mod_CreatePolygonsForHull( int hullnum );
void Mod_ReleaseHullPolygons( void ); void Mod_ReleaseHullPolygons( void );

View File

@@ -239,7 +239,7 @@ hull_t *Mod_HullForStudio( model_t *model, float frame, int sequence, vec3_t ang
bSkipShield = false; bSkipShield = false;
*numhitboxes = 0; // assume error *numhitboxes = 0; // assume error
if( mod_studiocache->value ) if( mod_studiocache.value )
{ {
bonecache = Mod_CheckStudioCache( model, frame, sequence, angles, origin, size, pcontroller, pblending ); bonecache = Mod_CheckStudioCache( model, frame, sequence, angles, origin, size, pcontroller, pblending );
@@ -286,7 +286,7 @@ hull_t *Mod_HullForStudio( model_t *model, float frame, int sequence, vec3_t ang
// tell trace code about hitbox count // tell trace code about hitbox count
*numhitboxes = (bSkipShield) ? (mod_studiohdr->numhitboxes - 1) : (mod_studiohdr->numhitboxes); *numhitboxes = (bSkipShield) ? (mod_studiohdr->numhitboxes - 1) : (mod_studiohdr->numhitboxes);
if( mod_studiocache->value ) if( mod_studiocache.value )
Mod_AddToStudioCache( frame, sequence, angles, origin, size, pcontroller, pblending, model, studio_hull, *numhitboxes ); Mod_AddToStudioCache( frame, sequence, angles, origin, size, pcontroller, pblending, model, studio_hull, *numhitboxes );
return studio_hull; return studio_hull;
@@ -851,11 +851,11 @@ void Mod_LoadStudioModel( model_t *mod, const void *buffer, qboolean *loaded )
char poolname[MAX_VA_STRING]; char poolname[MAX_VA_STRING];
studiohdr_t *phdr; studiohdr_t *phdr;
Q_snprintf( poolname, sizeof( poolname ), "^2%s^7", loadmodel->name ); Q_snprintf( poolname, sizeof( poolname ), "^2%s^7", mod->name );
if( loaded ) *loaded = false; if( loaded ) *loaded = false;
loadmodel->mempool = Mem_AllocPool( poolname ); mod->mempool = Mem_AllocPool( poolname );
loadmodel->type = mod_studio; mod->type = mod_studio;
phdr = R_StudioLoadHeader( mod, buffer ); phdr = R_StudioLoadHeader( mod, buffer );
if( !phdr ) return; // bad model if( !phdr ) return; // bad model
@@ -886,9 +886,9 @@ void Mod_LoadStudioModel( model_t *mod, const void *buffer, qboolean *loaded )
// give space for textures and skinrefs // give space for textures and skinrefs
size1 = thdr->numtextures * sizeof( mstudiotexture_t ); size1 = thdr->numtextures * sizeof( mstudiotexture_t );
size2 = thdr->numskinfamilies * thdr->numskinref * sizeof( short ); size2 = thdr->numskinfamilies * thdr->numskinref * sizeof( short );
mod->cache.data = Mem_Calloc( loadmodel->mempool, phdr->length + size1 + size2 ); mod->cache.data = Mem_Calloc( mod->mempool, phdr->length + size1 + size2 );
memcpy( loadmodel->cache.data, buffer, phdr->length ); // copy main mdl buffer memcpy( mod->cache.data, buffer, phdr->length ); // copy main mdl buffer
phdr = (studiohdr_t *)loadmodel->cache.data; // get the new pointer on studiohdr phdr = (studiohdr_t *)mod->cache.data; // get the new pointer on studiohdr
phdr->numskinfamilies = thdr->numskinfamilies; phdr->numskinfamilies = thdr->numskinfamilies;
phdr->numtextures = thdr->numtextures; phdr->numtextures = thdr->numtextures;
phdr->numskinref = thdr->numskinref; phdr->numskinref = thdr->numskinref;
@@ -905,52 +905,52 @@ void Mod_LoadStudioModel( model_t *mod, const void *buffer, qboolean *loaded )
else else
{ {
// NOTE: don't modify source buffer because it's used for CRC computing // NOTE: don't modify source buffer because it's used for CRC computing
loadmodel->cache.data = Mem_Calloc( loadmodel->mempool, phdr->length ); mod->cache.data = Mem_Calloc( mod->mempool, phdr->length );
memcpy( loadmodel->cache.data, buffer, phdr->length ); memcpy( mod->cache.data, buffer, phdr->length );
phdr = (studiohdr_t *)loadmodel->cache.data; // get the new pointer on studiohdr phdr = (studiohdr_t *)mod->cache.data; // get the new pointer on studiohdr
#if !XASH_DEDICATED #if !XASH_DEDICATED
ref.dllFuncs.Mod_StudioLoadTextures( mod, phdr ); ref.dllFuncs.Mod_StudioLoadTextures( mod, phdr );
#endif #endif
// NOTE: we wan't keep raw textures in memory. just cutoff model pointer above texture base // NOTE: we wan't keep raw textures in memory. just cutoff model pointer above texture base
loadmodel->cache.data = Mem_Realloc( loadmodel->mempool, loadmodel->cache.data, phdr->texturedataindex ); mod->cache.data = Mem_Realloc( mod->mempool, mod->cache.data, phdr->texturedataindex );
phdr = (studiohdr_t *)loadmodel->cache.data; // get the new pointer on studiohdr phdr = (studiohdr_t *)mod->cache.data; // get the new pointer on studiohdr
phdr->length = phdr->texturedataindex; // update model size phdr->length = phdr->texturedataindex; // update model size
} }
} }
else else
{ {
// just copy model into memory // just copy model into memory
loadmodel->cache.data = Mem_Calloc( loadmodel->mempool, phdr->length ); mod->cache.data = Mem_Calloc( mod->mempool, phdr->length );
memcpy( loadmodel->cache.data, buffer, phdr->length ); memcpy( mod->cache.data, buffer, phdr->length );
phdr = loadmodel->cache.data; phdr = mod->cache.data;
} }
// setup bounding box // setup bounding box
if( !VectorCompare( vec3_origin, phdr->bbmin )) if( !VectorCompare( vec3_origin, phdr->bbmin ))
{ {
// clipping bounding box // clipping bounding box
VectorCopy( phdr->bbmin, loadmodel->mins ); VectorCopy( phdr->bbmin, mod->mins );
VectorCopy( phdr->bbmax, loadmodel->maxs ); VectorCopy( phdr->bbmax, mod->maxs );
} }
else if( !VectorCompare( vec3_origin, phdr->min )) else if( !VectorCompare( vec3_origin, phdr->min ))
{ {
// movement bounding box // movement bounding box
VectorCopy( phdr->min, loadmodel->mins ); VectorCopy( phdr->min, mod->mins );
VectorCopy( phdr->max, loadmodel->maxs ); VectorCopy( phdr->max, mod->maxs );
} }
else else
{ {
// well compute bounds from vertices and round to nearest even values // well compute bounds from vertices and round to nearest even values
Mod_StudioComputeBounds( phdr, loadmodel->mins, loadmodel->maxs, true ); Mod_StudioComputeBounds( phdr, mod->mins, mod->maxs, true );
RoundUpHullSize( loadmodel->mins ); RoundUpHullSize( mod->mins );
RoundUpHullSize( loadmodel->maxs ); RoundUpHullSize( mod->maxs );
} }
loadmodel->numframes = Mod_StudioBodyVariations( loadmodel ); mod->numframes = Mod_StudioBodyVariations( mod );
loadmodel->radius = RadiusFromBounds( loadmodel->mins, loadmodel->maxs ); mod->radius = RadiusFromBounds( mod->mins, mod->maxs );
loadmodel->flags = phdr->flags; // copy header flags mod->flags = phdr->flags; // copy header flags
if( loaded ) *loaded = true; if( loaded ) *loaded = true;
} }

View File

@@ -28,10 +28,9 @@ static model_info_t mod_crcinfo[MAX_MODELS];
static model_t mod_known[MAX_MODELS]; static model_t mod_known[MAX_MODELS];
static int mod_numknown = 0; static int mod_numknown = 0;
poolhandle_t com_studiocache; // cache for submodels poolhandle_t com_studiocache; // cache for submodels
convar_t *mod_studiocache; CVAR_DEFINE( mod_studiocache, "r_studiocache", "1", FCVAR_ARCHIVE, "enables studio cache for speedup tracing hitboxes" );
convar_t *r_wadtextures; CVAR_DEFINE_AUTO( r_wadtextures, "0", 0, "completely ignore textures in the bsp-file if enabled" );
convar_t *r_showhull; CVAR_DEFINE_AUTO( r_showhull, "0", 0, "draw collision hulls 1-3" );
model_t *loadmodel;
/* /*
=============================================================================== ===============================================================================
@@ -134,9 +133,9 @@ Mod_Init
void Mod_Init( void ) void Mod_Init( void )
{ {
com_studiocache = Mem_AllocPool( "Studio Cache" ); com_studiocache = Mem_AllocPool( "Studio Cache" );
mod_studiocache = Cvar_Get( "r_studiocache", "1", FCVAR_ARCHIVE, "enables studio cache for speedup tracing hitboxes" ); Cvar_RegisterVariable( &mod_studiocache );
r_wadtextures = Cvar_Get( "r_wadtextures", "0", 0, "completely ignore textures in the bsp-file if enabled" ); Cvar_RegisterVariable( &r_wadtextures );
r_showhull = Cvar_Get( "r_showhull", "0", 0, "draw collision hulls 1-3" ); Cvar_RegisterVariable( &r_showhull );
Cmd_AddCommand( "mapstats", Mod_PrintWorldStats_f, "show stats for currently loaded map" ); Cmd_AddCommand( "mapstats", Mod_PrintWorldStats_f, "show stats for currently loaded map" );
Cmd_AddCommand( "modellist", Mod_Modellist_f, "display loaded models list" ); Cmd_AddCommand( "modellist", Mod_Modellist_f, "display loaded models list" );
@@ -287,7 +286,6 @@ model_t *Mod_LoadModel( model_t *mod, qboolean crash )
Con_Reportf( "loading %s\n", mod->name ); Con_Reportf( "loading %s\n", mod->name );
mod->needload = NL_PRESENT; mod->needload = NL_PRESENT;
mod->type = mod_bad; mod->type = mod_bad;
loadmodel = mod;
// call the apropriate loader // call the apropriate loader
switch( *(uint *)buf ) switch( *(uint *)buf )
@@ -403,7 +401,7 @@ static void Mod_PurgeStudioCache( void )
int i; int i;
// refresh hull data // refresh hull data
SetBits( r_showhull->flags, FCVAR_CHANGED ); SetBits( r_showhull.flags, FCVAR_CHANGED );
#if !XASH_DEDICATED #if !XASH_DEDICATED
Mod_ReleaseHullPolygons(); Mod_ReleaseHullPolygons();
#endif #endif

View File

@@ -23,8 +23,8 @@ GNU General Public License for more details.
// precalculated bit masks for WriteUBitLong. // precalculated bit masks for WriteUBitLong.
// Using these tables instead of doing the calculations // Using these tables instead of doing the calculations
// gives a 33% speedup in WriteUBitLong. // gives a 33% speedup in WriteUBitLong.
static dword BitWriteMasks[32][33]; static uint32_t BitWriteMasks[32][33];
static dword ExtraMasks[32]; static uint32_t ExtraMasks[32];
const char *svc_strings[svc_lastmsg+1] = const char *svc_strings[svc_lastmsg+1] =
{ {
"svc_bad", "svc_bad",
@@ -119,7 +119,7 @@ void MSG_InitExt( sizebuf_t *sb, const char *pDebugName, void *pData, int nBytes
void MSG_StartWriting( sizebuf_t *sb, void *pData, int nBytes, int iStartBit, int nBits ) void MSG_StartWriting( sizebuf_t *sb, void *pData, int nBytes, int iStartBit, int nBits )
{ {
// make sure it's dword aligned and padded. // make sure it's dword aligned and padded.
Assert(((dword)pData & 3 ) == 0 ); Assert(((uint32_t)pData & 3 ) == 0 );
sb->pDebugName = "Unnamed"; sb->pDebugName = "Unnamed";
sb->pData = (byte *)pData; sb->pData = (byte *)pData;
@@ -219,14 +219,14 @@ void MSG_WriteUBitLong( sizebuf_t *sb, uint curData, int numbits )
int nBitsLeft = numbits; int nBitsLeft = numbits;
int iCurBit = sb->iCurBit; int iCurBit = sb->iCurBit;
uint iDWord = iCurBit >> 5; // Mask in a dword. uint iDWord = iCurBit >> 5; // Mask in a dword.
dword iCurBitMasked; uint32_t iCurBitMasked;
int nBitsWritten; int nBitsWritten;
Assert(( iDWord * 4 + sizeof( int )) <= (uint)MSG_GetMaxBytes( sb )); Assert(( iDWord * 4 + sizeof( int )) <= (uint)MSG_GetMaxBytes( sb ));
iCurBitMasked = iCurBit & 31; iCurBitMasked = iCurBit & 31;
((dword *)sb->pData)[iDWord] &= BitWriteMasks[iCurBitMasked][nBitsLeft]; ((uint32_t *)sb->pData)[iDWord] &= BitWriteMasks[iCurBitMasked][nBitsLeft];
((dword *)sb->pData)[iDWord] |= curData << iCurBitMasked; ((uint32_t *)sb->pData)[iDWord] |= curData << iCurBitMasked;
// did it span a dword? // did it span a dword?
nBitsWritten = 32 - iCurBitMasked; nBitsWritten = 32 - iCurBitMasked;
@@ -238,8 +238,8 @@ void MSG_WriteUBitLong( sizebuf_t *sb, uint curData, int numbits )
curData >>= nBitsWritten; curData >>= nBitsWritten;
iCurBitMasked = iCurBit & 31; iCurBitMasked = iCurBit & 31;
((dword *)sb->pData)[iDWord+1] &= BitWriteMasks[iCurBitMasked][nBitsLeft]; ((uint32_t *)sb->pData)[iDWord+1] &= BitWriteMasks[iCurBitMasked][nBitsLeft];
((dword *)sb->pData)[iDWord+1] |= curData << iCurBitMasked; ((uint32_t *)sb->pData)[iDWord+1] |= curData << iCurBitMasked;
} }
sb->iCurBit += numbits; sb->iCurBit += numbits;
} }
@@ -284,7 +284,7 @@ qboolean MSG_WriteBits( sizebuf_t *sb, const void *pData, int nBits )
int nBitsLeft = nBits; int nBitsLeft = nBits;
// get output dword-aligned. // get output dword-aligned.
while((( dword )pOut & 3 ) != 0 && nBitsLeft >= 8 ) while((( uint32_t )pOut & 3 ) != 0 && nBitsLeft >= 8 )
{ {
MSG_WriteUBitLong( sb, *pOut, 8 ); MSG_WriteUBitLong( sb, *pOut, 8 );
@@ -295,9 +295,9 @@ qboolean MSG_WriteBits( sizebuf_t *sb, const void *pData, int nBits )
// read dwords. // read dwords.
while( nBitsLeft >= 32 ) while( nBitsLeft >= 32 )
{ {
MSG_WriteUBitLong( sb, *(( dword *)pOut ), 32 ); MSG_WriteUBitLong( sb, *(( uint32_t *)pOut ), 32 );
pOut += sizeof( dword ); pOut += sizeof( uint32_t );
nBitsLeft -= 32; nBitsLeft -= 32;
} }
@@ -383,37 +383,37 @@ void MSG_WriteCmdExt( sizebuf_t *sb, int cmd, netsrc_t type, const char *name )
} }
} }
#endif #endif
MSG_WriteUBitLong( sb, cmd, sizeof( byte ) << 3 ); MSG_WriteUBitLong( sb, cmd, sizeof( uint8_t ) << 3 );
} }
void MSG_WriteChar( sizebuf_t *sb, int val ) void MSG_WriteChar( sizebuf_t *sb, int val )
{ {
MSG_WriteSBitLong( sb, val, sizeof( char ) << 3 ); MSG_WriteSBitLong( sb, val, sizeof( int8_t ) << 3 );
} }
void MSG_WriteByte( sizebuf_t *sb, int val ) void MSG_WriteByte( sizebuf_t *sb, int val )
{ {
MSG_WriteUBitLong( sb, val, sizeof( byte ) << 3 ); MSG_WriteUBitLong( sb, val, sizeof( uint8_t ) << 3 );
} }
void MSG_WriteShort( sizebuf_t *sb, int val ) void MSG_WriteShort( sizebuf_t *sb, int val )
{ {
MSG_WriteSBitLong( sb, val, sizeof(short ) << 3 ); MSG_WriteSBitLong( sb, val, sizeof( int16_t ) << 3 );
} }
void MSG_WriteWord( sizebuf_t *sb, int val ) void MSG_WriteWord( sizebuf_t *sb, int val )
{ {
MSG_WriteUBitLong( sb, val, sizeof( word ) << 3 ); MSG_WriteUBitLong( sb, val, sizeof( uint16_t ) << 3 );
} }
void MSG_WriteLong( sizebuf_t *sb, int val ) void MSG_WriteLong( sizebuf_t *sb, int val )
{ {
MSG_WriteSBitLong( sb, val, sizeof( int ) << 3 ); MSG_WriteSBitLong( sb, val, sizeof( int32_t ) << 3 );
} }
void MSG_WriteDword( sizebuf_t *sb, dword val ) void MSG_WriteDword( sizebuf_t *sb, uint val )
{ {
MSG_WriteUBitLong( sb, val, sizeof( dword ) << 3 ); MSG_WriteUBitLong( sb, val, sizeof( uint32_t ) << 3 );
} }
void MSG_WriteFloat( sizebuf_t *sb, float val ) void MSG_WriteFloat( sizebuf_t *sb, float val )
@@ -518,7 +518,7 @@ qboolean MSG_ReadBits( sizebuf_t *sb, void *pOutData, int nBits )
int nBitsLeft = nBits; int nBitsLeft = nBits;
// get output dword-aligned. // get output dword-aligned.
while((( dword )pOut & 3) != 0 && nBitsLeft >= 8 ) while((( uint32_t )pOut & 3) != 0 && nBitsLeft >= 8 )
{ {
*pOut = (byte)MSG_ReadUBitLong( sb, 8 ); *pOut = (byte)MSG_ReadUBitLong( sb, 8 );
++pOut; ++pOut;
@@ -528,8 +528,8 @@ qboolean MSG_ReadBits( sizebuf_t *sb, void *pOutData, int nBits )
// read dwords. // read dwords.
while( nBitsLeft >= 32 ) while( nBitsLeft >= 32 )
{ {
*((dword *)pOut) = MSG_ReadUBitLong( sb, 32 ); *((uint32_t *)pOut) = MSG_ReadUBitLong( sb, 32 );
pOut += sizeof( dword ); pOut += sizeof( uint32_t );
nBitsLeft -= 32; nBitsLeft -= 32;
} }
@@ -591,7 +591,7 @@ uint MSG_ReadBitLong( sizebuf_t *sb, int numbits, qboolean bSigned )
int MSG_ReadCmd( sizebuf_t *sb, netsrc_t type ) int MSG_ReadCmd( sizebuf_t *sb, netsrc_t type )
{ {
int cmd = MSG_ReadUBitLong( sb, sizeof( byte ) << 3 ); int cmd = MSG_ReadUBitLong( sb, sizeof( uint8_t ) << 3 );
#ifdef DEBUG_NET_MESSAGES_READ #ifdef DEBUG_NET_MESSAGES_READ
if( type == NS_SERVER ) if( type == NS_SERVER )
@@ -608,22 +608,22 @@ int MSG_ReadCmd( sizebuf_t *sb, netsrc_t type )
int MSG_ReadChar( sizebuf_t *sb ) int MSG_ReadChar( sizebuf_t *sb )
{ {
return MSG_ReadSBitLong( sb, sizeof( char ) << 3 ); return MSG_ReadSBitLong( sb, sizeof( int8_t ) << 3 );
} }
int MSG_ReadByte( sizebuf_t *sb ) int MSG_ReadByte( sizebuf_t *sb )
{ {
return MSG_ReadUBitLong( sb, sizeof( byte ) << 3 ); return MSG_ReadUBitLong( sb, sizeof( uint8_t ) << 3 );
} }
int MSG_ReadShort( sizebuf_t *sb ) int MSG_ReadShort( sizebuf_t *sb )
{ {
return MSG_ReadSBitLong( sb, sizeof( short ) << 3 ); return MSG_ReadSBitLong( sb, sizeof( int16_t ) << 3 );
} }
int MSG_ReadWord( sizebuf_t *sb ) int MSG_ReadWord( sizebuf_t *sb )
{ {
return MSG_ReadUBitLong( sb, sizeof( word ) << 3 ); return MSG_ReadUBitLong( sb, sizeof( uint16_t ) << 3 );
} }
float MSG_ReadCoord( sizebuf_t *sb ) float MSG_ReadCoord( sizebuf_t *sb )
@@ -650,12 +650,12 @@ void MSG_ReadVec3Angles( sizebuf_t *sb, vec3_t fa )
int MSG_ReadLong( sizebuf_t *sb ) int MSG_ReadLong( sizebuf_t *sb )
{ {
return MSG_ReadSBitLong( sb, sizeof( int ) << 3 ); return MSG_ReadSBitLong( sb, sizeof( int32_t ) << 3 );
} }
dword MSG_ReadDword( sizebuf_t *sb ) uint MSG_ReadDword( sizebuf_t *sb )
{ {
return MSG_ReadUBitLong( sb, sizeof( dword ) << 3 ); return MSG_ReadUBitLong( sb, sizeof( uint32_t ) << 3 );
} }
float MSG_ReadFloat( sizebuf_t *sb ) float MSG_ReadFloat( sizebuf_t *sb )

View File

@@ -94,7 +94,7 @@ void MSG_WriteByte( sizebuf_t *sb, int val );
void MSG_WriteShort( sizebuf_t *sb, int val ); void MSG_WriteShort( sizebuf_t *sb, int val );
void MSG_WriteWord( sizebuf_t *sb, int val ); void MSG_WriteWord( sizebuf_t *sb, int val );
void MSG_WriteLong( sizebuf_t *sb, int val ); void MSG_WriteLong( sizebuf_t *sb, int val );
void MSG_WriteDword( sizebuf_t *sb, dword val ); void MSG_WriteDword( sizebuf_t *sb, uint val );
void MSG_WriteCoord( sizebuf_t *sb, float val ); void MSG_WriteCoord( sizebuf_t *sb, float val );
void MSG_WriteFloat( sizebuf_t *sb, float val ); void MSG_WriteFloat( sizebuf_t *sb, float val );
void MSG_WriteVec3Coord( sizebuf_t *sb, const float *fa ); void MSG_WriteVec3Coord( sizebuf_t *sb, const float *fa );
@@ -131,7 +131,7 @@ int MSG_ReadByte( sizebuf_t *sb );
int MSG_ReadShort( sizebuf_t *sb ); int MSG_ReadShort( sizebuf_t *sb );
int MSG_ReadWord( sizebuf_t *sb ); int MSG_ReadWord( sizebuf_t *sb );
int MSG_ReadLong( sizebuf_t *sb ); int MSG_ReadLong( sizebuf_t *sb );
dword MSG_ReadDword( sizebuf_t *sb ); uint MSG_ReadDword( sizebuf_t *sb );
float MSG_ReadCoord( sizebuf_t *sb ); float MSG_ReadCoord( sizebuf_t *sb );
float MSG_ReadFloat( sizebuf_t *sb ); float MSG_ReadFloat( sizebuf_t *sb );
void MSG_ReadVec3Coord( sizebuf_t *sb, vec3_t fa ); void MSG_ReadVec3Coord( sizebuf_t *sb, vec3_t fa );

View File

@@ -84,10 +84,10 @@ such as during the connection stage while waiting for the client to load,
then a packet only needs to be delivered if there is something in the then a packet only needs to be delivered if there is something in the
unacknowledged reliable unacknowledged reliable
*/ */
convar_t *net_showpackets; CVAR_DEFINE_AUTO( net_showpackets, "0", 0, "show network packets" );
convar_t *net_chokeloopback; CVAR_DEFINE_AUTO( net_chokeloop, "0", 0, "apply bandwidth choke to loopback packets" );
convar_t *net_showdrop; CVAR_DEFINE_AUTO( net_showdrop, "0", 0, "show packets that are dropped" );
convar_t *net_qport; CVAR_DEFINE_AUTO( net_qport, "0", FCVAR_READ_ONLY, "current quake netport" );
int net_drop; int net_drop;
netadr_t net_from; netadr_t net_from;
@@ -243,15 +243,18 @@ Netchan_Init
*/ */
void Netchan_Init( void ) void Netchan_Init( void )
{ {
char buf[32];
int port; int port;
// pick a port value that should be nice and random // pick a port value that should be nice and random
port = COM_RandomLong( 1, 65535 ); port = COM_RandomLong( 1, 65535 );
Q_snprintf( buf, sizeof( buf ), "%i", port );
net_showpackets = Cvar_Get ("net_showpackets", "0", 0, "show network packets" ); Cvar_RegisterVariable( &net_showpackets );
net_chokeloopback = Cvar_Get( "net_chokeloop", "0", 0, "apply bandwidth choke to loopback packets" ); Cvar_RegisterVariable( &net_chokeloop );
net_showdrop = Cvar_Get( "net_showdrop", "0", 0, "show packets that are dropped" ); Cvar_RegisterVariable( &net_showdrop );
net_qport = Cvar_Getf( "net_qport", FCVAR_READ_ONLY, "current quake netport", "%i", port ); Cvar_RegisterVariable( &net_qport );
Cvar_FullSet( net_qport.name, buf, net_qport.flags );
net_mempool = Mem_AllocPool( "Network Pool" ); net_mempool = Mem_AllocPool( "Network Pool" );
@@ -349,7 +352,7 @@ Returns true if the bandwidth choke isn't active
qboolean Netchan_CanPacket( netchan_t *chan, qboolean choke ) qboolean Netchan_CanPacket( netchan_t *chan, qboolean choke )
{ {
// never choke loopback packets. // never choke loopback packets.
if( !choke || ( !net_chokeloopback->value && NET_IsLocalAddress( chan->remote_address ) )) if( !choke || ( !net_chokeloop.value && NET_IsLocalAddress( chan->remote_address ) ))
{ {
chan->cleartime = host.realtime; chan->cleartime = host.realtime;
return true; return true;
@@ -1331,7 +1334,7 @@ void Netchan_UpdateProgress( netchan_t *chan )
if( host.downloadcount == 0 ) if( host.downloadcount == 0 )
{ {
scr_download->value = -1.0f; scr_download.value = -1.0f;
host.downloadfile[0] = '\0'; host.downloadfile[0] = '\0';
} }
@@ -1399,7 +1402,7 @@ void Netchan_UpdateProgress( netchan_t *chan )
} }
scr_download->value = bestpercent; scr_download.value = bestpercent;
#endif // XASH_DEDICATED #endif // XASH_DEDICATED
} }
@@ -1699,7 +1702,7 @@ void Netchan_TransmitBits( netchan_t *chan, int length, byte *data )
chan->cleartime += ( MSG_GetNumBytesWritten( &send ) + UDP_HEADER_SIZE ) * fRate; chan->cleartime += ( MSG_GetNumBytesWritten( &send ) + UDP_HEADER_SIZE ) * fRate;
if( net_showpackets->value && net_showpackets->value != 2.0f ) if( net_showpackets.value && net_showpackets.value != 2.0f )
{ {
Con_Printf( " %s --> sz=%i seq=%i ack=%i rel=%i tm=%f\n" Con_Printf( " %s --> sz=%i seq=%i ack=%i rel=%i tm=%f\n"
, ns_strings[chan->sock] , ns_strings[chan->sock]
@@ -1769,7 +1772,7 @@ qboolean Netchan_Process( netchan_t *chan, sizebuf_t *msg )
sequence_ack &= ~BIT( 30 ); sequence_ack &= ~BIT( 30 );
sequence_ack &= ~BIT( 31 ); sequence_ack &= ~BIT( 31 );
if( net_showpackets->value && net_showpackets->value != 3.0f ) if( net_showpackets.value && net_showpackets.value != 3.0f )
{ {
Con_Printf( " %s <-- sz=%i seq=%i ack=%i rel=%i tm=%f\n" Con_Printf( " %s <-- sz=%i seq=%i ack=%i rel=%i tm=%f\n"
, ns_strings[chan->sock] , ns_strings[chan->sock]
@@ -1783,7 +1786,7 @@ qboolean Netchan_Process( netchan_t *chan, sizebuf_t *msg )
// discard stale or duplicated packets // discard stale or duplicated packets
if( sequence <= (uint)chan->incoming_sequence ) if( sequence <= (uint)chan->incoming_sequence )
{ {
if( net_showdrop->value ) if( net_showdrop.value )
{ {
const char *adr = NET_AdrToString( chan->remote_address ); const char *adr = NET_AdrToString( chan->remote_address );
@@ -1796,7 +1799,7 @@ qboolean Netchan_Process( netchan_t *chan, sizebuf_t *msg )
// dropped packets don't keep the message from being used // dropped packets don't keep the message from being used
net_drop = sequence - ( chan->incoming_sequence + 1 ); net_drop = sequence - ( chan->incoming_sequence + 1 );
if( net_drop > 0 && net_showdrop->value ) if( net_drop > 0 && net_showdrop.value )
Con_Printf( "%s:dropped %i packets at %i\n", NET_AdrToString( chan->remote_address ), net_drop, sequence ); Con_Printf( "%s:dropped %i packets at %i\n", NET_AdrToString( chan->remote_address ), net_drop, sequence );
// if the current outgoing reliable message has been acknowledged // if the current outgoing reliable message has been acknowledged

View File

@@ -315,16 +315,28 @@ static const delta_field_t ent_fields[] =
{ NULL }, { NULL },
}; };
enum
{
DT_EVENT_T = 0,
DT_MOVEVARS_T,
DT_USERCMD_T,
DT_CLIENTDATA_T,
DT_WEAPONDATA_T,
DT_ENTITY_STATE_T,
DT_ENTITY_STATE_PLAYER_T,
DT_CUSTOM_ENTITY_STATE_T,
};
static delta_info_t dt_info[] = static delta_info_t dt_info[] =
{ {
{ "event_t", ev_fields, NUM_FIELDS( ev_fields ) }, [DT_EVENT_T] = { "event_t", ev_fields, NUM_FIELDS( ev_fields ) },
{ "movevars_t", pm_fields, NUM_FIELDS( pm_fields ) }, [DT_MOVEVARS_T] = { "movevars_t", pm_fields, NUM_FIELDS( pm_fields ) },
{ "usercmd_t", cmd_fields, NUM_FIELDS( cmd_fields ) }, [DT_USERCMD_T] = { "usercmd_t", cmd_fields, NUM_FIELDS( cmd_fields ) },
{ "clientdata_t", cd_fields, NUM_FIELDS( cd_fields ) }, [DT_CLIENTDATA_T] = { "clientdata_t", cd_fields, NUM_FIELDS( cd_fields ) },
{ "weapon_data_t", wd_fields, NUM_FIELDS( wd_fields ) }, [DT_WEAPONDATA_T] = { "weapon_data_t", wd_fields, NUM_FIELDS( wd_fields ) },
{ "entity_state_t", ent_fields, NUM_FIELDS( ent_fields ) }, [DT_ENTITY_STATE_T] = { "entity_state_t", ent_fields, NUM_FIELDS( ent_fields ) },
{ "entity_state_player_t", ent_fields, NUM_FIELDS( ent_fields ) }, [DT_ENTITY_STATE_PLAYER_T] = { "entity_state_player_t", ent_fields, NUM_FIELDS( ent_fields ) },
{ "custom_entity_state_t", ent_fields, NUM_FIELDS( ent_fields ) }, [DT_CUSTOM_ENTITY_STATE_T] = { "custom_entity_state_t", ent_fields, NUM_FIELDS( ent_fields ) },
{ NULL }, { NULL },
}; };
@@ -347,16 +359,13 @@ static delta_info_t *Delta_FindStruct( const char *name )
return NULL; return NULL;
} }
int Delta_NumTables( void ) static int Delta_NumTables( void )
{ {
return NUM_FIELDS( dt_info ); return NUM_FIELDS( dt_info );
} }
delta_info_t *Delta_FindStructByIndex( int index ) static delta_info_t *Delta_FindStructByIndex( int index )
{ {
if( index < 0 || index >= NUM_FIELDS( dt_info ))
return NULL;
return &dt_info[index]; return &dt_info[index];
} }
@@ -435,17 +444,12 @@ static int Delta_IndexForFieldInfo( const delta_field_t *pInfo, const char *fiel
return -1; return -1;
} }
static qboolean Delta_AddField( const char *pStructName, const char *pName, int flags, int bits, float mul, float post_mul ) static qboolean Delta_AddField( delta_info_t *dt, const char *pName, int flags, int bits, float mul, float post_mul )
{ {
delta_info_t *dt;
delta_field_t *pFieldInfo; delta_field_t *pFieldInfo;
delta_t *pField; delta_t *pField;
int i; int i;
// get the delta struct
dt = Delta_FindStruct( pStructName );
Assert( dt != NULL );
// check for coexisting field // check for coexisting field
for( i = 0, pField = dt->pFields; i < dt->numFields; i++, pField++ ) for( i = 0, pField = dt->pFields; i < dt->numFields; i++, pField++ )
{ {
@@ -464,13 +468,13 @@ static qboolean Delta_AddField( const char *pStructName, const char *pName, int
pFieldInfo = Delta_FindFieldInfo( dt->pInfo, pName ); pFieldInfo = Delta_FindFieldInfo( dt->pInfo, pName );
if( !pFieldInfo ) if( !pFieldInfo )
{ {
Con_DPrintf( S_ERROR "Delta_Add: couldn't find description for %s->%s\n", pStructName, pName ); Con_DPrintf( S_ERROR "Delta_Add: couldn't find description for %s->%s\n", dt->pName, pName );
return false; return false;
} }
if( dt->numFields + 1 > dt->maxFields ) if( dt->numFields + 1 > dt->maxFields )
{ {
Con_DPrintf( S_WARN "Delta_Add: can't add %s->%s encoder list is full\n", pStructName, pName ); Con_DPrintf( S_WARN "Delta_Add: can't add %s->%s encoder list is full\n", dt->pName, pName );
return false; // too many fields specified (duplicated ?) return false; // too many fields specified (duplicated ?)
} }
@@ -491,7 +495,7 @@ static qboolean Delta_AddField( const char *pStructName, const char *pName, int
return true; return true;
} }
void Delta_WriteTableField( sizebuf_t *msg, int tableIndex, const delta_t *pField ) static void Delta_WriteTableField( sizebuf_t *msg, int tableIndex, const delta_t *pField )
{ {
int nameIndex; int nameIndex;
delta_info_t *dt; delta_info_t *dt;
@@ -572,7 +576,7 @@ void Delta_ParseTableField( sizebuf_t *msg )
Delta_Shutdown(); Delta_Shutdown();
// add field to table // add field to table
Delta_AddField( dt->pName, pName, flags, bits, mul, post_mul ); Delta_AddField( dt, pName, flags, bits, mul, post_mul );
} }
static qboolean Delta_ParseField( char **delta_script, const delta_field_t *pInfo, delta_t *pField, qboolean bPost ) static qboolean Delta_ParseField( char **delta_script, const delta_field_t *pInfo, delta_t *pField, qboolean bPost )
@@ -820,43 +824,43 @@ void Delta_Init( void )
Delta_InitFields (); // initialize fields Delta_InitFields (); // initialize fields
delta_init = true; delta_init = true;
dt = Delta_FindStruct( "movevars_t" ); dt = Delta_FindStructByIndex( DT_MOVEVARS_T );
Assert( dt != NULL ); Assert( dt != NULL );
if( dt->bInitialized ) return; // "movevars_t" already specified by user if( dt->bInitialized ) return; // "movevars_t" already specified by user
// create movevars_t delta internal // create movevars_t delta internal
Delta_AddField( "movevars_t", "gravity", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f ); Delta_AddField( dt, "gravity", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "stopspeed", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f ); Delta_AddField( dt, "stopspeed", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "maxspeed", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f ); Delta_AddField( dt, "maxspeed", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "spectatormaxspeed", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f ); Delta_AddField( dt, "spectatormaxspeed", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "accelerate", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f ); Delta_AddField( dt, "accelerate", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "airaccelerate", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f ); Delta_AddField( dt, "airaccelerate", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "wateraccelerate", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f ); Delta_AddField( dt, "wateraccelerate", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "friction", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f ); Delta_AddField( dt, "friction", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "edgefriction", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f ); Delta_AddField( dt, "edgefriction", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "waterfriction", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f ); Delta_AddField( dt, "waterfriction", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "bounce", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f ); Delta_AddField( dt, "bounce", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "stepsize", DT_FLOAT|DT_SIGNED, 16, 16.0f, 1.0f ); Delta_AddField( dt, "stepsize", DT_FLOAT|DT_SIGNED, 16, 16.0f, 1.0f );
Delta_AddField( "movevars_t", "maxvelocity", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f ); Delta_AddField( dt, "maxvelocity", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
if( FBitSet( host.features, ENGINE_WRITE_LARGE_COORD )) if( FBitSet( host.features, ENGINE_WRITE_LARGE_COORD ))
Delta_AddField( "movevars_t", "zmax", DT_FLOAT|DT_SIGNED, 18, 1.0f, 1.0f ); Delta_AddField( dt, "zmax", DT_FLOAT|DT_SIGNED, 18, 1.0f, 1.0f );
else Delta_AddField( "movevars_t", "zmax", DT_FLOAT|DT_SIGNED, 16, 1.0f, 1.0f ); else Delta_AddField( dt, "zmax", DT_FLOAT|DT_SIGNED, 16, 1.0f, 1.0f );
Delta_AddField( "movevars_t", "waveHeight", DT_FLOAT|DT_SIGNED, 16, 16.0f, 1.0f ); Delta_AddField( dt, "waveHeight", DT_FLOAT|DT_SIGNED, 16, 16.0f, 1.0f );
Delta_AddField( "movevars_t", "skyName", DT_STRING, 1, 1.0f, 1.0f ); Delta_AddField( dt, "skyName", DT_STRING, 1, 1.0f, 1.0f );
Delta_AddField( "movevars_t", "footsteps", DT_INTEGER, 1, 1.0f, 1.0f ); Delta_AddField( dt, "footsteps", DT_INTEGER, 1, 1.0f, 1.0f );
Delta_AddField( "movevars_t", "rollangle", DT_FLOAT|DT_SIGNED, 16, 32.0f, 1.0f ); Delta_AddField( dt, "rollangle", DT_FLOAT|DT_SIGNED, 16, 32.0f, 1.0f );
Delta_AddField( "movevars_t", "rollspeed", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f ); Delta_AddField( dt, "rollspeed", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "skycolor_r", DT_FLOAT|DT_SIGNED, 16, 1.0f, 1.0f ); // 0 - 264 Delta_AddField( dt, "skycolor_r", DT_FLOAT|DT_SIGNED, 16, 1.0f, 1.0f ); // 0 - 264
Delta_AddField( "movevars_t", "skycolor_g", DT_FLOAT|DT_SIGNED, 16, 1.0f, 1.0f ); Delta_AddField( dt, "skycolor_g", DT_FLOAT|DT_SIGNED, 16, 1.0f, 1.0f );
Delta_AddField( "movevars_t", "skycolor_b", DT_FLOAT|DT_SIGNED, 16, 1.0f, 1.0f ); Delta_AddField( dt, "skycolor_b", DT_FLOAT|DT_SIGNED, 16, 1.0f, 1.0f );
Delta_AddField( "movevars_t", "skyvec_x", DT_FLOAT|DT_SIGNED, 16, 32.0f, 1.0f ); // 0 - 1 Delta_AddField( dt, "skyvec_x", DT_FLOAT|DT_SIGNED, 16, 32.0f, 1.0f ); // 0 - 1
Delta_AddField( "movevars_t", "skyvec_y", DT_FLOAT|DT_SIGNED, 16, 32.0f, 1.0f ); Delta_AddField( dt, "skyvec_y", DT_FLOAT|DT_SIGNED, 16, 32.0f, 1.0f );
Delta_AddField( "movevars_t", "skyvec_z", DT_FLOAT|DT_SIGNED, 16, 32.0f, 1.0f ); Delta_AddField( dt, "skyvec_z", DT_FLOAT|DT_SIGNED, 16, 32.0f, 1.0f );
Delta_AddField( "movevars_t", "wateralpha", DT_FLOAT|DT_SIGNED, 16, 32.0f, 1.0f ); Delta_AddField( dt, "wateralpha", DT_FLOAT|DT_SIGNED, 16, 32.0f, 1.0f );
Delta_AddField( "movevars_t", "fog_settings", DT_INTEGER, 32, 1.0f, 1.0f ); Delta_AddField( dt, "fog_settings", DT_INTEGER, 32, 1.0f, 1.0f );
dt->numFields = NUM_FIELDS( pm_fields ) - 4; dt->numFields = NUM_FIELDS( pm_fields ) - 4;
// now done // now done
@@ -914,7 +918,7 @@ Delta_ClampIntegerField
prevent data to out of range prevent data to out of range
===================== =====================
*/ */
static int Delta_ClampIntegerField( delta_t *pField, int iValue, qboolean bSigned, int numbits ) static int Delta_ClampIntegerField( delta_t *pField, int iValue, int signbit, int numbits )
{ {
#ifdef _DEBUG #ifdef _DEBUG
if( numbits < 32 && abs( iValue ) >= (uint)BIT( numbits )) if( numbits < 32 && abs( iValue ) >= (uint)BIT( numbits ))
@@ -922,10 +926,13 @@ static int Delta_ClampIntegerField( delta_t *pField, int iValue, qboolean bSigne
#endif #endif
if( numbits < 32 ) if( numbits < 32 )
{ {
int signbits = bSigned ? ( numbits - 1 ) : numbits; int signbits = numbits - signbit;
int maxnum = BIT( signbits ) - 1; int maxnum = BIT( signbits ) - 1;
int minnum = bSigned ? ( -maxnum - 1 ) : 0;
iValue = bound( minnum, iValue, maxnum ); if( iValue > maxnum )
iValue = maxnum;
else if( signbit && iValue < -maxnum - 1 )
iValue = -maxnum - 1;
} }
return iValue; // clamped; return iValue; // clamped;
@@ -941,7 +948,7 @@ assume from and to is valid
*/ */
static qboolean Delta_CompareField( delta_t *pField, void *from, void *to, double timebase ) static qboolean Delta_CompareField( delta_t *pField, void *from, void *to, double timebase )
{ {
qboolean bSigned = ( pField->flags & DT_SIGNED ) ? true : false; int signbit = ( pField->flags & DT_SIGNED ) ? 1 : 0;
float val_a, val_b; float val_a, val_b;
int fromF, toF; int fromF, toF;
@@ -956,65 +963,67 @@ static qboolean Delta_CompareField( delta_t *pField, void *from, void *to, doubl
if( pField->flags & DT_BYTE ) if( pField->flags & DT_BYTE )
{ {
if( pField->flags & DT_SIGNED ) if( signbit )
{ {
fromF = *(signed char *)((byte *)from + pField->offset ); fromF = *(int8_t *)((int8_t *)from + pField->offset );
toF = *(signed char *)((byte *)to + pField->offset ); toF = *(int8_t *)((int8_t *)to + pField->offset );
} }
else else
{ {
fromF = *(byte *)((byte *)from + pField->offset ); fromF = *(uint8_t *)((int8_t *)from + pField->offset );
toF = *(byte *)((byte *)to + pField->offset ); toF = *(uint8_t *)((int8_t *)to + pField->offset );
} }
fromF = Delta_ClampIntegerField( pField, fromF, bSigned, pField->bits ); fromF = Delta_ClampIntegerField( pField, fromF, signbit, pField->bits );
toF = Delta_ClampIntegerField( pField, toF, bSigned, pField->bits ); toF = Delta_ClampIntegerField( pField, toF, signbit, pField->bits );
if( !Q_equal(pField->multiplier, 1.0) ) if( !Q_equal(pField->multiplier, 1.0f ))
fromF *= pField->multiplier; fromF *= pField->multiplier;
if( !Q_equal( pField->multiplier, 1.0 ) ) if( !Q_equal( pField->multiplier, 1.0f ))
toF *= pField->multiplier; toF *= pField->multiplier;
} }
else if( pField->flags & DT_SHORT ) else if( pField->flags & DT_SHORT )
{ {
if( pField->flags & DT_SIGNED ) if( signbit )
{ {
fromF = *(short *)((byte *)from + pField->offset ); fromF = *(int16_t *)((int8_t *)from + pField->offset );
toF = *(short *)((byte *)to + pField->offset ); toF = *(int16_t *)((int8_t *)to + pField->offset );
} }
else else
{ {
fromF = *(word *)((byte *)from + pField->offset ); fromF = *(uint16_t *)((int8_t *)from + pField->offset );
toF = *(word *)((byte *)to + pField->offset ); toF = *(uint16_t *)((int8_t *)to + pField->offset );
} }
fromF = Delta_ClampIntegerField( pField, fromF, bSigned, pField->bits ); fromF = Delta_ClampIntegerField( pField, fromF, signbit, pField->bits );
toF = Delta_ClampIntegerField( pField, toF, bSigned, pField->bits ); toF = Delta_ClampIntegerField( pField, toF, signbit, pField->bits );
if( !Q_equal( pField->multiplier, 1.0 ) ) if( !Q_equal(pField->multiplier, 1.0f ))
fromF *= pField->multiplier; fromF *= pField->multiplier;
if( !Q_equal( pField->multiplier, 1.0 ) ) if( !Q_equal( pField->multiplier, 1.0f ))
toF *= pField->multiplier; toF *= pField->multiplier;
} }
else if( pField->flags & DT_INTEGER ) else if( pField->flags & DT_INTEGER )
{ {
if( pField->flags & DT_SIGNED ) if( signbit )
{ {
fromF = *(int *)((byte *)from + pField->offset ); fromF = *(int32_t *)((int8_t *)from + pField->offset );
toF = *(int *)((byte *)to + pField->offset ); toF = *(int32_t *)((int8_t *)to + pField->offset );
} }
else else
{ {
fromF = *(uint *)((byte *)from + pField->offset ); fromF = *(uint32_t *)((int8_t *)from + pField->offset );
toF = *(uint *)((byte *)to + pField->offset ); toF = *(uint32_t *)((int8_t *)to + pField->offset );
} }
fromF = Delta_ClampIntegerField( pField, fromF, bSigned, pField->bits ); fromF = Delta_ClampIntegerField( pField, fromF, signbit, pField->bits );
toF = Delta_ClampIntegerField( pField, toF, bSigned, pField->bits ); toF = Delta_ClampIntegerField( pField, toF, signbit, pField->bits );
if( !Q_equal( pField->multiplier, 1.0 ) )
if( !Q_equal(pField->multiplier, 1.0f ))
fromF *= pField->multiplier; fromF *= pField->multiplier;
if( !Q_equal( pField->multiplier, 1.0 ) )
if( !Q_equal( pField->multiplier, 1.0f ))
toF *= pField->multiplier; toF *= pField->multiplier;
} }
else if( pField->flags & ( DT_ANGLE|DT_FLOAT )) else if( pField->flags & ( DT_ANGLE|DT_FLOAT ))
@@ -1025,8 +1034,8 @@ static qboolean Delta_CompareField( delta_t *pField, void *from, void *to, doubl
} }
else if( pField->flags & DT_TIMEWINDOW_8 ) else if( pField->flags & DT_TIMEWINDOW_8 )
{ {
val_a = Q_rint((*(float *)((byte *)from + pField->offset )) * 100.0 ); val_a = Q_rint((*(float *)((byte *)from + pField->offset )) * 100.0f );
val_b = Q_rint((*(float *)((byte *)to + pField->offset )) * 100.0 ); val_b = Q_rint((*(float *)((byte *)to + pField->offset )) * 100.0f );
val_a -= Q_rint(timebase * 100.0); val_a -= Q_rint(timebase * 100.0);
val_b -= Q_rint(timebase * 100.0); val_b -= Q_rint(timebase * 100.0);
fromF = FloatAsInt( val_a ); fromF = FloatAsInt( val_a );
@@ -1037,7 +1046,7 @@ static qboolean Delta_CompareField( delta_t *pField, void *from, void *to, doubl
val_a = (*(float *)((byte *)from + pField->offset )); val_a = (*(float *)((byte *)from + pField->offset ));
val_b = (*(float *)((byte *)to + pField->offset )); val_b = (*(float *)((byte *)to + pField->offset ));
if( !Q_equal( pField->multiplier, 1.0 ) ) if( !Q_equal( pField->multiplier, 1.0f ))
{ {
val_a *= pField->multiplier; val_a *= pField->multiplier;
val_b *= pField->multiplier; val_b *= pField->multiplier;
@@ -1063,7 +1072,7 @@ static qboolean Delta_CompareField( delta_t *pField, void *from, void *to, doubl
toF = Q_strcmp( s1, s2 ); toF = Q_strcmp( s1, s2 );
} }
return ( fromF == toF ) ? true : false; return fromF == toF;
} }
/* /*
@@ -1078,7 +1087,6 @@ int Delta_TestBaseline( entity_state_t *from, entity_state_t *to, qboolean playe
delta_info_t *dt = NULL; delta_info_t *dt = NULL;
delta_t *pField; delta_t *pField;
int i, countBits; int i, countBits;
int numChanges = 0;
countBits = MAX_ENTITY_BITS + 2; countBits = MAX_ENTITY_BITS + 2;
@@ -1089,10 +1097,10 @@ int Delta_TestBaseline( entity_state_t *from, entity_state_t *to, qboolean playe
} }
if( FBitSet( to->entityType, ENTITY_BEAM )) if( FBitSet( to->entityType, ENTITY_BEAM ))
dt = Delta_FindStruct( "custom_entity_state_t" ); dt = Delta_FindStructByIndex( DT_CUSTOM_ENTITY_STATE_T );
else if( player ) else if( player )
dt = Delta_FindStruct( "entity_state_player_t" ); dt = Delta_FindStructByIndex( DT_ENTITY_STATE_PLAYER_T );
else dt = Delta_FindStruct( "entity_state_t" ); else dt = Delta_FindStructByIndex( DT_ENTITY_STATE_T );
Assert( dt && dt->bInitialized ); Assert( dt && dt->bInitialized );
@@ -1112,7 +1120,7 @@ int Delta_TestBaseline( entity_state_t *from, entity_state_t *to, qboolean playe
if( !Delta_CompareField( pField, from, to, timebase )) if( !Delta_CompareField( pField, from, to, timebase ))
{ {
// strings are handled difference // strings are handled differently
if( FBitSet( pField->flags, DT_STRING )) if( FBitSet( pField->flags, DT_STRING ))
countBits += Q_strlen((char *)((byte *)to + pField->offset )) * 8; countBits += Q_strlen((char *)((byte *)to + pField->offset )) * 8;
else countBits += pField->bits; else countBits += pField->bits;
@@ -1133,7 +1141,7 @@ assume from and to is valid
*/ */
static qboolean Delta_WriteField( sizebuf_t *msg, delta_t *pField, void *from, void *to, double timebase ) static qboolean Delta_WriteField( sizebuf_t *msg, delta_t *pField, void *from, void *to, double timebase )
{ {
qboolean bSigned = ( pField->flags & DT_SIGNED ) ? true : false; int signbit = FBitSet( pField->flags, DT_SIGNED ) ? 1 : 0;
float flValue, flAngle; float flValue, flAngle;
uint iValue; uint iValue;
const char *pStr; const char *pStr;
@@ -1148,49 +1156,49 @@ static qboolean Delta_WriteField( sizebuf_t *msg, delta_t *pField, void *from, v
if( pField->flags & DT_BYTE ) if( pField->flags & DT_BYTE )
{ {
if( bSigned ) if( signbit )
iValue = *(int8_t *)((int8_t *)to + pField->offset ); iValue = *(int8_t *)((int8_t *)to + pField->offset );
else else
iValue = *(uint8_t *)((int8_t *)to + pField->offset ); iValue = *(uint8_t *)((int8_t *)to + pField->offset );
iValue = Delta_ClampIntegerField( pField, iValue, bSigned, pField->bits ); iValue = Delta_ClampIntegerField( pField, iValue, signbit, pField->bits );
if( !Q_equal( pField->multiplier, 1.0 ) ) if( !Q_equal( pField->multiplier, 1.0 ) )
iValue *= pField->multiplier; iValue *= pField->multiplier;
MSG_WriteBitLong( msg, iValue, pField->bits, bSigned ); MSG_WriteBitLong( msg, iValue, pField->bits, signbit );
} }
else if( pField->flags & DT_SHORT ) else if( pField->flags & DT_SHORT )
{ {
if( bSigned ) if( signbit )
iValue = *(int16_t *)((int8_t *)to + pField->offset ); iValue = *(int16_t *)((int8_t *)to + pField->offset );
else else
iValue = *(uint16_t *)((int8_t *)to + pField->offset ); iValue = *(uint16_t *)((int8_t *)to + pField->offset );
iValue = Delta_ClampIntegerField( pField, iValue, bSigned, pField->bits ); iValue = Delta_ClampIntegerField( pField, iValue, signbit, pField->bits );
if( !Q_equal( pField->multiplier, 1.0 ) ) if( !Q_equal( pField->multiplier, 1.0 ) )
iValue *= pField->multiplier; iValue *= pField->multiplier;
MSG_WriteBitLong( msg, iValue, pField->bits, bSigned ); MSG_WriteBitLong( msg, iValue, pField->bits, signbit );
} }
else if( pField->flags & DT_INTEGER ) else if( pField->flags & DT_INTEGER )
{ {
if( bSigned ) if( signbit )
iValue = *(int32_t *)((int8_t *)to + pField->offset ); iValue = *(int32_t *)((int8_t *)to + pField->offset );
else else
iValue = *(uint32_t *)((int8_t *)to + pField->offset ); iValue = *(uint32_t *)((int8_t *)to + pField->offset );
iValue = Delta_ClampIntegerField( pField, iValue, bSigned, pField->bits ); iValue = Delta_ClampIntegerField( pField, iValue, signbit, pField->bits );
if( !Q_equal( pField->multiplier, 1.0 ) ) if( !Q_equal( pField->multiplier, 1.0 ) )
iValue *= pField->multiplier; iValue *= pField->multiplier;
MSG_WriteBitLong( msg, iValue, pField->bits, bSigned ); MSG_WriteBitLong( msg, iValue, pField->bits, signbit );
} }
else if( pField->flags & DT_FLOAT ) else if( pField->flags & DT_FLOAT )
{ {
flValue = *(float *)((byte *)to + pField->offset ); flValue = *(float *)((byte *)to + pField->offset );
iValue = (int)((double)flValue * pField->multiplier); iValue = (int)((double)flValue * pField->multiplier);
iValue = Delta_ClampIntegerField( pField, iValue, bSigned, pField->bits ); iValue = Delta_ClampIntegerField( pField, iValue, signbit, pField->bits );
MSG_WriteBitLong( msg, iValue, pField->bits, bSigned ); MSG_WriteBitLong( msg, iValue, pField->bits, signbit );
} }
else if( pField->flags & DT_ANGLE ) else if( pField->flags & DT_ANGLE )
{ {
@@ -1202,19 +1210,19 @@ static qboolean Delta_WriteField( sizebuf_t *msg, delta_t *pField, void *from, v
} }
else if( pField->flags & DT_TIMEWINDOW_8 ) else if( pField->flags & DT_TIMEWINDOW_8 )
{ {
bSigned = true; // timewindow is always signed signbit = 1; // timewindow is always signed
flValue = *(float *)((byte *)to + pField->offset ); flValue = *(float *)((byte *)to + pField->offset );
iValue = (int)Q_rint( timebase * 100.0 ) - (int)Q_rint( flValue * 100.0 ); iValue = (int)Q_rint( timebase * 100.0 ) - (int)Q_rint( flValue * 100.0 );
iValue = Delta_ClampIntegerField( pField, iValue, bSigned, pField->bits ); iValue = Delta_ClampIntegerField( pField, iValue, signbit, pField->bits );
MSG_WriteBitLong( msg, iValue, pField->bits, bSigned ); MSG_WriteBitLong( msg, iValue, pField->bits, signbit );
} }
else if( pField->flags & DT_TIMEWINDOW_BIG ) else if( pField->flags & DT_TIMEWINDOW_BIG )
{ {
bSigned = true; // timewindow is always signed signbit = 1; // timewindow is always signed
flValue = *(float *)((byte *)to + pField->offset ); flValue = *(float *)((byte *)to + pField->offset );
iValue = (int)Q_rint( timebase * pField->multiplier ) - (int)Q_rint( flValue * pField->multiplier ); iValue = (int)Q_rint( timebase * pField->multiplier ) - (int)Q_rint( flValue * pField->multiplier );
iValue = Delta_ClampIntegerField( pField, iValue, bSigned, pField->bits ); iValue = Delta_ClampIntegerField( pField, iValue, signbit, pField->bits );
MSG_WriteBitLong( msg, iValue, pField->bits, bSigned ); MSG_WriteBitLong( msg, iValue, pField->bits, signbit );
} }
else if( pField->flags & DT_STRING ) else if( pField->flags & DT_STRING )
{ {
@@ -1396,7 +1404,7 @@ void MSG_WriteDeltaUsercmd( sizebuf_t *msg, usercmd_t *from, usercmd_t *to )
delta_info_t *dt; delta_info_t *dt;
int i; int i;
dt = Delta_FindStruct( "usercmd_t" ); dt = Delta_FindStructByIndex( DT_USERCMD_T );
Assert( dt && dt->bInitialized ); Assert( dt && dt->bInitialized );
pField = dt->pFields; pField = dt->pFields;
@@ -1423,7 +1431,7 @@ void MSG_ReadDeltaUsercmd( sizebuf_t *msg, usercmd_t *from, usercmd_t *to )
delta_info_t *dt; delta_info_t *dt;
int i; int i;
dt = Delta_FindStruct( "usercmd_t" ); dt = Delta_FindStructByIndex( DT_USERCMD_T );
Assert( dt && dt->bInitialized ); Assert( dt && dt->bInitialized );
pField = dt->pFields; pField = dt->pFields;
@@ -1458,7 +1466,7 @@ void MSG_WriteDeltaEvent( sizebuf_t *msg, event_args_t *from, event_args_t *to )
delta_info_t *dt; delta_info_t *dt;
int i; int i;
dt = Delta_FindStruct( "event_t" ); dt = Delta_FindStructByIndex( DT_EVENT_T );
Assert( dt && dt->bInitialized ); Assert( dt && dt->bInitialized );
pField = dt->pFields; pField = dt->pFields;
@@ -1485,7 +1493,7 @@ void MSG_ReadDeltaEvent( sizebuf_t *msg, event_args_t *from, event_args_t *to )
delta_info_t *dt; delta_info_t *dt;
int i; int i;
dt = Delta_FindStruct( "event_t" ); dt = Delta_FindStructByIndex( DT_EVENT_T );
Assert( dt && dt->bInitialized ); Assert( dt && dt->bInitialized );
pField = dt->pFields; pField = dt->pFields;
@@ -1514,7 +1522,7 @@ qboolean MSG_WriteDeltaMovevars( sizebuf_t *msg, movevars_t *from, movevars_t *t
int i, startBit; int i, startBit;
int numChanges = 0; int numChanges = 0;
dt = Delta_FindStruct( "movevars_t" ); dt = Delta_FindStructByIndex( DT_MOVEVARS_T );
Assert( dt && dt->bInitialized ); Assert( dt && dt->bInitialized );
pField = dt->pFields; pField = dt->pFields;
@@ -1549,7 +1557,7 @@ void MSG_ReadDeltaMovevars( sizebuf_t *msg, movevars_t *from, movevars_t *to )
delta_info_t *dt; delta_info_t *dt;
int i; int i;
dt = Delta_FindStruct( "movevars_t" ); dt = Delta_FindStructByIndex( DT_MOVEVARS_T );
Assert( dt && dt->bInitialized ); Assert( dt && dt->bInitialized );
pField = dt->pFields; pField = dt->pFields;
@@ -1586,7 +1594,7 @@ void MSG_WriteClientData( sizebuf_t *msg, clientdata_t *from, clientdata_t *to,
int i, startBit; int i, startBit;
int numChanges = 0; int numChanges = 0;
dt = Delta_FindStruct( "clientdata_t" ); dt = Delta_FindStructByIndex( DT_CLIENTDATA_T );
Assert( dt && dt->bInitialized ); Assert( dt && dt->bInitialized );
pField = dt->pFields; pField = dt->pFields;
@@ -1627,7 +1635,7 @@ void MSG_ReadClientData( sizebuf_t *msg, clientdata_t *from, clientdata_t *to, d
int i; int i;
qboolean noChanges; qboolean noChanges;
dt = Delta_FindStruct( "clientdata_t" ); dt = Delta_FindStructByIndex( DT_CLIENTDATA_T );
Assert( dt && dt->bInitialized ); Assert( dt && dt->bInitialized );
pField = dt->pFields; pField = dt->pFields;
@@ -1667,7 +1675,7 @@ void MSG_WriteWeaponData( sizebuf_t *msg, weapon_data_t *from, weapon_data_t *to
int i, startBit; int i, startBit;
int numChanges = 0; int numChanges = 0;
dt = Delta_FindStruct( "weapon_data_t" ); dt = Delta_FindStructByIndex( DT_WEAPONDATA_T );
Assert( dt && dt->bInitialized ); Assert( dt && dt->bInitialized );
pField = dt->pFields; pField = dt->pFields;
@@ -1705,7 +1713,7 @@ void MSG_ReadWeaponData( sizebuf_t *msg, weapon_data_t *from, weapon_data_t *to,
delta_info_t *dt; delta_info_t *dt;
int i; int i;
dt = Delta_FindStruct( "weapon_data_t" ); dt = Delta_FindStructByIndex( DT_WEAPONDATA_T );
Assert( dt && dt->bInitialized ); Assert( dt && dt->bInitialized );
pField = dt->pFields; pField = dt->pFields;
@@ -1788,15 +1796,15 @@ void MSG_WriteDeltaEntity( entity_state_t *from, entity_state_t *to, sizebuf_t *
if( FBitSet( to->entityType, ENTITY_BEAM )) if( FBitSet( to->entityType, ENTITY_BEAM ))
{ {
dt = Delta_FindStruct( "custom_entity_state_t" ); dt = Delta_FindStructByIndex( DT_CUSTOM_ENTITY_STATE_T );
} }
else if( delta_type == DELTA_PLAYER ) else if( delta_type == DELTA_PLAYER )
{ {
dt = Delta_FindStruct( "entity_state_player_t" ); dt = Delta_FindStructByIndex( DT_ENTITY_STATE_PLAYER_T );
} }
else else
{ {
dt = Delta_FindStruct( "entity_state_t" ); dt = Delta_FindStructByIndex( DT_ENTITY_STATE_T );
} }
Assert( dt && dt->bInitialized ); Assert( dt && dt->bInitialized );
@@ -1906,15 +1914,15 @@ qboolean MSG_ReadDeltaEntity( sizebuf_t *msg, entity_state_t *from, entity_state
if( cls.legacymode ? ( to->entityType == ENTITY_BEAM ) : FBitSet( to->entityType, ENTITY_BEAM )) if( cls.legacymode ? ( to->entityType == ENTITY_BEAM ) : FBitSet( to->entityType, ENTITY_BEAM ))
{ {
dt = Delta_FindStruct( "custom_entity_state_t" ); dt = Delta_FindStructByIndex( DT_CUSTOM_ENTITY_STATE_T );
} }
else if( delta_type == DELTA_PLAYER ) else if( delta_type == DELTA_PLAYER )
{ {
dt = Delta_FindStruct( "entity_state_player_t" ); dt = Delta_FindStructByIndex( DT_ENTITY_STATE_PLAYER_T );
} }
else else
{ {
dt = Delta_FindStruct( "entity_state_t" ); dt = Delta_FindStructByIndex( DT_ENTITY_STATE_T );
} }
Assert( dt && dt->bInitialized ); Assert( dt && dt->bInitialized );
@@ -1932,6 +1940,27 @@ qboolean MSG_ReadDeltaEntity( sizebuf_t *msg, entity_state_t *from, entity_state
return true; return true;
} }
/*
==================
Delta_WriteDescriptionToClient
send delta communication encoding
==================
*/
void Delta_WriteDescriptionToClient( sizebuf_t *msg )
{
int tableIndex;
int fieldIndex;
for( tableIndex = 0; tableIndex < Delta_NumTables(); tableIndex++ )
{
delta_info_t *dt = Delta_FindStructByIndex( tableIndex );
for( fieldIndex = 0; fieldIndex < dt->numFields; fieldIndex++ )
Delta_WriteTableField( msg, tableIndex, &dt->pFields[fieldIndex] );
}
}
/* /*
============================================================================= =============================================================================

View File

@@ -77,8 +77,6 @@ typedef struct
void Delta_Init( void ); void Delta_Init( void );
void Delta_InitClient( void ); void Delta_InitClient( void );
void Delta_Shutdown( void ); void Delta_Shutdown( void );
int Delta_NumTables( void );
delta_info_t *Delta_FindStructByIndex( int index );
void Delta_AddEncoder( char *name, pfnDeltaEncode encodeFunc ); void Delta_AddEncoder( char *name, pfnDeltaEncode encodeFunc );
int Delta_FindField( delta_t *pFields, const char *fieldname ); int Delta_FindField( delta_t *pFields, const char *fieldname );
void Delta_SetField( delta_t *pFields, const char *fieldname ); void Delta_SetField( delta_t *pFields, const char *fieldname );
@@ -87,7 +85,7 @@ void Delta_SetFieldByIndex( delta_t *pFields, int fieldNumber );
void Delta_UnsetFieldByIndex( delta_t *pFields, int fieldNumber ); void Delta_UnsetFieldByIndex( delta_t *pFields, int fieldNumber );
// send table over network // send table over network
void Delta_WriteTableField( sizebuf_t *msg, int tableIndex, const delta_t *pField ); void Delta_WriteDescriptionToClient( sizebuf_t *msg );
void Delta_ParseTableField( sizebuf_t *msg ); void Delta_ParseTableField( sizebuf_t *msg );

View File

@@ -108,23 +108,24 @@ typedef struct
} net_state_t; } net_state_t;
static net_state_t net; static net_state_t net;
static convar_t *net_ipname; static CVAR_DEFINE_AUTO( net_address, "0", FCVAR_PRIVILEGED|FCVAR_READ_ONLY, "contain local address of current client" );
static convar_t *net_hostport; static CVAR_DEFINE( net_ipname, "ip", "localhost", FCVAR_PRIVILEGED, "network ip address" );
static convar_t *net_iphostport; static CVAR_DEFINE( net_iphostport, "ip_hostport", "0", FCVAR_READ_ONLY, "network ip host port" );
static convar_t *net_clientport; static CVAR_DEFINE( net_hostport, "hostport", "0", FCVAR_READ_ONLY, "network default host port" );
static convar_t *net_ipclientport; static CVAR_DEFINE( net_ipclientport, "ip_clientport", "0", FCVAR_READ_ONLY, "network ip client port" );
static convar_t *net_fakelag; static CVAR_DEFINE( net_clientport, "clientport", "0", FCVAR_READ_ONLY, "network default client port" );
static convar_t *net_fakeloss; static CVAR_DEFINE( net_fakelag, "fakelag", "0", FCVAR_PRIVILEGED, "lag all incoming network data (including loopback) by xxx ms." );
static convar_t *net_address; static CVAR_DEFINE( net_fakeloss, "fakeloss", "0", FCVAR_PRIVILEGED, "act like we dropped the packet this % of the time." );
convar_t *net_clockwindow; CVAR_DEFINE( net_clockwindow, "clockwindow", "0.5", FCVAR_PRIVILEGED, "timewindow to execute client moves" );
netadr_t net_local; netadr_t net_local;
netadr_t net6_local; netadr_t net6_local;
// cvars equivalents for IPv6 // cvars equivalents for IPv6
static convar_t *net_ip6name; static CVAR_DEFINE( net_ip6name, "ip6", "localhost", FCVAR_PRIVILEGED, "network ip6 address" );
static convar_t *net_ip6hostport; static CVAR_DEFINE( net_ip6hostport, "ip6_hostport", "0", FCVAR_READ_ONLY, "network ip6 host port" );
static convar_t *net_ip6clientport; static CVAR_DEFINE( net_ip6clientport, "ip6_clientport", "0", FCVAR_READ_ONLY, "network ip6 client port" );
static convar_t *net6_address; static CVAR_DEFINE_AUTO( net6_address, "0", FCVAR_PRIVILEGED|FCVAR_READ_ONLY, "contain local IPv6 address of current client" );
/* /*
==================== ====================
@@ -273,8 +274,8 @@ static void NET_NetadrToSockadr( netadr_t *a, struct sockaddr_storage *s )
else if( a->type == NA_IP ) else if( a->type == NA_IP )
{ {
((struct sockaddr_in *)s)->sin_family = AF_INET; ((struct sockaddr_in *)s)->sin_family = AF_INET;
((struct sockaddr_in *)s)->sin_addr.s_addr = *(uint32_t *)&a->ip;
((struct sockaddr_in *)s)->sin_port = a->port; ((struct sockaddr_in *)s)->sin_port = a->port;
((struct sockaddr_in *)s)->sin_addr.s_addr = a->ip4;
} }
else if( a->type6 == NA_IP6 ) else if( a->type6 == NA_IP6 )
{ {
@@ -313,7 +314,7 @@ static void NET_SockadrToNetadr( const struct sockaddr_storage *s, netadr_t *a )
if( s->ss_family == AF_INET ) if( s->ss_family == AF_INET )
{ {
a->type = NA_IP; a->type = NA_IP;
*(int *)&a->ip = ((struct sockaddr_in *)s)->sin_addr.s_addr; a->ip4 = ((struct sockaddr_in *)s)->sin_addr.s_addr;
a->port = ((struct sockaddr_in *)s)->sin_port; a->port = ((struct sockaddr_in *)s)->sin_port;
} }
else if( s->ss_family == AF_INET6 ) else if( s->ss_family == AF_INET6 )
@@ -443,6 +444,7 @@ static void NET_InitializeCriticalSections( void )
void NET_ResolveThread( void ) void NET_ResolveThread( void )
{ {
struct sockaddr_storage addr; struct sockaddr_storage addr;
qboolean res;
RESOLVE_DBG( "[resolve thread] starting resolve for " ); RESOLVE_DBG( "[resolve thread] starting resolve for " );
RESOLVE_DBG( nsthread.hostname ); RESOLVE_DBG( nsthread.hostname );
@@ -452,13 +454,14 @@ void NET_ResolveThread( void )
RESOLVE_DBG( " with gethostbyname\n" ); RESOLVE_DBG( " with gethostbyname\n" );
#endif #endif
if( NET_GetHostByName( nsthread.hostname, nsthread.family, &addr )) if(( res = NET_GetHostByName( nsthread.hostname, nsthread.family, &addr )))
RESOLVE_DBG( "[resolve thread] success\n" ); RESOLVE_DBG( "[resolve thread] success\n" );
else else
RESOLVE_DBG( "[resolve thread] failed\n" ); RESOLVE_DBG( "[resolve thread] failed\n" );
mutex_lock( &nsthread.mutexres ); mutex_lock( &nsthread.mutexres );
nsthread.addr = addr; nsthread.addr = addr;
nsthread.busy = false; nsthread.busy = false;
nsthread.result = res ? NET_EAI_OK : NET_EAI_NONAME;
RESOLVE_DBG( "[resolve thread] returning result\n" ); RESOLVE_DBG( "[resolve thread] returning result\n" );
mutex_unlock( &nsthread.mutexres ); mutex_unlock( &nsthread.mutexres );
RESOLVE_DBG( "[resolve thread] exiting thread\n" ); RESOLVE_DBG( "[resolve thread] exiting thread\n" );
@@ -543,6 +546,7 @@ static net_gai_state_t NET_StringToSockaddr( const char *s, struct sockaddr_stor
memset( &nsthread.addr, 0, sizeof( nsthread.addr )); memset( &nsthread.addr, 0, sizeof( nsthread.addr ));
detach_thread( nsthread.thread ); detach_thread( nsthread.thread );
asyncfailed = false;
} }
else else
{ {
@@ -722,7 +726,7 @@ const char *NET_AdrToString( const netadr_t a )
if( a.type == NA_LOOPBACK ) if( a.type == NA_LOOPBACK )
return "loopback"; return "loopback";
if( a.type6 == NA_IP6 ) if( a.type6 == NA_IP6 || a.type6 == NA_MULTICAST_IP6 )
{ {
uint8_t ip6[16]; uint8_t ip6[16];
@@ -749,7 +753,7 @@ const char *NET_BaseAdrToString( const netadr_t a )
if( a.type == NA_LOOPBACK ) if( a.type == NA_LOOPBACK )
return "loopback"; return "loopback";
if( a.type6 == NA_IP6 ) if( a.type6 == NA_IP6 || a.type6 == NA_MULTICAST_IP6 )
{ {
uint8_t ip6[16]; uint8_t ip6[16];
@@ -1065,7 +1069,7 @@ net_gai_state_t NET_StringToAdrNB( const char *string, netadr_t *adr )
if( !Q_stricmp( string, "localhost" ) || !Q_stricmp( string, "loopback" )) if( !Q_stricmp( string, "localhost" ) || !Q_stricmp( string, "loopback" ))
{ {
adr->type = NA_LOOPBACK; adr->type = NA_LOOPBACK;
return true; return NET_EAI_OK;
} }
res = NET_StringToSockaddr( string, &s, true, AF_UNSPEC ); res = NET_StringToSockaddr( string, &s, true, AF_UNSPEC );
@@ -1243,11 +1247,11 @@ static void NET_AdjustLag( void )
dt = bound( 0.0, dt, 0.1 ); dt = bound( 0.0, dt, 0.1 );
lasttime = host.realtime; lasttime = host.realtime;
if( host_developer.value || !net_fakelag->value ) if( host_developer.value || !net_fakelag.value )
{ {
if( net_fakelag->value != net.fakelag ) if( net_fakelag.value != net.fakelag )
{ {
diff = net_fakelag->value - net.fakelag; diff = net_fakelag.value - net.fakelag;
converge = dt * 200.0f; converge = dt * 200.0f;
if( fabs( diff ) < converge ) if( fabs( diff ) < converge )
converge = fabs( diff ); converge = fabs( diff );
@@ -1288,14 +1292,14 @@ static qboolean NET_LagPacket( qboolean newdata, netsrc_t sock, netadr_t *from,
if( newdata ) if( newdata )
{ {
if( net_fakeloss->value != 0.0f ) if( net_fakeloss.value != 0.0f )
{ {
if( host_developer.value ) if( host_developer.value )
{ {
net.losscount[sock]++; net.losscount[sock]++;
if( net_fakeloss->value <= 0.0f ) if( net_fakeloss.value <= 0.0f )
{ {
ninterval = fabs( net_fakeloss->value ); ninterval = fabs( net_fakeloss.value );
if( ninterval < 2 ) ninterval = 2; if( ninterval < 2 ) ninterval = 2;
if(( net.losscount[sock] % ninterval ) == 0 ) if(( net.losscount[sock] % ninterval ) == 0 )
@@ -1303,7 +1307,7 @@ static qboolean NET_LagPacket( qboolean newdata, netsrc_t sock, netadr_t *from,
} }
else else
{ {
if( COM_RandomLong( 0, 100 ) <= net_fakeloss->value ) if( COM_RandomLong( 0, 100 ) <= net_fakeloss.value )
return false; return false;
} }
} }
@@ -1392,7 +1396,7 @@ qboolean NET_GetLong( byte *pData, int size, size_t *outSize, int splitsize )
for( i = 0; i < NET_MAX_FRAGMENTS; i++ ) for( i = 0; i < NET_MAX_FRAGMENTS; i++ )
net.split_flags[i] = -1; net.split_flags[i] = -1;
if( net_showpackets && net_showpackets->value == 4.0f ) if( net_showpackets.value == 4.0f )
Con_Printf( "<-- Split packet restart %i count %i seq\n", net.split.split_count, sequence_number ); Con_Printf( "<-- Split packet restart %i count %i seq\n", net.split.split_count, sequence_number );
} }
@@ -1406,7 +1410,7 @@ qboolean NET_GetLong( byte *pData, int size, size_t *outSize, int splitsize )
net.split.split_count--; net.split.split_count--;
net.split_flags[packet_number] = sequence_number; net.split_flags[packet_number] = sequence_number;
if( net_showpackets && net_showpackets->value == 4.0f ) if( net_showpackets.value == 4.0f )
Con_Printf( "<-- Split packet %i of %i, %i bytes %i seq\n", packet_number + 1, packet_count, size, sequence_number ); Con_Printf( "<-- Split packet %i of %i, %i bytes %i seq\n", packet_number + 1, packet_count, size, sequence_number );
} }
else else
@@ -1577,7 +1581,7 @@ int NET_SendLong( netsrc_t sock, int net_socket, const char *buf, size_t len, in
pPacket->packet_id = (packet_number << 8) + packet_count; pPacket->packet_id = (packet_number << 8) + packet_count;
memcpy( packet + sizeof( SPLITPACKET ), buf + ( packet_number * body_size ), size ); memcpy( packet + sizeof( SPLITPACKET ), buf + ( packet_number * body_size ), size );
if( net_showpackets && net_showpackets->value == 3.0f ) if( net_showpackets.value == 3.0f )
{ {
netadr_t adr; netadr_t adr;
@@ -1813,14 +1817,14 @@ static void NET_OpenIP( qboolean change_port, int *sockets, const char *net_ifac
qboolean sv_nat = Cvar_VariableInteger("sv_nat"); qboolean sv_nat = Cvar_VariableInteger("sv_nat");
qboolean cl_nat = Cvar_VariableInteger("cl_nat"); qboolean cl_nat = Cvar_VariableInteger("cl_nat");
if( change_port && ( FBitSet( net_hostport->flags, FCVAR_CHANGED ) || sv_nat )) if( change_port && ( FBitSet( net_hostport.flags, FCVAR_CHANGED ) || sv_nat ))
{ {
// reopen socket to set random port // reopen socket to set random port
if( NET_IsSocketValid( sockets[NS_SERVER] )) if( NET_IsSocketValid( sockets[NS_SERVER] ))
closesocket( sockets[NS_SERVER] ); closesocket( sockets[NS_SERVER] );
sockets[NS_SERVER] = INVALID_SOCKET; sockets[NS_SERVER] = INVALID_SOCKET;
ClearBits( net_hostport->flags, FCVAR_CHANGED ); ClearBits( net_hostport.flags, FCVAR_CHANGED );
} }
if( !NET_IsSocketValid( sockets[NS_SERVER] )) if( !NET_IsSocketValid( sockets[NS_SERVER] ))
@@ -1828,7 +1832,7 @@ static void NET_OpenIP( qboolean change_port, int *sockets, const char *net_ifac
port = hostport; port = hostport;
if( !port ) if( !port )
{ {
port = sv_nat ? PORT_ANY : net_hostport->value; port = sv_nat ? PORT_ANY : net_hostport.value;
if( !port ) if( !port )
port = PORT_SERVER; // forcing to default port = PORT_SERVER; // forcing to default
@@ -1842,14 +1846,14 @@ static void NET_OpenIP( qboolean change_port, int *sockets, const char *net_ifac
// dedicated servers don't need client ports // dedicated servers don't need client ports
if( Host_IsDedicated( )) return; if( Host_IsDedicated( )) return;
if( change_port && ( FBitSet( net_clientport->flags, FCVAR_CHANGED ) || cl_nat )) if( change_port && ( FBitSet( net_clientport.flags, FCVAR_CHANGED ) || cl_nat ))
{ {
// reopen socket to set random port // reopen socket to set random port
if( NET_IsSocketValid( sockets[NS_CLIENT] )) if( NET_IsSocketValid( sockets[NS_CLIENT] ))
closesocket( sockets[NS_CLIENT] ); closesocket( sockets[NS_CLIENT] );
sockets[NS_CLIENT] = INVALID_SOCKET; sockets[NS_CLIENT] = INVALID_SOCKET;
ClearBits( net_clientport->flags, FCVAR_CHANGED ); ClearBits( net_clientport.flags, FCVAR_CHANGED );
} }
if( !NET_IsSocketValid( sockets[NS_CLIENT] )) if( !NET_IsSocketValid( sockets[NS_CLIENT] ))
@@ -1857,7 +1861,7 @@ static void NET_OpenIP( qboolean change_port, int *sockets, const char *net_ifac
port = clientport; port = clientport;
if( !port ) if( !port )
{ {
port = cl_nat ? PORT_ANY : net_clientport->value; port = cl_nat ? PORT_ANY : net_clientport.value;
if( !port ) if( !port )
port = PORT_ANY; // forcing to default port = PORT_ANY; // forcing to default
@@ -1865,7 +1869,7 @@ static void NET_OpenIP( qboolean change_port, int *sockets, const char *net_ifac
sockets[NS_CLIENT] = NET_IPSocket( net_iface, port, family ); sockets[NS_CLIENT] = NET_IPSocket( net_iface, port, family );
if( !NET_IsSocketValid( sockets[NS_CLIENT] )) if( !NET_IsSocketValid( sockets[NS_CLIENT] ))
sockets[NS_CLIENT] = NET_IPSocket( net_ipname->string, PORT_ANY, family ); sockets[NS_CLIENT] = NET_IPSocket( net_ipname.string, PORT_ANY, family );
} }
return; return;
@@ -1901,8 +1905,8 @@ void NET_GetLocalAddress( void )
if( net.allow_ip ) if( net.allow_ip )
{ {
// If we have changed the ip var from the command line, use that instead. // If we have changed the ip var from the command line, use that instead.
if( Q_stricmp( net_ipname->string, "localhost" )) if( Q_stricmp( net_ipname.string, "localhost" ))
Q_strncpy( buff, net_ipname->string, sizeof( buff )); Q_strncpy( buff, net_ipname.string, sizeof( buff ));
else Q_strncpy( buff, hostname, sizeof( buff )); else Q_strncpy( buff, hostname, sizeof( buff ));
if( NET_StringToAdrEx( buff, &net_local, AF_INET )) if( NET_StringToAdrEx( buff, &net_local, AF_INET ))
@@ -1914,7 +1918,7 @@ void NET_GetLocalAddress( void )
net_local.port = ((struct sockaddr_in *)&address)->sin_port; net_local.port = ((struct sockaddr_in *)&address)->sin_port;
net_addr_string = NET_AdrToString( net_local ); net_addr_string = NET_AdrToString( net_local );
Con_Printf( "Server IPv4 address %s\n", net_addr_string ); Con_Printf( "Server IPv4 address %s\n", net_addr_string );
Cvar_FullSet( "net_address", net_addr_string, net_address->flags ); Cvar_FullSet( "net_address", net_addr_string, net_address.flags );
} }
else Con_DPrintf( S_ERROR "Could not get TCP/IPv4 address. Reason: %s\n", NET_ErrorString( )); else Con_DPrintf( S_ERROR "Could not get TCP/IPv4 address. Reason: %s\n", NET_ErrorString( ));
} }
@@ -1924,8 +1928,8 @@ void NET_GetLocalAddress( void )
if( net.allow_ip6 ) if( net.allow_ip6 )
{ {
// If we have changed the ip var from the command line, use that instead. // If we have changed the ip var from the command line, use that instead.
if( Q_stricmp( net_ip6name->string, "localhost" )) if( Q_stricmp( net_ip6name.string, "localhost" ))
Q_strncpy( buff, net_ip6name->string, sizeof( buff )); Q_strncpy( buff, net_ip6name.string, sizeof( buff ));
else Q_strncpy( buff, hostname, sizeof( buff )); else Q_strncpy( buff, hostname, sizeof( buff ));
if( NET_StringToAdrEx( buff, &net6_local, AF_INET6 )) if( NET_StringToAdrEx( buff, &net6_local, AF_INET6 ))
@@ -1937,7 +1941,7 @@ void NET_GetLocalAddress( void )
net6_local.port = ((struct sockaddr_in6 *)&address)->sin6_port; net6_local.port = ((struct sockaddr_in6 *)&address)->sin6_port;
net_addr_string = NET_AdrToString( net6_local ); net_addr_string = NET_AdrToString( net6_local );
Con_Printf( "Server IPv6 address %s\n", net_addr_string ); Con_Printf( "Server IPv6 address %s\n", net_addr_string );
Cvar_FullSet( "net6_address", net_addr_string, net6_address->flags ); Cvar_FullSet( "net6_address", net_addr_string, net6_address.flags );
} }
else Con_DPrintf( S_ERROR "Could not get TCP/IPv6 address. Reason: %s\n", NET_ErrorString( )); else Con_DPrintf( S_ERROR "Could not get TCP/IPv6 address. Reason: %s\n", NET_ErrorString( ));
} }
@@ -1969,10 +1973,10 @@ void NET_Config( qboolean multiplayer, qboolean changeport )
{ {
// open sockets // open sockets
if( net.allow_ip ) if( net.allow_ip )
NET_OpenIP( changeport, net.ip_sockets, net_ipname->string, net_iphostport->value, net_ipclientport->value, AF_INET ); NET_OpenIP( changeport, net.ip_sockets, net_ipname.string, net_iphostport.value, net_ipclientport.value, AF_INET );
if( net.allow_ip6 ) if( net.allow_ip6 )
NET_OpenIP( changeport, net.ip6_sockets, net_ip6name->string, net_ip6hostport->value, net_ip6clientport->value, AF_INET6 ); NET_OpenIP( changeport, net.ip6_sockets, net_ip6name.string, net_ip6hostport.value, net_ip6clientport.value, AF_INET6 );
// validate sockets for dedicated // validate sockets for dedicated
if( Host_IsDedicated( )) if( Host_IsDedicated( ))
@@ -2100,21 +2104,23 @@ void NET_Init( void )
if( net.initialized ) return; if( net.initialized ) return;
net_clockwindow = Cvar_Get( "clockwindow", "0.5", FCVAR_PRIVILEGED, "timewindow to execute client moves" ); Cvar_RegisterVariable( &net_address );
net_address = Cvar_Get( "net_address", "0", FCVAR_PRIVILEGED|FCVAR_READ_ONLY, "contain local address of current client" ); Cvar_RegisterVariable( &net_ipname );
net_ipname = Cvar_Get( "ip", "localhost", FCVAR_PRIVILEGED, "network ip address" ); Cvar_RegisterVariable( &net_iphostport );
net_iphostport = Cvar_Get( "ip_hostport", "0", FCVAR_READ_ONLY, "network ip host port" ); Cvar_RegisterVariable( &net_hostport );
net_hostport = Cvar_Getf( "hostport", FCVAR_READ_ONLY, "network default host port", "%i", PORT_SERVER ); Cvar_RegisterVariable( &net_ipclientport );
net_ipclientport = Cvar_Get( "ip_clientport", "0", FCVAR_READ_ONLY, "network ip client port" ); Cvar_RegisterVariable( &net_clientport );
net_clientport = Cvar_Getf( "clientport", FCVAR_READ_ONLY, "network default client port", "%i", PORT_CLIENT ); Cvar_RegisterVariable( &net_fakelag );
net_fakelag = Cvar_Get( "fakelag", "0", FCVAR_PRIVILEGED, "lag all incoming network data (including loopback) by xxx ms." ); Cvar_RegisterVariable( &net_fakeloss );
net_fakeloss = Cvar_Get( "fakeloss", "0", FCVAR_PRIVILEGED, "act like we dropped the packet this % of the time." );
Q_snprintf( cmd, sizeof( cmd ), "%i", PORT_SERVER );
Cvar_FullSet( "hostport", cmd, FCVAR_READ_ONLY );
// cvar equivalents for IPv6 // cvar equivalents for IPv6
net_ip6name = Cvar_Get( "ip6", "localhost", FCVAR_PRIVILEGED, "network ip6 address" ); Cvar_RegisterVariable( &net_ip6name );
net_ip6hostport = Cvar_Get( "ip6_hostport", "0", FCVAR_READ_ONLY, "network ip6 host port" ); Cvar_RegisterVariable( &net_ip6hostport );
net_ip6clientport = Cvar_Get( "ip6_clientport", "0", FCVAR_READ_ONLY, "network ip6 client port" ); Cvar_RegisterVariable( &net_ip6clientport );
net6_address = Cvar_Get( "net6_address", "0", FCVAR_PRIVILEGED|FCVAR_READ_ONLY, "contain local IPv6 address of current client" ); Cvar_RegisterVariable( &net6_address );
// prepare some network data // prepare some network data
for( i = 0; i < NS_COUNT; i++ ) for( i = 0; i < NS_COUNT; i++ )
@@ -2150,11 +2156,11 @@ void NET_Init( void )
// specify custom ip // specify custom ip
if( Sys_GetParmFromCmdLine( "-ip", cmd )) if( Sys_GetParmFromCmdLine( "-ip", cmd ))
Cvar_FullSet( "ip", cmd, net_ipname->flags ); Cvar_FullSet( "ip", cmd, net_ipname.flags );
// specify custom ip6 // specify custom ip6
if( Sys_GetParmFromCmdLine( "-ip6", cmd )) if( Sys_GetParmFromCmdLine( "-ip6", cmd ))
Cvar_FullSet( "ip6", cmd, net_ip6name->flags ); Cvar_FullSet( "ip6", cmd, net_ip6name.flags );
// adjust clockwindow // adjust clockwindow
if( Sys_GetParmFromCmdLine( "-clockwindow", cmd )) if( Sys_GetParmFromCmdLine( "-clockwindow", cmd ))
@@ -2194,6 +2200,8 @@ HTTP downloader
================================================= =================================================
*/ */
#define MAX_HTTP_BUFFER_SIZE (BIT( 13 ))
typedef struct httpserver_s typedef struct httpserver_s
{ {
char host[256]; char host[256];
@@ -2234,7 +2242,7 @@ typedef struct httpfile_s
qboolean process; qboolean process;
// query or response // query or response
char buf[BUFSIZ+1]; char buf[MAX_HTTP_BUFFER_SIZE+1];
int header_size, query_length, bytes_sent; int header_size, query_length, bytes_sent;
} httpfile_t; } httpfile_t;
@@ -2246,10 +2254,10 @@ static struct http_static_s
} http; } http;
static convar_t *http_useragent; static CVAR_DEFINE_AUTO( http_useragent, "", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "User-Agent string" );
static convar_t *http_autoremove; static CVAR_DEFINE_AUTO( http_autoremove, "1", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "remove broken files" );
static convar_t *http_timeout; static CVAR_DEFINE_AUTO( http_timeout, "45", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "timeout for http downloader" );
static convar_t *http_maxconnections; static CVAR_DEFINE_AUTO( http_maxconnections, "4", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "maximum http connection number" );
/* /*
======================== ========================
@@ -2304,7 +2312,7 @@ static void HTTP_FreeFile( httpfile_t *file, qboolean error )
} }
// Called because there was no servers to download, free file now // Called because there was no servers to download, free file now
if( http_autoremove->value == 1 ) // remove broken file if( http_autoremove.value == 1 ) // remove broken file
FS_Delete( incname ); FS_Delete( incname );
else // autoremove disabled, keep file else // autoremove disabled, keep file
Con_Printf( "cannot download %s from any server. " Con_Printf( "cannot download %s from any server. "
@@ -2379,18 +2387,18 @@ process incoming data
*/ */
static qboolean HTTP_ProcessStream( httpfile_t *curfile ) static qboolean HTTP_ProcessStream( httpfile_t *curfile )
{ {
char buf[BUFSIZ+1]; char buf[sizeof( curfile->buf )];
char *begin = 0; char *begin = 0;
int res; int res;
if( curfile->header_size >= BUFSIZ ) if( curfile->header_size >= sizeof( buf ))
{ {
Con_Reportf( S_ERROR "Header to big\n"); Con_Reportf( S_ERROR "Header too big, the size is %s\n", curfile->header_size );
HTTP_FreeFile( curfile, true ); HTTP_FreeFile( curfile, true );
return false; return false;
} }
while( ( res = recv( curfile->socket, buf, BUFSIZ - curfile->header_size, 0 )) > 0) // if we got there, we are receiving data while( ( res = recv( curfile->socket, buf, sizeof( buf ) - curfile->header_size, 0 )) > 0) // if we got there, we are receiving data
{ {
curfile->blocktime = 0; curfile->blocktime = 0;
@@ -2403,7 +2411,7 @@ static qboolean HTTP_ProcessStream( httpfile_t *curfile )
if( begin ) // Got full header if( begin ) // Got full header
{ {
int cutheadersize = begin - curfile->buf + 4; // after that begin of data int cutheadersize = begin - curfile->buf + 4; // after that begin of data
char *length; char *content_length_line;
Con_Reportf( "HTTP: Got response!\n" ); Con_Reportf( "HTTP: Got response!\n" );
@@ -2422,10 +2430,13 @@ static qboolean HTTP_ProcessStream( httpfile_t *curfile )
} }
// print size // print size
length = Q_stristr( curfile->buf, "Content-Length: " ); content_length_line = Q_stristr( curfile->buf, "Content-Length: " );
if( length ) if( content_length_line )
{ {
int size = Q_atoi( length += 16 ); int size;
content_length_line += sizeof( "Content-Length: " ) - 1;
size = Q_atoi( content_length_line );
Con_Reportf( "HTTP: File size is %d\n", size ); Con_Reportf( "HTTP: File size is %d\n", size );
@@ -2525,7 +2536,7 @@ void HTTP_Run( void )
{ {
char name[MAX_SYSPATH]; char name[MAX_SYSPATH];
if( iActiveCount > http_maxconnections->value ) if( iActiveCount > http_maxconnections.value )
continue; continue;
if( !curfile->server ) if( !curfile->server )
@@ -2624,14 +2635,14 @@ void HTTP_Run( void )
{ {
string useragent; string useragent;
if( !COM_CheckStringEmpty( http_useragent->string ) || !Q_strcmp( http_useragent->string, "xash3d" )) if( !COM_CheckStringEmpty( http_useragent.string ) || !Q_strcmp( http_useragent.string, "xash3d" ))
{ {
Q_snprintf( useragent, sizeof( useragent ), "%s/%s (%s-%s; build %d; %s)", Q_snprintf( useragent, sizeof( useragent ), "%s/%s (%s-%s; build %d; %s)",
XASH_ENGINE_NAME, XASH_VERSION, Q_buildos( ), Q_buildarch( ), Q_buildnum( ), Q_buildcommit( )); XASH_ENGINE_NAME, XASH_VERSION, Q_buildos( ), Q_buildarch( ), Q_buildnum( ), Q_buildcommit( ));
} }
else else
{ {
Q_strncpy( useragent, http_useragent->string, sizeof( useragent )); Q_strncpy( useragent, http_useragent.string, sizeof( useragent ));
} }
curfile->query_length = Q_snprintf( curfile->buf, sizeof( curfile->buf ), curfile->query_length = Q_snprintf( curfile->buf, sizeof( curfile->buf ),
@@ -2666,7 +2677,7 @@ void HTTP_Run( void )
curfile->blocktime += host.frametime; curfile->blocktime += host.frametime;
wait = true; wait = true;
if( curfile->blocktime > http_timeout->value ) if( curfile->blocktime > http_timeout.value )
{ {
Con_Printf( S_ERROR "timeout on request send:\n%s\n", curfile->buf ); Con_Printf( S_ERROR "timeout on request send:\n%s\n", curfile->buf );
HTTP_FreeFile( curfile, true ); HTTP_FreeFile( curfile, true );
@@ -2708,7 +2719,7 @@ void HTTP_Run( void )
else else
curfile->blocktime += host.frametime; curfile->blocktime += host.frametime;
if( curfile->blocktime > http_timeout->value ) if( curfile->blocktime > http_timeout.value )
{ {
Con_Printf( S_ERROR "timeout on receiving data!\n"); Con_Printf( S_ERROR "timeout on receiving data!\n");
HTTP_FreeFile( curfile, true ); HTTP_FreeFile( curfile, true );
@@ -2867,6 +2878,10 @@ static void HTTP_AddCustomServer_f( void )
{ {
HTTP_AddCustomServer( Cmd_Argv( 1 )); HTTP_AddCustomServer( Cmd_Argv( 1 ));
} }
else
{
Con_Printf( S_USAGE "http_addcustomserver <url>\n" );
}
} }
/* /*
@@ -2986,10 +3001,11 @@ void HTTP_Init( void )
Cmd_AddRestrictedCommand( "http_clear", HTTP_Clear_f, "cancel all downloads" ); Cmd_AddRestrictedCommand( "http_clear", HTTP_Clear_f, "cancel all downloads" );
Cmd_AddRestrictedCommand( "http_list", HTTP_List_f, "list all queued downloads" ); Cmd_AddRestrictedCommand( "http_list", HTTP_List_f, "list all queued downloads" );
Cmd_AddCommand( "http_addcustomserver", HTTP_AddCustomServer_f, "add custom fastdl server"); Cmd_AddCommand( "http_addcustomserver", HTTP_AddCustomServer_f, "add custom fastdl server");
http_useragent = Cvar_Get( "http_useragent", "", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "User-Agent string" );
http_autoremove = Cvar_Get( "http_autoremove", "1", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "remove broken files" ); Cvar_RegisterVariable( &http_useragent );
http_timeout = Cvar_Get( "http_timeout", "45", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "timeout for http downloader" ); Cvar_RegisterVariable( &http_autoremove );
http_maxconnections = Cvar_Get( "http_maxconnections", "4", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "maximum http connection number" ); Cvar_RegisterVariable( &http_timeout );
Cvar_RegisterVariable( &http_maxconnections );
// Read servers from fastdl.txt // Read servers from fastdl.txt
line = serverfile = (char *)FS_LoadFile( "fastdl.txt", 0, false ); line = serverfile = (char *)FS_LoadFile( "fastdl.txt", 0, false );

View File

@@ -50,8 +50,8 @@ typedef enum
#include "netadr.h" #include "netadr.h"
extern convar_t *net_showpackets; extern convar_t net_showpackets;
extern convar_t *net_clockwindow; extern convar_t net_clockwindow;
void NET_Init( void ); void NET_Init( void );
void NET_Shutdown( void ); void NET_Shutdown( void );

View File

@@ -70,10 +70,10 @@ GNU General Public License for more details.
#define NET_MAX_MESSAGE PAD_NUMBER(( NET_MAX_PAYLOAD + HEADER_BYTES ), 16 ) #define NET_MAX_MESSAGE PAD_NUMBER(( NET_MAX_PAYLOAD + HEADER_BYTES ), 16 )
#define MASTERSERVER_ADR "mentality.rip:27010" #define MASTERSERVER_ADR "mentality.rip:27010"
#define MASTERSERVER_ADR_TEST "mentality.rip:27011"
#define MS_SCAN_REQUEST "1\xFF" "0.0.0.0:0\0" #define MS_SCAN_REQUEST "1\xFF" "0.0.0.0:0\0"
#define PORT_MASTER 27010 #define PORT_MASTER 27010
#define PORT_CLIENT 27005
#define PORT_SERVER 27015 #define PORT_SERVER 27015
#define MULTIPLAYER_BACKUP 64 // how many data slots to use when in multiplayer (must be power of 2) #define MULTIPLAYER_BACKUP 64 // how many data slots to use when in multiplayer (must be power of 2)

View File

@@ -138,7 +138,7 @@ PM_HullPointContents
================== ==================
*/ */
int PM_HullPointContents( hull_t *hull, int num, const vec3_t p ) int GAME_EXPORT PM_HullPointContents( hull_t *hull, int num, const vec3_t p )
{ {
mplane_t *plane; mplane_t *plane;

File diff suppressed because it is too large Load Diff

View File

@@ -85,7 +85,7 @@ static qboolean Sound_ParseID3Frame( const did3v2_frame_t *frame, const byte *bu
string key, value; string key, value;
int32_t key_len, value_len; int32_t key_len, value_len;
if( buffer[0] == 0x00 || buffer[1] == 0x03 ) if( buffer[0] == 0x00 || buffer[0] == 0x03 )
{ {
key_len = Q_strncpy( key, &buffer[1], sizeof( key )); key_len = Q_strncpy( key, &buffer[1], sizeof( key ));
value_len = frame_length - (1 + key_len + 1); value_len = frame_length - (1 + key_len + 1);
@@ -129,7 +129,7 @@ static qboolean Sound_ParseID3Tag( const byte *buffer, fs_offset_t filesize )
{ {
// old id3v1 header found // old id3v1 header found
if( CHECK_IDENT( header->ident, 'T', 'A', 'G' )) if( CHECK_IDENT( header->ident, 'T', 'A', 'G' ))
Con_Printf( S_ERROR "Sound_ParseID3Tag: ID3v1 is not supported! Convert to ID3v2.4!\n", header->major_ver ); Con_Printf( S_ERROR "Sound_ParseID3Tag: ID3v1 is not supported! Convert to ID3v2.4!\n" );
return true; // missing tag header is not an error return true; // missing tag header is not an error
} }

View File

@@ -95,12 +95,16 @@ byte *Sound_Copy( size_t size )
uint GAME_EXPORT Sound_GetApproxWavePlayLen( const char *filepath ) uint GAME_EXPORT Sound_GetApproxWavePlayLen( const char *filepath )
{ {
string name;
file_t *f; file_t *f;
wavehdr_t wav; wavehdr_t wav;
size_t filesize; size_t filesize;
uint msecs; uint msecs;
f = FS_Open( filepath, "rb", false ); Q_strncpy( name, filepath, sizeof( name ));
COM_FixSlashes( name );
f = FS_Open( name, "rb", false );
if( !f ) if( !f )
return 0; return 0;

View File

@@ -1,6 +1,7 @@
/* /*
snd_wav.c - wav format load & save snd_wav.c - wav format load & save
Copyright (C) 2010 Uncle Mike Copyright (C) 2010 Uncle Mike
Copyright (C) 2023 FTEQW developers
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@@ -13,6 +14,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
*/ */
#include <stddef.h>
#include "soundlib.h" #include "soundlib.h"
static const byte *iff_data; static const byte *iff_data;
@@ -60,27 +62,22 @@ static int GetLittleLong( void )
FindNextChunk FindNextChunk
================= =================
*/ */
static void FindNextChunk( const char *name ) static void FindNextChunk( const char *filename, const char *name )
{ {
int remaining;
while( 1 ) while( 1 )
{ {
iff_dataPtr = iff_lastChunk; ptrdiff_t remaining = iff_end - iff_lastChunk;
remaining = iff_end - iff_dataPtr;
if( remaining < 8 ) if( remaining < 8 )
{ {
// didn't find the chunk
iff_dataPtr = NULL; iff_dataPtr = NULL;
return; return;
} }
iff_dataPtr += 4; iff_dataPtr = iff_lastChunk + 4;
iff_chunkLen = GetLittleLong();
remaining -= 8; remaining -= 8;
iff_chunkLen = GetLittleLong();
if( iff_chunkLen < 0 ) if( iff_chunkLen < 0 )
{ {
iff_dataPtr = NULL; iff_dataPtr = NULL;
@@ -89,16 +86,17 @@ static void FindNextChunk( const char *name )
if( iff_chunkLen > remaining ) if( iff_chunkLen > remaining )
{ {
Con_DPrintf( "%s: '%s' truncated by %i bytes\n", __func__, filename, iff_chunkLen - remaining );
iff_chunkLen = remaining; iff_chunkLen = remaining;
} }
remaining -= iff_chunkLen; remaining -= iff_chunkLen;
iff_dataPtr -= 8; iff_dataPtr -= 8;
iff_lastChunk = iff_dataPtr + 8 + iff_chunkLen;
if( iff_chunkLen & 1 && remaining )
iff_chunkLen++;
if( !Q_strncmp( (const char *)iff_dataPtr, name, 4 )) iff_lastChunk = iff_dataPtr + 8 + iff_chunkLen;
if ((iff_chunkLen&1) && remaining)
iff_lastChunk++;
if (!Q_strncmp(iff_dataPtr, name, 4))
return; return;
} }
} }
@@ -108,10 +106,10 @@ static void FindNextChunk( const char *name )
FindChunk FindChunk
================= =================
*/ */
static void FindChunk( const char *name ) static void FindChunk( const char *filename, const char *name )
{ {
iff_lastChunk = iff_data; iff_lastChunk = iff_data;
FindNextChunk( name ); FindNextChunk( filename, name );
} }
/* /*
@@ -164,7 +162,7 @@ qboolean Sound_LoadWAV( const char *name, const byte *buffer, fs_offset_t filesi
iff_end = buffer + filesize; iff_end = buffer + filesize;
// find "RIFF" chunk // find "RIFF" chunk
FindChunk( "RIFF" ); FindChunk( name, "RIFF" );
if( !( iff_dataPtr && !Q_strncmp( (const char *)iff_dataPtr + 8, "WAVE", 4 ))) if( !( iff_dataPtr && !Q_strncmp( (const char *)iff_dataPtr + 8, "WAVE", 4 )))
{ {
@@ -174,7 +172,7 @@ qboolean Sound_LoadWAV( const char *name, const byte *buffer, fs_offset_t filesi
// get "fmt " chunk // get "fmt " chunk
iff_data = iff_dataPtr + 12; iff_data = iff_dataPtr + 12;
FindChunk( "fmt " ); FindChunk( name, "fmt " );
if( !iff_dataPtr ) if( !iff_dataPtr )
{ {
@@ -219,13 +217,13 @@ qboolean Sound_LoadWAV( const char *name, const byte *buffer, fs_offset_t filesi
} }
// get cue chunk // get cue chunk
FindChunk( "cue " ); FindChunk( name, "cue " );
if( iff_dataPtr ) if( iff_dataPtr )
{ {
iff_dataPtr += 32; iff_dataPtr += 32;
sound.loopstart = GetLittleLong(); sound.loopstart = GetLittleLong();
FindNextChunk( "LIST" ); // if the next chunk is a LIST chunk, look for a cue length marker FindNextChunk( name, "LIST" ); // if the next chunk is a LIST chunk, look for a cue length marker
if( iff_dataPtr ) if( iff_dataPtr )
{ {
@@ -244,7 +242,7 @@ qboolean Sound_LoadWAV( const char *name, const byte *buffer, fs_offset_t filesi
} }
// find data chunk // find data chunk
FindChunk( "data" ); FindChunk( name, "data" );
if( !iff_dataPtr ) if( !iff_dataPtr )
{ {

View File

@@ -30,8 +30,8 @@ GNU General Public License for more details.
#if !XASH_WIN32 && !XASH_MOBILE_PLATFORM && !XASH_LOW_MEMORY #if !XASH_WIN32 && !XASH_MOBILE_PLATFORM && !XASH_LOW_MEMORY
#define XASH_COLORIZE_CONSOLE true #define XASH_COLORIZE_CONSOLE true
// use with caution, running engine in Qt Creator may cause a freeze in read() call // use with caution, running engine in Qt Creator may cause a freeze in read() call
// I was never encountered this bug anywhere else, so still enable by default // I have never encountered this bug anywhere else, so still enable by default
// #define XASH_USE_SELECT 1 #define XASH_USE_SELECT 1
#else #else
#define XASH_COLORIZE_CONSOLE false #define XASH_COLORIZE_CONSOLE false
#endif #endif
@@ -54,6 +54,7 @@ static LogData s_ld;
char *Sys_Input( void ) char *Sys_Input( void )
{ {
#if XASH_USE_SELECT #if XASH_USE_SELECT
if( Host_IsDedicated( ))
{ {
fd_set rfds; fd_set rfds;
static char line[1024]; static char line[1024];
@@ -148,7 +149,7 @@ void Sys_InitLog( void )
s_ld.logfileno = fileno( s_ld.logfile ); s_ld.logfileno = fileno( s_ld.logfile );
fprintf( s_ld.logfile, "=================================================================================\n" ); 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, "\t%s (build %i commit %s (%s-%s)) started at %s\n", s_ld.title, Q_buildnum(), Q_buildcommit(), Q_buildos(), Q_buildarch(), Q_timestamp( TIME_FULL ) );
fprintf( s_ld.logfile, "=================================================================================\n" ); fprintf( s_ld.logfile, "=================================================================================\n" );
} }
} }

View File

@@ -649,3 +649,31 @@ qboolean Sys_NewInstance( const char *gamedir )
return false; return false;
} }
/*
==================
Sys_GetNativeObject
Get platform-specific native object
==================
*/
void *Sys_GetNativeObject( const char *obj )
{
void *ptr;
if( !COM_CheckString( obj ))
return NULL;
ptr = FS_GetNativeObject( obj );
if( ptr )
return ptr;
// Backend should consider that obj is case-sensitive
#if XASH_ANDROID
ptr = Android_GetNativeObject( obj );
#endif // XASH_ANDROID
return ptr;
}

View File

@@ -70,6 +70,7 @@ void Sys_InitLog( void );
void Sys_CloseLog( void ); void Sys_CloseLog( void );
void Sys_Quit( void ) NORETURN; void Sys_Quit( void ) NORETURN;
qboolean Sys_NewInstance( const char *gamedir ); qboolean Sys_NewInstance( const char *gamedir );
void *Sys_GetNativeObject( const char *obj );
// //
// sys_con.c // sys_con.c

View File

@@ -632,12 +632,14 @@ int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length)
else else
{ {
const char* PATH = getenv("PATH"); const char* PATH = getenv("PATH");
const char* begin;
size_t argv0_length;
if (!PATH) if (!PATH)
break; break;
size_t argv0_length = strlen(argv[0]); argv0_length = strlen(argv[0]);
const char* begin = PATH; begin = PATH;
while (1) while (1)
{ {
const char* separator = strchr(begin, ':'); const char* separator = strchr(begin, ':');
@@ -795,7 +797,7 @@ int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length)
return length; return length;
} }
#elif defined(__sgi) || defined(__SWITCH__) || defined(__vita__) #elif defined(__sgi)
/* /*
* These functions are stubbed for now to get the code compiling. * These functions are stubbed for now to get the code compiling.
@@ -822,6 +824,22 @@ int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length)
return -1; return -1;
} }
#elif defined(__SWITCH__) || defined(__vita__)
/* Not possible on this platform */
WAI_FUNCSPEC
int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length)
{
return -1;
}
WAI_FUNCSPEC
int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length)
{
return -1;
}
#else #else
#error unsupported platform #error unsupported platform

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