Compare commits

...

1895 Commits

Author SHA1 Message Date
Ivan Avdeev f5eb2dada8
Merge pull request #739 from w23/stream-E374
Synchronization stuff started on stream E374

Addresses a bunch of validation synchronization hazards. Not all of them. And the remaining ones require more involved state tracking, a big effort.

Also contains a few minor tweaks:
- stop using SDL_GL functions, silence errors
- increase acceleration structures buffer size -- with recent mesa update BLASes got bigger somewhat (?)
2024-05-07 07:54:00 -07:00
Ivan Avdeev 0980493bb2 vk: tweak image barriers so it draws rt frames
This makes RT rendering work w/o sync hazards.
But it will still fail with one if menu is called.

It's as much as it can go w/o proper state tracking.
2024-05-01 20:27:57 -04:00
Ivan Avdeev 660513fd5f vk: make validation not complain about first 2 RT frames
Not sure what's happening with the rest, but first couple works.
2024-05-01 17:21:40 -04:00
Ivan Avdeev fcd9c77bea vk: make rt renderer not fail validation at startup 2024-05-01 17:21:22 -04:00
Ivan Avdeev 14ab0662df vk: issue a barrier for staging buffer uploads
Trad rendering still works with this slightly more tight sync model.

It is suboptimal as it doesn't really know the previous op on the
buffer, so it has to do the ALL_COMMANDS stages, which makes validation
a bit sore.
2024-05-01 16:04:52 -04:00
Ivan Avdeev c3a41f9097 vk: create BOUNDED_ARRAY empty 2024-05-01 16:02:18 -04:00
Ivan Avdeev 2d49b9f983 vk: work around sync validation woes for trad renderer
This is a very dirty way of silencing errors, trading them for a
waterfall of warnings. But it will allow making progress for now.
2024-05-01 11:11:01 -04:00
Ivan Avdeev ca72c8991b sdl: use SDL_GL_SetSwapInterval only for REF_GL 2024-04-29 19:40:27 -04:00
Ivan Avdeev 8a648619c4 vk: revert -nort commit
`rt_force_disable` is perfectly fine, it just needs to be written into
either `vk.cfg` or `video.cfg` to work. Other configs are read *after*
`R_VkInit()` function get called.
2024-04-29 18:28:28 -04:00
Ivan Avdeev 68c076bce3 vk: add explicit depth buffer synchronization for trad renderer
Fixes sync hazard validation error for depth buffer.
2024-04-12 11:58:04 -04:00
Ivan Avdeev bc294977fd vk: add `-vknort` argument to force disable RT 2024-04-12 11:01:43 -04:00
Ivan Avdeev a205f3fe3e
Merge pull request #575 from nilsoncore/memory_usage
profiler: track memory usage (#502)

* [x]  vulkan device memory:
  * [x]  allocated
  * [x]  used as storage for buffers/images/etc
  * [x]  unusable alignment holes
* [x]  vulkan buffers
  * [x]  allocated
  * [x]  used as storage
  * [x]  unusable alignment holes
* [x]  images memory total
* [ ]  cpu memory allocated in ref/vk

(copied & pasted from Issue #502)
2024-03-28 10:10:52 -07:00
nilsoncore 3c7481a7cb Merge branch 'vulkan' into memory_usage 2024-03-25 08:27:41 +03:00
nilsoncore 4d2a6c0e1d vk: devmem: fix print formats for linux #2 2024-03-24 21:01:55 +03:00
nilsoncore 4bac2cc96f vk: devmem: fix print formats for linux. 2024-03-24 20:33:03 +03:00
nilsoncore 790bf25263 vk: devmem: fix previously conflicting code.
- `mem->priv_.devmem` -> `slot_index`;
- Move static `VK_DevMemUsageTypeString()` out of `devmem.h` header.
2024-03-22 06:31:39 +03:00
nilsoncore 8363cedf93 vk: devmem: resolve conflicts with `w23:vulkan` branch. 2024-03-22 06:05:51 +03:00
Ivan Avdeev 2b19a8ca50
Merge pull request #736 from w23/E373-tradsky
E373: Draw skybox in traditional renderer

Fixes #732
2024-02-07 07:04:35 -08:00
Ivan Avdeev cf966b38cb vk: fix a couple of misc warnings 2024-02-07 09:41:45 -08:00
Ivan Avdeev f9c77060d7 vk: unload previous skybox prior to loading a new one
Fixes #737
2024-02-07 09:40:33 -08:00
Ivan Avdeev e5a33ea0c3 vk: don't forget to add new shaders 2024-02-06 10:20:35 -05:00
Ivan Avdeev 9fc1f85bcd vk: use original skybox for trad renderer
Also fix:
- a bunch of texture/image destruction issues
- `_xvk_remove_all_sky_surfaces` getting stuck
2024-02-05 13:21:21 -05:00
Ivan Avdeev 30f2b6372b vk: make trad render draw skybox
It does it in a super dirty way, trad renderer needs a massive
refactoring.

It also displays patched skybox, however, we need it to display the
oridingal one.
2024-02-05 12:52:20 -05:00
Ivan Avdeev a2661fe95d vk: add skybox pipeline for traditional renderer
It is not wired up to render anything yet, but we just made sure that it
builds and gets destroyed.

Also, fixup dynamic BLAS double-free.
2024-02-05 10:57:50 -05:00
Ivan Avdeev 5ed4839a31
Merge pull request #735 from w23/fix-rope-holes-729
vk: rt: add workaround for holes in geometry

Once upon a time, there were some BLASes. There were the BLASes for dynamic geometry, that were to be used every frame to draw very dynamic things, like sprites and beams. They were initialized at the very begining of the renderer's lifetime, and were expected to live happily for the entire process duration. However, an evil NewMap appeared. It didn't care abount anything or anyone, so when it came, it just cleared all the allocators, and allowed other BLASes to be allocated into the same space as dynamic BLASes were already given. This made BLASes live on top of each other, use each others toys and make them fight. They weren't happy.

So we just kill them and creat them again from scratch, when the evil NewMap comes.

The end.

Fixes #729
2024-02-02 10:12:08 -08:00
Ivan 'provod' Avdeev cba60f7953 vk: rt: add workaround for holes in geometry
Once upon a time, there were some BLASes. There were the BLASes for dynamic geometry, that were to be used every frame to draw very dynamic things, like sprites and beams. They were initialized at the very begining of the renderer's lifetime, and were expected to live happily for the entire process duration.
However, an evil NewMap appeared. It didn't care abount anything or anyone, so when it came, it just cleared all the allocators, and allowed other BLASes to be allocated into the same space as dynamic BLASes were already given. This made BLASes live on top of each other, use each others toys and make them fight. They weren't happy.

So we just kill them and creat them again from scratch, when the evil NewMap comes.

The end.

Fixes #729
2024-02-02 11:45:43 -05:00
Ivan Avdeev 67ea7af5bb
Merge pull request #726 from w23/handmade-brdfs
Hand-made organic bespoke GMO-free BRDFs

- [x] Fix black metals in #666
  - [x] Better diffuse-vs-specular channels tracking
  - [x] specular reflections
- [x] Fix new `test_material` glitches
- [x] Fix #461 
- [x] Fix #151 
- [x] Fix #266 
- [x] Filter out zero-area degenerate triangles (NOTE: might affect normal smoothing)
- [x] Implement #126 
  - [x] sun solid angle parametrization
- [x] Make new brdfs sampling functions
- [ ] distant light circular glitches
  - [x] not enough float precision, addressed to a degree with slight modifications to equations
- [x] Address glow over weapons in RT, see #442 
- [x] bounces
  - [x] diffuse
    - [x] why is it so dark?
  - [x] specular
- [x] Peformance differences. Why is there no CPU-GPU parallelism anymore?
  - [x] `VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT` forces cpu-gpu sync. 💩 
    - [x] Make a special flag for it
- [x] Update rendertests
  - [x] add more channels
  - [x] add white furnace display test
2024-02-01 12:54:13 -08:00
Ivan Avdeev 315073a564 vk: add `-vkdbg_shaderprintf` to enable printfs in shaders
Under `-vkvalidate` enables `debugPrintfEXT()` in shaders, allowing
extra validation and error reporting from shaders.
Severely degrades performance, so should be enabled only for debugging.
2024-02-01 12:57:12 -05:00
Ivan Avdeev aaa6de330c vk: rt: add experimental second Á-Trous pass for indirect diffuse
Now indirect diffuse channel gets blurred with 2 Á-Trous passes. It
mostly follows the paper, except for Σd_i, which gives very bad
viusal artifacts.
2024-02-01 10:36:34 -05:00
Ivan Avdeev a56e6a42a5 vk: rt: parametrize different light channels differently in denoiser 2024-01-29 12:49:32 -05:00
Ivan Avdeev 5d6c1d4bfc vk: rt: tune denoiser "a-trous" parameters a bit 2024-01-29 12:07:20 -05:00
Ivan Avdeev 1f8e9fe0c2 vk: rt: slightly cleanup bounce loop shader code 2024-01-29 11:30:41 -05:00
Ivan Avdeev ae3f79c67a vk: rt: attenuate secondary bounces
`throughput` should be scaled based on BRDF. I.e. diffuse bounces should
be scales by base_color at the very least.

This fixes lighting being too bright after 3-5 bounces.
2024-01-29 11:02:48 -05:00
Ivan Avdeev be8da3252a vk: rt: fixup too bright direct lighting 2024-01-26 14:38:31 -05:00
Ivan Avdeev a578becdd9 vk: rt: add diffuse and specular debug display modes
These will display diffuse and specular channels, both direct and
indirect, after spatial denoiser, but before temporal one.
2024-01-26 14:02:19 -05:00
Ivan Avdeev 6169734f91 vk: rt: do À-Trous lighting denoise
Works reasonably well, but a bit under-tuned, and remains only single-pass for now.
2024-01-26 13:59:15 -05:00
Ivan Avdeev cf59921c41 vk: rt: degrade spatial image quality by box blur denoiser
Our gaussian blur is incorrect, as it doesn't preserve luminance, and
the final imaga ends up being darker than it should be.

Do a box blur as a simple test. It does result in a correctly looking
white furnace test image (modulo square blocks and luminance leaking).
2024-01-26 12:50:08 -05:00
Ivan Avdeev e8400398bd vk: rt: add debug non-blurring denoiser code
Enabling it makes it clear that blurSamples() loses luminance.
Also it exposes temporal denoiser glitches.
2024-01-26 11:24:49 -05:00
Ivan Avdeev 579b9e00ac vk: rt: enable white furnace via new rt_debug_flags 2024-01-26 10:52:17 -05:00
Ivan Avdeev 6d58ad8df0 vk: rt: add white furnace debug display mode
Known issues:
- it doesn't really look how it's supposed to look
- using debug display mode for it was a mistake
2024-01-26 10:34:46 -05:00
Ivan Avdeev 18269ebf81 vk: rt: fixup 2024-01-23 12:13:48 -05:00
Ivan Avdeev 7e7351c599 vk: rt: attenuate bounce channels better
Divide by probabilities, multiply specular by fresnel.
2024-01-23 11:24:47 -05:00
Ivan Avdeev b01fa98c8b vk: rt: improve spec-vs-diff estimation for bounces
Estimate relative specular contribution based on fresnel term and
base_color. Pick bounce type based on that.
2024-01-23 10:47:21 -05:00
Ivan Avdeev c7bf03c260 vk: rt: add incomplete and super experimental specular bounces
VNDF sampling is blatantly copypasted from 2023 paper
no specular BRDF attenuation is made
it's very dirty and not optimized
2024-01-22 10:37:50 -05:00
Ivan Avdeev 8359a04750 vk: rt: fixup bounce brightness
Shoulnd't have multiplied by diffuse BRDF result. It should be encoded
in diffuse-vs-specular split, and the cosine term is already taken care
of in sampling.
2024-01-19 12:51:32 -05:00
Ivan Avdeev d20bbe1761 vk: attenuate flashlight 2024-01-19 12:26:06 -05:00
Ivan Avdeev 6e2a3d9004 vk: rt: add cvar to force backface culling for testing 2024-01-19 12:25:29 -05:00
Ivan Avdeev e12b2c47b4 vk: rt: added minimal distance for legacy soft blending
Only engage soft particles/blending after a certain distance. Makes
certain see-beams-through-weapons visual glitches disappear.

Engages soft particles with a smoothstep so the don't immediately pop up
after a certain distance, rather appear gradually.
2024-01-19 12:02:26 -05:00
Ivan Avdeev 6ee8af040e vk: throttle zero normal messages 2024-01-19 11:42:15 -05:00
Ivan Avdeev 073dbc55f8 vk: fixup studio model zero normal printing 2024-01-19 11:39:26 -05:00
Ivan 'provod' Avdeev 344c804468 vk: remove extra includes 2024-01-19 11:34:44 -05:00
Ivan 'provod' Avdeev 5f3a0c233b vk: rt: investigate more nans
Found that some studio models end up producing zero-length normals. See #731
2024-01-19 11:34:31 -05:00
Ivan Avdeev 6a7cb77809 vk: shave todo yak 2024-01-18 11:37:16 -05:00
Ivan Avdeev 0e4e754fdb vk: cleanup todo a bit x2 2024-01-18 11:34:07 -05:00
Ivan Avdeev e22f30608a vk: cleanup todo a bit 2024-01-18 11:33:45 -05:00
Ivan Avdeev e808fa0d9d vk: rt: enable patching environment light solid angle
Two ways:
- skybox.mat `sun_solid_angle`
- entity patch field `_xvk_solid_angle`

Both values should be specified in steradians
2024-01-18 11:14:20 -05:00
Ivan Avdeev 0e403e119f vk: silence degenerate triangle diagnostic logs 2024-01-18 11:13:16 -05:00
Ivan Avdeev de60cde7ab vk: rt: suggest dithering for precision errors 2024-01-18 09:59:02 -05:00
Ivan Avdeev 93cc0b5dd7 vk: rt: improve cosθ computation precision for sphere lights
It is only a bit better, makes some artifacts for strong small lights on
distant objects less visible.
2024-01-18 09:55:01 -05:00
Ivan Avdeev 7ef9bb87a9 vk: rt: fixup environment attenuation
Now environment emissive strength also depends on cos_theta (derived
from sun solid angle).
2024-01-16 13:22:32 -05:00
Ivan Avdeev e7ff1f3d3a vk: filter out degenerate triangles in brush models
This fixes lighting NaNs caused by NaN poison from invalid/zero normals.
2024-01-16 12:29:15 -05:00
Ivan Avdeev 9f1b034769 vk: rt: fix point light cos>1. for large distances 2024-01-15 12:24:24 -05:00
Ivan Avdeev 2cc2ca3965 vk: rt: add extra debug printfs around oob light clusters 2024-01-15 12:11:52 -05:00
Ivan Avdeev 2507a629cf vk: rt: move empirical light scaling to native code
There are lots of empirical (and less-well undrestood things) scaling
color values in native code, it makes sense to consolidate them in one
place:
- less weird math in shaders. shader should be as streamlined as
  possible
- one big block of weird math is untangleable in the future when we get
  to work on light and clusters
2024-01-15 12:08:56 -05:00
Ivan Avdeev f157762043 vk: rt: pass r² to points lights from native 2024-01-15 11:40:17 -05:00
Ivan Avdeev 70b0f33f45 vk: update TODO; improve NewMap printing for debug 2024-01-15 11:28:34 -05:00
Ivan 'provod' Avdeev dc6cca0d7f vk: rt: skip stale light clusters point light indexes
See #730
2024-01-15 11:26:31 -05:00
Ivan Avdeev 065bab855a vk: rt: fixup debug validaion modes in shaders 2024-01-12 13:48:53 -05:00
Ivan Avdeev e398fe5ef3 vk: rt: diagnose remaining point/sphere light NaNs
They're due to `P` being NaN already, which is fed from outside.
2024-01-12 13:39:36 -05:00
Ivan Avdeev 0fd97e2544 vk: rt: sample point light sources as spherical
1. Sample point lights as spheres. Use existing pdf value (`one_over_pdf`), as it was basically correct.
   Compute max_theta angle based on light radius and distance to the
   center. Sample cone direction based on this theta angle, in z=n space.
   Don't do anyhting fancy wrt horizon, etc.

2. Sample environment light with max theta derived from real world sun
   solid angle. Uses the same cone direction sampling.

Known issues:
- still get some NaNs sometimes, esp. on test_light map.
- Too many different light sources try to use the same code. They should
  be split.

Relevant issues: #266, #151
2024-01-12 13:31:02 -05:00
Ivan Avdeev aac4983069 vk: update todo once more 2024-01-11 12:05:42 -05:00
Ivan 'provod' Avdeev 5a89649917 vk: update TODO.md 2024-01-11 11:59:39 -05:00
Ivan 'provod' Avdeev 3153a83621 vk: rt: add material debug display mode
Also add debug display modes info
2024-01-11 11:56:23 -05:00
Ivan 'provod' Avdeev 02afc7b320 vk: rt: invert pdf for point lights
This makes math even more stable, but it removes imprecisions that were accidentally helping the rendered image. Thus it looks a bit darker.
Fixing that would need proper sampling, with disc angle and what not.
2024-01-11 11:36:35 -05:00
Ivan 'provod' Avdeev dd17dee35d vk: rt: improve point light computation stability
Guard against:
- spot_attenuation being too small
- pdf denom being zero. It could be inverted, e.g. not pdf=1/denom, but one_over_pdf = denom and then multiplying color with that directly, but we'd still need to clamp it to positive values.
2024-01-11 11:20:45 -05:00
Ivan 'provod' Avdeev 8f5b5657ce vk: rt: skip loading zero-area polygon lights
These cause NaNs in lighting computation, which leads to visual glitches, like strong yellow or green lighting.

Fixes #461
2024-01-11 10:35:37 -05:00
Ivan Avdeev 107c4fb048 vk: rt: add comment of what's left for math stability 2024-01-09 13:24:20 -05:00
Ivan Avdeev 8248d1d9b3 vk: rt: mask invalid H in case L ~= -V 2024-01-09 13:21:37 -05:00
Ivan Avdeev 2961ad5b1a vk: rt: use simple hemisphere cosine sampling for diffuse bounces
As opposed to more compute intensive local-frame sampling. They seem to
produce the same results.

Local-frame sampling might still be needed for specular bounces.
2024-01-09 12:09:41 -05:00
Ivan Avdeev c64000195d vk: rt: organize shader printf debugging
Introduce several shader debugging/validation tiers:
1. Basic key values validation, to make sure there are no nasty NaNs or
   invalid values written to G-buffers. Enabled by `DEBUG_VALIDATE` macro
   in debug.glsl
2. Key value validation with whining: use `debugPrintfEXT()` function to
   report any invalid values to Vulkan validation layers. Enabled using
   `DEBUG_VALIDATE_PRINT` macro. Currently this is the one enabled, as
   it allows us to catch any serious numerical issues during development
   and testing.
3. Extra validation and printing for intermediate values. This is for
   deeper investigations, and enabled only there temporarily.
2024-01-09 12:05:31 -05:00
Ivan Avdeev a147c89a53 vk: rt: fixup reprojection black borders 2024-01-08 13:55:39 -05:00
Ivan 'provod' Avdeev 20e9af6496 vk: rt: allow disabling debug printfs in shaders 2024-01-08 13:45:00 -05:00
Ivan 'provod' Avdeev 64520ef5a1 vk: rt: fix magenta light glitches
It was due to some light samples having dot(N,L) < 0.
2024-01-08 13:32:49 -05:00
Ivan 'provod' Avdeev dee067c771 vk: remove unused code 2024-01-08 13:29:52 -05:00
Ivan 'provod' Avdeev 62fd27ad65 vk: mark all shader printfs as S_ERROR 2024-01-08 13:29:30 -05:00
Ivan 'provod' Avdeev 96b4ea6345 vk: rt: use shader printf debugging to fix some nans 2024-01-08 12:03:56 -05:00
Ivan 'provod' Avdeev a5086486fa vk: silence too eager stage mask sync validation complaint 2024-01-08 11:55:14 -05:00
Ivan Avdeev 5906f72e0d vk: rt: pick bounce direction by cosine-hemisphere sampling
Also:
- move sampling to brdf.glsl
- do only 1 bounce w/o comparison (for testing)
- do only diffuse (for testing)
2024-01-05 20:06:01 -05:00
Ivan Avdeev 0bc585eddc vk: rt: split between diffuse and specular bounces
- Turn off old-vs-new brdfs comparison.
- Enable picking up specular bounces.
- Use the same final color mixing for bounces too (except for legacy
  blending, which will remain suboptimal)
2024-01-04 13:21:08 -05:00
Ivan Avdeev 55fe48659e [wip] vk: rt: add 2nd bounces w/ idiotic sampling
Completely rework bounces, allow 2nd+ bounces.

Still work in progress with lots of debug code.
2024-01-04 13:10:26 -05:00
Ivan Avdeev 54cbc85da5 vk: rt: bring bounces back with idiotic sampling
Very bad random sampling strategy, just to see some bounces.
It's super slow and noisy and isn't even unbiased or correct.
2024-01-04 11:27:02 -05:00
Ivan Avdeev e12a53fb81 vk: rt: use more correct diffuse term derivation
glTF spec one is not correct, it depends on "cached" fresnel factor, and
thus ends up including base_color twice.
2024-01-04 10:23:47 -05:00
Ivan Avdeev 6a04888a3c vk: rt: fix artifacts due to missing dot(N,L) term
We missed it because BRDF model of glTF 2.0 expects this term to be in
the rendering equation integral, and not in the BRDF function itself.

Boksajak's `brdf.h` model does include this term in the BRDF because the
cancel out for some usages beautifully.

Also, add comparison macro so we can see old-vs-new PBR model.
2024-01-04 09:56:04 -05:00
Ivan Avdeev e9b05ff849 vk: rt: add direct_{diff,spec} debug display
also try to simplify brdf ggx math
2024-01-02 13:32:49 -05:00
Ivan Avdeev 5544b99db9 vk: rt: do not forget to add new files you dumbass 2024-01-02 13:12:40 -05:00
Ivan Avdeev 88b24ad3bd vk: rt: rewrite direct-eval brdfs from scratch
Deprecate `brdf.h` usage, start writing our own BRDF functions.

Use glTF 2.0 BRDF mixing model as a simple starting point.
Mix-in base_color into specular early, as it is light-direction
dependent and cannot be easily separated.

Disable bounces for now, as we don't have yet good sampling story, need
to write "backwards" BRDFs that give us ray directions to sample, and
accommodate for that sampling bias in BRDF attenuation itself.

Also introduces some other weird artifacts on `test_material` map, investigation pending.

Related to black metals in #666
2024-01-02 13:01:58 -05:00
Ivan Avdeev 6ffaad02f2
Merge pull request #724 from w23/stream-E355
Stuff done during stream E355

- [x] fix accidental translucency for alpha-masked geometries: #721
2024-01-01 10:25:36 -08:00
Ivan Avdeev 9088ab3dc4 vk: rt: fixup accidental translucency for alpha-masked geometries
Fixes #721
2024-01-01 11:07:53 -05:00
Ivan Avdeev 84babdfff8
Merge pull request #719 from w23/stream-E352
Stuff done during streams E352-E354

- [x] tune emissive/additive blending so that it matches original, fixes #668
- [x] make additive studio and brush models single-sided, fixes #665
- [x] convert override_color (from TriApi) to linear space together with gamma
- [x] apply soft-alpha-depth universally, fixes #722
2023-12-29 09:17:36 -08:00
Ivan Avdeev 3bc293d8aa vk: rt: compute legacy blending in sRGB-γ colorspace
This makes all blending look very close to the original, and fixes a
whole class of blending-looking-wrong issues.

Fixes #668
2023-12-29 12:10:54 -05:00
Ivan Avdeev 1028564eec vk: rt: enable soft alpha depth globally
Fixes #722
2023-12-28 12:09:04 -05:00
Ivan Avdeev 46e95f1255 vk: rt: linearize kusochki.color/override_color 2023-12-28 11:21:32 -05:00
Ivan Avdeev 310ecff585 vk: rt: make additive brush models single-sided
Fixes #665
2023-12-22 15:19:24 -05:00
Ivan Avdeev 180f3ed9cb vk: rt: allow per-model back face culling
Make transparent studio models, e.g. holograms, single-sided.

Related: #665
2023-12-22 15:14:27 -05:00
Ivan Avdeev caac371681 vk: rt: tune emissive/additive blending so that it matches original
To match original more closely it additive geometry should be added to
final color in sRGB-γ space. You might not like that it is physically
incorrect, but this is what peak compatibility looks like.

Related to #668
2023-12-22 14:23:22 -05:00
Ivan Avdeev 59f7d264c2
Merge pull request #716 from 0x4E69676874466F78/rad&patches
Add new rad files
add c2a5a.rad c2a5d.rad c2a5e.rad
2023-12-21 06:35:33 -08:00
Ivan Avdeev 57fcd5aea8
Merge pull request #717 from Aty-0/bluenoise-micro-fix
Fix traditional render tries to load bluenoise, #710
2023-12-21 06:35:09 -08:00
Aty_0 c60d851ad8 Fix traditional render tries to load bluenoise 2023-12-20 23:43:12 +03:00
NightFox 0a6b40e0ab
Add new rad files 2023-12-20 18:15:54 +03:00
Ivan Avdeev 4b605810f3
Merge pull request #713 from 0x4E69676874466F78/rad&patches
Update patches

Fix texture coordinates for monitors (c1a0, c1a1f)
2023-12-20 06:41:54 -08:00
Ivan Avdeev c3d4d0fbe9
Merge pull request #715 from w23/stream-E350
Stuff done during stream E350

- [x] Restore skybox reflection
- [x] Improve skybox log messages
2023-12-20 06:41:12 -08:00
Ivan Avdeev e33185c04c vk: update overall agenda a bit 2023-12-19 12:05:33 -05:00
Ivan Avdeev 239d7bc362 rt: try to clear temporal buffers on discontinuities once more
Found out that it wasn't really clearing anything.
Now it does call clear, but still there are temporal denoising
artifacts. The issue remains elusive.

Related: #661
2023-12-19 11:35:37 -05:00
Ivan Avdeev 7d7535c5c5 vk: improve logs around skybox loading 2023-12-19 10:18:57 -05:00
Ivan Avdeev d52d44e0ce vk: rt: restore skybox sampling for bounces 2023-12-19 10:06:28 -05:00
NightFox fc1a553bc7
Fix texture coordinates for monitors (c1a0, c1a1f) 2023-12-19 01:48:02 +03:00
Ivan Avdeev a0b36a4301 vk: trad: allow rendering with replaced PBR textures
Use `vk_use_material_textures` cvar to show new PBR material textures
for traditional rendering.
Note that they're often sampled in an incorrect colorspace, so they look
different from RT.

Fixes #711
2023-12-18 09:57:01 -08:00
Ivan Avdeev 7e0553d408
Merge pull request #708 from w23/stream-E346
Skybox improvements (E346-E349)

- [x] #706 
  - [x] Do not load skybox if map doesn't have any `SURF_DRAWSKY` surfaces.
  - [x] Cache: do not reload the same skybox.
  - [x] Enable loading packed KTX2 cubemaps as skyboxes in engine/imagelib
- [x] Reuse existing imagelib cubemap loading routines, remove custom skybox loading code
- [x] Allow hiding `SURF_DRAWSKY` surfaces via `"_xvk_remove_all_sky_surfaces" "1"`, #579 
- [x] #677 
  - [x] Add skybox exposure control for HDR skyboxes
  - [x] Allow reloading skyboxes when reloading patches
2023-12-18 09:56:04 -08:00
Ivan Avdeev 5659fb0b6f imagelib: c90-ize ktx2 loader even more 2023-12-18 12:43:52 -05:00
Ivan Avdeev 6d79e84f5b imagelib: c90-ize ktx2 loader face cursors 2023-12-18 12:39:21 -05:00
Ivan Avdeev bec1e0f558 vk: rt: add tunable skybox exposure
E.g. add `desert.mat` alongside `desert.ktx2` (or
`desrt_{rt,lf,...}.png` files) with the following contents:
```
exposure 0.3
```
Skybox texture color will be multiplied by this value.
2023-12-18 12:26:01 -05:00
Ivan Avdeev 356f7bdf71 imagelib: load KTX2 cubemaps directly 2023-12-18 11:37:46 -05:00
Ivan Avdeev 2776373652 imagelib: do not overwrite the correct image size when building cubemap
For some very unknown reason there's a line that fixes image size to
w*h*4, which would correspond to RGBA8 pixel format w/o alignment.

This is extremely incorrect for other pixel format, e.g. compressed
ones.

Not sure why this size-fixing was there, but removing it fixes sided
KTX2 compressed skybox corruption.
2023-12-15 09:14:23 -05:00
Ivan Avdeev b1b333f74a vk: use imagelib cubemap/skybox loader
Engine imagelib already has skybox loader. It uses rgbdata_t
IMAGE_CUBEMAP flag.
1. Support IMAGE_CUBEMAP
2. Utilize imagelib skybox loader, do not try to load individual skybox
   sides manually.

This will allow loading KTX2 cubemaps directly.

Known issues:
1. Compressed KTX2 sides are not rotated correctly. Engine/imagelib is
   unable to rotate compressed images.
2. Some KTX2 sides are corrupted. Cause unknown.
2023-12-14 13:40:34 -05:00
Ivan Avdeev 6a11c6e64f vk: rt: add notes regarding engine imagelib
Also:
- add more info to texture upload debug logs
- remove obsoleted code
- prepare for engine/imagelib-side cubemaps
2023-12-14 12:41:11 -05:00
Ivan Avdeev 6fc318143e vk: rt: allow hiding all SURF_DRAWSKY surfaces while retaining skybox
Neede for getting rid of some skybox 𝘱𝘦𝘯𝘦𝘵𝘳𝘢𝘵𝘪𝘰𝘯 glitches, see #579
2023-12-14 10:54:07 -05:00
Ivan Avdeev 3cbc11a8f0 vk: rt: optimize hires skybox loading
- Do not load skybox at all if there are no SURF_DRAWSKY, #706, #579
- Do not reload the same skybox, #706

Also refactor skybox loading a bit. Prepare for KTX2 skyboxes.
2023-12-14 10:33:26 -05:00
nilsoncore a06998321e vk: devmem: track peak single allocation size 2023-12-14 08:13:26 +03:00
nilsoncore cba1b02103 vk: devmem: print human-friendly memory size values
Raw values are still printed in subsequent messages.
2023-12-14 08:00:21 +03:00
nilsoncore ceb4437f8c vk: devmem: print number of alloc slots on overflow 2023-12-14 07:54:23 +03:00
nilsoncore 05ac770c81 vk: devmem: track alignment holes correctly
Get `alignment_hole` right from the `alolcator` instead of calculating
outside.
Improve allocation slot variable naming on slot allocation selection.
Restructure internal `vk_devmem_t` fields into `internal` struct.
Make `VK_DevMemUsageTypeString` visibility scope to file-only.
2023-12-14 07:50:15 +03:00
nilsoncore 1117c5969e vk: devmem: simplify flags formatting
Use `PRI_VKxxxFLAGS_FMT` as an inline format macro and
`PRI_VKxxxFLAGS_ARG( ... )` as an inline argument macro for that format.
Also bring back those `!!`.
2023-12-14 07:39:44 +03:00
Ivan Avdeev 9a0ff43a97
Merge pull request #707 from 0x4E69676874466F78/no_ray_warn
Improved warning when there are no ray extensions

fix #670
2023-12-12 14:42:44 -08:00
NightFox 726572b78c
minor reorganization 2023-12-13 01:13:48 +03:00
NightFox 0d3c9ba88d
Warning after getting a candidate 2023-12-12 19:46:04 +03:00
Ivan Avdeev f3f14ac968
Merge pull request #705 from w23/stream-E345
Thing done during stream E345

- [x] fix incorrect basecolor brdf multiplication, #666 
- [x] Do not patch sprite textures for traditional raster, #695
2023-12-12 07:07:50 -08:00
NightFox 852b7c28ba
Slight improvement of code 2023-12-12 14:56:35 +03:00
NightFox 1a9f97bb14
Added warnings about 32bit when configure 2023-12-12 14:31:20 +03:00
NightFox e1868c752f
Improved warning when there are no ray extensions
fix #670
2023-12-12 13:55:12 +03:00
Ivan Avdeev 5c42f34654 vk: rt: mark sky surfaces as non-geometry
SURF_SKY shouldn't receive any light, neither direct, nor indirect. Mark
it as non-geometry with ray length < 0.
2023-12-11 13:17:33 -05:00
Ivan Avdeev 4ac62076bb vk: use original texture for sprites in rasterization mode
Traditional rasterization should not use any of the patched textures.

Fixes #695
2023-12-11 12:55:32 -05:00
Ivan Avdeev c8123952a2 vk: rt: fix incorrect basecolor brdf multiplication
PBR model used implies the following rules:
- for metals both diffuse and specular components should be tinted by
  material base color.
- for dielectrics, only diffuse should be tinted, specular should remain
  as is.

Partially fixes #666
2023-12-11 11:48:44 -05:00
Ivan Avdeev 20da50ca7b
Merge pull request #701 from 0x4E69676874466F78/0x4E69676874466F78-rad-1
Add & update rad files
2023-12-08 07:37:52 -08:00
NightFox e89e44d94a
Add & update rad files
c2a4d.rad, c2a4e.rad, c2a4f.rad
2023-12-08 18:35:44 +03:00
Ivan Avdeev b6af3a6b56
Merge pull request #699 from 0x4E69676874466F78/0x4E69676874466F78-rad-1
Update c2a4a.rad
2023-12-07 07:59:16 -08:00
NightFox b22d87ae82
Update c2a4a.rad
add missing +A~FIFTIES_LGT2
2023-12-07 18:54:40 +03:00
Ivan Avdeev db4c3c50c7
Merge pull request #698 from 0x4E69676874466F78/0x4E69676874466F78-rad-1
Add new rad files & patch
2023-12-07 07:10:15 -08:00
NightFox 20cbe33f2f
add c2a3e.patch 2023-12-07 17:12:21 +03:00
NightFox 1bec8ad9b9
Add new rad files 2023-12-07 17:11:55 +03:00
Ivan Avdeev 80b524d643
Merge pull request #690 from w23/stream-E342
Stuff done during stream E342

- [x] revert back indirect specular kernel size
2023-12-05 09:59:57 -08:00
Ivan Avdeev 6cb45dda77 vk: update notes and todo 2023-12-05 12:59:30 -05:00
Ivan Avdeev e00f758594 vk: revert back indirect specular kernel size 2023-12-05 11:14:25 -05:00
Ivan Avdeev dc0b968028
Merge pull request #689 from 0x4E69676874466F78/0x4E69676874466F78-rad-1
Update rad files
2023-12-05 06:29:30 -08:00
NightFox 58572380ab
Update rad files 2023-12-05 17:11:26 +03:00
NightFox de3f350bb4
Update rad files
add missing ~LIGHT3B
2023-12-05 17:00:40 +03:00
NightFox 23c059baac
Update rad files 2023-12-05 16:32:30 +03:00
Ivan Avdeev eba28376d9
Merge pull request #686 from w23/stream-E341
Things done during stream E341

- [x] `vk/mod` in logs
- [x] fix NaNites, #685 
- [x] fix double switchable lights, #679
2023-12-04 11:01:14 -08:00
Ivan Avdeev f244aaaddf vk: update TODO 2023-12-04 13:57:06 -05:00
Ivan Avdeev 4fc6db36b4 vk: rt: fix adding switchable/animated light twice
Skip adding animated surfaces as static lights. We'd like them to be
static, but currently there's no distinction between immovable lights
and switchable lights or lights with dynamic emissive value.

Fixes #679
2023-12-04 13:48:12 -05:00
Ivan Avdeev 84f6d7d10b vk: rt: fix reading garbage values out of indirect spec bounds
Indirect specular and diffuse have half frame resolution.
Denoiser code was incorrectly reading past the valid range for indirect
specular values. This was sometimes giving visual glitches at frame
borders.

Fixes #685
2023-12-04 12:14:44 -05:00
Ivan Avdeev 0549822d53 vk: print 'vk/module' in logs 2023-12-04 11:29:38 -05:00
Ivan Avdeev 2986e128c4
Merge pull request #683 from 0x4E69676874466F78/0x4E69676874466F78-rad-2
Added new rad files
2023-12-04 08:13:15 -08:00
Ivan Avdeev 9fed89a835
Merge pull request #682 from 0x4E69676874466F78/CI_test
Create for_ignored.yml (pass through for ignored files)
2023-12-04 07:15:09 -08:00
NightFox 4f988fcb78
Create for_ignored.yml (pass through for ignored files)
Added pass through for ignored files
2023-12-04 12:17:07 +03:00
NightFox cdb1532979
Added new rad files
c2a* maps
2023-12-04 00:31:37 +03:00
Ivan Avdeev b06081047a
Merge pull request #675 from w23/stream-E339
Things done during stream E339

- [x] Fix dynamic polylights for func_water entities; fixes #672
- [x] Reuse GPU scope names; fixes #667 
- [x] Support changing resolution; fixes #343 
  - [x] Make max resolution grow gradually
2023-12-01 08:01:10 -08:00
Ivan Avdeev 4fd70777b7 vk: rt: increase max frame size gradually when needed 2023-12-01 10:55:58 -05:00
Ivan Avdeev 4d1b64bb19 vk: update TODO.md 2023-11-30 13:20:03 -05:00
Ivan Avdeev 605647aecc vk: rt: support changing screen resolution
Fixes #343
2023-11-30 13:01:40 -05:00
Ivan Avdeev bde036fc45 vk: find existing gpu scope with the same name
fixes #667
2023-11-30 11:57:15 -05:00
Ivan Avdeev 32f05816e1 vk: rt: extract dynamic polylight to brush model
They don't really belong to neither rt_model_t, nor render model.
Allows having dynamic polylights for func_water entities without "main"
render model, and only water submodels.
2023-11-30 11:20:32 -05:00
Ivan Avdeev c9b485f8a7
Merge pull request #671 from w23/stream-E338
Things committed during streams E338-E339

- [x] Allow patching rendermode for func_* entities, fixes #663
- [x] Print out screenshot timings
- [x] Unsuccessfully reset denoiser statistics on discontinuities
2023-11-30 08:09:07 -08:00
Ivan Avdeev 7417cfa06f vk: rt: try to clear denoiser statistics on frame discontinuities
Somehow doesn't fix the teleport/levelchange glitches, but still feels
like a step in the right direction.
2023-11-30 10:27:47 -05:00
Ivan Avdeev 73d320f51f vk: print how long it took to make a screenshot 2023-11-30 10:26:52 -05:00
Ivan Avdeev d5f8b593f9 vk: make rendermode patching a bit less ugly 2023-11-30 10:20:47 -05:00
Ivan Avdeev 40a270cff8
Merge pull request #673 from 0x4E69676874466F78/0x4E69676874466F78-rad-1
Update rad files

add c2a1, c2a1a, c2a1b
2023-11-30 07:05:57 -08:00
Ivan Avdeev a0fbb12efb
Merge pull request #674 from 0x4E69676874466F78/0x4E69676874466F78-github-actions
Update c-cpp.yml (add paths-ignore)

For CI/GH Actions: ignore things that do not participate in builds
2023-11-30 07:05:26 -08:00
NightFox 8d5638ef6b
Update c-cpp.yml (add paths-ignore)
add paths-ignore:
      - '**.md'
      - 'ref/vk/data/**'
2023-11-30 15:59:34 +03:00
NightFox 36a6e56ee1
Update rad files
add c2a1, c2a1a, c2a1b
2023-11-30 15:37:22 +03:00
Ivan Avdeev dd21e665b1 vk: patch rendermode for entities
Probably not the best way to do it, but this is an attempt.

Issue #663
2023-11-28 13:01:14 -05:00
Ivan Avdeev e9dc10a503
Merge pull request #659 from w23/comparender
Stuff done during streams E333-E337

- [x] Engine/rendering support for reproducible rendering and testing:
  - [x] `screenshot filename.png`
  - [x] `wait NUM`
  - [x] ~~`imagecompare`~~ -> moved to [HLRTest](https://rtxash.omgwtf.ru/Half-Life-RTX/HLRTest) repo
  - [x] ~~example rendertest script~~ -> moved to HLRTest repo
  - [x] how to organize saves, rendertest.script, golden images? -> I KNOW HOW -> HLRTest repo
  - [ ] how to run these in CI? -- we just don't know
- [x] Consolidate all bindings to shader tops
- [x] fixup per-model material mapping, fix #669
2023-11-27 10:28:17 -08:00
Ivan Avdeev 735260a3c5 vk: brush: fixup per-model material mapping
fixes #669
2023-11-27 13:20:06 -05:00
Ivan Avdeev bbd96b3e0e vk: consolidate all bindings to the top of shaders
That way it is more clear what we declare, why and how.
2023-11-23 12:25:24 -05:00
Ivan Avdeev 016cdeaa6c vk: tools: speedup imagecompare 16x
Use -O3 -march=native
Save into tga, not png
2023-11-21 12:50:29 -05:00
Ivan Avdeev 2fbe477dd2 vk: renderscript: add arguments 2023-11-21 12:11:01 -05:00
Ivan Avdeev 2139b32f75 vk: rt: allow disabling temporal denoiser 2023-11-21 12:10:14 -05:00
Ivan Avdeev 036379707d vk: imagecompare: highlight with green the desired zero-difference image 2023-11-21 11:01:39 -05:00
Ivan Avdeev f11461772a vk: add rt_debug_fixed_random_seed cvar
Needed to pin random seed to a known value to make sure that frames are
reproducible for regression testing purposes.
2023-11-21 11:00:45 -05:00
Ivan Avdeev 4897f97726 vk: add rendertest maker script 2023-11-21 10:45:25 -05:00
Ivan Avdeev 1ac00a8792 vk: imagecompare: highlight total difference > 1% 2023-11-21 10:43:39 -05:00
Ivan Avdeev 27ed4b157a vk: rt: fixup `rt_debug_display_only lighting` 2023-11-21 10:27:58 -05:00
Ivan Avdeev 9953a47397 vk: add example rendertest script 2023-11-20 13:04:48 -05:00
Ivan Avdeev 4897da4f45 vk: document frame comparison effort 2023-11-20 13:02:21 -05:00
Ivan Avdeev 2a2aaecd92 engine: allow specifying amount of frames to wait on `wait` command 2023-11-20 13:01:37 -05:00
Ivan Avdeev a6fe7cc3a6 engine: allow specifying screenshot filenames in command directly 2023-11-20 13:01:01 -05:00
Ivan Avdeev 17267fd8c3 vk: tools: add imagecompare tool to compare screenshots
Produces diff image file and total difference.
2023-11-20 12:59:32 -05:00
Ivan Avdeev 6b1eeee26b
Merge pull request #658 from 0x4E69676874466F78/rad&patches
Rad&patches
2023-11-20 06:41:22 -08:00
NightFox 5a3912dcb0
update c2a5.patch
more smooth
2023-11-20 16:30:21 +03:00
NightFox 7e3e847b43
update patches
fix wagonchik texture coordinates and more correct textures/materials
other minor changes (I'd already forgotten)
2023-11-20 00:36:31 +03:00
NightFox acc103221a
add ba_security2.patch 2023-11-20 00:32:34 +03:00
NightFox e67232e4bf
update c1a0c.rad
fix ~LIGHT3F for c1a0c
2023-11-20 00:23:13 +03:00
Ivan Avdeev 7c3448cd15
Merge pull request #657 from 0x4E69676874466F78/readme
Update README.md

fix build instructions link for README.md
fix upstream CONTRIBUTING.md (vulkan->master branch)
2023-11-18 10:13:52 -08:00
NightFox 38fa218340
Update CONTRIBUTING.md
fix upstream CONTRIBUTING.md (vulkan->master branch)
2023-11-18 20:58:48 +03:00
NightFox cc764e66d7
Update README.md
fix build instructions link
2023-11-18 20:37:22 +03:00
Ivan Avdeev f57a7feea0
Merge pull request #656 from w23/stream-E332
Things done during stream E332

- [x] comment on no light under emissive acid
- [x] normalmaps for water, fix #655 
- [x] add docs regarding regression tests
2023-11-17 09:42:03 -08:00
Ivan Avdeev 16de17527a vk: document regression testing approaches
ref: #646
2023-11-17 12:29:53 -05:00
Ivan Avdeev f0b80887e8 vk: brush: support normalmaps for water surfaces
Adds missing tangents.

Fixes #655
2023-11-17 11:06:09 -05:00
Ivan Avdeev de80c0da64 vk: comment on no light under emissive acid
ref: #56
2023-11-17 10:22:53 -05:00
Ivan Avdeev 7d8d59d338
Merge pull request #653 from 0x4E69676874466F78/vulkan
Update patches&rads
2023-11-17 07:08:39 -08:00
NightFox 174d601ba6
add c1a4g.rad 2023-11-17 13:08:34 +03:00
Ivan Avdeev 414c43f7a2
Merge pull request #652 from w23/stream-E331b
Thing done during stream E331

- [x] add `trihash` option to  `rt_debug_display_only` cvar
- [x] fix #465 
  - [x] update UVs
  - [ ] fix validation woes -- cannot reproduce anymore
2023-11-16 10:10:33 -08:00
Ivan Avdeev 9b18ffbc02 vk: update todo 2023-11-16 13:05:28 -05:00
Ivan Avdeev 85fbe15f65 vk: make conveyors move again
Known issues: validation-induced crash on changlevel

fixes #465
2023-11-16 13:00:00 -05:00
NightFox 8858433928
Update c0a0d.rad
temporary tune !TOXICGRN, !TOXICGRN2
2023-11-16 19:54:51 +03:00
NightFox c23404cfa1
Update patches
c0a0d: more smooth geometry
2023-11-16 19:53:26 +03:00
Ivan Avdeev 4def45125c vk: add `trihash` to `rt_debug_display_only` cvar 2023-11-16 10:55:05 -05:00
Ivan Avdeev dc1ea9cb44 vk: shaders: normalize noise.glsl indentation 2023-11-16 10:54:21 -05:00
Ivan Avdeev 5f83cb1ef1
Merge pull request #651 from w23/stream-E331
E331: make water emissive again

- [x] Make acid water surfaces emissive again.
- [x] Update emissive color for them, fix #56
2023-11-16 07:53:09 -08:00
Ivan Avdeev b21a8240ec vk: update todo 2023-11-16 10:43:51 -05:00
Ivan Avdeev f535020f94 vk: update emissive color for water surfaces
In a not super efficient way: it will re-upload kusochki every time,
even though there has been no update.
2023-11-16 10:35:07 -05:00
Ivan Avdeev e4d7858330 vk: add emissive water surfaces to polygon lights
Makes acid water surfaces emissive again.
However, they are not assinged proper emissive color values for direct
ray hits yet, so they do emit light, but look dar still.

Ref: #56
2023-11-16 09:56:21 -05:00
Ivan Avdeev 1040a9608d
Merge pull request #649 from w23/stream-E328
E328-E330: Improve backface culling

- [x] Turn on backface culling in RT shaders for everything.
- [x] Force-disable culling for everything except alpha blended geometries.
- [x] Only leave water surfaces that are directed towards "air", fixes #264
2023-11-16 06:54:02 -08:00
Ivan Avdeev a3c52a8001 vk: hide "back" water surfaces
Only leave water surfaces directed towards "air".
This is consistent with:
- non-`kRenderNormal` surfaces, for which there's only one surface present
- opt2 for translucent surfaces, where we aim to detect medium boundary
  direction based on normal-vs-ray-direction

Also add notes about translucent surfaces in general, more info about
water rendering under ref_gl, etc.

Fixes #264
2023-11-14 11:44:29 -05:00
Ivan Avdeev 78548960e7 vk: improve culling; add notes about water and culling
Cull everything except:
- opaque geometry: to avoid shadow and reflection holes
- bleded geometry: particles and such should be visible from any angle

Alpha-tested geometries result in visual glitches when not culled
(double-sided ladders, double shadows, etc). These glitches are worse
than slightly misaligned shadows.

Translucent geometries are still matter of research.
2023-11-13 12:22:23 -05:00
Ivan Avdeev d802404d1c vk: brush: investigate water surfaces orientation
Adds a few things:
- verbose logs about surface flags/type/orientation
- same about surface subdivided polys
- tries culling back water surfaces (doesn't work that well)
- tries culling in rt shaders

This still unfinished
2023-11-10 10:30:24 -05:00
Ivan Avdeev 70fe5af12e
Merge pull request #648 from w23/stream-E327
Stuff done during stream E327

- [x] Fix alternate worldmodel anims #644
- [x] Hide water sides appropriately
2023-11-09 10:48:35 -08:00
Ivan Avdeev f6c19527d5 vk: brush: hide side water surfaces for entities w/o EF_WATERSIDES
Worldmodel draws all water surfaces regardless of their
orientation/PLANE_Z.

All other entities only draw sides when EF_WATERSIDES effect bit is set.
2023-11-09 12:55:56 -05:00
Ivan Avdeev 4145969198 vk: brush: do not try to invert water height when underwater
Not sure that we need it.
2023-11-09 10:49:53 -05:00
Ivan Avdeev 5c3be09161 vk: brush: force worldmodel alternate_anims textures static
Many static worldmodel surfaces still contain alternate texture chains.
That was making these surfaces dynamic, even though there's no way to
trigger these alternate anims.

Make worldmodel ignore alternate_anims when looking for animated
surfaces.

Fixes #644
2023-11-09 10:32:47 -05:00
Ivan Avdeev 738fcec129
Update CONTRIBUTING.md (#645)
Add a section for this specific project
2023-11-09 07:30:49 -08:00
Ivan Avdeev 2fdd6e719e
Merge pull request #647 from 0x4E69676874466F78/vulkan
Update patches
2023-11-09 07:24:49 -08:00
NightFox 840d618e4d
Update patches
Minor changes (replacement by _xvk_tex_rotate)
2023-11-09 15:54:12 +03:00
Ivan Avdeev 7f3fa2285a
Merge pull request #643 from w23/stream-E326
Things done during stream E326

- [x] list supported arguments for `rt_debug_display_only`
- [x] make `vk_debug_log` a command
- [x] rotate your owl, fix #625
- [x] fix skybox surface assert
- [x] half-fix water levels
- [x] add alternate anims to infotool
2023-11-07 10:54:44 -08:00
Ivan Avdeev 3e9f6bc7a4 vk: half-fix water levels being too high
Pass current entity to compute wave height. Still doesn't switch to
negative height when underwater for some reason.
And still displays water sides.

Add some notes regarding water geometry generation and drawing.
2023-11-07 13:45:25 -05:00
Ivan Avdeev c575cb6cfd vk: add alternate_anim display to infotool 2023-11-07 13:45:06 -05:00
Ivan Avdeev 2c0e7033ed vk: fix crashing on maps with skybox
We were using a negative value for `SURF_SKY` surfaces, which hit an
assert on uploading kusochki.
2023-11-07 13:30:46 -05:00
Ivan Avdeev c6c58a9842 vk: allow rotating matrices in patches
Adds `_xvk_tex_rotate` field for surface patches. Angle is specified in
degrees.

Note that it rotates the texture around origin, which might be very far
away. So offset patching might be needed to re-align.
2023-11-07 12:03:40 -05:00
Ivan Avdeev 266f57e8a5 vk: make `vk_debug_log` a command, not a cvar
This makes it easily switchable at any point in time.

Still not sure how to properly manage log verbosity cvars:
- cvars are loaded after initialization and map load, so we can't really
  depend on saved cvar values.
- reloading cvars each frame cancels `-vkverboselogs` arg that is
  supposed to work around the above limitation
2023-11-07 11:59:12 -05:00
Ivan Avdeev 9eff6fa907 vk: list supported arguments for `rt_debug_display_only` 2023-11-07 10:32:35 -05:00
Ivan Avdeev a18ed8ddc6
Merge pull request #642 from w23/E325
Things done during stream E325

- [x] fix #638
- [x] fix #640 
- [x] fix #641
2023-11-06 10:32:21 -08:00
Ivan Avdeev a25bf841ac vk: fix bright artifacts coming from unpatched chrome materials
Fixes a typo that rewrote roughness value with garbage.

Also adds a few more debug channel displays for lighting phases. And
prints out available debug displays.

Fixes #641
2023-11-06 12:47:21 -05:00
Ivan Avdeev 4509e2075d vk: fix changing textures on buttons, etc
Detect changes in alternate_anims sequences.

Fixes #640
2023-11-06 11:42:07 -05:00
Ivan Avdeev f8c0baf78d vk: fixup -vkverboselogs, make it actually work 2023-11-06 11:07:58 -05:00
Ivan Avdeev dfcfd786a9 vk: fix material basecolor_map handling
- Do not replace inherited base color texture
- Do not acquire default base color texture

Fixes #638
2023-11-06 10:31:55 -05:00
Ivan Avdeev d5ee8ba750
Merge pull request #637 from 0x4E69676874466F78/vulkan
Update patches
2023-11-06 07:13:38 -08:00
NightFox fd356e6124
update c1a0c.patch 2023-11-06 00:00:17 +03:00
NightFox 6963c158a4
update c1a0c.patch 2023-11-05 23:43:12 +03:00
NightFox 42dfd56f87
update c1a1c.patch 2023-11-05 20:45:28 +03:00
NightFox 0927e25ce2
update patches
Improvement geometry smoothing (normals)
2023-11-04 19:23:21 +03:00
Ivan Avdeev 365fffacca
Merge pull request #636 (stream E324)
- [x] debug: display individual channels #631 
- [x] debug: implement `r_lightmap` #634 
- [x] debug: display surfaces #635
- [x] name cvars and commands consistently #632 
- [x] allow enabling verbose logs at init
2023-11-03 10:37:25 -07:00
Ivan Avdeev 6e56c8c78d vk: add -vkverboselogs argument to enable super verbose logs at init 2023-11-03 13:23:10 -04:00
Ivan Avdeev a42e5051b7 vk: cleanup cvar prefixes
Now:
- Not necessarily vulkan-specific cvars are prefixed with `r_`
- Vulkan-specific but not RT-specific things are `vk_`
- RT-specific are `rt_`

Fixes #632
2023-11-03 13:15:11 -04:00
Ivan Avdeev 3a7d047f09 vk: add `surfhash` argument to `rt_debug_display_only`
Allows highlighting all the surfaces with random colors to easily see
the surfaces structure and boundaries.

Fixes #635
2023-11-03 12:05:36 -04:00
Ivan Avdeev 28eec97cbf vk: implement r_lightmap for both traditional and RT renderers
Display lightmap plus lighting for traditional.
Display all collected lights (including bounces and simple transparency)
for RT.

Fixes #634
2023-11-03 11:26:57 -04:00
Ivan Avdeev 0ba85e3f08 vk: add `rt_debug_display_only` cvar
Displays only the specified channel.

Fixes #631
2023-11-03 10:58:13 -04:00
Ivan Avdeev 2a3f48fd50 vk: fix occasional inverted normal maps
When texture coordinates are inverted, it makes tangent look into
oppsite direction, which inverts TBN and therefore normal map.

Make sure the tangent points to a consistent direction.

Fixes #627
2023-11-02 10:58:11 -07:00
Ivan Avdeev dfa240a4db vk: fix weird lines on suit studio model
It was using old pre-transform values for prev_verts, and that was
confusing temporal denoiser.

We should bone-transform vertices first, and only then store them as
prev_verts.

Fixes #585
2023-11-02 10:13:56 -07:00
Ivan Avdeev 1a5edc8271
Merge pull request #626 from w23/vulkan-upstream-merge-20231102
Merge from upstream
2023-11-02 09:08:20 -07:00
Ivan Avdeev c869223690 vk: fix compilation after upstream merge 2023-11-02 11:46:30 -04:00
Ivan Avdeev 1f9b489bdc Merge remote-tracking branch 'upstream/master' into vulkan-upstream-merge-20231102 2023-11-02 11:31:59 -04: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
Ivan Avdeev 6fda8bd977 vk: add a mechanism for exclusion of single surfaces from smoothing
Uses `_xvk_smoothing_excluded` field.

Surfaces can still be smoothed with a limited list of neightbours explicitly
by being included in a smoothing group.

Fixes #619
2023-10-31 09:55:06 -07:00
Ivan 'provod' Avdeev 5698746f42 vk: do not crash on corrupted scopes stack
This is not a valid reason to assert/crash, even though it is clearly a programming mistake.
If the stack is corrupted, just print its contents as an S_ERROR and continue.

Also:
- Fix the ultimate reason for stack being unbalanced for #604
- Do not analyze scopes when not needed, i.e. when `r_speeds` is zero.

Fixes #604
2023-10-31 09:13:47 -07:00
Ivan Avdeev f1c8b3ef2f
Merge pull request #612 from w23/texture-storage
Improve texture storage and lookup

- [x] Fix #594 
  - [x] Free engine textures
  - [x] Fixup descriptor sets
  - [x] Fix PBR leaks
    - [x] texture refcounts
      - [x] acquire/release textures in materials
- [x] Done #210 to separate refcount-aware material loading from refcount-unaware ref_interface_t
- [x] Done #602
- [x] #601
- [x] Fixes #617
- [x] кто украл скайбокс?! -- повар украл скайбокс
- [x] Convert blue noise to 3D texture
- [x] fixes #613
2023-10-31 08:49:18 -07:00
Ivan Avdeev a9df5cd86f
Merge branch 'vulkan' into texture-storage 2023-10-31 08:19:40 -07:00
Ivan Avdeev 737d1324e8 vk: assign translucent material mode to transparent studio models
fixes #613
2023-10-31 11:15:15 -04:00
Ivan Avdeev effbf3ea3d vk: fixup material lookup by texture name 2023-10-31 11:03:08 -04:00
Ivan Avdeev 36c06a514e vk: massage texture module a bit more 2023-10-31 10:48:14 -04:00
Ivan Avdeev 5962290b9d vk: simplify texture uploading failure cleanup 2023-10-31 10:43:12 -04:00
Ivan Avdeev 67f336b3c8 vk: load blue noise 3d texture from an array of png files 2023-10-31 09:44:06 -04:00
NightFox 6f40adab98 update rad files
Refactoring, performance improvement (more for c1a0b), minor changes
2023-10-31 05:30:46 -07: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
Ivan 'provod' Avdeev 23341c144c vk: fixup blue noise 3d texture refactoring
Fixed a bunch of validation and shader errors
2023-10-30 13:51:23 -04:00
Ivan Avdeev df3c0e30ba vk: convert blue noise texture to 3D
Note: not tested
2023-10-30 13:43:09 -04:00
Ivan Avdeev 1f043a90a6 vk: remove dummy textures for new material name resolution
Use dedicated hash table for new material names.
Updates a lot of dependent code:
- surface patches now target materials, not textures:
  `s/_xvk_textures/_xvk_material`
- patching now affects only materials, not texture ids. All logic that
  depends on texture ids now operate on original textures.
- brush normal smoothing now ignores patched surface materials when
  deciding whether two surfaces can be smoothed.

The rationale is that patching should only affect newer PBR/RT code paths.
2023-10-30 12:43:26 -04:00
Ivan Avdeev 8c37b25b31 vk: destroy textures on shutdown more explicitly 2023-10-30 10:44:57 -04:00
Ivan Avdeev 97a889cabb vk: fix missing skybox 2023-10-30 10:19:13 -04:00
Alibek Omarov ea55e78855 ref: _inline -> static 2023-10-29 23:38:43 +03:00
NightFox 114015c208 update patches 2023-10-29 11:40:06 -07: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
Ivan Avdeev bc26e8150a vk: fixup mip auto generation 2023-10-27 10:50:46 -04:00
Ivan Avdeev 96864cf0bd vk: silence extra logs, add diagnostic checks 2023-10-27 10:41:39 -04:00
Ivan 'provod' Avdeev eab46bfe20 vk: fix unordered_roadmap windows compilation 2023-10-27 10:18:48 -04:00
Ivan Avdeev ef65ba56ba vk: fix textures leaking at shutdown; add hash table stats 2023-10-27 10:12:34 -04: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
Ivan Avdeev 7d53458ea3 vk: track all ref_interface texture access as a single refcount ref
Legacy ref_interface_t texture access is not refcountable. It does
create/destroy texture in a single call regardless of other users.
Track it with a separate flag that affects refcount with a single +1/-1.
2023-10-27 09:33:01 -04:00
Ivan 'provod' Avdeev bf9ca596eb vk: fix windows build
Windows lacks strcasestr, use Q_stristr
2023-10-27 09:05:53 -04: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
Ivan Avdeev 7eb1bedc9b vk: acquire/release textures more carefully in materials
Make sure that every texture used in materials is properly tracked.
2023-10-26 12:00:34 -04:00
Ivan Avdeev a5e3adf518 vk: make texture hash table case insensitive
Too many places in the engine and the renderer expect texture names to
be insensitive: RAD files, material references, probably engine and game
calls too.

Make it universally case insensitive. Also, add rudimentary tests for
it.
2023-10-26 11:38:37 -04:00
Ivan Avdeev d37020806a vk: fixup re-creating texture images 2023-10-26 11:04:23 -04:00
Ivan Avdeev ee35b02a5d vk: update todo for E318,E319 2023-10-26 10:39:35 -04:00
Ivan Avdeev 063b3d5246 vk: assert on empty pool allocation early 2023-10-26 10:39:12 -04:00
Ivan Avdeev afd98e50c9 vk: fixup disappearing surface lights
Previous hash table was case insensitive, while the new one is
sensitive.
For now the workaround is to tolower texture names in rad files.

Proper way would be to address case-sensitivity globally. Currently it's
not very consistent.
2023-10-26 10:10:01 -04:00
Ivan Avdeev 67e5109b4a vk: fixup loading pbr materials
Texture lookup was returning incorrect index=1 all the time.

Known issues:
- surface lights disappeared
2023-10-26 09:56:19 -04: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
Ivan Avdeev 718d6d2592 vk: move textures to urmom
Known issues:
- pbr materials are completely broken. They end up not being able to
  find textures, seemingly due to memory corruption on materials side,
  not textures.
- There are still places that try to get texture=1
2023-10-24 14:02:32 -04:00
Ivan Avdeev beddef8831 vk: remove direct dependence on vk_textures[] from vk_textures.c
also fixup textures shutdown
2023-10-24 12:24:14 -04:00
Ivan Avdeev c36080c982 vk: move things around between {r,vk}_texture
Another step in preparation for new hash table and better lifetime
management
2023-10-24 11:32:42 -04: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
Ivan Avdeev b016de0c83 vk: add unordered_roadmap simple hash map with tests
Adds unordered_roadmap simple hash map:
- open addressing with linear probing
- size is fixed at init/compile time
- operates on an pre-allocated array of items with hashmap headers

Also adds basic tests for it.
And properly enables tests for ref_vk (i.e. alolcator)
2023-10-23 13:13:16 -04: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 (d259421111289af3b49c055150e02213f39075a6) 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
Ivan Avdeev b0a7a13c19 Update README.md 2023-10-21 20:29:23 -07:00
Ivan Avdeev ab6f18fc32 vk: incapsulate skybox textures 2023-10-20 13:04:33 -04:00
Ivan Avdeev af032bd2be vk: begin texture r_/vk_ split
no functional changes, just copied some functions over
2023-10-20 12:39:46 -04:00
Alibek Omarov b76a75d6b4 ref: gl: respect gl_texture_nearest value for skyboxes 2023-10-20 18:55:22 +03:00
Ivan Avdeev b315f463cf vk: rename vk_textures to r_textures 2023-10-20 11:18:55 -04:00
Ivan Avdeev c4935e483c vk: BREAK texture management with refcounts
THIS COMMIT IS BROKEN AND LEADS TO MISSING TEXTURES

There's a "race" between texture release/acquire on changelevel.
Textures end up being deleted when they shouldn't.

Addressing this is tedious, will be done in the following commits.
2023-10-20 10:55:19 -04:00
Ivan Avdeev 18261da713 vk: massage texture module function names
Bring function names to a single style.
Make them state what they actually do.
2023-10-19 11:15:48 -04: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
Ivan 'provod' Avdeev fd97dc2c24 vk: fix texture corruption after a few changelevels
We were running out of descriptor sets, as they weren't being freed at all.
Now there's a 1-1 table of texture-descset, and no way to run out of them.

Better solution would be to move this descset management to vk_render, and allocate them dynamically from a smaller pool.
2023-10-17 13:17:47 -04:00
Ivan Avdeev e1d478fa28 vk: free textures on map change (DO NOT USE)
Leads to texture corruption and GPU crashes on Linux.
2023-10-17 11:43:38 -04:00
Ivan Avdeev 806932b949 vk: clean up public rendering texture api 2023-10-17 11:26:29 -04:00
Ivan Avdeev aa44ab71e5 vk: show only `speeds.` metrics when doing `SPEEDS_BIT_STATS`(2) 2023-10-17 07:46:16 -07:00
Ivan Avdeev 2f7b9d5d14
Merge pull request #609 from w23/vulkan-upstream-merge-20231017
Merge from upstream
2023-10-17 07:12:45 -07:00
Ivan Avdeev bd07444d6e Merge remote-tracking branch 'upstream/master' into vulkan-upstream-merge-20231017 2023-10-17 09:48:42 -04:00
Ivan Avdeev 2f365b7f97
Merge pull request #603 from w23/dds_ktx
Support DDS and KTX2

- [x] Pass KTX2 as raw data
- [x] Simplify image uploading (there are 2 copies of the same uploading code for regular textures and for KTX2)
- [x] Extract long format lists from `vk_image.c` to e.g. `vk_image_extra.h`
- [x] Support DDS formats
  - [x] BC7
    - [x] PoC works
  - [x] read supplied mips
- [x] Pass most common KTX2 subformats as correct PF_ format
  - [x] BC5
  - [x] BC6H
  - [x] BC7 -- need UNORM/SRGB expansion
  - [x] BC4 -- need to add it
- [x] Alpha flag for KTX2 formats
- [x] swizzle r->rgba
- [x] check il_dds_hardware
- [x] add `IL_KTX2_RAW_SUPPORTED`
- [x] format imagelib things
- [x] extract image size function to img_utils

Fixes #154
2023-10-16 10:04:53 -07:00
Ivan Avdeev c5b6599be7 imagelib: deduplicate Image_ComputeSize function
Make so that img_ktx2 and img_dds use a common copy of the function
2023-10-16 12:37:58 -04:00
Ivan Avdeev 1d90bb1835 imagelib: format new ktx2 code to codestyle 2023-10-16 12:30:12 -04:00
Ivan Avdeev 1834f388b8 imagelib: check flags for DDS and KTX2 support
- Checks for `IL_DDS_HARDWARE` support for compressed formats in KTX2
- Checks for `IL_KTX2_RAW` before providing raw KTX2 data
2023-10-16 12:17:35 -04:00
Ivan Avdeev ee81a7228d vk: better swizzling
- expand BC4 and BC5 compressed blocks
- negate alpha semantic
2023-10-16 12:08:54 -04:00
Ivan Avdeev d9a4d9d562 imagelib: add color+alpha flags for new KTX2/BC formats 2023-10-16 11:32:32 -04:00
Ivan Avdeev 405934f860
update stale comment
s/dds/ktx2/
2023-10-16 08:03:41 -07:00
Ivan 'provod' Avdeev 9dbde6d547 vk: fix roughness on studio model chrome textures
With deprecation of `set` flag, roughness was always replaced on studio model chome textures.
2023-10-16 08:00:15 -07: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
Ivan 'provod' Avdeev f5d99dab41 imagelib: add dds/fourcc BC5S, BC4{S,U} formats support 2023-10-15 20:20:04 -04: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
Ivan Avdeev 1b1d79cbd6
Merge pull request #600 from zgdump/fix-fake-textures
Фикс аллокаций текстур-заглушек

> Это бэкпорт моего фикса для оригинального Xash3D-FWGS, сделанного в незаконченном менеджере текстур.

> Чинит #532.
2023-10-13 20:24:07 -07:00
Ivan 'provod' Avdeev 2e2e17b008 imagelib: vk: add support for BC4
Tested with KTX2 and ref_vk
Added to DDS too.
Not added to any other renderers.
2023-10-13 21:47:22 -04:00
Ivan 'provod' Avdeev b64d8865fd imagelib: support BC7 in KTX2; split into UNORM and SRGB
Also, fix KTX2 mips corruption.
2023-10-13 21:31:39 -04:00
Valery Klachkov 61d32cd384 Fix dummy textures allocation. Fixes 532
It's backport from my old texture manager for Xash3D-FWGS
2023-10-13 20:47:30 +03:00
Ivan Avdeev 91e20382ad imagelib: expand KTX2 support to other renderers
Only for BC5 and BC6H formats for now.

However, adding new formats is easy:
1. Copy format's definition from `VkFormat` to `ktx2.h`
2. Map it to `PF_` format in `Image_KTX2Format()`
3. Done
4. Really, that should be it.
5. I mean, most formats would require PF_ enum extension, but we're not
   going to support all of them right?
2023-10-13 10:32:50 -04:00
Ivan Avdeev a7a7026fdc vk: imagelib: support more dds/compressed formats
- vk: support more compressed formats from imagelib
- imagelib: add BC5(s/u) support for DDS
2023-10-13 09:39:11 -04:00
Ivan Avdeev 3ac5e88b59 vk: extract long functions from vk_image 2023-10-13 09:04:20 -04:00
Ivan Avdeev a0e1dfe4cd vk: use imagelib mipmaps if available 2023-10-13 09:02:08 -04:00
Ivan Avdeev 7cbd34ebdb vk: prototype dds/pf_bc* loading support
known issues:
- doesn't handle mips properly yet.
2023-10-12 14:33:18 -04:00
Ivan Avdeev 0a5f061ba3 vk: consolidate and simplify texture uploading 2023-10-12 14:05:15 -04:00
Ivan Avdeev 8ba7b3649e vk: extract tex/image uploading routines 2023-10-12 13:39:07 -04:00
Ivan Avdeev 4158234fb2 rename ktx_ to ktx2_ for consistency 2023-10-12 12:51:58 -04:00
Ivan Avdeev 4efbb11178 imagelib: attempt to fix ktx2 compilation in C90 mode 2023-10-12 12:46:50 -04:00
Ivan Avdeev 90119ae84a imagelib: add rudimentary KTX2 support
It only does a very basic header validation, and passes the entire file
as PF_KTX2_RAW format. This is to simplify KTX2 reading in ref_vk and
trying out different formats. KTX2 has support for >200 format, and
passing all of them through PF_ types is a non-starter.

The plan is to figure out which formats we want to support, and add
their support to imagelib/ktx2 incrementally, leaving the rest as
PF_KTX2_RAW, so ref_vk still can use them.
2023-10-12 12:38:35 -04:00
Ivan Avdeev 726fcee3f7
Merge pull request #593 from w23/materials-table
Materials table and friends

- [ ] KTX2 #154
  - [x] proof of concept
  - [x] proper alignment for blocks (validation complains)
- [ ] texture leaks: #594 
  - [x] investigate
- [x] `inherit`/`use`
- [x] Fix #211 
  - [x] make materials table
  - [ ] ~~make materials by-name lookup independent of texture table, stop doing dummy textures~~ moved to #601 
- [ ] normalmap glitches, #595
  - [x] investigated, seems to be offline normalization vs bit depth/precision issue; needs offline changes
2023-10-12 08:43:49 -07:00
Alibek Omarov 4acd0e5304 engine: platform: sdl: grab input only in true fullscreen mode 2023-10-11 16:49:49 +03:00
Ivan Avdeev 9ca7aad276 vk: align textures to texel block size on upload
fixes occasional validation woes
2023-10-10 14:02:49 -04:00
Ivan Avdeev 5ba5fc4831 vk: fixup build after backmerge 2023-10-10 14:00:47 -04:00
NightFox ecdb68370b
Merge branch 'vulkan' into materials-table 2023-10-10 20:32:04 +03:00
Ivan Avdeev 7396403984 vk: materials: allow inheriting previously defined materials
`"inherit" "debug_test"` will replace all fields for the current
material with ones from material named "debug_test".
`"inherit"` should be specified before any material fields, except for
selectors like "new", "for" and "for_rendermode".
2023-10-10 13:27:10 -04:00
Ivan Avdeev 82dea7a86b
Merge pull request #597 from w23/srgb-gamma
sRGB-γ all the things

- [x] Makes all textures SRGB by default
- [x] For traditional renderer: convert back to SRGB space like it's 1998 again
  - [x] Make different `VkImageView`s, for linear (trad) and SRGB (rt) to avoid extra conversion
    - see https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#formats-compatibility-classes
supported surface formats, and also whether the image can be used as a storage destination in compute shader.
- [x] Improve `view_unorm` handling:
  - [x] Don't create a separate view for natively `UNORM`
  - [x] Create fallback 
- [x] Use "native" hint for pbr base_color
- [x] Remove `test_val` from shaders
- [x] Do model and material colors srgb-linear conversion in C
- [x] Investigate lighting brightness
  - Nihrena neponyatno. 

Problems caused by this amazing change:
- Undesired interpolation artifacts: #599 (see discussion below).
- Dark places are too dark (caused by more correct linear-to-sRGB conversion that differs from the fast one for smaller values).
- Lighting looks a bit different (probably has the same cause as above)
2023-10-10 09:47:25 -07:00
Ivan Avdeev fc36fb7c13 vk: create unorm image view only if asked and needed
Do not create unorm image view:
- if not asked
- already has unorm format
- format has no meaningful unorm counterpart
2023-10-10 12:18:58 -04:00
Ivan Avdeev 7b69988e41 vk: materials: use native color hint explicitly to avoid enforcing gamma 2023-10-10 12:08:25 -04:00
Ivan Avdeev bf403027c6 vk: rt: do linear vertex_color interpolation 2023-10-10 12:01:39 -04:00
Ivan Avdeev fadde2ea0d vk: rt: convert more engine-supplied colors from sRGB to linear
- model.color
- vertex_color
2023-10-10 11:56:42 -04: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
Ivan 'provod' Avdeev 4fa614d35b vk: rt: do not use fast srgb-linear conversion
FAST mode is incorrect for low values and leads to visible rendering artifacts.
2023-10-09 19:49:54 -04:00
Ivan Avdeev d76d6429d0 vk: rt: ensure that base_color_a is stored in sRGB-γ
Storing it linearly was a mistake: it is 8-bit only, and lacks enough
precision for dark values. It also doesn't really need any more
precision, and should be limited to 0..1 range.

Therefore, it makes sense to treat it as sRGB explicitly.
2023-10-09 14:51:29 -04:00
Ivan Avdeev 7bfba01954 vk: rt: add test for srgb-vs-linear model color 2023-10-09 14:51:07 -04:00
Ivan Avdeev 9843f53cde vk: rt: recreate images on format change 2023-10-09 14:48:50 -04:00
Ivan Avdeev 57093d7198 vk: remove extra stuff, add comments about SRGB swapchain 2023-10-09 13:13:11 -04:00
Ivan Avdeev 2ec92eea0d vk: add a bunch of profiler scopes to rt rendering 2023-10-09 13:02:04 -04:00
Ivan Avdeev 3b40469a87 vk: fix validation sync error on changelevel 2023-10-09 12:48:38 -04:00
Ivan Avdeev 1d2da5831e vk: image: make a raw unorm image view for trad renderer
Traditional renderer operates in sRGB-γ space (as everyone was in 199x).
Making vulkan textures explicitly SRGB for RT renderer breaks color for
trad rendere. Make sure trad renderer still has raw SRGB-unaware texture
sampling.

Adds an UNORM image view for all relevant SRGB textures, and uses them
exclusively for trad renderer. RT still gets proper SRGB views.

Also rename XVK_ to R_Vk for images
2023-10-09 12:39:12 -04: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
nilsoncore 79e0e52061 vk: profiler: devmem: save `peak` instead of `total` metrics
Also minor code structure changes.
2023-10-07 16:58:04 +03:00
Ivan Avdeev c5bbcae242
Merge pull request #596 from a1batross/vulkan
Merge upstream

It's me again, bringing you changes from upstream master branch.

No really interesting changes yet, mostly code refactoring, bug fixes, optimizations.
* We finally migrated all cvars to static allocation, making it's easier for CPU to access cvar values. I do not recommend migrating for renderers yet because of known bug with `GLCONFIG` cvars.
* In OpenGL renderer we started to use `GenTextures` call instead of directly binding arbitrary texture IDs, which also fixed few bugs with overlay programs.
* I probably finally fixed the bug where the engine crashes on startup on Linux, somewhere deep in SDL. At least, I haven't seen it for a while.
* We also finally allow C99 code in the engine. I don't think engine will be ported to new old standard overnight, it's just now fine for new code. 
* We support `.pk3dir`. It's a Quake engine's convention to allow mounting directories that end with `.pk3dir`, as if they were archives. It simplifies development process, where current dev version of assets could be in `pk3dir` and packaged into `pk3` for release.
* I added simple tool called `xar` that unpacks data from `.pak`, `.pk3` and `.wad` archives using `filesystem_stdio`.
2023-10-06 21:33:42 -07:00
Alibek Omarov 3f505103e1 ref: vk: do not create cl_righthand cvar 2023-10-07 00:53:15 +03:00
Alibek Omarov 2c520a6a55 ref: vk: enable compiling with older Vulkan headers 2023-10-07 00:53:15 +03:00
Alibek Omarov fcc6bba88a Merge upstream/master 2023-10-07 00:53:04 +03:00
Ivan Avdeev 9b9e89adec vk: make all texture samplers return values in linear space
Make sure that all SRGB-gamma textures are marked with SRGB format (this
includes all the original textues, 8bit PNG textues). All other
textures (roughness, metallic, normal maps) are linear (UNORM).

Trust KTX2 texture that they store in the correct colorspace.

Then we can just sample textures w/o SRGBtoLINEAR'izing them. Supposedly
this is better because of hw interpolation in the correct colorspace.

This is a bit experimental because Compressonator can't really into
BC7_SRGB, which is sad. And also we need to re-gamma all the textures
for the gamma/srgb-unaware traditional renderer.
2023-10-06 15:06:44 -04:00
Ivan Avdeev 60f83245ee vk: rt: make base_color_a linear-space
Convert from gamma to linear at the point where we read from texture.

Prerequisite for making textures in a right colorspace.
2023-10-06 13:51:32 -04:00
Ivan Avdeev 41ac5fa0eb vk: fix printing 64-bit numbers in x86 linux 2023-10-06 13:13:31 -04:00
Ivan Avdeev 96e9ef20ab vk: rt: make normalmaps switchable between xyz.png and xy.ktx2
They have slightly different incompatible encodings. Switch between them
using #define at build time.

Old png code can be removed when we fully switch to KTX2.
2023-10-06 13:05:42 -04:00
Alibek Omarov a738b2a50b ref: restore missing PARM_TEX_MEMORY RenderAPI parameter 2023-10-06 19:24:02 +03:00
NightFox 56737fd05f
Merge pull request #591 from w23/everything-is-smooth
vk: patch: allow smoothing entire brush model
2023-10-05 22:00:39 +03:00
Ivan Avdeev ab53aae359 vk: textures: preliminary KTX2 support
Loads something. Not everything. Not everything correctly.
Doesn't do validity checks.

Makes colorspace (srgb gamma vs linear) inconsistent between textures
(ktx has correct srgb-vs-unorm, all is unorm (but srgb gamma
semantically) in png)
Makes normals inconsistent too (.xy in ktx, .xyz in png)

related #154
2023-10-05 14:23:46 -04:00
Ivan Avdeev 7e3f8785f7 vk: fix normalmap glitches
Was triggered by renormalizing normal z when applying normal scale.
Not sure why exactly, though, the math checks out.

Doing it a bit differently solves the issue.

Fixes #595
2023-10-05 12:48:48 -04:00
Ivan Avdeev 9b90e920a7 vk: add textures counts/size to metrics
Also split frame flame graphs and metric graphs to different `r_speeds`
bits.

related to #594
2023-10-05 12:20:07 -04: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
NightFox e04a19a0af
Merge pull request #559 from w23/bluenoise
vk: textures: add blue noise textures
2023-10-04 22:55:53 +03:00
NightFox 206fd528d8
Merge branch 'vulkan' into bluenoise 2023-10-04 22:44:49 +03:00
Ivan Avdeev 0d6f6d26af vk: material: add material table independent of texture table
It still reuses texture table for name lookup for now.
2023-10-03 12:48:26 -04:00
Alibek Omarov 2fdd080eef mainui: update 2023-10-02 19:31:35 +03:00
Ivan Avdeev 6bfa4c90fa vk: brush: assign white texture for kRenderTransColor
kRenderTransColor mode strips geometry of its texture and makes it solid
color. Previously we were noticing this rendermode late, and failed to
update the textures.

Now we depend on reading this rendermode from map entities, and
pre-assigning correct (white) textures on load.

Assumes that rendermode doesn't change at runtime for brush models.

Fixes #528
2023-10-02 11:39:00 -04:00
Ivan Avdeev 1bbcf44864 vk: patch: allow smoothing entire brush model
fixes #589
2023-10-02 11:18:22 -04:00
Ivan Avdeev b740e0848d
Merge pull request #590 from 0x4E69676874466F78/vulkan
update patches
2023-10-02 07:59:31 -07:00
NightFox bdc66ba52b
Merge branch 'vulkan' into vulkan 2023-10-02 17:58:26 +03:00
Ivan Avdeev 737cd944bb
Merge pull request #572 from w23/lol-materials
- [x] Pass material reference via geom/render API
- [x] Show original textures for traditional renderer, #571
- [x] Remove old material type flags
  - [x] ~~Move sky surfaces to a separate BLAS~~ Remove `SURF_DRAWSKY` from geometries completely #474 
  - [x] **REVERT** `SURF_DRAWSKY` changes. Such surfaces still need to be "drawn" to hide geometry behind it (see comments).
  - [x] Chrome material: have an explicit material for it
    - [x] This needs vk_texture vs vk_material index decoupling
- [x] Assess #577
- [x] Improve paths #578 
  - [x] `pbr/maps/c0a0a.bsp/c0a0a.bsp.mat` -> `pbr/maps/c0a0a.bsp/c0a0a.mat`
  - [x] `pbr/halflife.wad/halflife.wad.mat` -> `pbr/halflife.wad/halflife.mat`
  - [x] Rename files in PBR repo for the above
  - [x] `luchiki/maps/c0a0.bsp.patch` -> `luchiki/maps/c0a0.patch`
  - [x] Rename patch files too
  - [x] Same for spr,mdl
  - [x] Rename
- [x] Pass material mode directly, instead of render type
- [x] Advanced material patching/selection
  - [x] Need a few advanced selection examples
    - [x] #317
    - [x] стёкла у костюма (??)
  - [x] #526
  - [x] #577
  - [x] #213
2023-10-02 07:54:10 -07:00
NightFox bd98fdd1d7
update patches 2023-10-02 01:46:47 +03:00
Ivan Avdeev 8ff89bd5ef vk: materials: add rendermode-specific overrides
Example:
```c1a0d.mat
{
	"for_rendermode" "kRenderTransTexture"
	"for" "table2"
	"basecolor_map" "/colors/white.png"
	"metal_map" "/colors/white.png"
	"roughness_map" "/colors/black.png"
}
```

Fixes #213
2023-09-29 13:59:27 -04:00
Ivan Avdeev 4e01947b6b vk: fix crashing on reloading materials
Needed to drop entity data cache before clearing studio model cache

Fixes #577
2023-09-29 13:02:51 -04:00
Ivan Avdeev e97691b27c vk: patch: allow mapping texture to materials for brush entities
```
{
	"_xvk_ent_id" "39"
	"_xvk_map_material" "generic028 mirror"
}
```

NOTES:
- might severely degrade performance in some cases/under debug as we're
  doing N^2 search with strcmp for rendered entities.
2023-09-29 12:48:32 -04:00
Ivan Avdeev 7839792964 vk: materials: fix bsp/mat file extension culling 2023-09-29 12:39:36 -04:00
Alibek Omarov 95f87e24ee ref: soft: do not register cl_righthand cvar 2023-09-29 13:45:24 +03:00
Ivan Avdeev 1f82f352f9
Merge pull request #581 from 0x4E69676874466F78/patch
Update de_dust2.patch
2023-09-28 08:46:16 -07:00
NightFox 884a4ad97e
Update de_dust2.patch
perestoralsya
2023-09-27 00:05:15 +03:00
Ivan Avdeev b07c5c3740 vk: rt: pass material mode directly from draw command
Different render sources (model types, render types, etc) might require
different material modes. E.g. brush should be translucent (refractive+mirror)
for blend mix modes. However, smoke particles should not be
mirror/refractive for the same blend mix render type.
2023-09-26 13:14:28 -04:00
Ivan 'provod' Avdeev f63dcd14ce vk: rt: draw skybox where ray hasn't hit anything
fixes #579
2023-09-26 12:41:10 -04:00
Ivan 'provod' Avdeev 02efba3902 Merge branch 'vulkan' into lol-materials 2023-09-26 12:36:37 -04:00
Ivan Avdeev acd87043fb vk: materials: load by mdl/spr individually, not by global {models,sprites}.mat 2023-09-26 12:27:24 -04:00
Ivan Avdeev b549ac76f6 vk: add logs and notes about mod/spr load sequence 2023-09-26 12:25:40 -04:00
Ivan Avdeev 3aae128e61
Merge pull request #580 from 0x4E69676874466F78/patch
de_dust2.patch
2023-09-26 06:03:34 -07:00
nilsoncore e3d86af5ab vk: profiler: devmem: code style consistency
Also clarify one comment about enabling stats metrics only with
`-vkdebugmem` parameter.
2023-09-25 23:47:04 +03:00
nilsoncore 95223077b6 vk: profiler: devmem: take into account alignment holes
Also improve `VK_DevMemFree` debug printing: include usage type, size,
alignment, and unusable alignment hole size.
2023-09-25 23:43:45 +03:00
NightFox 24c0faca99
de_dust2.patch
remove bad sky surfaces
2023-09-25 21:40:18 +03:00
Ivan Avdeev 26224b4aca vk: materials: add a few stream E301 notes 2023-09-25 13:57:43 -04:00
Ivan Avdeev e8a09c85e5 vk: load map patches without extra .bsp extension
e.g. `c1a0d.patch`, not `c1a0d.bsp.patch`

Ref: #578
2023-09-25 12:53:58 -04:00
Ivan Avdeev e26ce740f1 vk: cut orig file extension from material files
E.g. load `pbr/halflife.wad/halflife.mat` not `pbr/halflife.wad/halflife.wad.mat`

Requires changes to the PBR repo.

Reference: #578
2023-09-25 12:44:41 -04:00
nilsoncore 985ebd23c2 vk: profiler: metrics: fix switch-case scoping to build on linux 2023-09-24 06:23:15 +03:00
nilsoncore aebc730b35 vk: profiler: metrics: make var column wider to fit new wider ones 2023-09-24 06:06:42 +03:00
nilsoncore c7f8a2a8f6 vk: profiler: devmem: store stats for each devmem usage type
Make struct `vk_devmem_allocation_stats_t` which will be able to store
overall stats and stats generic for each usage type.
Move Vulkan related devmem allocation arguments into their own type -
`vk_devmem_allocate_args_t`.
Store `vk_devmem_usage_type_t` inside `vk_devmem_t`, so we can handle
deallocations (frees) for each corresponding type aside from overall
stats.
Make `VK_DevMemAllocateBuffer` and `VK_DevMemAllocateImage` macros which
call generic function `VK_DevMemAllocate` with correspoding usage type
set.
Make function `VK_DevMemUsageTypeString` to be able to get short string
of long enum name.
2023-09-24 06:06:42 +03:00
nilsoncore f515228142 vk: devmem: fix debug message so it builds on linux (hopefully) 2023-09-24 06:06:42 +03:00
Ivan Avdeev 9ac7340974 vk: bring back SURF_DRAWSKY geometries
Needed to hide invisible geometry on e.g. c5a1. Breaks de_dust2 roofs
(#474). That will need to be addressed some other way.

Still uses special value for base_color texture to signal SKY SURFACE.
A supposedly better way to do this would be to have them have a special
material.
2023-09-22 10:15:34 -04:00
Ivan Avdeev 638bd163af vk: remove chrome material type; patch roughness manually instead
Also, material struct is now embedded into geometry, so it can be
individually patched.
2023-09-22 09:43:27 -04:00
nilsoncore a909f7bcab vk: profiler: use existing functions
Use built-in `Q_memprint` to output memory sizes.
Use built-in `COM_FileWithoutPath` instead of newly added
`get_filepath_from_filepath` to truncate full filepath from filename.
2023-09-22 05:06:57 +03:00
nilsoncore 4f6d9b8e1e vk: devmem: code style consistency 2023-09-22 05:01:46 +03:00
nilsoncore 5a745249e1 vk: devmem: integrate it with `r_speeds` metrics
Clarify type name `vk_device_memory_t` as `vk_device_memory_slot_t`
to not confuse it with `vk_devmem_t` as their names are pretty much
the same.
Add additional helper functions to standardize VK flags output format.
Also maybe it is a good idea to have it inside `vk_flags.{h,c}`,
for example.
Improve debug printing: bring colors and improve readability.
Add internal (private) field `_block_size` to `vk_devmem_t` so we can
keep track of how much memory we freed.
2023-09-22 04:59:23 +03:00
Ivan Avdeev dce0598962 vk: remove special SURF_DRAWSKY handling
1. Completely remove them from geometries
2. Draw skybox where the ray hasn't hit anything
3. In the same fashion sky is not shadowed when there's nothing hit by
   the shadow ray.

This allows completely removing the sky material flag.
Also supposedly fixes #474
2023-09-21 12:53:17 -04:00
Ivan Avdeev cd4014766b vk: explicitly pass old original texture for trad renderer
Fixes #571
2023-09-19 13:20:04 -04:00
Ivan Avdeev 07f1bac938 vk: pass material reference explicitly in geom structure
This is needed to enable advanced material patching, where the material
can be picked up based on source type, render mode, surface number, etc
etc and all of the above combined if needed.

Previous scheme was picking up materials very late when all of this info
has been already lost.
2023-09-19 13:05:12 -04:00
Ivan Avdeev 258c3ec48e
Merge pull request #567 from nilsoncore/vulkan
vk: profiler: fix source locations for scopes (#542)

Fix source locations for scopes in `r_speeds_list_metrics` as described in Issue #542. 
Also slightly simplify metrics list print formatting and add an option to print it as a table. It can be turned on/off via cvar `r_speeds_metrics_as_table`. 
This does not look very good in HL itself because it uses non-monospace font by default in console, but it looks much cleaner and readable in console and log file output.
2023-09-17 20:20:46 -07:00
nilsoncore 02604cd901 vk: profiler: metrics: remove outdated comment 2023-09-18 05:57:49 +03:00
nilsoncore 977eda258a vk: profiler: metrics: little tweaks
Remove unnecessary `crtlib.h` import in `profiler.h`.
Simplify `get_filename_from_filepath` function.
Add extra guards in metrics line printing to make sure we would not
leak/blow up anything.
2023-09-18 02:57:09 +03:00
nilsoncore 37600be985 vk: profiler: metrics: call print on lines only if necessary 2023-09-18 01:47:58 +03:00
nilsoncore e939d3eab6 vk: profiler: metrics: drop arguments, use globals
This is related to static function of metrics print.  It probably does
not need to expose arguments and can just use globals directly.
2023-09-18 00:55:18 +03:00
nilsoncore d5df2d2791 vk: profiler: metrics: store filepath, but print only filename
Previously, source filepath was truncated right at metric registration,
so only the filename was stored.  Now, full source filepath is stored.
The truncation to its filename happens only in metrics print.  This way
we preserve full information, but also throw away redundancy in print.
2023-09-18 00:35:35 +03:00
nilsoncore 79c2d5768f vk: profiler: metrics: separate printing methods into different commands
Remove command `r_speeds_list_metrics` and cvar
`r_speeds_metrics_as_table`.  Now, there are 2 new commands:
`r_speeds_mlist` - to print metrics as a list, and
`r_speeds_mtable` - to print metrics as a table.
Both of them can handle optional filter argument.
2023-09-17 17:16:20 +03:00
nilsoncore b4aa0fcaf1 vk: profiler: metrics: print filenames instead of filepaths
Reduces enormous amount of space used by absolute filepaths in
metrics print.  This does not mean we cannot locate the files now.
Pretty much all of the vk files have such prefix in their name.
2023-09-17 17:06:49 +03:00
nilsoncore 6659c83c6d vk: profiler: print metrics header twice (top and bottom)
Second header down below the metrics print may help to visually see
the output format without the need to scroll console all the way up.
2023-09-17 16:35:19 +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
nilsoncore c07fe8cd9c vk: profiler: add option to print metrics as table
Slightly improve metrics list print formatting and
add new option to print it as a table.  Table alignment relies on
monospace font.
This can be turned on/off with cvar `r_speeds_metrics_as_table`.
2023-09-16 14:08:34 +03:00
nilsoncore d2b71eb3f7 vk: profiler: fix source locations for scopes (#542)
Fix source locations for scopes in `r_speeds_list_metrics`.
Closes #542.
2023-09-16 14:00:54 +03:00
Alibek Omarov dc71456174 scripts: flatpak: upgrade to Freedesktop SDK 23.08 2023-09-15 22:32:52 +03:00
Ivan Avdeev e28b87beb3
Merge pull request #565 from w23/stream-E296
Fixes made during stream E296

- [x] Fixes #551
  - [x] Also checked that #175 doesn't happen anymore
- [x] Accidentally fixes #174
2023-09-15 11:15:14 -07:00
Ivan Avdeev e27bfdc682 vk: studio: minor changes around FIXMEs
accidentally fixes #174
2023-09-15 14:00:37 -04:00
Alibek Omarov c6b6938e14 wscript: fix RPATH usage on OSX (by @sofakng) 2023-09-15 20:35:51 +03:00
Ivan Avdeev 2e1cb8173e vk: studio: use explicitly set RI.currentmodel over entity->model
`thirdperson` mode overrides entity model while leaving entity->model
with the old value. Vk renderer was assuming that those are the same.

Fixes #551
2023-09-15 12:47:53 -04:00
Ivan Avdeev 54717e60e1
Merge pull request #563 from w23/E295
Fixes made during stream E295

- [x] Fixes #441
- [x] Fixes #433 
- [x] Fixes #562
2023-09-14 11:52:01 -07:00
Ivan Avdeev 755b2d59a9 vk: fixup BLAS preallocation on Linux/amdgpu
Fixing pool allocator to properly signal allocation failure uncovered an
existing issue where we were lacking enough memory for dynamic model
BLASes on Linux/amdgpu. Erroneously the same memory region was used for
>1 BLAS. Surprisingly this hasn't led to any noticeable issues so far.

Increasing accels buffer size fixes the issue.
2023-09-14 13:57:59 -04:00
Ivan 'provod' Avdeev 06a7de02a8 vk: clear EntityData on new map regardless of save-load
Entity data gets reallocate on every NewMap regardless of whether it was a load from a save. Thus all entity pointers and data are invalidated. EntityData keeps things using pointers as keys.
Make sure it is properly cleared on `R_NewMap()`

Fixes #562
2023-09-14 13:48:39 -04:00
Ivan 'provod' Avdeev 7d115168ae vk: alolcator: report pool allocation failures correctly
Returning `0` instead of `ALO_ALLOC_FAILED` let to API consumers believe that allocation was successful. This lead to asserts failing when trying to free such allocations.

Makes #562 not crash (but miss studio models anyway)
2023-09-14 13:42:47 -04:00
Ivan Avdeev 3333d03a7b vk: studio: add submodel render acquire/release diagnostics
For #562 investigation
2023-09-14 13:02:01 -04:00
Ivan Avdeev 9ceb129576 vk: sprite: enable lerping
It Just Works™  even with raytracing, as RT just blends everything
(including coplanar sprites) order-dependent correctly.

Fixes #433
2023-09-14 12:13:30 -04:00
Ivan Avdeev 40a79d7280 vk: sprite: fix fading
Fixes #441
2023-09-14 11:58:32 -04: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
Ivan Avdeev 5767ddb30c vk: studio: do not ignore parent bones when detecting static submodels
python/357 has bullets submodels which are animated using parent bones.
Their direct bones are static, and thus the entire submodel was picked
up as static.

Now when computing bone transform for particular sequence/anim frame
also merge it with parent transform. Bones are laid out sequentially in
their "dependency order" so using a direct parent is fine, as it also
contains its parent transforms.

Fixes: #554
2023-09-12 11:12:40 -07:00
Ivan 'provod' Avdeev 64e1a9b763 vk: do not draw into empty swapchain
On Windows we're seeing a max size = 0x0 swapchains. Those cannot be created or used. Make sure that we're not, and we're not trying to draw anything when there's no swapchain available.

Unfortunately we still have to call some rendering functions (without actually rendering anything) to make sure that various invariants hold.

fixes #463
2023-09-12 10:48:26 -07: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
Ivan Avdeev a1cae92a2c vk: textures: add blue noise textures
They are not used by anything yet.

Fallback to generating regular noise textures if bluenoise ones weren't
found.

Real blue noise textures require Half-Life-PBR repo textures.
2023-09-11 12:31:03 -04:00
Ivan Avdeev d9207963f9
Merge pull request #557 from w23/E292
Things done in stream E292
2023-09-08 12:45:14 -07:00
Ivan Avdeev 26a4fff486 vk: brush: improve animated surfaces detection
Explicitly check that there are at least two different textures in an
animation sequence.

Fixes #555
2023-09-08 14:22:37 -04:00
Ivan Avdeev 48b7fcb153 vk: add a bunch of profiler metrics
Done as part of investigation for #555
2023-09-08 14:12:35 -04:00
Ivan Avdeev 49bfd28d3c
Merge pull request #556 from 0x4E69676874466F78/vulkan
Update patches&rads
2023-09-08 10:50:09 -07:00
NightFox f3b55c63bb
Update rads
performance improvement for c1a0/c1a0d
2023-09-08 17:39:27 +03:00
NightFox 9c7d8a6ee0
Update patches 2023-09-08 17:17:23 +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
Ivan Avdeev 4944b5eb05
Merge pull request #552 from w23/E291
Fixes from stream E291
- [x] Late studio models: #546 
- [x] Silence verbose logs: #545 
- [x] Synchronize kusochki updates: #553
2023-09-07 08:42:43 -07:00
Ivan 'provod' Avdeev 6d749ea8d0 vk: synchronize updating kusochki
Do not aggravate the validator by uploading to the same memory region twice. Make sure that there's synchronization between updating kusochki.

Fixes #553
2023-09-07 11:19:41 -04:00
Ivan Avdeev 13eef5dda2 vk: silence a bunch of verbose logs
There are some limits that we hit multiple times in a frame that result
int S_ERROR logs. Throttle them

Fixes #545
2023-09-07 10:43:21 -04:00
Ivan Avdeev b8eb6156a8 vk: studio: allow late "pre"loading for studio models
Sometimes the initial list of models doesn't contain everything that is
used later. I don't know why. So detect this and allow loading model
infos later.

Fixes #546
2023-09-07 10:18:31 -04:00
Ivan Avdeev 29508cd324
Merge pull request #547 from w23/brush-smoothing
Smooth normals between selected brush surfaces if the angle between them is small enough.

- [x] Per-vertex-per-surface smoothing functionality (differs from qrad, which is per-edge; this gives artifacts as (supposedly) we have higher than lightmap lighting resolution)
- [x] Automatically select surfaces with less than X degrees between normals.
- [x] Make this X threshold adjustable from <map>.bsp.patch
- [ ] ~~Try not joining coplanar surfaces~~ -- doesn't seem to be affecting anything.
- [ ] ~~Think about linking surfaces more. Should we link distant surfaces w/o direct edges to this one?~~ -- it seems that we should be fine for now. Per-surface+vertex vs per-edge smoothing has no clear winner, just different tradeoffs.
- [ ] ~~Scale normals according to surfaces areas, so larger surfaces have more weight (experimental; may improve some artifacts)~~ -- also, non trivial to compute, and may not affect things too much.
- [x] Patch: add explicit smoothing or no-smoothing for given surfaces.

Fixes #139, supersedes #348
2023-09-05 10:18:46 -07:00
Ivan Avdeev bdbfbef8a2 vk: add commented out normal debugging code 2023-09-05 13:06:00 -04:00
Ivan Avdeev f42ea011f1 vk: mapents: fix not clearing smoothing groups 2023-09-05 13:03:53 -04:00
Ivan Avdeev 58ed5e7277 vk: brush: add explicit smoothing group inclusion 2023-09-05 12:54:57 -04:00
Ivan Avdeev 61416cfc66 vk: brush: do not link pairs that were explicitly excluded in patches
This doesn't work as expected in some cases, as surfaces might still get
linked transitively by neighbours. Solving this seems non-trivial for
now, but maybe we can just live with it
2023-09-05 12:35:28 -04:00
Ivan Avdeev d8d5019971 vk: filter smoothing normals by texture
thanks to G.I.F
2023-09-05 12:07:02 -04:00
Ivan Avdeev 0856e9e70d vk: add patchable smoothing threshold
Automatically smooth normals between surfaces with normals less than 45
degrees off.

Can be adjusted from map.bsp.patch file like this (e.g. to 50 degrees):
```
{
	"_xvk_smoothing_threshold" "50"
}
```
2023-09-04 14:35:19 -04:00
Ivan Avdeev a9dcf94f1b vk: add initial support for brush surface normal smoothing
Lots of artifacts

Relevant: #139, #348
2023-09-04 13:49:03 -04: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
Ivan Avdeev 883ccff13f
Merge pull request #537 from w23/blas-mgmt
Improve BLAS management

This PR is to address #533 and related issues, e.g.:
- [x] Fixes #236
- [x] Fixes #350
- [x] Fixes #354
- [x] #364
- [x] Fixes #422
- [x] Fixes #443
- [x] Fixes #533
- [x] Fixes #539
- [x] Fixes #458 

An arbitrary list of other things to do in this PR also:
- [x] Use new model create and render for brushes
- [ ] ? split materials from kusochki
- [x] fix sprite textures: pass texture override and upload dynamic/instanced kusochki
- [x] orient sprites
- [ ] fix NewMap-vs-long allocations for:
  - [ ] accel buffer
  - [ ] kusochki
- [ ] create/allocate tlas only once
- [x] studio models:
  - [x] pre-cached models with prebuilt blases
  - [x] blas update
  - [x] counters for static-vs-dynamic cache entries count
    - [x] better `r_speeds_graphs`
      - [x] add/remove commands which modify the string
      - [x] constant monitoring of the available metrics: metric registering later should start being drawn
  - [ ] ~~cache eviction/LRU (needs proper allocs for accel buffer and kusochki)~~ -- doesn't seem to be a problem for now. Can totally live without.
  - [x] previous vertices and transform
- [x] Fix animated textures: pass and update kusochki
- [x] Fix emissive textures
  - loading order has changes, now kusochki are uploaded when brush model is loaded, and before lighting data is applied, thus losing emissive values
- [x] Remove deprecated APIs:
  - [x] dynamic model
  - [x] `VK_RenderModelInit_old`
  - [x] `VK_RenderModelDraw_old`
  - [x] `deprecated` section from `vk_render_model_t`
  - [x] old ray model
  - [x] old ray model cache
- [x] hide `rt_blas_t` as rt-internal, only expose new `rt_model_t`
- [x] restore TriApi/dynamic geometry for RT
  - [x] dynamic drawing for RT
  - [x] dynamic `rt_blas_t`
- [x] brush water update
  - [x] rt_blas update
  - [x] vk/rt models update
- [x] studio dynamic models
  - [x] reloading c2a5 leads to geometry exhaustion (cannot allocate N vertices M indices, and missing models)
  - [x] better static model detection: many sequences/frames are the same and are not in fact animated. This can be detected at load time.
- [x] `r_speeds` persistent metrics which are not reset on every frame, e.g. allocation counts, cache sizes, etc
2023-08-31 10:10:59 -07:00
Ivan Avdeev 1d9b987379 vk: treat emissive animated texture frames as polylights
Probably not the most optimal solution, but it works.

Fixes, #458
2023-08-31 12:49:30 -04:00
Ivan Avdeev 9c4fd15e65 vk: fix animated textures for brush models 2023-08-31 12:11:17 -04:00
Ivan Avdeev 3e14591082 vk: wkrutily lampotschkee
fixed missing emissive values for brush models
2023-08-31 11:45:51 -04: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
Ivan Avdeev ea1a98716d vk: restore dynamic polygon lights 2023-08-29 13:39:36 -04:00
Ivan Avdeev 0ccc107859 vk: associate more logs with modules 2023-08-29 13:12:35 -04:00
Ivan Avdeev 6d3c5bfa3e vk: add runtime-toggleable debug logs with module granularity
Use e.g. `vk_debug_log "mat,tex,brush"` to enable verbose debug (-dev 2)
logs for Material, Textures and Brush modules.
2023-08-29 12:31:57 -04: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
Ivan Avdeev e978871470 remove unused vk_previous_frame module 2023-08-28 13:12:02 -04:00
Ivan Avdeev ffa9603747 vk: studio: fix motion vectors for denoiser
Track prev_verts by render submodel
2023-08-28 12:59:54 -04:00
Ivan 'provod' Avdeev 2dc68544d6 vk: studio: remove obsolete comments 2023-08-28 09:11:48 -07:00
Ivan 'provod' Avdeev 45a141aa36 vk: studio: clear submodule cache at appropriate times
Add render refcount to submodels to diagnose when it can't properly clear things due to them being used somewhere still.

Also add `speeds.submodels_cache_{dynamic,static}` counters to show how many submodels render models have been allocated.
2023-08-28 09:11:48 -07:00
Ivan 'provod' Avdeev 03fc537d54 vk: studio: implement proper per-submodel rendermodel cache
Gives out individual render submodels for dynamic ones, receives and remembers them when they are not needed anymore.

Stores only one render submodel for static ones. Reuses/instantiates it for everyone.
2023-08-28 09:11:48 -07:00
Ivan 'provod' Avdeev c42cf2088c vk: studio: handle first half of entity reuse
Detect whether studio model has changed, and replace it with a new one.
It does (as predicted) run into a gpu sync issue if reuse happened while previous frame with the old user is still being drawn.
2023-08-28 09:11:48 -07:00
Ivan 'provod' Avdeev 567d014ada vk: studio: precompute per-submodel dynamic-ness
Basically go through all sequences and bones, and try to find out whether a given submodel is affected by animation frames.
2023-08-28 09:11:48 -07:00
Ivan 'provod' Avdeev 9636b541c5 vk: studio: make dynamic-ness detection more granular
also comment on the upcoming submodel caching plans
2023-08-28 09:11:48 -07:00
Ivan Avdeev 47cc51d9b1 vk: studio: track studio model state by entity 2023-08-28 09:11:48 -07:00
Ivan Avdeev 09d8534b01 vk: studio: extract all model/cache stuff into separate files 2023-08-28 09:11:48 -07:00
Ivan Avdeev f99d43ec4c add a bunch of wip changes wrt studio model cache 2023-08-28 09:11:48 -07: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
Ivan Avdeev f691b4b4b0 vk: add "persistent" speeds metrics for used memory, etc
Renames previous METRICS to COUNTERS. These are still reset to zero
every frame.

Adds new METRICS which are preserved, maintained externally to speeds,
and only sampled by speeds code once per frame.

Also adds new metrics:
- `studio.cached_submodels` -- number of submodels in cache
- `geom.used` -- memory used by long allocations
- `geom.{vertices,indices}` -- counts of vertices/indices for long
  allocations
- `geom.dyn_{vertices,indices}` -- counts of vertices/indices for
  single-frame dynamic allocations
2023-06-14 11:23:09 -07: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
Ivan Avdeev d13c0d4748 vk: add studio dynamic and static submodels metrics 2023-06-13 12:19:18 -07:00
Ivan Avdeev 5dda220751 vk/speeds: preserve metric names that might not be registered initially
When `r_speeds_graphs` cvar is read for the first time, not all metrics
might be registered yet. It leads to some graphs missing.

Retry searching for these metrics on further frames, thus preserving the
graph list from previous session fully.
2023-06-13 11:52:46 -07:00
Ivan Avdeev c72ff1d0c5 vk: add ability to delete graphs by their names
Also, track single changes vs cvar changes: do not reload everything
from cvar on every update
2023-06-13 10:32:32 -07:00
Ivan Avdeev 0b47621f69 vk: add r_speeds_graph <add/del/clear> command
Allows adding graphs w/o editing the cvar manually

Delete is not implemented yet
2023-06-13 10:12:41 -07:00
Ivan Avdeev 046ae3d7f3 vk: rename metrics to module.name, prettify list
- Add variable name and registration src:line to the
  `r_speeds_list_metrics` output. Makes it easier to reason about where
  does this metric come from.
- Group metrics by their modules, makes it easier to discover.
- Do not print the list immediately on command, do it later in the
  frame. Makes it print correct latest frame values.
2023-06-13 09:39:50 -07: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
Ivan Avdeev 6583ed0c31 vk: fixup sequences fps formatting 2023-06-09 11:34:39 -07:00
Ivan 'provod' Avdeev ba041fce36 vk: update animated studio models geometry
Still slightly KORYAVY as:
- there's no cache eviction, it might get full pretty quick
- static-vs-dynamic animation decision is pretty rudimentary, might consider non-animated things as dynamic
- args passing vs global state is meh
2023-06-09 11:28:30 -07:00
Ivan 'provod' Avdeev cadf3dbdfc rt: update blas for brush water
Enable updating rt_blas, and use that for updating brush water models
2023-06-09 10:03:00 -07: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
Ivan Avdeev 406a5f9d4b vk: remove old dynamic beam segs code 2023-06-07 10:54:09 -07:00
Ivan Avdeev 4409e57a8d rt: fix dynamic models colors 2023-06-07 10:43:54 -07:00
Ivan Avdeev 0b8fe6fe33 rt: implement fast dynamic models
It works, and works really fast.
Known issues:
- missing colors
2023-06-07 10:24:29 -07:00
Alibek Omarov b84aba68fa engine: platform: implement generic GetNativeObject for POSIX systems without SDL2 2023-06-07 04:07:53 +03:00
Ivan Avdeev e6bf0c452a rt: more removals 2023-06-06 11:21:47 -07:00
Ivan Avdeev 789982277d rt: remove more unused and obsolete things 2023-06-06 10:50:16 -07:00
Ivan Avdeev 98f8300ca2 vk: remove lots of obsolete code
TriApi/dynamic stuff is still not passed to RT, but removing old code
makes it easier to reason about.
2023-06-06 10:40:10 -07:00
Ivan Avdeev 8e0a9ac4d4 vk: remove old dynamic model implementation too
Breaks dynamic model RT rendering, as it is not implemented yet
2023-06-06 10:20:00 -07:00
Ivan Avdeev c105d45265 vk: remove public render dynamic model api
It still remains internally, and generates too many BLASes.
2023-06-06 09:50:24 -07:00
Ivan Avdeev 0e13ed38c1 vk: revert beam segs to use triapi, like gl 2023-06-06 09:29:05 -07:00
Ivan Avdeev c271078196 vk/speeds: print current metric value next to graphs 2023-06-06 09:27:52 -07: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
Ivan Avdeev 3e2e5e7cb2 vk: remove old dynamic model api usage from brush+water
This makes water static for now, and also makes it look weird, e.g.:
- no culling of water sides (it is "dynamic" in a sense that it's an
  entity property, not model property)
2023-06-05 12:53:25 -07: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
Ivan 'provod' Avdeev a2b0164e03 vk: put barney back together
Fixes computing total vertices/indices count. Were referencing the same `pmesh` for all meshes.

Floating and missing heads issue seems to be due to incorrect fixed animation frames. I.e. animation frames contain offsets to the correct positions. Should be fixed when animations are done.
2023-06-03 12:10:56 -07:00
Alibek Omarov a40a325d3c 3rdparty: mainui: update 2023-06-03 03:54:49 +03:00
Ivan Avdeev df102994c4 vk: pre-build and cache studio submodels on first draw
Known issues:
- no animations, stuck at first rendered frame of a given submodel.
  This is as intended for now, needs BLAS update functionality not yet implemented.
- wrong positions/transforms. Reasons unknown. May be "as intended" too.
- missing heads
- Barney model corruption. Consistent between maps/instances/animation
  frames.
2023-06-02 11:49:02 -07: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
Ivan Avdeev c34c56e203 vk: add r_speeds_list_metrics command, with filter 2023-06-01 12:12:10 -07:00
Ivan Avdeev 3bbca26087 vk: fix disappearing sprites for traditional renderer 2023-06-01 11:42:23 -07:00
Ivan Avdeev 72acf4882d vk: orient sprites to camera
Somehow makes sprites correctly oriented (and winding-culled) for ray
tracing, but makes them disappear (winding-culled) for traditional
renderer. This makes zero sense.
2023-06-01 11:00:50 -07:00
Ivan Avdeev edb151bd1b rt: apply instanced texture overrides to rt_model; makes sprites apply correct textures 2023-06-01 10:15:30 -07:00
Ivan Avdeev 8f47115a01 rt: hide internal apis 2023-06-01 09:25:55 -07:00
Ivan Avdeev ed4d0070f8 vk: override sprite textures for quad instances
Applies correct sprite textures for traditional renderer. Doesn't apply
them to RT yet.
2023-05-31 11:00:28 -07:00
Ivan 'provod' Avdeev 32cb4f73be vk: fixup sprite size and color, also reorient it
Sprites are still not oriented properly though
2023-05-31 10:16:06 -07:00
Ivan 'provod' Avdeev dd8f06ae60 rt: recreate sprite model on every map
This is a workaround for inconsistent memory management: some subsystems completely clear their memories and start allocating from zero. This leads to overwriting long lived sprite model with garbage.

TODO FIXME
2023-05-31 10:15:27 -07:00
Ivan 'provod' Avdeev 8b50ebb035 rt: pass and assign rt_blas debug names 2023-05-31 10:13:40 -07:00
Ivan Avdeev e9ea962bc0 vk: begin refactoring rendermodel api, instantiate sprites, crash gpu 2023-05-31 09:39:27 -07:00
Ivan 'provod' Avdeev c157c9acfc rt: don't forget to add new blases to render list 2023-05-31 08:46:34 -07:00
Ivan Avdeev 0853f1c182 rt: start adding new rt_blas-based rt_model_t
Make brush models use it. Black screen, kekw. But not explicit error
messages. Need to investigate.
2023-05-30 12:14:44 -07: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
Ivan Avdeev 7ee16cd82f vk: track block/geom/brush lifetimes
Make sure that things get created and destroyed at the right times.
Allow longer-than-map block allocations.
Fix brush model leaks -- previously they weren't destroyed on map
change/game exit properly. Also free geometry ranges accordingly.

Add a note about map loading process, and various models lifetimes.
2023-05-26 10:45:44 -07: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
Ivan Avdeev d24961db15 vk: add block allocator draft
The intent is to manage long-vs-single-frame allocations better.
Previously long allocations were map-long bump allocations, and couldn't be freed
mid-map, as there was neither a reference to the allocated range, nor a
way to actully free it.

Add a two-mode block allocator (similar to previous debuffer alloc) that
allows making long and once allocations. But now long allocations are
backed by "pool" allocator and return references to the range.

This commit doesn't do the deallocation yet, so map chaning doesn't yet
work.
2023-05-25 12:12:18 -07: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
Ivan Avdeev 9200cbfc25 rt: step even closer to explicit blas+kusochki management
- stop tracking color/xform/mmode with vk_ray_model
- do not expose model to things that don't need to know
2023-05-22 11:02:40 -07:00
Ivan Avdeev 8724efd748 rt: massage vk_ray_model a bit
- explicitly group cache-related fields
- move kusochki allocation to where it's actually used

this makes a step towards better blas management from bottom up
2023-05-22 10:39:48 -07: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
Ivan Avdeev 322e7bc419 vk: recreate suboptimal swapchains with correct synchronization 2023-05-18 12:32:00 -07:00
Ivan Avdeev b5f79f3815 rt: DRY the accel creation code 2023-05-18 12:10:21 -07:00
Ivan Avdeev e55e411639 vk: add a couple of TODO comments 2023-05-18 12:00:58 -07:00
Ivan Avdeev b65f84793a rt: start refactoring blas/tlas mgmt code
Draft the new accel/blas apis. Consolidate everything accel-related into
vk_ray_accel.c. Start splitting into more atomic functions. Prepare for
blas-model+kusochki split. etc etc.

The new code isn't really used yet.
2023-05-18 11:59:14 -07:00
Ivan Avdeev 4af9f65cd0 vk: use better debug_break in validation errors callback
Allows us to continue in gdb
2023-05-18 11:58:00 -07:00
Ivan Avdeev 7060a86662 rt: propose rt_blas api 2023-05-17 11:28:09 -07:00
Ivan Avdeev 14a648d16c rt: prepare for blas mgmt refactoring
1. Rename models passed to TLAS to instances.
2. Remove BLAS validation: old, doesn't make sense anymore.
3. Draft general blas mgmt approach in NOTES.md
2023-05-17 10:42:18 -07: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
Ivan Avdeev 7d6c12218f vk: comment on why we need inverse model matrix 2023-05-15 09:47:03 -07:00
Ivan Avdeev e54913f8af rt: improve prev frame bone matrix tracking for studio models
Still has some artifacts, but is generally rather close. Will look at
this again when caching studio model BLASes, as we'd be able to look at
them without extra animations.
2023-05-15 09:47:03 -07:00
Ivan Avdeev 091c61a45f vk: make sure studio model vertices are local space
TODO:
- revert not applying rotationmatrix in local vk_studio code
- make sure that prev_frame stuff hasn't changed
2023-05-15 09:47:03 -07:00
Ivan Avdeev e49f517dc0 vk: don't apply studio model matrix to vertices 2023-05-15 09:47:03 -07: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
NightFox c91db96008 update patches 2023-05-05 15:12:28 -07:00
NightFox e86e16235c add rad files for cstrike 2023-05-05 15:12:28 -07:00
NightFox a2c6e3b444 Add cs_assault.rad 2023-05-05 15:12:28 -07:00
NightFox 596d35ddfa update rad files 2023-05-05 15:12:28 -07:00
NightFox b49dca536d Rename c1a3b.bsp.patch to c1a3b-dayone.bsp.patch 2023-05-05 15:12:28 -07:00
NightFox d2f45c53a0 Rename c1a3c.bsp.patch to c1a3c-dayone.bsp.patch 2023-05-05 15:12:28 -07:00
NightFox 48f9813edd update patches 2023-05-05 15:12:28 -07: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
Ivan Avdeev babfbb08ab vk: improve mvp matrix handling a bit 2023-05-04 11:10:22 -07:00
Ivan Avdeev 4f43b316a6 rt: material: print fauly lines on unknown keys 2023-05-04 11:10:22 -07:00
Ivan Avdeev 481aa651c6 vk: refactor passing m,v,p matrices around
View and projection now set only once in a logical place.
Model matrix is now closely associated with its model, and not stored as
a global state.
2023-05-04 11:10:22 -07:00
Ivan Avdeev 0b6ef9fd65 vk: remove a couple unused things from vk_render draw structs 2023-05-04 11:10:22 -07:00
Ivan 'provod' Avdeev 58433a2221 rt: only load textures for potentially usable materials
Skip loading textures for materials which are not going to be used.
2023-05-04 11:10:22 -07:00
Alibek Omarov 78e239d883 engine: soundlib: wav: attempt to make FindNextChunk more safe 2023-05-02 08:54:37 +03:00
Alibek Omarov 5a7b68fcc1 filesystem: add new export FS_GetFullDiskPath, similar to FS_GetDiskPath, but generates full path to the file, including searchpath 2023-05-02 08:52:54 +03:00
Alibek Omarov c33a384975 engine: client: s_vox: do not crash in VOX if sentence wasn't sound in sequences 2023-05-02 08:51:53 +03:00
Ivan Avdeev 2dcc5073aa ci: disable nswitch and psvita targets
We're not doing anything relevant to them in the vulkan branch, and
all they do is take extra time for CI to complete
2023-05-01 17:03:22 -07:00
Ivan Avdeev 528a715c76 ci: disable upload step as unnecessary for vulkan branch 2023-05-01 17:03:22 -07:00
Ivan Avdeev 3affb12574 ci: try re-enabling `build` dependency
Let's see whether that fixes constant failure in upload
2023-05-01 17:03:22 -07:00
Ivan 'provod' Avdeev 1cfb183cbd rt: extract per-model data from kusochki 2023-05-01 17:03:22 -07:00
Ivan Avdeev 0d8a7f76f5
Merge pull request #529 from w23/E260
- [x] Improves #528 a bit
- [x] Fixes #523 
  - [x] Fix ![image](https://user-images.githubusercontent.com/321361/235242886-bbae06cf-4375-4e11-bae0-8bc4e7644d59.png)
  - [ ] ~верни зеркало! ![image](https://user-images.githubusercontent.com/321361/235250971-6652e2b2-e531-4b41-b603-1c50306b7ea3.png)~
  - [x] test_brush2 лесенки пропали на растеризации
2023-05-01 10:45:31 -07:00
Ivan Avdeev 54d909b715 vk: make sure blending is the same as for gl for brush models
Essentially just copy R_SetRenderMode() logic to vk_brush
2023-05-01 10:27:30 -07:00
Ivan Avdeev 209bf1faa2
Merge pull request #525 from a1batross/vulkan
Sync with upstream

♥️ @a1batross
2023-04-30 21:46:38 -07:00
Alibek Omarov 5b582b744a engine: client: check if filesystem was initialized during client shutdown 2023-04-30 10:14:02 +03:00
Alibek Omarov c96f8ba722 engine: client: in_joy: do not create cvar on shutdown 2023-04-30 10:14:02 +03:00
Alibek Omarov 9f92e2a1f7 engine: client: console: do not save history if nothing was executed in console 2023-04-30 10:14:02 +03:00
Alibek Omarov 710b234493 engine: add new pretty --help output 2023-04-30 10:14:02 +03:00
Alibek Omarov 75759530e3 engine: remove doublecolons from MSGBOX macros 2023-04-30 10:14:02 +03:00
Alibek Omarov 5162ab62fd engine: filesystem: do not crash if engine was shutdown before filesystem was loaded 2023-04-30 10:14:02 +03:00
Alibek Omarov 3e2a215c15 engine: client: in_joy: rename -nojoy to -noenginejoy to avoid conflict with client.dll's joystick support 2023-04-30 10:14:02 +03:00
Alibek Omarov e2540bd446 filesystem: turn unused caseinsensitive argument in InitStdio into a reserved argument (set to true by default) 2023-04-30 10:14:02 +03:00
Alibek Omarov 07fd4f37ef engine: remove unused -caseinsensitive command line argument 2023-04-30 10:14:02 +03:00
Alibek Omarov 92b72a7d33 game_launch: add icons that were used for Android port 2023-04-30 00:56:28 +03:00
Alibek Omarov 6cc3832582 ci: fix incorrectly commented out build
Co-authored-by: Ivan Avdeev <lists@provod.works>
2023-04-29 22:58:03 +03:00
Alibek Omarov 12dbfb467a ref: vk: studio: port optimized R_LightLambert function 2023-04-29 22:57:02 +03:00
Ivan Avdeev b93ef2e52c vk: fix freeing NULL bmodel memory 2023-04-28 13:29:02 -07:00
Ivan 'provod' Avdeev e1d250e8da vk: split geometries into static and animated
Load geometries only once, and then update only those which have animated textures.

Fixes #523
2023-04-28 12:35:48 -07:00
Ivan 'provod' Avdeev f722f38617 vk: infotool: mark ent index as dynamic 2023-04-28 11:31:41 -07:00
Ivan 'provod' Avdeev 52f99ec329 rt: only upload kusochki when needed
- Once at load
- When color/mode/prevxform changed

Breaks animated textures.
#523
2023-04-28 11:19:57 -07:00
Ivan Avdeev b17c00654b vk: silence a couple NOT IMPLEMENTED messages
- We're not going to implement R_ShowTextures for ref_vk, at least in
  its gl form.
- It seems that Mod_GetCurrentVis() can just return NULL, at least
  ref_soft does it.

Fixes #269, fixes #254
2023-04-28 10:32:01 -07:00
Ivan Avdeev 3447dfc5d6 rt: linearize alpha value for blending
This makes transparent brushes look more correct. But also makes sprites
look a bit dull.

Fixes #528
2023-04-28 10:12:15 -07:00
Alibek Omarov 62590dd2a9 ref: vk: use safe string functions, as unsafe versions were removed from libpublic 2023-04-28 17:43:50 +03:00
Alibek Omarov e5e2a63ba2 ref: vk: fix matrix4x4_identity to m_matrix4x4_identity which conflicts in Vita port 2023-04-28 17:43:01 +03:00
Alibek Omarov a117338435 ref: vk: port to RefAPI 4 2023-04-28 17:34:05 +03:00
Alibek Omarov d75dcd358e public: restore unused, removed in upstream Matrix4x4_SetOrigin. Actually used in Vulkan fork 2023-04-28 17:33:23 +03:00
Alibek Omarov c4757058e1 Merge upstream master 2023-04-28 17:15:31 +03:00
Alibek Omarov cb3b16e2ec engine: client: implement v_dark in engine, instead of making it ref-specific 2023-04-28 16:52:22 +03:00
Alibek Omarov bd3dc71f39 engine: server: refactor banid, explicitly does not allow ban using userid for now 2023-04-28 16:24:41 +03:00
Ivan Avdeev 8ac1a76259 rt: rename traceAdditive to traceSimpleBlending
This is to more clearly distinguish between simple blended things that
don't participate in lighting, and future more involved blending with
refraction and being affected by light
2023-04-27 10:59:38 -07:00
Ivan Avdeev 847777fb6b rt: do not forget to clear scratch buffer before loading new map
Fixes rare random crashes when loading maps with many models in it.
2023-04-27 10:59:38 -07:00
Ivan Avdeev 0b8b5b571b rt: sort transparent geometry ray hits
Limit to 8 layer for now. Seems to be working just fine.
VGPR usage and performance impact will be checked later.
2023-04-27 10:59:38 -07:00
Ivan Avdeev b79a65f8a1 rt: fixup incorrect oit application
Still doesn't work for us, as we also have purely emissive/additive
polygons. wOIT doesn't seem to support that fundamentally, each surface
should still attenuate the background.

Didn't even get to the _weighted_ part of it because of that.
2023-04-27 10:59:38 -07:00
Ivan Avdeev 449bcc4db9 rt: fixup blending emissive in background 2023-04-27 10:59:38 -07:00
Ivan Avdeev ae510dd3ff rt: use kusok.model.color
Fixes blending differences in test_brush/test_sprite maps. They now look
fairly similar (modulo color correction).

OIT is still a bit off, but good enough for now
2023-04-27 10:59:38 -07:00
Ivan 'provod' Avdeev d6a41bc041 rt: try weighted oit
Known issues:
- test_brush blend modes are broken
- emissive does not participate in weighted oit properly
2023-04-27 10:59:38 -07:00
Ivan 'provod' Avdeev d576818550 rt: implement mix blending with undefined order
Known issues:
- apparently BLEND_MIX surfaces should also participate in lighting. Figure out how.
- sensitive to ray tracing order. Need proper OIT (or hacks)
2023-04-27 10:59:38 -07:00
Ivan 'provod' Avdeev 3800d6559e rt: restore glow
This required uploaded kusochki only later during frame time, just before rendering the model. Otherwise they would get incorrect rendermode.

Also add blend mode debug colors.
2023-04-27 10:59:38 -07:00
Ivan 'provod' Avdeev 1ebc1d207c rt: commoditize setting material mode
Known issues:
- Breaks sprite glow for some reason.
2023-04-27 10:59:38 -07:00
Ivan 'provod' Avdeev 5b370509fe rt: group Material and ModelMetadata in Kusok
They have mismatching frequencies. ModelMetadata should be per-Model, there should be only a few dozen of these.
There maybe hundreds (or even thousands) of materials, but one material can be still referenced by many kusochki.

This only moves fields into new structs, which still belong to Kusok. The real extraction will happen later, see #52.
2023-04-27 10:59:38 -07:00
Alibek Omarov 48176233bd public: move FOV calculating functions out of libpublic, as they are very specific to engine view 2023-04-26 05:22:34 +03:00
Alibek Omarov a292d2fd53 platform: win32: replace Q_sprintf calls by Q_snprintf 2023-04-26 05:20:45 +03:00
Alibek Omarov 27aad9f4a0 ref: gl: add size argument to COM_Default/ReplaceExtension calls 2023-04-26 05:20:45 +03:00
Alibek Omarov 71a3cedba8 filesystem: add size argument to COM_Default/ReplaceExtension calls 2023-04-26 05:20:45 +03:00
Alibek Omarov ec2951cf45 engine: add size argument to COM_Default/ReplaceExtension calls 2023-04-26 05:20:45 +03:00
Alibek Omarov ff436ae100 public: crtlib: add safe COM_DefaultExtension and COM_ReplaceExtension 2023-04-26 05:20:45 +03:00
Alibek Omarov cfdfdd5c93 utils: mdldec: add size argument to COM_FileBase calls 2023-04-26 05:20:45 +03:00
Alibek Omarov 8b96e7ca87 ref: add size argument to COM_FileBase calls 2023-04-26 05:20:45 +03:00
Alibek Omarov 1603b8028c filesystem: add size argument to COM_FileBase calls 2023-04-26 05:20:45 +03:00
Alibek Omarov 8c7db8499f engine: add size argument to COM_FileBase calls 2023-04-26 05:20:45 +03:00
Alibek Omarov fbdd79644b public: test new COM_FileBase and compare it's results with old implementation (embedded into test itself) 2023-04-26 05:20:45 +03:00
Alibek Omarov ac39090f6e public: crtlib: add safe COM_FileBase implementation 2023-04-26 05:20:45 +03:00
Alibek Omarov 8f207362a5 public: remove Q_sprintf, and patch all code that used it to use Q_snprintf instead 2023-04-26 05:20:45 +03:00
Alibek Omarov b16fa8eddc public: remove Q_strcat and Q_strcpy, and patch the code that uses it 2023-04-26 05:20:45 +03:00
Alibek Omarov 2261b0dcab scripts: gha: set --disable-werror for building HLSDK 2023-04-25 13:10:12 +03:00
Alibek Omarov 9eb49fc673 scripts: gha: win32: finally use destdir instead of prefix on Windows 2023-04-25 13:05:34 +03:00
Alibek Omarov c61c84ad4f Revert "wscript: check malloc.h first to make checks on Windows slightly faster"
This reverts commit 1464e1e2be.
2023-04-25 12:39:47 +03:00
Alibek Omarov 71c9fd2772 wscript: do not check for --prefix without --enable-packaging, as it's still valid to use 2023-04-25 03:01:35 +03:00
Alibek Omarov 1464e1e2be wscript: check malloc.h first to make checks on Windows slightly faster 2023-04-25 02:39:07 +03:00
Alibek Omarov cf557d191a wscript: make prefix vs destdir installing more safe and predictable 2023-04-25 02:38:36 +03:00
Alibek Omarov b72033eb74 engine: client: fix master server query through NetAPI 2023-04-23 22:05:11 +03:00
Alibek Omarov cec903fd10 mainui: update 2023-04-23 18:44:17 +03:00
Alibek Omarov b333edeefe public: crtlib: remove unused Q_strlwr macro 2023-04-23 18:31:08 +03:00
Alibek Omarov 76c7273600 utils: mdldec: remove usage of string functions with unspecified size 2023-04-23 18:30:44 +03:00
Alibek Omarov 096ee34f67 public: remove Q_vsprintf, replace by proper Q_vsnprintf proper calls
Fixes weird off by one error caused by glibc updates? I didn't tracked
what causes it exactly but replacing it seems to work. Anyway, we should
remove all 99999 hacks in libpublic.
2023-04-23 18:19:28 +03:00
Ivan Avdeev aab689a37b ci: temporarily disable the nswitch target
It started failing suddenly w/o any changes on our part. It is irrelevant for this fork, so disable it for now.
2023-04-22 13:45:25 -07:00
Ivan Avdeev 935c2e7f5e rt: remove a bunch of extra material flags
These are either unused, or their meaning can be recovered through other
means.
2023-04-21 23:34:27 -07:00
Ivan Avdeev 41b033efbd vk: comment various material-related things
This is in preparation for #460
2023-04-21 23:34:27 -07:00
Alibek Omarov 5b52a9a19f engine: protocol: increase MAX_LIGHTSTYLES from 64 to 256, protocol limit as it encoded as unsigned byte 2023-04-20 10:35:21 +03:00
Ivan Avdeev e9f15edbd5 vk: fix refercing func_wall ents by indexes; only model names work 2023-04-19 20:25:00 -07:00
Ivan Avdeev d7660cf358 vk: patch func_wall ents by their index, not model name
Note that referencing them by ent->index inside the engine is not
possible, as this index is not stable enough.
2023-04-19 20:25:00 -07:00
Ivan Avdeev ca2a794341 vk: patch func_wall model/ents visible offsets
Fixes #335

Patching is still done using "model" key, using "_xvk_ent_id" needs
complete overhaul of how patching is done
2023-04-19 20:25:00 -07:00
Ivan Avdeev 7c6e22bb2c rt: extract basic func_wall patching support from PR #506
That PR has more stuff in it which we decided to drop.

This commit only contains:
- Detection of func_wall models, and adding their lights as static
  (fixes #415).
- Patching func_wall models offsets, #335. Does not yet patch them
  visually, but patches their light sources. Will be addressed in next
  commits. Patching is done via model name, not entity id, also will be
  fixed.
- Does not address culling (#118). This is the part dropped from the PR.
  Needs different approach. TBD
2023-04-19 20:25:00 -07:00
Alibek Omarov cacfff008f engine: common: enable autocomplete for mp3 command 2023-04-19 17:54:45 +03:00
Alibek Omarov 398cec626e engine: client: remove media/ prefix for CD tracks, add it while parsing cdaudio.txt for compatibility 2023-04-19 17:54:28 +03:00
Alibek Omarov cadad6ce34 github: attempt to avoid release draft issue by sleeping for 20s 2023-04-19 16:32:21 +03:00
Alibek Omarov 588d080a63 github: migrate to softprops/action-gh-release to avoid drafts being randomly created (thanks @SNMetamorph) 2023-04-19 15:05:41 +03:00
Alibek Omarov 1affc36f06 engine: client: more accurate ScreenShake implementation, thanks @vasiavasiavasia95 for sharing it 2023-04-18 17:28:27 +03:00
Alibek Omarov 8d6ac3fad4 engine: common: net_encode: cosmetic changes, static-ize functions, move private macros 2023-04-18 05:16:57 +03:00
Alibek Omarov 0d5d30398b filesystem: VFileSystem009: refactoring 2023-04-18 04:50:47 +03:00
Alibek Omarov eb0686fca1 filesystem: fix wrong data type for character in Gets and Ungetc 2023-04-18 04:47:55 +03:00
Alibek Omarov 41025c0049 engine: client: reset connection retries counter on changelevel
Fixes an issue when connection retry counter near the failure state
and the server changes level
2023-04-18 04:45:27 +03:00
Tim Schumacher 6518a5cf8b engine: whereami: Add SerenityOS 2023-04-17 19:30:11 +03:00
Alibek Omarov 49936120ca public: tests: add new test to check return values of Q_Architecture/PlatformStringByID and Q_buildnum 2023-04-17 19:11:16 +03:00
Alibek Omarov e4a5b95e81 public: build: split Q_buildnum to separate function that calculates build number from arbitrary date string 2023-04-17 19:10:40 +03:00
Alibek Omarov 84fc8d4281 public: build: fix naming for 32-bit RISCV with double precision float ABI 2023-04-17 19:09:59 +03:00
Alibek Omarov e9da3e2976 public: build: reorder enums by probability, rename ARCHITECTURE_ ABI macros to just ARCH_ for easier matching 2023-04-17 06:37:08 +03:00
Alibek Omarov c1252b5642 scripts: waifulib: vgui: fix Logs aren't being imported 2023-04-17 06:36:58 +03:00
Alibek Omarov 7d54952422 3rdparty: vgui_support: update submodule 2023-04-17 05:22:02 +03:00
Alibek Omarov b28d10f69f scripts: waifulib: split vgui_support VGUI detection to separate module 2023-04-17 05:20:22 +03:00
Alibek Omarov 6cb3b2f01a wscript: print modules help before engine common options 2023-04-17 05:19:56 +03:00
Alibek Omarov 248be5458f engine: common: hpak: do not print hashpak contents in quiet mode 2023-04-17 04:39:21 +03:00
Alibek Omarov 2e7306e96a engine: network: fix missing newline in IP port allocation error message 2023-04-17 04:37:16 +03:00
Ivan Avdeev cfddb75bc5
rt: remove freeze_models functionality (#513)
It's been obsolete and broken for many months now.

Fixes #509
2023-04-15 10:51:34 -07:00
Ivan Avdeev b4dde5bafd
rt: don't cull c/cw triangles to fix shadow leaks (#508)
de_cbble contains a bunch of floating boxes, which makes sunlight leak if internal back-facing surfaces are culled.

Generally, we should not be culling ray traced triangles (unless absolutely necessary for correctness), as it makes the shader perform additional unnecessary checks.

Try disabling culling universally and see whether it breaks anything.

Fixes #507
2023-04-15 09:44:04 -07:00
Alibek Omarov 558ded6d6a filesystem: tests: interface: use correct type for module on Win32 2023-04-15 04:58:29 +03:00
Alibek Omarov c52dc69360 scripts: gha, cirrus: fix failing workflows because of --enable-fs-tests flag removal 2023-04-15 04:24:45 +03:00
Alibek Omarov ba1648c689 mainui: update 2023-04-15 04:19:14 +03:00
Alibek Omarov 101a7a1240 engine: client: try to fix random crash in CL_ClearWorld when using legacy protocol 2023-04-15 04:08:40 +03:00
Alibek Omarov 25d6b2b069 engine: client: fix FlushEntityPacket message overflow on legacy servers 2023-04-15 04:08:40 +03:00
Alibek Omarov f67b97e63c engine: common: mod_bmodel: remove useless copy before Q_strnlwr, as Q_strnlwr already copies string 2023-04-15 04:08:40 +03:00
Alibek Omarov 9a24cb8c96 engine: client: console: remove useless function Con_StringLength 2023-04-15 04:08:40 +03:00
Alibek Omarov c157b7def3 filesystem: tests: interface: various fixes
* correctly check success variable value in CreateInterface
* get rid of C language quirks because this file is C++
* check that globals were filled
2023-04-15 04:08:12 +03:00
Alibek Omarov de88aec958 filesystem: restore DarkPlaces contributors copyrights lost in filesystem_stdio
* Add Xash3D FWGS contributors copyrights
2023-04-15 02:39:38 +03:00
Alibek Omarov 7f31871b5a engine: common: zone: restore Id Software and Darkplaces copyrights, add Xash3D FWGS copyrights 2023-04-15 02:39:16 +03:00
Alibek Omarov f55ef63e26 ref: optimize R_LightLambert function
* Quick exit if no local lights
* Try to minimize Q_min() checks by apply it on temp variables
* Cap final light values only once, after all local lights are calculated
2023-04-14 20:33:07 +03:00
Ivan Avdeev 2dd4059704 vk: fix func_wall surface patching
Non-worldmodel models were using incorrect surface indexes when asking
for surface patches.
2023-04-14 10:08:40 -07:00
Alibek Omarov 824a34ee1e engine: common: imgelib: fix declaration after statement in test code 2023-04-14 18:58:43 +03:00
Ivan Avdeev b894337d0e vk: fix validation errors for empty combufs 2023-04-13 11:03:36 -07:00
Ivan Avdeev 1b0c8c763e vk: slightly improve texcoord patching
Now _xvk_tex_offset and _xvk_tex_scale can be used independently to
offset or scale texture coordinates for given surface list.
2023-04-13 11:03:36 -07:00
Ivan Avdeev b5e5d699bc vk: deduplicate map (re)loading code 2023-04-13 11:03:36 -07:00
Ivan Avdeev b3ffd911bb vk: allow dynamic surface/material patching
Refactor NewMap and patch loading a bit.
2023-04-13 11:03:36 -07:00
Alibek Omarov 46e2ccd2bf filesystem: wscript: check interface test before everything else
It makes sense since we're using sequential execution here anyway
2023-04-13 20:07:58 +03:00
Alibek Omarov 339c08d89f public: add basic test for our strcpy, strcmp and strcat functions 2023-04-13 19:56:31 +03:00
Alibek Omarov 2db2375b4d waifu: upgrade to latest revision 2023-04-13 18:43:08 +03:00
Alibek Omarov d86ab19351 wscript: refactoring, replace --enable-fs-tests with --enable-tests
* Run filesystem tests in sequential order, to avoid tests being run
before filesystem_stdio DLL is linked
* Include new interface test in filesystem
2023-04-13 18:40:27 +03:00
Alibek Omarov db40d58208 filesystem: add test for probing all interfaces 2023-04-13 18:39:21 +03:00
Alibek Omarov 33ff7bbd61 scripts: waifulib: compiler_optimizations: set default build type to release
I think this will make configuration less confusing, also we're stable enough to be built
with optimizations and without debug information
2023-04-13 16:14:09 +03:00
Ivan Avdeev 90591cfb3d vk: add patching props for surface texture coordinates 2023-04-12 11:57:07 -07:00
Ivan Avdeev 1fd9e49f63 vk: add normal_scale to materials 2023-04-12 11:57:07 -07:00
Ivan Avdeev 9116b0268e vk: scale metalness/roughness textures by m/r values in material
fixes #342
2023-04-12 11:57:07 -07:00
Ivan Avdeev 51318fc77f vk: read alpha for material base_color, fixes #308 2023-04-12 11:57:07 -07:00
Alibek Omarov 4d4162336a engine: common: mod_bmodel: apply code style fixes to match existing code, for consistency 2023-04-11 03:11:23 +03:00
Jonathan Poncelet 372514151d engine: common: mod_bmodel: Fixed default texture name check
REF_DEFAULT_TEXTURE defines the canonical name, so is used
instead of a string literal.
2023-04-11 01:41:20 +03:00
Jonathan Poncelet 6c9ce478a9 engine: common: mod_bmodel: Fixed Con_Printf warnings
Some formatting characters did not match up with their
values.
2023-04-11 01:41:20 +03:00
Jonathan Poncelet 78555ab125 engine: common: mod_bmodel: Tidied texture loading procedure 2023-04-11 01:41:20 +03:00
Ivan Avdeev 139807a559 vk: profiler: add device/driver info 2023-04-10 12:05:35 -07:00
Ivan Avdeev c917c7a818 vk: profiler: move graphs a bit lower 2023-04-10 10:24:57 -07:00
Ivan Avdeev 93153dd87e vk: profiler: tame the gpu scopes ladder 2023-04-10 10:24:57 -07:00
Ivan Avdeev 084874c5c8 vk: profiler: add gpu scopes for staging uploads 2023-04-10 10:24:57 -07:00
Ivan Avdeev a38f990ef5 vk: attempt to fix 32 bit build 2023-04-10 10:24:57 -07:00
Ivan 'provod' Avdeev fdab0f7536 vk: fix windows compilation 2023-04-10 10:24:57 -07:00
Ivan Avdeev 92ce698292 vk: profiler: cover staging with combuf scopes; add build_as time 2023-04-10 10:24:57 -07:00
Ivan Avdeev f6201e460f vk: profiler: register gpu scopes as metrics for graph purposes 2023-04-10 10:24:57 -07:00
Ivan Avdeev 6d43e02dd3 vk: profiler: draw internal gpu side frame structure 2023-04-10 10:24:57 -07:00
Ivan Avdeev 1bf6f6ee74 vk: profiler: extract gpu timestamps in a generic manner 2023-04-10 10:24:57 -07:00
Ivan Avdeev 73a6cf596a vk: init combuf
it does just work lol
2023-04-10 10:24:57 -07:00
Ivan Avdeev 4bd62ccbc0 [draft] vk: start refactoring commandbuffer/gpu profiler
Consolidate VkCommandBuffer management into a single entity. (somewhat
done for framectl, not done for staging)

Make sure that we pass enough metadata to be able to timestamp scopes in
cmdbuf.

It does compile, but it won't work: not all init code paths are used.
Also, there are many changes, so other failure modes are totally
possible.
2023-04-10 10:24:57 -07:00
Andrey Akhmichin f2c671d809 utils: mdldec: Fix typo. 2023-04-10 01:03:52 +03:00
Alibek Omarov 4bce193645 mainui: update 2023-04-03 06:45:05 +03:00
Alibek Omarov 129de871e3 engine: common: hpak: use statically allocated hpk_maxsize cvar because gamedll can re-register it for some reason 2023-04-03 06:22:55 +03:00
Alibek Omarov c24a1fafc5 engine: add missing HPAK_CheckSize/Integrity calls 2023-04-03 06:04:48 +03:00
Alibek Omarov cee3757e6f engine: common: hpak: add hpak deletion in validate function 2023-04-03 06:04:18 +03:00
Alibek Omarov 12ed092446 engine: client: register VGui surface cvars 2023-04-03 06:03:29 +03:00
Alibek Omarov 2fb19a0cfd public: matrixlib: cleanup unused functions 2023-04-03 05:14:59 +03:00
Alibek Omarov 79624fa400 ref: gl: cleanup unused functions 2023-04-03 05:09:33 +03:00
Alibek Omarov 550ced9c36 ref: gl: cleanup unused functions in frustum 2023-04-03 05:05:32 +03:00
Alibek Omarov fd795d5612 ref: soft: cleanup unused functions 2023-04-03 04:57:41 +03:00
Alibek Omarov dc0982932b engine: common: sequence: static-ize private functions 2023-04-03 04:33:19 +03:00
Alibek Omarov 5d387101b9 engine: client: remove unused Key_IsBind 2023-04-03 04:33:19 +03:00
Alibek Omarov eef1e1868a engine: common: remove unused BaseCmd_Replace 2023-04-03 04:33:19 +03:00
Alibek Omarov 4005ef831a engine: common: remove unused IsBackgroundMap/Demo calls, remove unused gamma function 2023-04-03 04:33:19 +03:00
Alibek Omarov b0c71c598f engine: common: remove unused Mod_AmbientLevels 2023-04-03 04:33:19 +03:00
Alibek Omarov d7848b7b8d engine: client: efx: remove unused CL_FreeParticle 2023-04-03 04:33:19 +03:00
Alibek Omarov 9cdce1ce69 engine: network: remove unused MSG_Read/WriteBitFloat 2023-04-03 04:17:54 +03:00
Alibek Omarov 84edd9d0c4 engine: client: use ReadVec3Angles in svc_setangle, as server uses WriteVec3Angles 2023-04-03 04:17:02 +03:00
Alibek Omarov d8355a651f engine: add missing Sequence_Init and Sequence_OnLevelLoad calls 2023-04-03 04:12:47 +03:00
Alibek Omarov 004ac8105e engine: common: identification: static-ize all functions 2023-04-03 04:04:25 +03:00
Alibek Omarov 2e8ab13242 engine: client: fix parsing svc_spawnentity on old protocol 2023-04-03 03:56:31 +03:00
Alibek Omarov 27d9fc0afe engine: client: sound: remove unused functions 2023-04-03 03:55:57 +03:00
Alibek Omarov 192d510924 engine: client: remove unused function CL_FreeEntity and everything that used it 2023-04-03 03:55:57 +03:00
Alibek Omarov 3614cfa878 engine: client: avi: remove unused function 2023-04-03 03:55:57 +03:00
Alibek Omarov 12efcf1c44 engine: network: remove some totally ununsed functions 2023-04-03 03:13:50 +03:00
Alibek Omarov a8de11643c engine: platform: sdl: make GL_CreateContext and GL_DeleteContext functions static 2023-04-03 03:13:33 +03:00
Alibek Omarov 597027277c engine: server: remove some totally unused functions 2023-04-03 03:12:52 +03:00
Alibek Omarov 48988e66bd engine: client: fix missing HTTP_ResetProcessState call 2023-04-03 03:11:39 +03:00
Alibek Omarov 37e3cf7e86 public: crtlib: remove unused functions 2023-04-03 02:46:23 +03:00
Alibek Omarov 01e0542223 engine: server: move master announce logic to masterlist, keep unique heartbeat challenge and heartbeat timer for each master 2023-04-03 00:57:47 +03:00
Alibek Omarov 93a7ccd14f engine: network: add net_gai_state_t enum for NET_StringToAdrNB result value 2023-04-03 00:15:35 +03:00
Alibek Omarov 892e5c59eb engine: server: convert public_server cvar to static allocation 2023-04-02 22:48:47 +03:00
Alibek Omarov c2992afb4a engine: network: make all HTTP commands and cvars restricted, except http_addcustomserver. Also zero http_useragent by default (it's autogenerated now) 2023-03-31 01:22:41 +03:00
Alibek Omarov b99e7a6304 engine: network: include build info to default HTTP useragent 2023-03-31 01:16:17 +03:00
Alibek Omarov 8888b456df engine: client: cl_tent: rewrite R_Sprite_Explode to be closer to original function but support Xash extensions 2023-03-30 04:42:48 +03:00
Alibek Omarov 53987f47e2 engine: client: use alternative ease-in ease-out function in sound fade 2023-03-30 04:40:54 +03:00
Ivan Avdeev 5c7bd9d285 vk: profiler: add low/hi watermarks for frame time graph 2023-03-29 11:59:22 -07:00
Ivan Avdeev cea37acfd2 vk: profiler: add width, and other improvements
- r_speeds_graphs_width now can be used to limit graphs width
- tweak layout slightly
- improve range printing based on metric semantic
2023-03-29 11:59:22 -07:00
Ivan 'provod' Avdeev b5dfef5574 vk: profiler: scale graphs properly
respect dpi scale
2023-03-29 11:59:22 -07:00
Ivan Avdeev adab64b797 vk: profiler: make graphs thin, add background 2023-03-29 11:59:22 -07:00
Ivan Avdeev 33aa4bc259 vk: profiler: add cvar for selecting metrics to plot
also:
- invert graphs
- add text labels
- fix vertical gaps
2023-03-29 11:59:22 -07:00
Ivan Avdeev af96609c04 vk: profiler: automatic graph range 2023-03-29 11:59:22 -07:00
Ivan Avdeev 2b2e69da72 vk: profiler: start implementing universal metric graphs 2023-03-29 11:59:22 -07:00
Alibek Omarov 7cac1d290d scripts: gha: it's pretty safe to not do clean on Waf, since it's much better at tracking modified files 2023-03-29 00:22:47 +03:00
Alibek Omarov 55b048aab9 github: enable nswitch and psvita CI builds back, test if continuous tag gets correctly deleted 2023-03-29 00:05:40 +03:00
Alibek Omarov 881a7edb9f github: try to fix uploading release again 2023-03-28 23:54:49 +03:00
Alibek Omarov 6c62136f11 engine: client: avi: convert filename to wide characters before passing it into VFW API 2023-03-28 22:42:16 +03:00
Alibek Omarov f34b35be5a engine: client: avi: re-attribute AVI support code by restoring original author copyright 2023-03-28 22:42:16 +03:00
Alibek Omarov 4b5ee87de1 engine: client: adapt to RefAPI 4 changes. Fix interpolation issue after reloading a save 2023-03-28 21:34:51 +03:00
Alibek Omarov 67903b55cc ref: soft: adapt to RefAPI 4 changes 2023-03-28 21:34:43 +03:00
Alibek Omarov 55bf0e8a53 ref: gl: adapt to RefAPI 4 changes 2023-03-28 20:45:26 +03:00
Alibek Omarov f1487cf576 engine: ref_api: bump RefAPI version to 4, R_StudioEstimateFrame now has time argument 2023-03-28 20:42:18 +03:00
Alibek Omarov 29e32310cf github: update linux builds to ubuntu-20.04 2023-03-28 20:08:42 +03:00
Alibek Omarov 2ea549f250 github: update upload-release-action to 2.5.0, print outputs in repackage binaries step 2023-03-28 19:49:35 +03:00
SNMetamorph b2ea8c9d18 engine: platform: win32: enabled attaching to existing console instead of creating new 2023-03-27 20:31:52 +03:00
Alibek Omarov 6e27926a10 engine: simplify XASH_USE_EVDEV macro usage by giving it's defined positive value 2023-03-27 17:28:19 +03:00
Alibek Omarov 96c30371b7 engine: client: better specify rawinput enabling condition on Win32 2023-03-27 17:22:48 +03:00
Alibek Omarov 9a42f4149f engine: client: disable enabling mouse cursor in key_message (typing in chat) 2023-03-27 17:22:48 +03:00
Alibek Omarov dca4226e4b github: re-use PrimeXT's actions to upload artifacts to GitHub Releases 2023-03-27 06:01:19 +03:00
Alibek Omarov b3c1c173a9 scripts: gha: exit if we can't move to a specified directory 2023-03-27 04:30:21 +03:00
Alibek Omarov 3e67445ef3 scripts: gha: psvita: fix building HLSDK, exit if we can't move to a directory 2023-03-27 04:27:55 +03:00
Alibek Omarov 127bd89b44 filesystem: remove unused watch.c file, added by mistake from inotify branch 2023-03-27 03:56:57 +03:00
SNMetamorph 3361e74f54 engine: client: console: fixed console scrolling on psvita platform 2023-03-27 03:52:51 +03:00
SNMetamorph 48e199bfa1 engine: common: enabled printing logs to stderr for psvita platform only in developer mode 2023-03-27 03:52:51 +03:00
SNMetamorph 575179dbf5 engine: client: added default dead zone values for psvita platform 2023-03-27 03:52:51 +03:00
SNMetamorph e024a67436 engine: platform: psvita: fixed vrtld error reporting 2023-03-27 03:52:51 +03:00
SNMetamorph e3103249f4 engine: platform: psvita: added developer mode button to launcher 2023-03-27 03:52:51 +03:00
SNMetamorph 0746cb5365 engine: platform: psvita: disabled back touch sensor 2023-03-27 03:52:51 +03:00
Alibek Omarov fcda7517fe engine: common: soundlib: add support for MP3 looping through custom ID3v2.4.0 tagging 2023-03-27 03:51:42 +03:00
Alibek Omarov 2c77f4c566 engine: client: notify client.dll about local player in firstplayer mode for use in custom renderers 2023-03-27 03:47:42 +03:00
Ivan Avdeev 8afd23a2d4 vk: profiler: clear metrics explicitly 2023-03-25 12:03:41 -07:00
Ivan Avdeev 1ae3ae4774 vk: profiler: register scopes and cpu/frame/gpu times as metrics
Make all the numbers we show as universal metrics
2023-03-25 12:03:41 -07:00
Ivan Avdeev 89f49276a5 vk: profiler: add beams count metric 2023-03-25 12:03:41 -07:00
Ivan Avdeev 68761fbbbb vk: profiler: add sprites count metric 2023-03-25 12:03:41 -07:00
Ivan Avdeev 2976f753e1 vk: profiler: add more lights metrics 2023-03-25 12:03:41 -07:00
Ivan Avdeev 2db83a22a5 vk: profiler: add studio models count metric 2023-03-25 12:03:41 -07:00
Ivan Avdeev f2ebcd663b vk: profiler: explicit metric types; also more metrics 2023-03-25 12:03:41 -07:00
Ivan Avdeev 8ecfae5bf0 vk: profiler: simplify metric registration 2023-03-25 12:03:41 -07:00
Ivan Avdeev cdc2a1258a vk: profiler: add staging stats 2023-03-25 12:03:41 -07:00
Ivan Avdeev 3b47c7315a vk: profiler: add dynamic model count 2023-03-25 12:03:41 -07:00
Ivan Avdeev 160a69d2cc vk: profiler: add BLAS stats 2023-03-25 12:03:41 -07:00
Ivan Avdeev e0e9305628 vk: profiler: add a way to add arbitrary metrics to profiler 2023-03-25 12:03:41 -07:00
Ivan Avdeev 576b4163b9 vk: profiler: rename slows to speeds (enough kekage) 2023-03-25 12:03:41 -07:00
Alibek Omarov 1caa276531 engine: common: imagelib: fix loading cubemaps
Loop break was a bug that was added after refactoring imagelib loader.

In fact, it was mindlessly copypasted from old code, where same break was
used to quickly exit from inner format bruteforcing loop, than outer cubemap
loading loop.
2023-03-25 07:02:29 +03:00
Alibek Omarov e673fe9a02 filesystem: only create readwrite directories if they look like a gamedirectory in rodir 2023-03-25 03:27:32 +03:00
Ivan 'provod' Avdeev 5f38f3467d rt: originate ray on the near plane
fixes #63

also, compute max distance based on the far plane distance
2023-03-24 14:04:30 -07:00
Alibek Omarov 3ccbc7a28c engine: client: ref_common: r_refdll is not a VIDRESTART cvar 2023-03-24 18:03:06 +03:00
Alibek Omarov 8bb5ec5e26 ref: remove renderer description export, it's unused now 2023-03-24 02:54:14 +03:00
Alibek Omarov 35ff062407 wscript: restore NSwitch and PSVita specific link and compiler flags 2023-03-24 02:28:25 +03:00
Alibek Omarov ec355a83d1 engine: client: ref_common: eliminate COM_FreeLibrary in renderer names query, hardcoding them instead 2023-03-24 01:52:14 +03:00
Alibek Omarov 182d8edb42 engine: wscript: define enabled renderers as macros 2023-03-24 01:50:53 +03:00
Alibek Omarov 762e4da7a0 wscript: generic refactoring
* Add RefDll class to aid in enabling renderers, creating help options, etc
* Fix optimization flags and werrors are being added twice
* Rewrite if not win32: if elif elif into a set of elifs
* Remove mandatory=True in checks, as it's a default option
2023-03-24 01:50:21 +03:00
Ivan 'provod' Avdeev 4a5fc186ea vk: profiler: fixup incorrect __FUNCTION__ macro usage
No idea how it could work before
2023-03-21 11:59:57 -07:00
Ivan Avdeev e1afb2a9de vk: profiler: collect and display ref cpu busy and waiting times 2023-03-21 11:59:57 -07:00
Ivan Avdeev 5d23494cfc vk: profiler: use existing R_SpeedsMessage to display profiling data 2023-03-21 11:59:57 -07:00
Ivan Avdeev 9d8ec1bc9d vk: profiler: control profiler with r_speeds command
use bits to enable particular performance data display:
0 -- off
1 -- simple frame time
2 -- more object count and sizes statistics (TODO)
4 -- overall gpu usage (TODO)
8 -- extended intra-frame data, function times graph, etc
2023-03-21 11:59:57 -07:00
Ivan Avdeev 55af70c422 vk: profiler: remove noisy printf 2023-03-21 11:59:57 -07:00
Ivan Avdeev bcb1d367b9 vk: profiler: refactor plotting functions slightly 2023-03-21 11:59:57 -07:00
Ivan Avdeev 2b8f74ff0e vk: profiler: minor cleanup 2023-03-21 11:59:57 -07:00
Ivan 'provod' Avdeev b4b63492f2 vk: profiler: fixup time scaling on windows 2023-03-21 11:59:57 -07:00
Ivan Avdeev 22d4202ad9 vk: profiler: draw total gpu time
Use VK_EXT_calibrated_timestamps to convert to host time.
2023-03-21 11:59:57 -07:00
Ivan Avdeev a66c44a266 vk: convert query timestamps to ns
also, fix linux build
2023-03-21 11:59:57 -07:00
Ivan 'provod' Avdeev 93a539df74 vk: display gpu time taken for a previous frame
its value will be incorrect for non-nv cards which have non-1 timestampPeriod
2023-03-21 11:59:57 -07:00
Ivan 'provod' Avdeev be95b65b22 vk: add better scope macro for profiler
also cover synchrnoized slow uploading for staging
2023-03-21 11:59:57 -07:00
Ivan 'provod' Avdeev 9a5e1fec4a vk: scale profiling bars the same way the font is scale
make sizes consistent with the default font on hidpi displays
2023-03-21 11:59:57 -07:00
Ivan Avdeev 2872b4d237 vk: add profiling pause, add swapchain acquire scope 2023-03-21 11:59:57 -07:00
Ivan Avdeev 1c9ff300a9 vk: draw profiler scope blocks
also add a couple more scopes to rendering
2023-03-21 11:59:57 -07:00
Ivan Avdeev be59d1d8e9 vk: tune profiler colors and animation a bit 2023-03-21 11:59:57 -07:00
Ivan Avdeev 39f2d78199 vk: start refactoring profiler
Convert direct stack manipulation to simple and cheap event writing.
Draw rudimentary frame times graph.

Related to #412
2023-03-21 11:59:57 -07:00
Alibek Omarov 098c4c009b engine: platform: sdl: fix incorrect HICON cast in SetClassLongPtr call 2023-03-21 05:16:07 +03:00
Alibek Omarov f8cf2c8953 scripts: continious_upload: retry if upload failed 2023-03-21 05:15:30 +03:00
Alibek Omarov cc6838ec97 scripts: gha: psvita: try to fix vitaGL dependency fetching 2023-03-21 04:32:37 +03:00
Alibek Omarov dca637d4bb engine: client: eliminate pfnServerCmd limit and, like GoldSrc, send our server command immediately to netchan 2023-03-21 04:25:32 +03:00
Alibek Omarov 3949422430 scripts: gha: psvita: fix HLSDK branches names, as all needed PSVita changes have been merged to hlsdk-portable 2023-03-20 18:14:51 +03:00
Alibek Omarov 2c8488f07a scripts: gha: psvita: disable SINGLE_THREADED_GC for vitaGL as it was fixed in upstream (thanks, @fgsfds) 2023-03-20 18:05:24 +03:00
Alibek Omarov 1df1fc32df scripts: gha: psvita: lock vitaGL revision, use --depth=1 in git clone 2023-03-20 18:05:24 +03:00
SNMetamorph eac8c116a8 engine: server: sv_init: compiling error fix & minor cleanup 2023-03-20 16:29:43 +03:00
SNMetamorph a03019f5e4 engine: server: sv_init: enabled handling sound resources specifically
This is for timely precaching on client side. Otherwise, files are being downloaded to client, but not precached immediatly after it, and therefore causing a late precaching of sound (obvious, this is bad)
2023-03-20 16:29:43 +03:00
SNMetamorph 714b4f45e4 engine: common: added COM_GetResourceTypeName function 2023-03-20 16:29:43 +03:00
SNMetamorph 68be8157ea engine: common: soundlib: added Sound_SupportedFileFormat function 2023-03-20 16:29:43 +03:00
Alibek Omarov ea2a8b6785 3rdparty: update submodules (extras, mainui, opus) 2023-03-20 16:03:36 +03:00
NightFox 190a691c6d Add simple soft shadows by @LifeKILLED
This is a temporary solution.
2023-03-18 11:39:56 -07:00
NightFox e5658f59cd
Update rads & patches (#479) 2023-03-18 11:38:11 -07:00
Alibek Omarov 8c80d3b85d engine: common: cvar: add exception for cl_dodmusic cvar to fix Day of Defeat Beta 1.3 music issue 2023-03-18 20:34:30 +03:00
Alibek Omarov 33c0764e65
engine: common: system: fix inverted COM_CheckStringEmpty in Sys_GetCurrentUser for Vita
Thanks @fgsfdsfgs for pointing out
2023-03-17 17:29:40 +03:00
Alibek Omarov d085c5a843 ref: gl: gl_cull: remove thirdperson check, as it handled in client instead 2023-03-15 06:29:29 +03:00
Alibek Omarov 4ada40e8a8 engine: client: check if we should discard local player entity before HUD_AddEntity call, allowing CL_IsThirdPerson hack used in MMod 2023-03-15 06:28:20 +03:00
Alibek Omarov 1630d87c0d engine: client: do not alter the state if invalid HANDLE was passed to pfnSPR_Set. Fixes Half-Life: MMod 2023-03-15 04:58:33 +03:00
Alibek Omarov 3a956a1ad3 engine: client: initialize variables in SPR_Width/Height/Frames functions, in case R_GetSpriteParms fails 2023-03-15 04:58:00 +03:00
Alibek Omarov 774ced312f wscript: enforce -Werror=strict-aliasing 2023-03-14 21:29:35 +03:00
Alibek Omarov fec3d33dcf engine: client: cl_securedstub: fix strict aliasing in secured module initializing 2023-03-14 21:29:35 +03:00
Alibek Omarov d4610e30fd engine: common: net_encode: fix strict aliasing by converting it to use float_bits_t union 2023-03-14 21:29:35 +03:00
Alibek Omarov 885cda971d engine: common: net_buffer: fix strict aliasing by converting it to use float_bits_t union 2023-03-14 21:29:35 +03:00
Alibek Omarov ef0b227967 ref: gl: alias: fix strict aliasing by converting it to use float_bits_t union 2023-03-14 21:29:35 +03:00
Alibek Omarov 19a785a98a public: mathlib: convert rsqrt to use float_bits_t union 2023-03-14 21:29:35 +03:00
Alibek Omarov b96bfcfe7a public: mathlib: convert FloatToHalf and HalfToFloat to use float_bits_t union 2023-03-14 21:29:35 +03:00
Alibek Omarov 412c635499 public: add float_bits_t union to access float as 32-bit signed or unsigned integer 2023-03-14 21:29:35 +03:00
Alibek Omarov da5ec56567 engine: common: con_utils: fix const qualifier discard in Con_CheckName 2023-03-14 00:35:07 +03:00
Alibek Omarov e664e80b27 engine: common: mod_bmodel: replace few more obvious va calls by temp buffer and Q_snprintf 2023-03-13 06:25:57 +03:00
Alibek Omarov d177b6f528 engine: cvar: consolidate auto description for GLCONFIG cvars
Fix bug when GLCONFIG cvars didn't had it's respective CLIENTDLL or GAMEUIDLL flags
2023-03-13 06:22:54 +03:00
Alibek Omarov 2ef3d78d9f engine: client: netgraph: replace CL_DrawString with va calls by CL_DrawStringf 2023-03-13 06:16:17 +03:00
Alibek Omarov 5ea5e1167b engine: client: font: add CL_DrawStringf wrapper 2023-03-13 06:15:45 +03:00
Alibek Omarov 116a605248 engine: common: replace some obvious va uses by temp buffer and Q_snprintf or equivalent code 2023-03-13 06:08:36 +03:00
Alibek Omarov 9690fe9334 engine: client: replace some obvious va uses by temp buffer and Q_snprintf 2023-03-13 06:03:44 +03:00
Alibek Omarov a81fa84321 engine: server: replace some obvious va uses to temp buffer and Q_snprintf 2023-03-13 06:00:38 +03:00
Alibek Omarov 5ef97ae99e engine: convert Info_SetValueForKey with va to Info_SetValueForKeyf 2023-03-13 05:37:45 +03:00
Alibek Omarov d667845777 engine: convert Cbuf_AddText with va to Cbuf_AddTextf 2023-03-13 05:31:27 +03:00
Alibek Omarov b12b2aaf79 engine: common: cmd: add Cbuf_AddTextf wrapper 2023-03-13 05:28:53 +03:00
Alibek Omarov 6b62f9c1b9 engine: convert Cvar_Get with va to Cvar_Getf 2023-03-13 05:19:32 +03:00
Alibek Omarov ba1cf25314 engine: convert MSG_WriteString with va to MSG_WriteStringf 2023-03-13 05:13:52 +03:00
Alibek Omarov fb2ba6a6e2 engine: common: net_buffer: add MSG_WriteStringf wrapper 2023-03-13 05:12:46 +03:00
Alibek Omarov fb6e310eab public: move va() function back to engine, it's not recommended to use in shared modules 2023-03-13 02:44:59 +03:00
Alibek Omarov bcbd1a59c6 engine: common: base_cmd: add a simple benchmark within basecmd_test command 2023-03-13 02:40:48 +03:00
Alibek Omarov 8e45a43ad2 engine: common: base_cmd: alphabetically order inserts for faster lookups 2023-03-13 02:39:54 +03:00
Alibek Omarov 115ed82c19 engine: common: base_cmd: static-ize internal fuctions 2023-03-13 02:39:02 +03:00
Alibek Omarov 5c1e06ae74 public: crclib: optimize COM_HashKey, implement typical djb hashing as this function is used for hashtables with string lookup 2023-03-13 02:37:19 +03:00
SNMetamorph f9205825b6 engine: platform: sdl: fixed psvita & nswitch platform initializing 2023-03-12 16:09:20 +03:00
Andrey Akhmichin 9040c34f48 ref: gl: replace va function calls. 2023-03-11 17:56:05 +03:00
Andrey Akhmichin 9e9703e6de engine: common: imagelib: replace va function calls. 2023-03-11 17:37:16 +03:00
Andrey Akhmichin 6486533355 engine: platform: android: replace va function calls. 2023-03-11 16:29:55 +03:00
Andrey Akhmichin 34160151a4 filesystem: replace va function calls. 2023-03-11 16:28:54 +03:00
Andrey Akhmichin daaaa324bd engine: platform: emscripten: replace va function calls. 2023-03-11 15:32:14 +03:00
Andrey Akhmichin af5c74981b ref: soft: replace va function calls. 2023-03-11 15:31:17 +03:00
Andrey Akhmichin 249ce6bca1 engine: platform: win32: replace va function calls. 2023-03-11 15:30:56 +03:00
Andrey Akhmichin b648c74815 engine: platform: posix: replace va function calls. 2023-03-11 15:30:29 +03:00
Andrey Akhmichin a2d459ae84 engine: common: add printf-like version of Cvar_Get function. 2023-03-11 15:29:54 +03:00
Andrey Akhmichin 573781b45d engine: platform: sdl: replace va function calls. 2023-03-11 15:29:34 +03:00
Andrey Akhmichin 3299999f3d engine: common: add printf-like version of Info_SetValueForKey function. 2023-03-11 15:28:54 +03:00
Alibek Omarov 91be4f6521 engine: common: cmd: fix inverted check in apropos 2023-03-11 07:50:33 +03:00
fgsfds f2f21b24a1 scripts: psvita: no need for fsigned-char either 2023-03-11 07:09:19 +03:00
fgsfds 9ef43a4794 scripts: psvita: no need to force GNU_SOURCE everywhere 2023-03-11 07:09:19 +03:00
fgsfds fc02a69686 docs: add nswitch and psvita to ports.md 2023-03-11 07:09:19 +03:00
fgsfds b10a0dc5c5 ci: psvita: build bshift libraries 2023-03-11 07:09:19 +03:00
fgsfds e5f0d1557c docs: psvita: add install/build instructions 2023-03-11 07:09:19 +03:00
fgsfds d8a3f4850a ci: psvita: libk is not required 2023-03-11 07:09:19 +03:00
fgsfds 882d957b5c ci: psvita: vdpm is in the current directory 2023-03-11 07:09:19 +03:00
fgsfds afd1727898 ci: psvita: only download necessary packages 2023-03-11 07:09:19 +03:00
fgsfds 70a73e47a7 psvita: use crtlib where possible 2023-03-11 07:09:19 +03:00
fgsfds fe3f15ad33 engine: input: psvita: reimplement OSK manually 2023-03-11 07:09:19 +03:00
fgsfds 66f625f840 engine: psvita: use a macro for ioctlsocket like on all other platforms 2023-03-11 07:09:19 +03:00
fgsfds 3e1833722f engine: psvita: check req in ioctlsocket() 2023-03-11 07:09:19 +03:00
fgsfds 4b8e11f561 engine: remove stray #if XASH_PSVITA 2023-03-11 07:09:19 +03:00
fgsfds 0d04c20578 ref: gl: psvita: skip deleting the shaders since glDeleteProgram can block for a long time 2023-03-11 07:09:19 +03:00
fgsfds 41c819f3d3 engine: psvita: keep old arguments in Sys_NewInstance 2023-03-11 07:09:19 +03:00
fgsfds 957154f097 scripts: psvita: move TITLEID and APPNAME to engine elf build arguments 2023-03-11 07:09:19 +03:00
fgsfds fad506ef03 ref: gl: vgl_shim: remove normal support, it's not necessary 2023-03-11 07:09:19 +03:00
fgsfds 9150bbdfd8 ref: gl: psvita: remove the GL_CheckExtension hack 2023-03-11 07:09:19 +03:00
fgsfds aa4e2f0ae4 ref: gl: psvita: use Cvar_FullSet to disable r_studio_drawelements 2023-03-11 07:09:19 +03:00
fgsfds 2bacc91922 ref: gl: move vgl_shim to ref/gl 2023-03-11 07:09:19 +03:00
fgsfds 458aa6d8b8 ci: psvita: copy the vpk as well 2023-03-11 07:09:19 +03:00
fgsfds 6963741020 ci: psvita: fix copypaste error 2023-03-11 07:09:19 +03:00
fgsfds b55aa982b0 ci: psvita: vrtld uses cmake 2023-03-11 07:09:19 +03:00
fgsfds 492481eea8 ci: basic psvita scripts 2023-03-11 07:09:19 +03:00
fgsfds 76bff9cd4b ref: gl: psvita: fix long hang on shutdown 2023-03-11 07:09:19 +03:00
fgsfds 47a6be86b1 engine: psvita: export stpcpy 2023-03-11 07:09:18 +03:00
fgsfds 287688d985 engine: psvita: implement Sys_NewInstance 2023-03-11 07:09:18 +03:00
fgsfds 610d528042 engine: psvita: implement Sys_GetCurrentUser 2023-03-11 07:09:18 +03:00
fgsfds 89ec39821e ref: gl: psvita: add fog support; bump max verts to 32768 2023-03-11 07:09:18 +03:00
fgsfds 82cfd3ecc3 ref: gl: psvita: revert arrayverts change, it doesn't matter that much 2023-03-11 07:09:18 +03:00
fgsfds 5a3e3b3977 ref: gl: add immediate mode shim for psvita 2023-03-11 07:09:18 +03:00
fgsfds 9cf6e421cb ref: gl: psvita: force-enable NPOT textures 2023-03-11 07:09:18 +03:00
fgsfds 5c56b51044 engine: client: don't pop up OSK during loading screens on the PSVita either 2023-03-11 07:09:18 +03:00
fgsfds 577add56f1 filesystem: fs is non case sensitive on nswitch and psvita 2023-03-11 07:09:18 +03:00
fgsfds adc5aa4659 psvita: don't default to -dev 255 2023-03-11 07:09:18 +03:00
fgsfds 5beed5ab29 engine: psvita: rebalance memory pools a bit 2023-03-11 07:09:18 +03:00
fgsfds 34dd52ca90 ref: gl: trust the GL_EXTENSIONS string on psvita 2023-03-11 07:09:18 +03:00
fgsfds 6304b51f32 psvita: fno-short-enums, make ref_gl function somewhat 2023-03-11 07:09:18 +03:00
fgsfds 97a7de3377 engine: server: remove duplicate registration for sv_autosave 2023-03-11 07:09:18 +03:00
fgsfds 7424b29e56 engine: initial psvita build support 2023-03-11 07:09:14 +03:00
Alibek Omarov 3c64d2ad80 public: build: don't confuse other libcs with built with glibc game libraries by specifying them into separate platform, like Android 2023-03-11 05:45:11 +03:00
Alibek Omarov 1274fa13c8 engine: common: cmd: slightly simplify apropos taking all arguments and checking for filtering symbols 2023-03-11 05:38:28 +03:00
Alibek Omarov 3765686077 public: make va() buffer size public 2023-03-11 05:28:17 +03:00
SNMetamorph 9fffd7a270 Documentation: added page about debugging mods using minidump files 2023-03-11 04:28:25 +03:00
SNMetamorph e37c07f44f engine: crashhandler: added support for minidumps generation 2023-03-11 04:28:25 +03:00
SNMetamorph 214a3cce73 engine: host: added -minidumps startup parameter for win32 platform 2023-03-11 04:28:25 +03:00
Andrey Akhmichin d738b07660 Documentation: mod-porting-guide.md: Update. 2023-03-11 04:22:30 +03:00
Ivan Avdeev 01de5957d8
vk: respect TF_NEAREST/CLAMP/BORDER flags (#471)
Use these flags to pick the right sampler. Fixes issues with blurry and leaking fonts, lines in main menu tiles, etc.

fixes #439, fixes #79
2023-03-08 14:16:21 -08:00
Ivan 'provod' Avdeev 6d7fd41494 rt: increase model cache size, fix #449
Apparently just increasing the model cache size limit is fine.
"LRU" cache eviction was not even used when testing.
2023-03-04 12:46:37 -08:00
Ivan 'provod' Avdeev 21534c044b rt: fix uploading too many light cells, fix #451
c5a1 has ~230k light cells, and tries to upload 77MiB of them. Previous staging size of 64MiB wasn't enough.
2023-03-04 12:46:37 -08:00
Ivan 'provod' Avdeev 62392ac4b6 rt: increase kusochki limit to 32768, fix #85
boot_camp worldmodel has ~11k surfaces, which means it will need at least 22k kusochki for 1:1 static:dynamic split.
2023-03-04 12:46:37 -08:00
Ivan 'provod' Avdeev c1483216ef rt: increase MAX_ACCELS to 2048, fix #366
test_shaders_room3 has lots of sprites, and currently we create a new BLAS for each sprite.
This is not great, and a proper fix would probably mean consolidating all dynamic transparent things into BLASes per render mode or something. But for now we can just increase the limit
2023-03-04 12:46:37 -08:00
Ivan 'provod' Avdeev 78a1b24e11 rt: enable entity light, fix #115 2023-03-04 12:46:37 -08:00
Ivan 'provod' Avdeev dc698c16dc vk: make sure deleted textures are not referenced in staging
This fixes -vkvalidate and fixes #464
2023-03-04 12:46:37 -08:00
NightFox 8ed23cb40f
More correct emissive textures (#456)
Я подобрал новое компромиссное значение которое не требует clamp.
Это не идеально, но пока сойдёт. Может давать немного больше солнечных зайчиков чем с clamp.
Позже надо будет разобраться с самим kusok.emissive.
2023-03-04 09:41:05 -08:00
Ivan Avdeev d1376a89e4
Merge "Enable live reloading light data" #457
- [x] Fixes #417 
- [x] Fixes #330 
- [x] Fixes #104
2023-03-03 16:50:41 -08:00
Ivan Avdeev c47c314512 rt: clear geom emissive values prior to loading light data
fix #104
2023-03-03 16:41:16 -08:00
Ivan Avdeev 4f2eb7680b rt: propagate emissive color patches to kusochki
Fixes #330

Also, fix incorrect patch application introduced by previous commit, it
would not read the patch color value, and could only switch the light
off.
2023-03-02 23:23:31 -08:00
Ivan Avdeev a284567002 rt: refactor loading surface lights, fix #417
Do not entangle brush model loading with loading surface lights.
Do a separate pass over brush model surfaces for the sole purpose of
finding light sources. Enables consistent live-reloading light data
after patching entities/surface/rad files.
2023-03-02 22:32:08 -08:00
Ivan Avdeev 58c9a9920e rt: do not allow direct access to pached surfaces 2023-03-02 20:27:18 -08:00
Alibek Omarov 48ca8f9a70 engine: server: fix call to non existent function, in this tree it's called IsMasterAdr 2023-03-02 17:36:56 +03:00
Alibek Omarov c565b0a505 mainui: update 2023-03-02 17:35:50 +03:00
NightFox ed9a06cae1 Update lighting patches 2023-03-01 22:50:02 -08:00
Ivan 'provod' Avdeev 8a457a17c2 rt: compute tangents for studio models
Enables applying normal maps to studio models.

Fixes #220, fixes #241
2023-03-01 10:47:31 -08:00
Alibek Omarov 474833a3bf engine: server: send heartbeats to master server if sv_nat is active, despite public cvar value 2023-03-01 15:57:30 +03:00
Alibek Omarov 602f23fbdf engine: server: check if we got info request from master server, that acts as a bridge for NAT servers 2023-03-01 15:57:30 +03:00
Ivan Avdeev bd2bda9a41
Fix: additive soft particles, skybox shadow
Add another flag to kusochki for glow geometry. Move flags to a new kusok.flags field.
- [x] Fixes #231 (or at least makes it not stand out too much)

Fix the way we check for environment/skybox lights, explicitly look for closest hit instead of any.
- [x] Fixes #424 and #413
2023-02-28 18:58:02 -08:00
Ivan 'provod' Avdeev 6b1e84308a rt: fix checking for skybox shadow intersection
Doing tereminate-on-first-hit is incorrect, as we might accidentally hit the skybox geometry first, and consider this as no shadow.
Unfortunately we have to explicitly find a closest hit and check whether that was a skybox.

Maybe there's even a better way, e.g. querying for skybox-only geometry first, and only then checking for a terminate-on-first-hit for everything else. But it likely doesn't matter that much, and would need profiling anyway.

Fixes #424 and #413
2023-02-28 18:50:07 -08:00
Ivan 'provod' Avdeev 59e8a8c4c3 rt: only overshoot additive for glow mode
Add another flag to kusochki for glow geometry.
Move flags to a new kusok.flags field.

Fixes #231 (or at least makes it not stand out too much)
2023-02-28 17:50:50 -08:00
Ivan Avdeev 149dc7cade
Merge pull request #446 from LifeKILLED/reprojection-fix
vk rt: fix reprojection
Right way to put previous model matrix
Fix bad index of previous frame
Fallback to current frame if previous frames are outdated
2023-02-28 12:08:19 -08:00
LifeKILLED 2f050a6618 Merge branch 'reprojection-fix' of https://github.com/lifekilled/xash3d-fwgs into reprojection-fix 2023-02-28 23:07:08 +04:00
LifeKILLED f4b0f5016b vk rt: fix reprojection 2023-02-28 23:06:09 +04:00
LifeKILLED 5fbee4a97a vk rt: fix linux build 2 2023-02-28 22:58:54 +04:00
LifeKILLED 70c52622e7 vk rt: try to fix linux build 2023-02-28 22:48:20 +04:00
LifeKILLED ed69eeb5af vk rt: fix reprojection 2023-02-28 22:30:54 +04:00
Ivan Avdeev da447d9e5b
Merge pull request #445 from FWGS/master
Merge from upstream
2023-02-27 17:11:04 -08:00
NightFox 429fb82f52 Update README.md 2023-02-27 16:55:59 -08:00
Ivan Avdeev 19603722ed
vk: add more beam types, tracers, triapi
- [x] fixes #293 
- [x] fixes #162 
- [x] add tracers, fix #263 
- [x] add basic triapi
2023-02-27 11:17:28 -08:00
Ivan 'provod' Avdeev c8e4ce0619 vk: fix tracers colors 2023-02-27 11:00:34 -08:00
Ivan 'provod' Avdeev d87690876f vk: fix TRI_QUADS and primitive_mode tracking 2023-02-27 10:51:11 -08:00
Ivan Avdeev 421c0ea733 vk: add tracers (not tested) 2023-02-27 10:37:03 -08:00
Ivan 'provod' Avdeev 30334db159 vk: draw the rest of the beams 2023-02-27 09:49:56 -08:00
Ivan 'provod' Avdeev 2daa130453 vk: set beam/triapi texture and render mode explicitly 2023-02-27 09:20:13 -08:00
Ivan 'provod' Avdeev cf5d3d9d47 vk: increase limits for triapi
c4a1 was using too many indices
2023-02-27 08:46:12 -08:00
Ivan 'provod' Avdeev a118e12e01 vk: stub just enough triapi to render more beam types
it is still drawn incorrectly, but at least something is visible, and we can iterate from here
2023-02-26 20:45:29 -08:00
Ivan 'provod' Avdeev ee4def1141 rt: modulate additive kusochki by vertex color attribute 2023-02-25 18:41:01 -08:00
Ivan 'provod' Avdeev 1fadbce860 vk: remove flag attribute in vertex
make color computation more uniform and not mode-specific
2023-02-25 18:38:22 -08:00
Ivan 'provod' Avdeev e4ad18f220 vk: do not modulate beam color twice
color is already applied at model/ubo level
2023-02-25 16:58:59 -08:00
Ivan 'provod' Avdeev f2182bb255 vk: fix beams per-vertex blending 2023-02-25 16:47:23 -08:00
Ivan Avdeev 26ad10483f
Merge pull request #432 from w23/sprite-improvements
- [x] fixes #297 
- [x] fixes #256 
- [x] Sprite rendering differs from GL, especially with glow(3) and solid/transalpha(4)
2023-02-25 14:27:20 -08:00
Ivan 'provod' Avdeev 1d17e55101 rt: hack all blending as additive
this is not correct, but at  least we get to see something
need to figure out how should blending work in rt:
- translucent materials that absorb light
- reflective+refractive
- etc
2023-02-25 13:22:56 -08:00
Ivan 'provod' Avdeev 3e2689b7f8 rt: improve sprite blending even moar
fixes most glaring sprite blending issues for ray tracing
2023-02-25 12:46:46 -08:00
Ivan 'provod' Avdeev 9f72a804e0 vk: improve traditional blending universally
it is now almost on par with the gl renderer
2023-02-25 12:09:20 -08:00
Ivan 'provod' Avdeev ce27bdb1b1 vk: fix studio models being modulated by ent color 2023-02-24 23:57:49 -08:00
Ivan 'provod' Avdeev cd524c20cf vk: make transparent brushes closer to gl
some of render modes are not affected by light, disable lightmaps for them
2023-02-24 23:54:41 -08:00
Ivan 'provod' Avdeev 03efb6ce83 fixup linux compiler warnings 2023-02-24 23:52:09 -08:00
Ivan 'provod' Avdeev 487c94662a rt: HACK flickering lerping sprites
Lerping between sprite frames means drawing two coplanar quads blended the right way. This is not something ray tracing can accommodate easily for all blending modes.
Disable lerping for now
2023-02-24 22:52:38 -08:00
Ivan 'provod' Avdeev 005b7c84eb vk: pass model color explicitly
Instead of passing model color around as an implicit global state, pass it per-model.
This makes it (a) easier to track, (b) easy to fix blending issues. E.g. this fixes incorrect coloring of brush and studio models, which is also different.
2023-02-24 22:48:26 -08:00
Ivan 'provod' Avdeev 92b1e78d85 vk: make trad sprites more like gl ones
still not fully there:
- glow is slightly off
- TransAlpha has wrong blending mode

apparently pipeline settings for brushes, models, and sprites are substantially different, need different pipelines
2023-02-24 17:43:07 -08:00
Alibek Omarov 7e9d46689c engine: client: fix multiline CenterPrint 2023-02-24 19:46:02 +03:00
Ivan 'provod' Avdeev a5b977c8a3 rt: make emissive surfaces ignore external light
this is not fully correct, but it fixes slightly off sprite colors for now
2023-02-23 20:08:02 -08:00
Ivan 'provod' Avdeev 41809b8952 vk: do not depth-test glow sprites
makes them more like gl ones

still not fully fixed though, need to work on their transparency, it should be also scaled
2023-02-23 20:07:06 -08:00
Ivan 'provod' Avdeev 4f6d51c368 vk: fix most of random sprite flickering
it was due to leaving garbage in vertex fields.

some animated spritest still flicker though
2023-02-23 20:05:58 -08:00
Ivan Avdeev d6d9011dcc
Merge pull request #431 from w23/better-extensions
change how device extensions are checked
make nv_checkpoint not depend on rt
split it logically from aftermath
don't crash when this extension is not available
2023-02-23 19:06:31 -08:00
Ivan Avdeev ad5e1b2b86 vk: fixup compilation w/o aftermath sdk 2023-02-23 18:59:14 -08:00
Ivan Avdeev 8514e2c7b8 ci: update vulkan sdk and distro versions 2023-02-23 14:18:02 -08:00
Ivan 'provod' Avdeev 1a6e967ddb vk: change how device extensions are checked
make nv_checkpoint not depend on rt
split it logically from aftermath
don't crash when this extension is not available
2023-02-23 13:48:41 -08:00
Alibek Omarov b6347d17c9 engine: client: sound: don't print sound/ twice in soundlist command 2023-02-19 12:25:03 +03:00
Alibek Omarov 8293bc91d4 engine: client: sound: fix PickDynamicChannel to correctly find channel with minimum time left 2023-02-18 03:37:20 +03:00
Alibek Omarov fb0f184d6b engine: common: lib_common: fix offset by one UB 2023-02-17 22:51:56 +03:00
Alibek Omarov 58e95c7d6f engine: client: console: elinimate unneeded Sys_DoubleTime call in Con_DrawDebug 2023-02-17 22:50:42 +03:00
Alibek Omarov 7a5381e658 engine: common: mod_studio: fix uninitialized adj array 2023-02-17 22:50:12 +03:00
Alibek Omarov 375c06400c engine: server: avoid unaligned access in pfnMessageEnd 2023-02-17 22:48:56 +03:00
Ivan Avdeev 55ff27c5d4
Merge pull request #428 from w23/merge-from-upstream-2023-02-16
Merge from upstream
2023-02-16 11:05:50 -08:00
Ivan Avdeev e61b45b8b6 disable flatpak build due to #430 2023-02-16 10:54:30 -08:00
Ivan Avdeev ac1665558f disable vulkan for nswitch 2023-02-16 10:54:08 -08:00
Ivan Avdeev 053d26e870 move ref_vk to ref/vk 2023-02-16 10:30:31 -08:00
Ivan Avdeev 604bd702d4 Merge remote-tracking branch 'upstream/master' into merge-from-upstream-2023-02-16 2023-02-16 10:19:30 -08:00
Alibek Omarov e481c86ba2 engine: client: console: fix NXPrintf newlines, small refactoring 2023-02-15 05:53:39 +03:00
Ivan Avdeev 1f774c6400
Merge significant ray tracer improvements #341 from w23/better-sampling-passes
Initial observation: our vgpr story is abysmal, so need to split the one uber-rt-shader into pieces.

Done here:
- ray tracing pipeline uber shader is split into separate compute phases -> perf x2 (with a possibility of further radical improvements)
- "programmable render": read spirv, extract bindings, auto-create missing resources, etc.
- better light sampling, significant image quality improvements
- better synchronization. cpu can continue preparing the next frame while previous one is still being drawn on GPU
- lots of other small fixes
2023-02-14 13:00:53 -08:00
Ivan 'provod' Avdeev 4dd793569c rt: add alpha-quality alpha blending
Do translucency in bounce stage. It's not great, but lets us see thing through.

Also fix reading OOB uninitialized memory for color/alpha.
2023-02-14 12:55:40 -08:00
Alibek Omarov 21b9f07323 engine: platform: sdl: remove legacy XASH_NANOGL macro from vid code, it's only relevant for ref_gl 2023-02-14 18:52:51 +03:00
Alibek Omarov 0bff62e696 engine: sprite: migrate header to stdint.h, remove usage of enums in data structs for portability, add static sizeof checks 2023-02-14 18:29:27 +03:00
Alibek Omarov 858597832d engine: alias: migrate header to stdint.h, remove usage of enums in data structs for portability, add static sizeof checks 2023-02-14 18:29:18 +03:00
Alibek Omarov 9b0ac7cb32 common: add shared synctype_t definition header, borrowed from Quake's modelgen.h 2023-02-14 18:18:16 +03:00
Alibek Omarov 3c27384b6b filesystem: speedup fs_ext_path case in FS_FindFile 2023-02-13 06:49:52 +03:00
Alibek Omarov 1e8c26a527 filesystem: wad: fix loading WADs by absolute paths 2023-02-13 06:49:29 +03:00
Alibek Omarov f4069de7f2 engine: move SlerpBones, CalcBonePosition/Quaternion from engine to libpublic 2023-02-13 05:23:13 +03:00
Alibek Omarov e95161aa14 filesystem: fix ClearSearchPath 2023-02-12 17:09:53 +03:00
Ivan Avdeev eaf8b3c55a
Merge pull request #421 from w23/denoiser-massage
1. Denoise different channels (diffuse, specular, indirect) differently.
2. Make indirect bounce half res.
2023-02-11 12:39:07 -08:00
Ivan 'provod' Avdeev 64ac964dfc rt: make indirect light run at half res 2023-02-11 12:12:57 -08:00
Ivan 'provod' Avdeev 218bd0a9c2 rt/denoiser: blur different channels differently 2023-02-11 11:36:45 -08:00
Ivan 'provod' Avdeev e9712f36e3 rt/denoiser: split into diffuse/specular/direct/indirect channels
apply to lighting only, not to the final color
2023-02-11 11:06:33 -08:00
Alibek Omarov 0984368a31 engine: server: GoldSrc compliant pfnServerExecute(), don't execute config.cfg for server! 2023-02-11 07:22:04 +03:00
Alibek Omarov f4961d9da7 engine: client: return empty string in pfnGetLevelName if no map is loaded yet 2023-02-11 06:50:46 +03:00
Alibek Omarov f42a174482 engine: client: empty current map name in CL_ClearState 2023-02-11 06:45:20 +03:00
Alibek Omarov 13bf607031 engine: client: call VidInit early in svc_serverdata parsing, GoldSrc compatibility 2023-02-11 06:43:38 +03:00
Alibek Omarov 3cfdb1213b engine: client: consolidate modern and legacy protocol parsing functions, if possible 2023-02-11 06:06:21 +03:00
Alibek Omarov d58105d64d scripts: flatpak: fix Half-Life directory detection 2023-02-11 03:56:40 +03:00
Alibek Omarov 1bdd844860 scripts: flatpak: minimize filesystem permissions, add Steam Flatpak data directory 2023-02-11 03:36:40 +03:00
Alibek Omarov 11f3d97cd7 scripts: flatpak: respect XDG data home in launcher script, add Steam Flatpak data directory 2023-02-11 03:36:40 +03:00
Alibek Omarov fccf044976 engine: initialize network buffers used on player connect and after 2023-02-09 17:57:45 +03:00
Alibek Omarov c23396f533 engine: client: keys: hardcode K_START_BUTTON as escape button, cancelselect doesn't exist anymore and many games seems to use this button for menu access, and back for pause 2023-02-09 06:32:14 +03:00
Alibek Omarov 33c9f7118b engine: platform: sdl: sanitize buttons/axes from SDL, add ABXY->BAYX swap for NSwitch 2023-02-09 06:31:19 +03:00
Alibek Omarov c741ec223f engine: client: keys: reserve some more buttons as gamepad buttons according to latest SDL2 GameController header 2023-02-09 06:30:08 +03:00
Alibek Omarov d6d98bd297 engine: platform: sdl: minor style changes 2023-02-09 05:59:34 +03:00
Alibek Omarov 5e1b5d89f7 engine: client: console: allow opening OSK and existing console with gamepads for all platforms 2023-02-09 05:58:54 +03:00
Alibek Omarov a0edfd28b2 engine: common: host: use DEFAULT_ALLOWCONSOLE macro to set default console state 2023-02-09 05:56:11 +03:00
Alibek Omarov 555fd02407 defaults: reorganize platform default overrides, disable touch for nswitch 2023-02-09 05:55:35 +03:00
Alibek Omarov f7f9cfecfc ci: nswitch: use waf install to copy build artifacts 2023-02-09 05:35:30 +03:00
Alibek Omarov 2aeee59a31 Merge remote-tracking branch 'fgsfds/switch_newer' 2023-02-09 05:18:06 +03:00
Ivan Avdeev 780b225735 mark a bunch of things as done 2023-02-08 14:55:17 -08:00
Ivan Avdeev a46d82f3b5
Merge pull request #419 from w23/bounces
Add indirect illumination
2023-02-08 10:32:02 -08:00
Ivan 'provod' Avdeev 3ecd21a25b rt: simplify bounce computations
use simpler polygon sampling
use smaller texture lods
2023-02-08 10:11:00 -08:00
Ivan 'provod' Avdeev c5a1343fc6 rt: add additive to bounces 2023-02-08 09:44:28 -08:00
Ivan 'provod' Avdeev 5b59c387c1 rt: add emissive to specular bounce
makes it sample skybox, but is probably incorrect in other circumstances
2023-02-08 09:35:21 -08:00
Ivan 'provod' Avdeev 62720a7ed3 rt: fix uninitialized memory denoiser glitches
was reading garbage when ray doesn't hit anything
2023-02-08 09:34:40 -08:00
Ivan 'provod' Avdeev 19c4e2a1d8 rt: add reflections
i was trying to add specular properly: replace them with specular bounce. but it doesn't really work that easily. need some kind of color mapping and figuring out how to make them look consistent.

this commit still does them separately, i.e. specular is done in direct lighting pass. no emissive is added on bounce. this probably makes it not reflect skybox ;_;.
2023-02-08 09:25:40 -08:00
Alibek Omarov 12b8965a8c mainui: update 2023-02-08 20:01:06 +03:00
Alibek Omarov b5b6b8b785 engine: network: fix some unitialized sockaddr_storage's 2023-02-08 20:00:51 +03:00
fgsfds 35e073ceff ci: nswitch: don't forget filesystem_stdio 2023-02-08 01:53:26 +01:00
fgsfds b2cc96cf0d scripts: wscript: nswitch: do the libstdc++ hack right before build to not pollute the environment 2023-02-08 01:37:35 +01:00
fgsfds f7489a3747 scripts: nswitch: it's arm64, not aarch64 2023-02-08 01:04:31 +01:00
fgsfds 0e7ebf6d44 Merge branch 'master' of https://github.com/FWGS/xash3d-fwgs into switch_newer 2023-02-08 00:56:20 +01:00
fgsfds 69607d7890 nswitch: do not link libstdc++ into dynamic libraries
instead only link it to the main executable with --whole-archive, letting the dynamic libs import anything they want from it
2023-02-08 00:52:48 +01:00
fgsfds 4e87eb068a engine: common: nswitch: use #if instead of #ifdef 2023-02-07 23:03:59 +01:00
Alibek Omarov 03a7c67731 public: build: revert arm64 renaming to aarch64, we shouldn't enforce naming changes without a reason 2023-02-08 00:03:15 +03:00
Alibek Omarov 5ba2449d10 engine: common: static-ify functions in mod_studio.c 2023-02-08 00:03:15 +03:00
fgsfds 0ee2fd8a8a ci: nswitch: do not dumb, 00 penalty 2023-02-07 20:52:23 +01:00
fgsfds 080b9b30a1 ci: nswitch: do not put the pkgtemp folder into the .7z 2023-02-07 20:45:42 +01:00
fgsfds 749ac5ed54 ci: nswitch: do not rely on dkp-pacman at all 2023-02-07 20:38:40 +01:00
fgsfds 6c8b9af6bb ci: nswitch: fix artifact packaging 2023-02-07 20:35:24 +01:00
fgsfds 07922c0239 ci: nswitch: actually set env vars properly 2023-02-07 20:26:24 +01:00
fgsfds 1a54ec92e0 github: ref name not required 2023-02-07 20:26:13 +01:00
fgsfds 663b574b8b github: checkout the switch_newer branch for now 2023-02-07 20:22:30 +01:00
fgsfds 430c51b71a ci: nswitch: there is no python-is-python3 where we're going 2023-02-07 20:14:11 +01:00
Ivan 'provod' Avdeev ea7879bff8 rt: add lighting to bounce
no specular just yet
2023-02-07 11:13:10 -08:00
fgsfds 20bcd03f19 ci: nswitch: ...and set it to be the default python install 2023-02-07 20:07:48 +01:00
fgsfds dab959fc32 ci: nswitch: the docker container is missing python, install it 2023-02-07 20:04:36 +01:00
fgsfds eff75e5d50 ci: nswitch: the docker container is missing dkp-toolchain-vars, install it 2023-02-07 20:00:49 +01:00
fgsfds d103f022b4 ci: nswitch: forgot run 2023-02-07 19:55:33 +01:00
fgsfds 72b8246969 ci: nswitch: attempt to use dkp's docker image
because they banned the ci server from accessing their pacman repo
2023-02-07 19:54:00 +01:00
Ivan 'provod' Avdeev 7188711451 rt: add test color-only bounce
no lighting yet, just base color
2023-02-07 10:46:57 -08:00
fgsfds 030d05f018 ci: nswitch: make install with sudo 2023-02-07 18:38:18 +01:00
fgsfds 59cd5493e7 github: add nswitch build target 2023-02-07 18:35:08 +01:00
fgsfds 98a7f6fa3f ci: add nswitch build scripts 2023-02-07 18:34:58 +01:00
Ivan Avdeev 3edcb7c007
Upload only dirty light clusters regions, PR #418
Ends up uploading only a few megs per frame, spread across a hundred or so ranges on average.
Still not great, now validation is too slow. But otherwise it's back to ~60fps.

I think it's end of the line for this approach. Even betterer light clusters would need a complete overhaul, e.g. being moved completely to GPU compute.

Fixes #385
2023-02-07 09:26:43 -08:00
fgsfds 65095df124 Merge branch 'master' of https://github.com/FWGS/xash3d-fwgs into switch_newer 2023-02-07 17:15:01 +01:00
fgsfds ee370ea007 Merge branch 'master' of https://github.com/FWGS/xash3d-fwgs into switch_newer 2023-02-07 17:14:47 +01:00
Alibek Omarov 05016f8639 engine: vgui: add EnableTextInput to the API 2023-02-06 16:42:09 +03:00
Alibek Omarov 12154de6f5 ref: soft: fix -Wsequence-point 2023-02-06 16:42:09 +03:00
Alibek Omarov 3fca567b81 wscript: few more warnings-as-errors 2023-02-06 16:42:09 +03:00
Ivan 'provod' Avdeev 0573186334 rt: upload dirty light clusters; use them in shaders
known issues:
- -vkvalidate performance is bad, as it has to validate dozens-hundreds of buffer uploads
- still doesn't solve the case where entire map ends up being updated
2023-02-05 23:35:08 -08:00
Alibek Omarov 634574f249 engine: platform: sdl: don't enable text mode with cursor??? 2023-02-06 00:29:14 +03:00
fgsfds f782d444a8 engine: platform: posix: don't redefine _GNU_SOURCE 2023-02-06 00:05:41 +03:00
fgsfds b68def2b9c engine: touch: only pop up touch keyboard on FINGERDOWN events 2023-02-06 00:05:32 +03:00
fgsfds d944301a60 engine: client: add barebones gamepad controls to input fields 2023-02-06 00:05:28 +03:00
fgsfds 15ba932046 engine: server: add sv_autosave cvar
* a1ba: added FCVAR_PRIVILEGED just in case
2023-02-06 00:05:20 +03:00
fgsfds b73c16c216 engine: net_ws: pass correct sockaddr lengths where needed 2023-02-05 23:51:48 +03:00
fgsfds 0ba4ef678c engine: net_ws: pass correct sockaddr lengths where needed 2023-02-05 03:39:32 +01:00
fgsfds 919d510f63 Merge branch 'master' of https://github.com/FWGS/xash3d-fwgs into switch_newer 2023-02-05 02:37:40 +01:00
fgsfds 6557ac7fb4 server: add sv_autosave cvar 2023-02-05 02:29:22 +01:00
Alibek Omarov 87c307f47e scripts: flatpak: install vgui 2023-02-05 04:27:58 +03:00
fgsfds f3e50b5500 add barebones gamepad controls for input fields and console 2023-02-05 02:27:12 +01:00
fgsfds 705f252ed8 nswitch: don't automatically pop up OSK when opening console 2023-02-05 02:26:48 +01:00
fgsfds cb28101732 touch: only pop up OSK on FINGERDOWN events 2023-02-05 02:26:17 +01:00
fgsfds f87863b8bc nswitch: always enable console 2023-02-05 02:18:11 +01:00
fgsfds 25fb89f717 nswitch: don't redefine O_BINARY 2023-02-05 02:16:56 +01:00
fgsfds 36e7856b9c don't redefine _GNU_SOURCE 2023-02-05 02:16:38 +01:00
Alibek Omarov 34b0cdc125 scripts: flatpak: use relative paths as RoDir doesn't allow absolute paths for now 2023-02-05 04:13:45 +03:00
fgsfds 25a1cb8ce7 Nintendo Switch support (again) 2023-02-05 02:09:32 +01:00
Alibek Omarov a610b1545b scripts: flatpak: check .local directory for steam library 2023-02-05 03:44:58 +03:00
Alibek Omarov 30b698067a scripts: flatpak: allow easy debugger attach 2023-02-05 03:25:07 +03:00
Alibek Omarov f63f1a0dc6 scripts: flatpak: add another default Steam library path 2023-02-05 02:43:36 +03:00
Alibek Omarov 9cb867a7d4 filesystem: wad: print errno if wad can't be opened 2023-02-05 02:42:35 +03:00
Alibek Omarov 00ddd95c27 scripts: flatpak: try to add ourselves to desktop menu entries 2023-02-05 02:25:21 +03:00
Alibek Omarov 0ffd1b9ff1 github: try to enable building flatpak bundle 2023-02-05 00:40:08 +03:00
Alibek Omarov 2109d49aa3 ci: disable xash-extras fetching, it's a submodule now 2023-02-05 00:06:19 +03:00
Alibek Omarov f910f4896c engine: client: font: finally add support for tab character in engine 2023-02-04 22:53:10 +03:00
Alibek Omarov 6eae3471cf engine: client: font: fix consecutive newlines skipped, add flag to reset color after a newline 2023-02-04 21:59:46 +03:00
Ivan Avdeev 5da5a1bc94 rt: collect stats on dirty light cells 2023-02-04 10:32:27 -08:00
Alibek Omarov c0fa91bec9 engine: client: consolidate client and menu scissor functions 2023-02-04 21:24:19 +03:00
Alibek Omarov ba6dd3c751 engine: client: font: fix another inverted check 2023-02-04 21:23:51 +03:00
Alibek Omarov fd63018fb5 engine: client: make client string drawing functions ignore linefeeds 2023-02-04 20:58:33 +03:00
Alibek Omarov 2225915702 engine: client: font: fix CL_DrawStringLen 2023-02-04 20:54:17 +03:00
Alibek Omarov d14e486721 engine: client: font: add special flag to ignore linefeeds when drawing strings 2023-02-04 20:53:52 +03:00
Ivan Avdeev 18a7c61505
#411 Trace alpha masked and transparent surfaces
Tracing alpha masked shadows is now extremely expensive, fps is roughly cut in half :(

Will need to address it separately
2023-02-03 12:22:43 -08:00
Ivan 'provod' Avdeev 51641234ab rt: fixup additive color 2023-02-03 12:00:29 -08:00
Ivan 'provod' Avdeev de6da4f03f rt: add additive transparency
known issues:
- colors are incorrect (probably because of kusok.color having the wrong value)
- mixes weirdly with denoiser
2023-02-03 11:52:39 -08:00
Ivan 'provod' Avdeev c615b9355a rt: only do alpha test shadows after opaque geometry
this honestly barely helps ;_;
2023-02-03 11:00:34 -08:00
Ivan 'provod' Avdeev 8ec8502a53 rt: unify shadowed with shadowedSky 2023-02-03 10:18:17 -08:00
Alibek Omarov 82b6da493a wscript: enforce GCC suspicious sizeof operations warnings as errors 2023-02-03 18:51:50 +03:00
Alibek Omarov bec0b36bb9 engine: client: font: fix colorcodes, don't reset Colo4ub, it will be reset by consequent draw calls anyway 2023-02-03 18:20:02 +03:00
Alibek Omarov e2c2821191 engine: client: font: do not apply filtering hack when fonts aren't upscaled 2023-02-03 18:06:07 +03:00
Alibek Omarov a19d34035d engine: client: font: do not use OpenFile on WADs >_< 2023-02-03 17:49:06 +03:00
Alibek Omarov 77ea03a62c engine: client: introduce bare-bones font manager and text drawing manager
* wire hud_fontscale so HUD font scaling can be used independently from
  hud_scale
* allow small optimizatinons, like optional UTF-8 decoding, or not calling
  SetRenderMode for each character
* even less copypasted code in text drawing between client code and console
* get rid of direct DrawCharacter calls when it can be just DrawString
* fix net_speeds, r_speeds with scaled console fonts
* try to fix MobilityAPI's pfnDrawCharacterScaled
* center keyboard keys in OSK code
2023-02-03 08:51:18 +03:00
Alibek Omarov 402a0f129d engine: platform: sdl: use SDL joystick rumble for Platform_Vibrate 2023-02-03 08:50:41 +03:00
Ivan Avdeev 3ebfb72819 fix linux linking 2023-02-02 11:07:41 -08:00
Ivan 'provod' Avdeev 395d5c4fcb rt: add alpha test for primary ray and for shadows
shadows are particularly slow
2023-02-02 10:22:52 -08:00
Alibek Omarov d7116afc92 engine: client: add hud_fontscale cvar to control HUD font scaling (not wired to any logic yet) 2023-02-02 04:57:53 +03:00
Alibek Omarov d5fe491c14 engine: client: add a little auto-disconnect message in case of server timeout 2023-02-02 02:49:25 +03:00
Ivan Avdeev 00732cd0c1
Merge pull request #410 from LifeKILLED/test-motion-vectors
Test motion vectors
2023-02-01 14:38:52 -08:00
LifeKILLED 889846f774 vk rt denoiser: fix variable initialize for linux build 2023-02-02 00:35:15 +04:00
LifeKILLED 1d0ebbcc33 vk rt denoiser: merge 2023-02-02 00:02:36 +04:00
LifeKILLED b1b644564f vk rt denoiser: merge 2023-02-02 00:01:34 +04:00
Alibek Omarov 92138428c5 engine: touch: don't emulate touch and mouse through SDL2 (taken from @Velaron branch) 2023-02-01 06:42:31 +03:00
Alibek Omarov f3ff942ea9 scripts: flatpak: add basic i386 flatpak script 2023-02-01 04:58:12 +03:00
Alibek Omarov ced6e8869a ref: fix chrome texture being misaligned 2023-02-01 04:55:47 +03:00
Alibek Omarov d7af50ea6c engine: ref: remove direction vectors from Ref API, renderers calculate them from viewangles to local data anyway 2023-01-31 07:18:23 +03:00
Alibek Omarov f7d4e5a2ea engine: server: don't show GAMESAVED message in autosaves, small refactoring 2023-01-31 07:16:08 +03:00
Alibek Omarov 2e3788f23d engine: dedicated: add CL_HudMessage to dedicated stubs 2023-01-31 07:14:26 +03:00
Alibek Omarov eaf9a9283a Revert "engine: network: do not read from uninitialized sockaddr storage"
This reverts commit 4f78ec01cf.
2023-01-31 04:33:27 +03:00
Alibek Omarov ae66291272 scripts: compiler_optimizations: added MSan target 2023-01-31 04:28:08 +03:00
Alibek Omarov 4f78ec01cf engine: network: do not read from uninitialized sockaddr storage 2023-01-31 04:14:18 +03:00
Alibek Omarov be084d5603 engine: crashhandler: fully initialize struct sigaction 2023-01-31 00:50:48 +03:00
Alibek Omarov aac0be1ab3 engine: imagelib: img_bmp: fully initialize local palette array 2023-01-31 00:50:04 +03:00
Alibek Omarov 6282acc825 engine: client: simplify drawing loading or paused bar, fix position with hud_scale active 2023-01-30 23:17:53 +03:00
Ivan 'provod' Avdeev c1cfe1008d rt: minor rt pipelines and pre-meatpipe cleanup 2023-01-30 11:31:46 -08:00
Ivan Avdeev be5e50d50b
Merge pull request #406 from w23/prev-feedback
Add previous frame images feedback
2023-01-30 10:33:28 -08:00
Ivan Avdeev 71f7449a8e comment and add additional checks for the previous commit 2023-01-30 10:21:18 -08:00
LifeKILLED 615a10c005 vk rt: remove unused struct from vk_studio.c 2023-01-30 16:36:44 +04:00
LifeKILLED 9ed9eb5451 vk rt: merge with reworked motion vectors 2023-01-30 09:01:46 +04:00
LifeKILLED 164259d6b1 rt denoiser: rework motion vectors, add simple temporal reprojection 2023-01-30 08:59:49 +04:00
Ivan 'provod' Avdeev 3a87934415 rt: add test previous frame blur 2023-01-30 08:57:16 +04:00
Ivan 'provod' Avdeev a5abde2162 rt/seba: export prev_ frame image resource index 2023-01-30 08:54:33 +04:00
LifeKILLED 571fc16c3b rt denoiser: rework motion vectors, add simple temporal reprojection 2023-01-30 08:53:18 +04:00
LifeKILLED 73c750020f merge with previous frames feedback 2023-01-30 05:23:08 +04:00
LifeKILLED 2627cb97af rt: reviewer's fixes 2023-01-30 05:15:41 +04:00
Ivan 'provod' Avdeev 3cb9ca0579 rt: add test previous frame blur 2023-01-28 14:50:43 -08:00
Ivan 'provod' Avdeev 858e3eed55 rt/seba: export prev_ frame image resource index 2023-01-28 12:55:53 -08:00
Alibek Omarov 39fd30a472 engine: client: fix HUD font loading 2023-01-27 19:07:26 +03:00
Alibek Omarov 279e391949 engine: sound: allow mouth move for CHAN_STREAM 2023-01-27 06:19:31 +03:00
Alibek Omarov 6df25392b8 engine: server: redirect special sounds, detected by leading asterisk, into CHAN_STREAM
In GoldSrc this magic symbol means that we should not override channel this
sound is playing on. Originally handled on client but for both static and dynamic sounds
so let's redirect channel on server side instead.
2023-01-27 06:19:31 +03:00
Alibek Omarov 327372e253 engine: client: call SND_ForceOpen/CloseMouth within SND_Open/CloseMouth to avoid copypasted code 2023-01-27 06:19:31 +03:00
Andrey Akhmichin 801dbaa387 engine: common: soundlib: libmpg: backport fix for CVE-2017-11126.
Original patch: https://www.mpg123.de/cgi-bin/scm/mpg123/trunk/src/libmpg123/layer3.c?view=patch&r1=4275&r2=4274
Same as: f246a0cdfd
2023-01-25 15:57:52 +03:00
Andrey Akhmichin ffd5c2d3d0 engine: common: soundlib: libmpg: backport fix for CVE-2017-12839.
Original patch: https://www.mpg123.de/cgi-bin/scm/mpg123/trunk/src/libmpg123/getbits.h?view=patch&r1=2024&r2=4323
Same as: 8a5e21a2a2
2023-01-25 15:57:52 +03:00
Alibek Omarov 84c14b32ec engine: client: fix filtering errors by adjusting texcoords by half of a pixel
Remove useless wrapper functions and conversions
Don't scale texcoords and position if hud_scale is not active
2023-01-25 04:17:48 +03:00
Alibek Omarov c481e52558 engine: client: consolidate variable and quake fixed width font loading functions 2023-01-25 02:38:18 +03:00
LifeKILLED c4881f57c9 rt denoiser: motion vectors for raytracing pipeline and for ray query 2023-01-23 04:00:36 +04:00
Ivan Avdeev 308e0962a3 update todo 2023-01-22 15:11:27 -08:00
Ivan Avdeev ab59393909
Merge pull request #403 from w23/primary-ray-compute
Convert primary ray pass to compute shader

Makes it work under open source mesa amdgpu driver (although it's ~30% slower than the old binary driver)
2023-01-22 15:09:48 -08:00
Ivan 'provod' Avdeev 28f40d5ca0 rt: compute the primary ray 2023-01-22 15:00:01 -08:00
Ivan Avdeev 9f3735240c
Merge pull request #400 from w23/rtables
Meatpipe-centric resource management
2023-01-22 13:48:51 -08:00
Ivan 'provod' Avdeev 9df38a6487 update todo 2023-01-22 13:43:33 -08:00
Ivan 'provod' Avdeev 8709f668c4 rt: track meatpipe-created resources by refcounts 2023-01-22 13:22:56 -08:00
LifeKILLED 4d370b072c vk rt denoiser: add motion vectors 2023-01-22 03:45:29 +04:00
Ivan 'provod' Avdeev d0fc84b7dd update todo 2023-01-21 13:15:49 -08:00
Ivan 'provod' Avdeev 3b77a84746 rt: make it paint things again
missing:
- proper resource destruction at exit and at meatpipe recreation time
2023-01-21 13:03:57 -08:00
Ivan 'provod' Avdeev 3e194c7c6d [wip] preregister all resources and get meatpipe to compile
still doesn't draw anything yet. needs writing descriptor values and barriers
2023-01-21 11:36:11 -08:00
Ivan Avdeev 59b3bbec08 fix linux build 2023-01-19 22:51:32 -08:00
Ivan 'provod' Avdeev 1ef9526aff [wip] begin creating gbuffer resources based on meatpipe description 2023-01-18 11:06:35 -08:00
Alibek Omarov b946ed4625 engine: platform: sdl: don't flood about closest display mode in case of no changes 2023-01-18 20:05:00 +03:00
Alibek Omarov ef1572b15b engine: crashhandler: fix build on FreeBSD (and probably on NetBSD and OpenBSD) 2023-01-18 19:45:21 +03:00
Alibek Omarov aaeb18f433 engine: inline version of MSG_BigShort 2023-01-18 19:29:27 +03:00
Alibek Omarov dd1d86c289 engine: platform: sdl: check usable display rect before creating window 2023-01-18 19:28:16 +03:00
Alibek Omarov 16b162f7bb engine: vid: position window in center by default 2023-01-18 19:27:40 +03:00
Alibek Omarov 500ca54550 Revert "engine: get rid of MSG_BigShort, use htons instead, since network headers are always included"
This reverts commit a6475f530b.
2023-01-18 19:21:51 +03:00
Ivan 'provod' Avdeev fbf2d7096d [WIP] pass resources from meatpipe to pass, track writability
doesn't draw anything yet
2023-01-16 22:57:48 -08:00
Alibek Omarov 5313dc9475 engine: client: fix uninitialized fadeTotalEnd in screenfade parsing code 2023-01-16 09:21:30 +03:00
Alibek Omarov 9c0c1a802c filesystem: fix strict order of loading archives 2023-01-15 13:12:39 +03:00
Alibek Omarov fbedbdca7d
engine: client: fix fullscreen reapplied on window resize 2023-01-14 18:52:38 +03:00
Alibek Omarov 6232e288e1 engine: client: fool proof R_SaveVideoMode 2023-01-14 11:45:42 +03:00
Alibek Omarov a6475f530b engine: get rid of MSG_BigShort, use htons instead, since network headers are always included 2023-01-14 10:58:04 +03:00
Alibek Omarov de84df99f3 engine: fix functions returning void returning void value 2023-01-14 10:58:03 +03:00
Alibek Omarov a5d5c1f60b wscript: cast-align is less effective than ubsan 2023-01-14 10:58:03 +03:00
Alibek Omarov 6ac3156a82 engine: fix discarded const pointer qualifier in PM_HullPointContents 2023-01-14 10:57:22 +03:00
Alibek Omarov 2705e77a4e ci: don't spew config.log when it's not needed, less verbosity 2023-01-14 10:06:32 +03:00
Alibek Omarov a09aa31b7a github: comment out CI builds for MAGX and Android 2023-01-14 09:52:44 +03:00
Xav101 9466461ce0
engine: preliminary support for SGI IRIX (#1211)
* Added definitions for IRIX

* Patchset to get dedicated server to compile on IRIX.

* Cleaned up debug statements in wscript

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

* Include the platform port files in the build

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

* Clean up formatting and remove unneeded debugging statements

* Added GPL copyright notice and description

* Moved to irix platform folder and edited script

* Re-introduced _inline macro

* Replace spaces with tabs

Co-authored-by: Xav101 <xaviernye@msn.com>
2023-01-14 09:35:30 +03:00
Alibek Omarov 74ce7e9b10 ref: don't apply rendercolor to studio models where it's not needed 2023-01-13 15:25:58 +03:00
Alibek Omarov 10481a4ecc github: upgrade SDL2 2023-01-13 11:50:01 +03:00
Alibek Omarov acd86ce490 engine: sound: select which to buffer raw channels will be painted to, choose stream buffer for voice 2023-01-13 08:50:33 +03:00
Alibek Omarov 1119a9ac22 engine: network: reenable DNS resolving in separate thread for Windows 2023-01-13 08:09:16 +03:00
Alibek Omarov 171c0c8d3b engine: common: zone: use stdint types 2023-01-12 04:04:53 +03:00
Alibek Omarov 9b5e0fef01 engine: common: zone: make Mem_Alloc return aligned addresses on ILP32, thanks Xav101 on Discord for heads up 2023-01-12 04:02:04 +03:00
Alibek Omarov 2f5e3b0aea mainui: update 2023-01-11 13:41:54 +03:00
Alibek Omarov ca3b0e6246 Documentation: document the _i?86 quirk in library naming scheme 2023-01-10 04:59:28 +03:00
Alibek Omarov eb0459a045 engine: strip Intel suffixes from server library name, but only on special platforms
Remove same code from filesystem, it's not what filesystem should do
2023-01-10 04:51:34 +03:00
Alibek Omarov 5d98e13fb8 public: add Q_ArcitectureStringByID function to get library naming compliant CPU and ABI string 2023-01-09 22:53:05 +03:00
Alibek Omarov 113904ea91 public: fix build 2023-01-09 22:47:54 +03:00
Alibek Omarov 1dc3cc2d57 public: add Q_PlatformStringByID function that returns library naming compliant string by platform identifier from buildenums 2023-01-09 08:06:58 +03:00
Alibek Omarov 15a5975abf public: build.h refactoring, removed XASH_MSVC, XASH_MINGW, as this header never intended to detect the compiler 2023-01-09 08:05:59 +03:00
Alibek Omarov 65debeb738 public: add header buildenums.h declaring all platforms, architectures and ABIs as integer constants. 2023-01-09 08:04:58 +03:00
Alibek Omarov 209a03a12a engine, public: prepare to removal of XASH_MSVC macro 2023-01-09 08:01:52 +03:00
Alibek Omarov c28aeb2362 engine: make crashhandler implementation choice private to crashhandler code 2023-01-09 07:55:54 +03:00
Alibek Omarov 9152bbf106 engine: client: more accurate decompilation of CL_LerpPoint and ComputeInterpolationAmount 2023-01-07 11:08:32 +03:00
Alibek Omarov 40ba0238f8 engine: client: cosmetic changes in pmove code 2023-01-07 11:07:32 +03:00
Alibek Omarov 4a3efa511c engine: client: correctly decompiled version of CL_AdjustClock (with removed useless float-to-int operation) 2023-01-07 07:23:14 +03:00
Alibek Omarov 2479d28cd5 engine: remove useless pfnHullPointContents wrapper 2023-01-06 00:38:05 +03:00
Alibek Omarov 787d3bc5dd engine: share playermove ClearPhysEnts function 2023-01-06 00:28:24 +03:00
Alibek Omarov 0bec78a958 engine: client: make few function between pmove and client interface shared, remove unused CL_PointContents wrapper 2023-01-06 00:09:36 +03:00
Alibek Omarov e305b81df0 engine: merge PM_TraceTexture into PM_TraceTexturePmove 2023-01-05 23:59:31 +03:00
Alibek Omarov 4cb109abe0 engine: make playermove funcs truly shared between client and server 2023-01-05 23:50:42 +03:00
Alibek Omarov 49a65edfc3 engine: imagelib: img_quant: fix a bug in quantizer (thanks, @SNMetamorph for fix) 2023-01-05 07:24:24 +03:00
Alibek Omarov c6bfc82019 ref: soft: implement screenshots 2023-01-05 07:09:23 +03:00
Alibek Omarov a4865fd2fc engine: client: fix ScreenFade FFADE_MODULATE rendering, more accurate alpha blending 2023-01-05 06:09:10 +03:00
Alibek Omarov 4bbd0cc404 ref: add new special rendermode that specifically used for modulate mode in engine's ScreenFade 2023-01-05 06:07:56 +03:00
Alibek Omarov 4684f174ee public: completely get rid of PATH_SEPARATOR macros 2023-01-05 06:06:07 +03:00
Alibek Omarov 34eb258cae filesystem: dir: remove PATH_SEPARATOR, fix return value when directory is caseinsensitive 2023-01-04 22:34:45 +03:00
Alibek Omarov b4c0ccbede filesystem: fix _wstat usage under Windows, remove PATH_SEPARATOR usage, fix listdirectory 2023-01-04 22:33:59 +03:00
Alibek Omarov 51b5d7a41d engine: host: ensure we always have right slashes under Windows 2023-01-04 19:39:52 +03:00
Alibek Omarov 15846a8ea8 filesystem: use POSIX funcs for Windows too, where possible, apply wide char conversion for Sys functions 2023-01-04 18:10:33 +03:00
Alibek Omarov e694081626 filesystem: dir: guarantee file existense in FS_FixFileCase for caseinsensitive directories 2023-01-04 18:09:00 +03:00
Alibek Omarov cb9605430d filesystem: bump FS_API_VERSION (removed unused argument from SysFileExists) 2023-01-04 18:07:18 +03:00
Alibek Omarov 80507b2eca engine: mod_bmodel: fix const qualifier discard warning 2023-01-04 17:55:59 +03:00
Alibek Omarov ed47346ef1 engine: crashhandler: fix _GNU_SOURCE redefined warning 2023-01-04 17:54:45 +03:00
Alibek Omarov 75ccd2283b public: fix Q_memmem counting haystack size incorrectly 2023-01-04 17:17:18 +03:00
Alibek Omarov 409edf5a70 filesystem: zip: use stdint types, use enum for errors 2023-01-04 17:15:40 +03:00
Alibek Omarov d047dfc319 engine: add few lines in mod_bmodel back, got removed in previous commits accidentally 2023-01-03 18:26:18 +03:00
Alibek Omarov 13ed2742b2 engine: check for bsp30ext before trying to use extended clipnodes, fix 32-bit clipnodes check 2023-01-03 07:50:50 +03:00
Alibek Omarov 03a3fb83b6 filesystem: write extended fields to gameinfo.txt, as this function is used to write game info when using rodir 2023-01-03 07:34:05 +03:00
Alibek Omarov df1c9a5029 engine: simplify blue shift swapped lump check, change TestBmodelLumps to avoid reading past mod buffer 2023-01-03 07:01:39 +03:00
Alibek Omarov 07e622f224 public: add generic implementation for Q_memmem 2023-01-03 06:58:58 +03:00
Alibek Omarov aa3a0fa392 engine: server: increase infostring size in SV_Info allowing longer hostnames but try to cut off if it's even longer than that 2023-01-03 04:01:53 +03:00
Alibek Omarov c1287b3950 engine: client: speed up reconnect for legacy servers 2023-01-03 03:19:46 +03:00
Alibek Omarov e5763e2e9a filesystem: dir: check dir casesensitivity after dir entries list was properly initialized 2023-01-03 01:15:28 +03:00
Alibek Omarov 42a3c7b059 filesystem: dir: fix dir entry cache init in case of directory was empty previously 2023-01-03 00:24:57 +03:00
Alibek Omarov e621c98602 engine: network: do not crash if one of v4 or v6 socket opening failed but crash if both. Fix hostport/clientport cvars usage 2022-12-30 02:06:15 +03:00
Alibek Omarov eb7eb4acbc engine: client: cl_scrn: minor refactoring 2022-12-30 01:58:26 +03:00
Alibek Omarov e5b32fe8ac engine: client: force nearest filter for HUD textures and sprites to avoid artifacts with hud_scale 2022-12-30 01:57:10 +03:00
Alibek Omarov 52061621ac engine: client: do not let client.dll overwrite usercmd that's was read from demo 2022-12-27 23:10:11 +03:00
Alibek Omarov 339711c3c7 filesystem: dir: check casefold directory flag 2022-12-27 02:31:46 +03:00
Alibek Omarov 256fe7ede9 scripts: make sure to test filesystem on CI 2022-12-27 02:31:46 +03:00
Alibek Omarov 2febe632c5 filesystem: add caseinsensitive emulation test 2022-12-27 02:31:46 +03:00
Alibek Omarov c454e37064 filesystem: allow to init with NULL overrides 2022-12-27 02:31:46 +03:00
Alibek Omarov fe1aba3561 filesystem: apply caseinsensitivity to file creation
Replace fs_writedir with fs_writepath, exposing current writeable searchpath.
Fix caseinsensitive FS_Search
Remove unused argument from listdirectory()
Minor optimizations and refactoring
2022-12-27 02:31:46 +03:00
Alibek Omarov 41aa867a21 engine: common: don't try to delete now non-existing config file after backing up 2022-12-27 02:31:46 +03:00
Alibek Omarov b36ebc294f filesystem: dir: exit from loop immediately if directory is caseinsensitive 2022-12-27 02:31:46 +03:00
Alibek Omarov 3d71e5d111 filesystem: dir: fix merging existing cache with new directory entries 2022-12-27 02:31:46 +03:00
Alibek Omarov ac59f25375 DO NOT MERGE filesystem: add naive FixFileCase 2022-12-27 02:31:46 +03:00
Alibek Omarov 3393e2d95c filesystem: implement directory entries caching, to avoid excessive directory listing syscalls to emulate case-insensitive filesystems
* simplify game directory initialization code
2022-12-27 02:31:46 +03:00
Alibek Omarov e1ea3387ee common: rename PATH_SPLITTER to PATH_SEPARATOR, change it's type to character 2022-12-27 02:31:46 +03:00
Alibek Omarov 071638794a public: redefine Q_strpbrk to C standard version, add Q_strchrnul 2022-12-27 02:31:46 +03:00
Alibek Omarov 953dd3d1a7 wscript: tidy up checks, add check for GNU strchrnul 2022-12-27 02:31:46 +03:00
Andrey Akhmichin 12bb0ca44b engine: server: Fix broken description for saves. 2022-12-25 04:26:00 +03:00
MoeMod Server #2 499cd48e83 filesystem: fix lseek for mpg123 2022-12-24 22:02:58 +03:00
Andrey Akhmichin 444e08f59a engine: common: simplify strings operations. 2022-12-21 03:26:41 +03:00
Andrey Akhmichin 9450c08eec engine: server: simplify strings operations. 2022-12-21 03:26:11 +03:00
Alibek Omarov 18e68f1ab3
filesystem: fix missing cast 2022-12-20 16:34:23 +03:00
Andrey Akhmichin 7555fefc18 ref: gl: simplify strings operations. 2022-12-20 16:11:21 +03:00
Andrey Akhmichin f4fb8b4ac2 engine: client: simplify strings operation. 2022-12-20 16:07:34 +03:00
Andrey Akhmichin 0d5cd89144 engine: client: Fix access to uninitialized variable. 2022-12-20 16:06:41 +03:00
Andrey Akhmichin e273e09fc9 engine: platform: win32: simplify strings operations. 2022-12-20 16:06:25 +03:00
Alibek Omarov 327017421c
engine: common: zone: redefine poolhandle_t back to pointer for 32-bit systems 2022-12-19 18:38:49 +03:00
Alibek Omarov 6e179346c9
common: redefine poolhandle_t back to pointer for 32-bit systems 2022-12-19 18:36:31 +03:00
Alibek Omarov ee218f36e0 filesystem: pak: no need to free files ptr anymore 2022-12-17 00:25:20 +03:00
Alibek Omarov f3400c983e engine: network: fix address comparator 2022-12-15 12:25:03 +03:00
Alibek Omarov 9397301a73 filesystem: remove excessive filename field from archive structs, use common in searchpath_t. Small optimizations for PAK 2022-12-15 04:06:38 +03:00
Alibek Omarov f1ec612819 filesystem: hungry 2022-12-15 01:06:20 +03:00
Alibek Omarov 08f834cd82 filesystem: make all archive searchpath functions private 2022-12-15 00:59:52 +03:00
Alibek Omarov 48c17d08d9 filesystem: dir: move searchpath initialization to dir.c, make all DIR functions static 2022-12-15 00:52:09 +03:00
Alibek Omarov f20fddee1c common: bspfile: add separate definitions for clipnodes limit for HLBSP and QBSP2 2022-12-15 00:42:40 +03:00
Alibek Omarov 754d55beef engine: common: fix for HLBSP extended clipnodes hack when BSP2 support is enabled 2022-12-13 11:34:42 +03:00
Alibek Omarov cd813bbfbe engine: server: do not apply sound precache check for sentences, as they may start with 0 index 2022-12-13 11:12:08 +03:00
Alibek Omarov 07afbd64d4 engine: common: host: force set HOST_FRAME status for dedicated as it finished initializing 2022-12-13 10:54:06 +03:00
Alibek Omarov af7d6f6fa8 engine: common: no point to allow if and else commands in unprivileged mode since scripting is available only for privileged 2022-12-12 08:18:00 +03:00
Alibek Omarov cb0f513bf0 engine: common: allow cvar substituion in privileged mode only to prevent leaking sensitive data 2022-12-12 08:14:01 +03:00
Alibek Omarov a3ef6c955c engine: don't double register rcon_password cvar 2022-12-12 08:13:24 +03:00
Alibek Omarov 60e7a7aa23 engine: server: set correct flags for rcon_ cvars on server 2022-12-12 08:05:55 +03:00
Alibek Omarov e1431e1040 engine: server: add rcon_enable cvar to control whether server should accept remote commands 2022-12-12 08:02:56 +03:00
Alibek Omarov b794f2fda0 mainui: update 2022-12-12 07:56:03 +03:00
Alibek Omarov 934d9ba69a filesystem: fix FS_GetDiskPath 2022-12-12 06:54:42 +03:00
Alibek Omarov 9e54ddfd55 engine: client: treat dem_unknown as no-op, until we find real cause of empty holes in demoheader 2022-12-12 06:31:54 +03:00
Alibek Omarov a86a24d33d mainui: update 2022-12-12 06:30:47 +03:00
Alibek Omarov fe9ed0ac9b engine: client: gameui: add new NET_CompareAdrSort function to menu API 2022-12-12 06:30:47 +03:00
Alibek Omarov 18c94b6ec4 engine: common: add network address comparator function 2022-12-12 06:30:47 +03:00
SNMetamorph 8fa0290e25 Documentation: extensions: added page about expanded common structures 2022-12-11 22:59:17 +03:00
SNMetamorph 080cd146dd common: com_model: changed common structs reserved fields type to intptr_t 2022-12-11 22:59:17 +03:00
SNMetamorph b1d910a3a5 engine: client: fixed connection hang when all resources downloaded (fix #829) 2022-12-09 19:20:53 +03:00
SNMetamorph 840283d6e5 engine: netchan: fixed fragbufs very high memory usage 2022-12-09 19:20:53 +03:00
SNMetamorph d72481e5ac engine: netchan: fixed downloading files output directory 2022-12-09 19:20:53 +03:00
SNMetamorph dbe9309475 engine: netchan: fixed wrong compressed file size calculation 2022-12-09 19:20:53 +03:00
Alibek Omarov 9fa4de6ee8 mainui: update 2022-12-08 06:55:32 +03:00
Alibek Omarov fd3c5e8384 ref: gl: VBO is disabled unless somebody picks it up and fixes memory corruption and other bugs 2022-12-08 06:50:12 +03:00
Alibek Omarov d50ed1c087 engine: common: host: don't prepend # to command arguments when changing game to dedicated, it wasn't used and implement anymore 2022-12-08 05:44:17 +03:00
Alibek Omarov e48133bf4b engine: server: fix sv_log output for enttools usage 2022-12-08 05:40:36 +03:00
Alibek Omarov ea3bfd969c engine: imagelib: img_wad: dirty hack to fix black holes in console background images 2022-12-08 05:40:11 +03:00
Alibek Omarov 7469d6a248 engine: server: implement server-to-master challenge extension, to secure server from IP spoofing 2022-12-07 23:39:57 +03:00
Alibek Omarov 859f36afce engine: server: remove Master_Add call in ActivateServer, server will announce itself through heartbeat 2022-12-07 23:14:34 +03:00
Alibek Omarov 436a788ac8 engine: client: disable FPS counter by default 2022-12-07 21:54:23 +03:00
Velaron 5098e24806 engine: client: touch: fix empty list when opening touch buttons menu for the first time 2022-12-07 15:35:51 +03:00
Alibek Omarov 1d8acc16f1 engine: server: give master server a small time window to reply (by default 4000 ms, should be enough even when master server is overloaded) 2022-12-06 20:28:44 +03:00
Alibek Omarov 802c7a86a9 engine: platform: sdl: add pause and scrolllock handlers 2022-12-06 11:50:38 +03:00
Alibek Omarov 406eb828da ref: gl: disable underwater distortion by default, enable for Quake compatible mode only 2022-12-05 11:59:29 +03:00
Alibek Omarov 0e9106685b engine: imagelib: img_png: fix Mem_Free on null ptr 2022-12-05 06:13:04 +03:00
Alibek Omarov 9b001987e9 engine: imagelib: fix crash when chunk length is more than file size 2022-12-05 05:39:41 +03:00
Alibek Omarov 5c2c02c317 engine: common: custom: use IL_LOAD_PLAYER_DECAL flag when loading custom player decals 2022-12-05 04:56:07 +03:00
Alibek Omarov 21c898d796 engine: imagelib: validate player decal image size (max 512x512) 2022-12-05 04:55:24 +03:00
Alibek Omarov e48b708fa6 engine: imagelib: img_png: validate image size through common engine function 2022-12-05 04:54:20 +03:00
Alibek Omarov ccf7619ae5 engine: imagelib: refactor image loading function 2022-12-05 03:22:07 +03:00
Alibek Omarov eabbd0061f mainui: update 2022-12-05 03:22:07 +03:00
Alibek Omarov 7d0d6b8e0d engine: common: host: implement adaptive sleeptime, log time to first time for debug purposes 2022-12-05 03:22:07 +03:00
Alibek Omarov eb36fe0155 filesystem: fill searchpath DIR functions only if file was found in direct path 2022-12-05 03:22:07 +03:00
Alibek Omarov 9381a40506 filesystem: check only DLLs for encryption 2022-12-05 03:22:07 +03:00
SNMetamorph a19270a0dc engine: client: max fragment size test retries increased to 3 2022-12-04 23:29:26 +03:00
SNMetamorph c34ce2d9e1 engine: client: fixed max fragment size wrong calculation 2022-12-04 23:29:26 +03:00
SNMetamorph 58465c3727 engine: common: fixed dedicated server bug
The problem is server wasn't executing server.cfg if map specified in startup parameters
2022-12-04 23:29:26 +03:00
Andrey Akhmichin 177ed2c603 engine: common: simplify strings operations. 2022-12-04 22:37:45 +03:00
Andrey Akhmichin 7bb994f7bc engine: common: imagelib: img_png.c: fix wrong palette decoding. 2022-12-04 22:09:24 +03:00
Andrey Akhmichin 0c4f35e2d0 filesystem: simplify strings operations. 2022-12-04 22:08:06 +03:00
Andrey Akhmichin 3287501f97 engine: client: simplify strings operations. 2022-12-04 22:04:07 +03:00
Andrey Akhmichin 2454594a18 engine: server: simplify strings operations. 2022-12-04 22:03:48 +03:00
Alibek Omarov 4daab23e2d mainui: update 2022-12-04 05:31:02 +03:00
Alibek Omarov 51161004eb engine: common: simplify string operations 2022-12-04 05:26:22 +03:00
Alibek Omarov 6477f1656e filesystem: simplify string operation 2022-12-04 05:26:22 +03:00
Alibek Omarov 270e2a76a8 engine: soundlib: simplify string operation 2022-12-04 05:26:22 +03:00
Alibek Omarov c61442e960 engine: imagelib: simplify string operation 2022-12-04 05:26:22 +03:00
Alibek Omarov d0928af355 mainui: update to png-decals branch 2022-12-04 05:26:22 +03:00
Alibek Omarov 674093517e 3rdparty: update various submodules 2022-12-02 21:29:51 +03:00
Alibek Omarov ebf3877cda engine: common: throw an error message into log in normal mode too! 2022-12-02 21:22:22 +03:00
Alibek Omarov e97310c441 engine: common: net_ws: fix uninitialized family in IPSocket 2022-12-02 21:21:53 +03:00
Alibek Omarov cbe3e608b6 engine: client: add cl_logoext cvar that's used by mainui to tell the engine which logo must be packed 2022-12-01 18:25:21 +03:00
Alibek Omarov f30f23ba51 engine: common: validate and load PNG images in customization 2022-12-01 18:25:11 +03:00
Alibek Omarov 1ba117a8e9 engine: client: netgraph: fix few global-buffer-overflow errors 2022-12-01 18:23:52 +03:00
Alibek Omarov d9a245dcb5 engine: reset cheat cvars on remote games 2022-12-01 02:44:01 +03:00
Alibek Omarov 9cbf5ab6a6 engine: client: streamline constructing master server scan request through common function 2022-12-01 01:51:07 +03:00
Alibek Omarov c9e4e62474 engine: client: allow IPv6 in NetAPI 2022-12-01 00:35:05 +03:00
Alibek Omarov aa6a1db0a9 engine: remove duplicate svc_strings definition 2022-12-01 00:34:33 +03:00
Alibek Omarov e9d66be10a mainui: update 2022-11-29 13:30:06 +03:00
Alibek Omarov 8b6f12418e engine: common: make few network cvars privileged 2022-11-29 13:29:47 +03:00
Alibek Omarov 7013d447ca engine: client: get rid of s_registration_sequence, it was incorrect way to look for unused sounds. We're trying to rely on cl.servercount here 2022-11-28 07:54:24 +03:00
Alibek Omarov 93b2f535e2 engine: client: tune max commands/max backup commands values for legacy protocol 2022-11-27 18:26:53 +03:00
Alibek Omarov 591d572870 mainui: update 2022-11-27 06:02:42 +03:00
SNMetamorph 3ab749cc2e engine: client: cl_tent: fixed incorrect players spray textures update 2022-11-27 04:50:30 +03:00
SNMetamorph 084fac3606 engine: common: hpak: fixed rest of bugs in HPAK_AddLump 2022-11-27 04:50:30 +03:00
Alibek Omarov f377461fdf engine: common: made a filter for a filter (lol), so it's possible to play selected games with cl_filterstuffcmd enabled 2022-11-27 04:45:03 +03:00
SNMetamorph a2971ce939 filesystem: fixed uninitialized pointers in FS_FindFile when fs_ext_path enabled 2022-11-26 02:45:18 +03:00
SNMetamorph 65671d8788 engine: common: minor code fixes in hpak.c 2022-11-25 23:05:48 +03:00
Andrey Akhmichin 809d5f1aa8 engine: client: in_touch.c: add spray button. 2022-11-25 22:32:33 +03:00
SNMetamorph 49fc6143ab engine: common: imagelib: fixed loading 32 bits per pixel BMP files 2022-11-25 22:30:49 +03:00
SNMetamorph 8717843333 engine: common: imagelib: fixed BMP files estimate size calculation with NPOT textures 2022-11-25 22:30:49 +03:00
SNMetamorph f6d8996968 engine: common: imagelib: added missed BMP compression type macros 2022-11-25 22:30:49 +03:00
Alibek Omarov 9389305072 engine: common: set cl_filterstuffcmd to 1 by default 2022-11-25 22:23:51 +03:00
Alibek Omarov b6bd4bc6f8 engine: server: precisely set client connected time after they were spawned 2022-11-25 05:45:20 +03:00
Alibek Omarov 4c6fbafd20 mainui: update 2022-11-25 02:37:07 +03:00
Velaron 43c6175918 filesystem: dir.c: safer string operations 2022-11-24 03:19:21 +03:00
Velaron fcd741e2b8 filesystem: fix FS_FixFileCase behavior 2022-11-24 03:19:15 +03:00
Velaron 89807250e5 filesystem: dir.c: optimize string operations 2022-11-24 03:19:10 +03:00
Velaron 24f7db19d8 filesystem: switch file operations to an interface 2022-11-24 03:19:05 +03:00
SNMetamorph 49d93c0e76 engine: common: custom: increased custom decal size limit to 128Kb, added wrong size warning 2022-11-22 17:59:41 +03:00
SNMetamorph 707c93c32c engine: common: hpak: all file operations made to use gamedir only 2022-11-22 17:59:41 +03:00
SNMetamorph e204f05726 engine: client: fixed players spray textures not being updated 2022-11-22 17:59:41 +03:00
SNMetamorph 3bd8ad50d2 ref: gl: fixed crash when opening "Customize" menu 2022-11-21 22:52:27 +03:00
Andrey Akhmichin 3488d4e65f public: simplified strings operations. 2022-11-18 19:32:17 +03:00
Alibek Omarov 3da736a1eb engine: server: try to solve issue when server dll has no voice mgr 2022-11-17 21:06:15 +03:00
Alibek Omarov e30c61c0e2 common: netadr: use static_assert macro 2022-11-17 19:44:47 +03:00
Alibek Omarov 64e97124c3 Merge master to ipv6 2022-11-17 19:34:46 +03:00
Alibek Omarov 46979419ae wscript: check Android's log library globally 2022-11-17 01:23:33 +03:00
Alibek Omarov 30d9b6d844 engine: platform: win32: fix compile 2022-11-17 01:20:01 +03:00
Alibek Omarov 88045ce3be ref: gl: link liblog for Android 2022-11-17 01:08:11 +03:00
Alibek Omarov dd881d3da9 engine: server: remove duplicate function 2022-11-16 23:37:26 +03:00
Alibek Omarov 76d0608ee1 ref: fix beams end point 2022-11-16 22:54:07 +03:00
Alibek Omarov a894ca60c6 engine: client: vgui: fix vgui viewport height being limited at 480 pixels 2022-11-16 22:05:31 +03:00
Alibek Omarov 023f6712f9 engine: client: always toggle mouse on when in console, menu or typing chat message 2022-11-16 21:14:48 +03:00
Alibek Omarov 42740149ac engine: client: fix mouse cursor being hidden in background map 2022-11-16 21:02:41 +03:00
Alibek Omarov 7b74015c4d engine: server: check if player can hear other before sending voicedata 2022-11-16 20:59:18 +03:00
Alibek Omarov 57c71efe53 Documentation: fix wrong envvar in windows xcompile instructions, better wording 2022-11-16 04:25:34 +03:00
Alibek Omarov 45de874598 wscript: always load msvc options 2022-11-16 04:20:02 +03:00
Alibek Omarov aa702f0678 scripts: waifulib: xcompile: add msvc-wine support in cross-compile helper script 2022-11-16 04:19:46 +03:00
Alibek Omarov 927dccc71d Documentation: add simple instructions on how to cross-compile for Windows from normal operating systems 2022-11-16 04:19:07 +03:00
Alibek Omarov c2a24fbbce engine: client: put internal vgui shutdown AFTER HUD_Shutdown, to simulate default, external behavior 2022-11-14 20:12:10 +03:00
SNMetamorph ae94a6aeba engine: client: fixed client VGUI API shutdown 2022-11-14 20:09:20 +03:00
Alibek Omarov e9da43666c engine: client: fix loading internal vgui (thx @SNMetamorph) 2022-11-14 20:08:01 +03:00
Alibek Omarov d27dd68072 engine: client: vgui: rework loading VGUI and probing client for internal vgui support API 2022-11-12 16:35:18 +03:00
Alibek Omarov b1ee27a3f3 filesystem: add new token internal_vgui_support to mark client dlls that have internal VGUI implementation(to support other UI systems) 2022-11-12 16:35:18 +03:00
SNMetamorph 32372654c2 engine: server: sv_client: fixed working ent_create command on XashXT/PrimeXT 2022-11-11 16:12:56 +03:00
Alibek Omarov 17d0b19f9e engine: use generic S_USAGE macro everywhere 2022-11-10 13:18:20 +03:00
Alibek Omarov d13f7f06e4 engine: fix framerate being capped to 60FPS with vsync, remove vid_displayfrequency cvar. Never sleep with vsync or timedemo, for accuracy 2022-11-10 13:05:03 +03:00
Alibek Omarov f469b56b93 engine: host: only sleep once between frames 2022-11-10 12:42:48 +03:00
Alibek Omarov ef74f86ce2 Documentation: restore enttools docs from old engine wiki 2022-11-10 12:37:51 +03:00
Alibek Omarov 616cbdb1eb engine: client: change cl_cmdrate and cl_smoothtime default values to match GoldSrc 2022-11-10 12:11:16 +03:00
Alibek Omarov 0a49e69818 engine: introduce Sys_DebugBreak function to raise an exception for debugger 2022-11-10 12:10:48 +03:00
Alibek Omarov adb8ec1da8 filesystem: try to normalize linux gamedll path for liblist.gam 2022-11-10 11:58:44 +03:00
SNMetamorph 5d73c6cb84 engine: server: backported enttools from old engine 2022-11-10 11:56:10 +03:00
SNMetamorph afa1d429fe engine: client: backported enttool from old engine 2022-11-10 11:56:10 +03:00
SNMetamorph d1309c3aeb engine: common: backported "set" command from old engine 2022-11-10 11:56:10 +03:00
SNMetamorph b35cf6e30c engine: platform: update VGUI cursor state in Platform_SetCursorType 2022-11-08 06:39:09 +06:00
SNMetamorph 8cbe0e5b30 engine: client: vgui: added VGui_UpdateInternalCursorState function 2022-11-08 06:39:09 +06:00
Andrey Akhmichin c1fe547925 public: update miniz to version 3.0.0 from upstream. 2022-11-06 12:35:04 +06:00
Andrey Akhmichin 1064b41ab2 readme: update. 2022-11-05 10:45:47 +06:00
Andrey Akhmichin 2a6c2e5db4 .github: workflows: update github actions. 2022-11-05 10:43:15 +06:00
Bien Pham 816337a7bb filesystem: set root directory as static
Counter-Strike uses COM_ExpandFileName to get
full path to filesystem_stdio. When reading liblist.gam,
the engine will clear the search path and the root search path
will be cleared. Set it as static so it will be excluded from clearing.
2022-11-02 18:07:25 +06:00
Andrey Akhmichin d237114962 engine: common: imagelib: img_png.c: unroll loops. 2022-11-02 14:14:05 +06:00
Andrey Akhmichin c1ca2c1a95 Documentation: opensource-mods.md: add "Oz Deathmatch". 2022-10-27 01:53:27 +06:00
SNMetamorph 44a43c2c09 engine: client: cl_parse: minor code fix in CL_ParseLegacyServerData 2022-10-27 00:52:16 +06:00
SNMetamorph ee8098839e engine: common: pm_trace: fixed non portable code in PM_ConvertTrace 2022-10-27 00:52:16 +06:00
Alibek Omarov 305b2579eb engine: client: voice: fix crackling voice file input on low FPS 2022-10-19 01:08:39 +03:00
Alibek Omarov 1a09d297ee engine: minimize SetCursorType calls count 2022-10-13 14:49:48 +03:00
Alibek Omarov d45e6e0ad1 engine: platform: sdl: SetCursorType shouldn't know about current game state 2022-10-13 14:07:48 +03:00
Alibek Omarov 2d2523df4a engine: client: touch: generalise touch emulation code
* fix doubleclicks and wheels in VGUI
2022-10-12 05:18:19 +03:00
Alibek Omarov 5a0fcfffb0 mainui: update 2022-10-10 13:09:01 +03:00
Alibek Omarov f252161d90
readme: fix typo and wording 2022-10-04 15:14:54 +03:00
Alibek Omarov e0216e2658
wscript: don't clean QtCreator files and reconfigure saved options
Cleanup imports
2022-10-04 03:02:49 +03:00
Alibek Omarov 0f2bb5720b wscript: respect --libdir argument with packaging enabled. Fix a typo in --disable-soft description 2022-10-02 22:28:53 +03:00
Alibek Omarov 0621e365ff mainui: update 2022-09-27 17:19:32 +03:00
Alibek Omarov 8ea455def7 mainui: update 2022-09-27 14:00:18 +03:00
Alibek Omarov 8cf822c426 mainui: update 2022-09-27 14:00:18 +03:00
Alibek Omarov 4a009c1c2c engine: client: touch: move copypasted code from export & writeconfig into separate function 2022-09-27 14:00:18 +03:00
Alibek Omarov 360dc4f7ed engine: try to make hashpaks more compatible between 32-bit and 64-bit platforms 2022-09-20 21:57:13 +03:00
Alibek Omarov ffe43e1f22 scripts: waifulib: fix error reporting in zip.py 2022-09-20 21:56:25 +03:00
Alibek Omarov a52d901f25 common: add STATIC_ASSERT macro
We're trying to guess if we have C11 static_assert defined in assert.h
otherwise use good ol' trick with negative array
2022-09-20 21:55:32 +03:00
Alibek Omarov 5bae2f06ad engine: platform: sdl: do not lock audio device, for some reason it sometimes causes problems although it shouldn't 2022-09-20 21:29:19 +03:00
Alibek Omarov 69b0954007 engine: change RenderAPI's RenderGetParm return type to intptr_t to insure compatibility with 64-bit 2022-09-20 18:06:19 +03:00
Alibek Omarov 0645402946 engine: fix crash when reading GoldSrc hashpaks 2022-09-19 06:03:01 +03:00
Владислав Сухов c59b244d04 scripts: gha: fix path to vgui_support submodule 2022-09-17 15:55:40 +03:00
Alibek Omarov 5678d9a253 engine: server: support MAP_ANON synonym for MAP_ANONYMOUS, disable allocating string pool near server library for OSX 2022-09-12 08:42:50 +03:00
dettlaff a520d245a6
wscript: fix typo in --enable-bundled-deps configure option 2022-09-12 07:18:24 +03:00
Alibek Omarov b56f6fa330 scripts: waifulib: fix zipfile init for older Python 2022-09-11 02:50:52 +03:00
Alibek Omarov f141869ce3 wscript: disable building extras.pk3 for Android 2022-09-11 02:22:26 +03:00
Alibek Omarov 807f3852bd scripts: gha: remove building extras.pak, as it's already being built 2022-09-11 02:20:36 +03:00
Alibek Omarov 084089b919 3rdparty: extras: build ZIP archive and install to engine default gamefolder 2022-09-11 02:13:23 +03:00
Alibek Omarov f571a41cf3 wscript: allow to setup engine default gamedir during configure 2022-09-11 02:12:44 +03:00
Alibek Omarov 686a966ff7 wscript: now waf builds extras archive by itself, using Python standard library's zipfile 2022-09-11 01:39:29 +03:00
Alibek Omarov c29eb458ea 3rdparty: add xash-extras submodule 2022-09-11 01:38:17 +03:00
Alibek Omarov 234c843f60 filesystem: integrate inotify for file changes 2022-09-10 22:55:07 +03:00
Alibek Omarov 7ed0499aa9 game_launch: wscript: fix Windows build 2022-09-10 22:52:52 +03:00
Alibek Omarov 401b145040 utils: mdldec: fix wscript to build 2022-09-10 22:52:52 +03:00
Alibek Omarov 3853ff5435 3rdparty: gl4es: add wscript to build 2022-09-10 22:52:52 +03:00
Alibek Omarov 744c6b2680 vgui_support: update submodule 2022-09-10 22:52:52 +03:00
Alibek Omarov 030a17fc58 mainui: update submodule 2022-09-10 22:52:52 +03:00
Alibek Omarov b1e2e84a11 wscript: adapt main and ref_gl wscripts to new directory layout, add flag to build all renderers at once 2022-09-10 22:52:52 +03:00
Alibek Omarov 12a6088912 ref: gl: move GLES wrappers libraries to 3rdparty folder 2022-09-10 22:52:52 +03:00
Alibek Omarov fe9f3f78a0 ref: soft: minimize dependency on internal engine headers 2022-09-10 22:52:52 +03:00
Alibek Omarov 327eb330ed ref: gl: minimize dependency on internal engine headers 2022-09-10 22:52:52 +03:00
Alibek Omarov 470121512a utils: mdldec: convert to include targets usage 2022-09-10 22:52:52 +03:00
Alibek Omarov dedc144b8b ref: soft: convert to include targets usage 2022-09-10 22:52:52 +03:00
Alibek Omarov 6d37398fad ref: gl: convert to include targets usage 2022-09-10 22:52:52 +03:00
Alibek Omarov 3c8fe508f0 game_launch: convert to include targets usage 2022-09-10 22:52:52 +03:00
Alibek Omarov 8ffb3aac8a engine: wscript: add dummy engine_includes target that only exposes few internal Xash headers for renderers and utils use 2022-09-10 22:52:52 +03:00
Alibek Omarov 0ed9391969 filesystem: wscript: add dummy filesystem_includes target that only exposes public filesystem_stdio include paths 2022-09-10 22:52:52 +03:00
Alibek Omarov e54289f811 public: wscript: add dummy sdk_includes target that only exposes standard HLSDK include paths 2022-09-10 22:52:52 +03:00
Alibek Omarov 17b091e5a9 wscript: adapt to new folder structure 2022-09-10 22:52:52 +03:00
Alibek Omarov 61c142e2db ref: move renderers into ref subdirectory 2022-09-10 22:52:52 +03:00
Alibek Omarov 7e664679a0 3rdparty: move mainui and vgui_support submodules into 3rdparty folder 2022-09-10 22:52:52 +03:00
Andrey Akhmichin fd152e82e8 engine: common: imagelib: img_png.c: add support for indexed and grayscale PNG images. 2022-09-08 12:11:02 +03:00
Alibek Omarov 0c50e43663 engine: client: enable sound for TE_TAREXPLOSION, use same sound parameters as GoldSrc 2022-09-08 04:16:29 +03:00
Alibek Omarov 7a2ac4a9c0 engine: client: use generic particles code for blob particles (from tempentity code) only if Quake compatibility was enabled 2022-09-08 04:16:29 +03:00
Andrey Akhmichin e6bb9d980d engine: client: in_touch.c: make touch buttons extention-independent. 2022-09-05 11:25:52 +03:00
Alibek Omarov 45cc7e5bcc 3rdparty: opus: update submodule 2022-08-31 19:51:52 +03:00
Alibek Omarov 4be4870982 engine: client: remove voice_codecinfo command, as Opus Custom don't give any encoder info, possibly an Opus bug 2022-08-31 19:50:31 +03:00
Alibek Omarov 19c2061831 wscript: define CUSTOM_MODES and try to link with export that only exists when CUSTOM_MODES was defined in build-time 2022-08-31 19:48:42 +03:00
Alibek Omarov 3a8c58d192 engine: platform: sdl: fix parentheses around IsAudioError macro 2022-08-31 07:13:02 +03:00
Alibek Omarov 24763f9b07 engine: server: request client to use Opus Custom codec 2022-08-31 06:54:58 +03:00
Alibek Omarov 0d7a2e7bad engine: platform: change capture API to allow locking/unlocking buffer to prevent race condition, use single function for pause 2022-08-31 06:50:06 +03:00
Alibek Omarov 82ab06efdd engine: client: voice: new version, move to Opus Custom codec
* Despite Opus Custom have strict requirements, it's more barebones, allowing us to use maximum
frame size and custom sample rate, without resampling
* Encode each frame size to network buffer, allowing smooth voice chat even in 10 FPS
* Fix possible buffer overruns, underruns and races with platform side
* Revise all usages of offset variables, samples vs bytes
2022-08-31 06:44:45 +03:00
Alibek Omarov 4110ee0928 wscript: require Opus Custom for build
Apparently, not all Linux distributions enable it. Anyway, we can build codec ourselves
2022-08-31 05:44:23 +03:00
Alibek Omarov 4b05cf4399 engine: client: better fix for notify debug messages, rely on host.allow_console variable to don't allow uninitialized console usage 2022-08-31 02:46:33 +03:00
Alibek Omarov f29a9f5f58 ref_gl: use skybox names generated by CheckSkybox function, don't checking same file twice
Also fixes priority for skyboxes
2022-08-31 02:42:19 +03:00
Alibek Omarov 28001ea150 engine: client: enable notify messages in non-developer mode 2022-08-28 00:48:12 +03:00
Alibek Omarov f633b3dbf6 engine: increase MAX_INIT_MSG to 192 kilobytes limit
* also avoid magic number in sv_client.c
2022-08-27 22:13:21 +03:00
Alibek Omarov bebfa611fc mainui: update 2022-08-25 21:47:17 +03:00
Alibek Omarov 3e9f2df2bf engine: client: fix incorrect mark for ConsolePrint notifications 2022-08-25 21:21:22 +03:00
Alibek Omarov fce8afabfb filesystem: allow acquiring C interface through CreateInterface export 2022-08-25 20:33:16 +03:00
Alibek Omarov 9d49985100 scripts: gha: build tarball for dedicated server 2022-08-25 19:40:27 +03:00
Alibek Omarov a7d4cafe10 wscript: finally disable building opus for dedicated 2022-08-25 19:33:16 +03:00
Alibek Omarov ca2a6635b6 engine: common: fix cmdlist and cvarlist to match the beginning of command or cvar 2022-08-25 19:22:06 +03:00
Alibek Omarov 7f1bb9b4a6 public: introduce Q_strnicmpext function
The goal is to provide both string compare with fixed length and simple pattern match
2022-08-25 19:21:47 +03:00
Alibek Omarov 7341a6b020 engine: client: add old GoldSrc feature where ConsolePrint could print to notification zone, similar to Con_NPrintf( 0, ... ) 2022-08-25 18:22:43 +03:00
Alibek Omarov ac05acf6dc
engine: network: I'm fucking blind 2022-08-23 20:04:59 +03:00
Alibek Omarov 3e1db432df
engine: network: fix IPv4 private address checks according to RFC1918
Thanks to @Mr0maks for the fix
2022-08-23 19:15:50 +03:00
Alibek Omarov 3c682507e7 engine: client: voice: notify client.dll about localplayer twice, through special loopback index and normal index 2022-08-22 11:44:13 +03:00
SNMetamorph e9ae6d08b5 engine: client: enable interpolation of local player angles 2022-08-22 10:24:15 +03:00
Alibek Omarov f435a81c97 engine: soundlib: rewrite sfx resampler, fix possible crash if sfx is too long
- make same rate and same width resamples noop, as everything signed now
- minimize comparisons in loop body
2022-08-22 10:14:01 +03:00
Alibek Omarov cb34c23844 common: increase MAX_MAP_MODELS to 1024, to match PrimeXT compilers 2022-08-21 17:27:48 +03:00
SNMetamorph 9f9141823a engine: added audio backend print to s_info command 2022-08-20 15:36:02 +03:00
Владислав Сухов d3437c70bd engine: soundlib: fix wrong sample rate unit 2022-08-20 15:35:14 +03:00
Alibek Omarov 8630ef2c67 engine: client: voice: allow using inputfromfile when microphone isn't connected 2022-08-20 06:13:33 +03:00
Alibek Omarov 0b50678912 engine: client: voice: refactor, fix issues when missing mic disables voice chat, fix few possible crashes and memory leaks 2022-08-20 03:56:54 +03:00
Alibek Omarov 22ff45f5d0 engine: platform: add audio capture shutdown functions 2022-08-20 03:17:51 +03:00
Alibek Omarov 905bbf1515 engine: server: read full voicedata message even if voice is disabled server wide 2022-08-19 22:22:40 +03:00
Alibek Omarov 88c1b1400d gitignore: add enc_temp_folder by the request of @SNMetamorph 2022-08-19 22:18:22 +03:00
SNMetamorph 8e48a98d48 engine: client: voice: codec quality levels changed 2022-08-19 20:47:01 +03:00
SNMetamorph 76dbefb9ec engine: client: voice: fixed initialization checks 2022-08-19 20:47:01 +03:00
Alibek Omarov 327dcc0293 engine: client: voice: simplify code, simplify including voice.h, do not depend on opus headers globally
Autofix few code style mistakes
2022-08-19 05:52:53 +03:00
Alibek Omarov e6c55107c7 wscript: fix game_launch not being included 2022-08-19 05:38:47 +03:00
Alibek Omarov c5dbbea9ef engine: server: drop bots fake ping to zero 2022-08-19 04:33:41 +03:00
SNMetamorph 74707551ae engine: client: voice: fixed hanging voice status 2022-08-19 04:14:25 +03:00
SNMetamorph 2f5f5ef0a6 engine: client: voice: fixed sound playback from file 2022-08-19 04:14:25 +03:00
SNMetamorph f7dc9d8e72 engine: client: voice: frame size increased to 40 msec 2022-08-19 04:14:25 +03:00
Alibek Omarov 238162bb79 wscript: move system opus detection to main wscript, so we can avoid including subproject 2022-08-19 04:03:53 +03:00
Alibek Omarov 1fda8753bd wscript: rework subproject filtering, use lambdas everywhere. Deprecate --ignore-projects flag, use Waf capability to select targets instead 2022-08-19 03:10:34 +03:00
SNMetamorph a688bed79f engine: client: cl_parse: moved buffer to stack in CL_ParseVoiceData 2022-08-18 04:46:11 +03:00
SNMetamorph b0ff51d5a0 engine: client: voice: changed bitrate units to kbps in voice_codecinfo 2022-08-18 04:46:11 +03:00
SNMetamorph 68f633e9cd wscript: fixed opus include path 2022-08-18 04:46:11 +03:00
SNMetamorph a520af42e8 wscript: opus subproject set as mandatory 2022-08-18 04:46:11 +03:00
SNMetamorph 0a6885e02d engine: client: voice chat cvars set as privileged 2022-08-18 04:46:11 +03:00
SNMetamorph aa5a509316 engine: client: voice: added GPL notice 2022-08-18 04:46:11 +03:00
SNMetamorph 97879430e9 engine: small code fixes related to voice chat 2022-08-18 04:46:11 +03:00
SNMetamorph ae97eae42f engine: client: voice: implemented automatic gain control 2022-08-18 04:46:11 +03:00
SNMetamorph c5d7e3c783 engine: client: fixed players voice state changing 2022-08-18 04:46:11 +03:00
SNMetamorph 9bcd36cc24 engine: voice code minor refactoring 2022-08-18 04:46:11 +03:00
SNMetamorph c6881a425f engine: client: added support for variable voice chat quality 2022-08-18 04:46:11 +03:00
SNMetamorph 8d0209b122 engine: server: added support for variable voice chat quality 2022-08-18 04:46:11 +03:00
SNMetamorph 279894cfd4 engine: client: added console command voice_codecinfo 2022-08-18 04:46:11 +03:00
SNMetamorph 169ee14724 engine: client: disabled voice on legacy protocol servers 2022-08-18 04:46:11 +03:00
SNMetamorph 8866d5cfd6 engine: wscript: added Opus headers to include directories 2022-08-18 04:46:11 +03:00
SNMetamorph 3b9a7910d0 opus: fixed path to submodule 2022-08-18 04:46:11 +03:00
SNMetamorph b5885d4107 3rdparty: opus: wscript: removed Opus demo sources from build 2022-08-18 04:46:11 +03:00
SNMetamorph a254a342b1 engine: voice: minor code fixes 2022-08-18 04:46:11 +03:00
SNMetamorph 0db95d76a8 engine: wscript: removed opus from opt.load() 2022-08-18 04:46:11 +03:00
Alibek Omarov 69a9211fc9 engine: include voice.h globally 2022-08-18 04:46:11 +03:00
Alibek Omarov 44cd03f464 wscript: refactor opus wscript files, now it builds only if system package wasn't found 2022-08-18 04:46:11 +03:00
Velaron 9242a0a510 engine: update voice 2022-08-18 04:46:11 +03:00
Velaron 2b9e050f57 engine: voice support 2022-08-18 04:46:11 +03:00
Alibek Omarov 9d4fe707bb engine: client: carefully check legacy server response, check info string before passing it to UI 2022-08-17 21:52:54 +03:00
Alibek Omarov 0d2552c3f6 engine: server: prevent DoS through master server query 2022-08-17 21:23:08 +03:00
Alibek Omarov b3c9637422 engine: server: send server info to all master servers 2022-08-17 21:18:16 +03:00
Alibek Omarov 01a3321d63 engine: client: only accept server list from master servers (thanks @tyabus for idea) 2022-08-17 21:17:51 +03:00
Alibek Omarov 5a5e72c424 engine: print current bug-compatibility level, if enabled 2022-08-17 14:44:03 +03:00
Alibek Omarov b8dc7494eb engine: client: move timescale pitch apply to channel mixing 2022-08-16 00:03:44 +03:00
Alibek Omarov 532cd779a7 Documentation: document bug compatibility mode 2022-08-15 06:00:00 +03:00
Alibek Omarov d202a6c572 engine: server: emulate pfnPEntityOfEntIndex bug only with explicitly enabled GoldSrc bug compatibility 2022-08-15 06:00:00 +03:00
Alibek Omarov 6e864e4f8f engine: introduce bug compatibility levels
* for now we only have GoldSrc bug compatibility, can be used for
  games that require precise GoldSrc behaviour, like CSCZDS
* enabled with -bugcomp command line
* added text in --help
2022-08-15 06:00:00 +03:00
Alibek Omarov 6ef76fe665 engine: server: fix bots are counted as real players 2022-08-13 22:46:20 +03:00
Alibek Omarov 314672d82c engine: client: fix invalid playerinfo being accessed by renderer 2022-08-13 01:29:45 +03:00
Alibek Omarov 1d558b33d6 engine: client: don't let set unsupported con_charset 2022-08-13 00:58:45 +03:00
Alibek Omarov 911385d019 engine: client: fix memory leak on player disconnect 2022-08-13 00:47:04 +03:00
SNMetamorph 5b97c2135a engine: server: fixed "wrong version" spamming in NAT bypass mode (fix #953) 2022-08-10 04:11:17 +03:00
Alibek Omarov 365f24e1fe
waf.bat: use unicode charset
Fixes compiler messages in Russian
2022-08-09 13:47:38 +03:00
Alibek Omarov 7157c3b441 engine: platform: sdl: don't enable high dpi code for Apple
It seems enables HighDPI awareness but doesn't create HighDPI OpenGL context
It needs some plist magic to be enabled back again
2022-08-08 23:53:20 +03:00
Alibek Omarov 2b8b3e1993 engine: server: new IP filter, rewritten with IPv6 in mind 2022-06-09 03:10:02 +03:00
Alibek Omarov b0a889d1a1 engine: bring back simple netadr_t, as we don't care about IPv4-to-IPv6 mapped addresses anymore 2022-06-09 03:10:02 +03:00
Alibek Omarov bd1bfea695 engine: second iteration of IPv6 support
Made code smaller
Fixed problem where v6 and v4 socket can't use same port
Added support for v4-to-v6 mapped addresses, although it's kept unused
Probably final version
2022-06-09 03:10:02 +03:00
Alibek Omarov a1299e1dfe common: third iteration of ipv6 netadr_t, now binary compatible with v4-to-v6 mapped addresses 2022-06-09 03:10:02 +03:00
Alibek Omarov 1a5a76a201 engine: common: minor fixes to ipv6text library 2022-06-09 03:10:02 +03:00
Alibek Omarov b072b627a2 engine: enable getaddrinfo on Windows, fix build 2022-06-09 03:10:02 +03:00
Alibek Omarov 5d18c6d678 engine: fix declaration-after-statement 2022-06-09 03:10:02 +03:00
Alibek Omarov 59fba30a52 engine: IPv6 support
* v6 equivalent cvars
* hostname resolving for v6
* fix for nonblocking hostname resolve (inverted check)
* enabled by default, probably should be disabled for dedicated servers
2022-06-09 03:10:02 +03:00
Alibek Omarov 193cde83b6 engine: add IPv6 address parsing/printing library from GameNetworkingSockets 2022-06-09 03:10:02 +03:00
Alibek Omarov 12bfb8f795 common: another approach on netadr_t with better compatibility 2022-06-09 03:10:02 +03:00
Alibek Omarov 9ae72dbc47 common: update netadr_t structure to include IPv6 addresses 2022-06-09 03:10:02 +03:00
702 changed files with 52147 additions and 29040 deletions

View File

@ -1,5 +1,13 @@
name: Build & Deploy Engine
on: [push, pull_request]
on:
push:
paths-ignore:
- '**.md'
- 'ref/vk/data/**'
pull_request:
paths-ignore:
- '**.md'
- 'ref/vk/data/**'
jobs:
# cleanup:
# runs-on: self-hosted
@ -13,27 +21,34 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-18.04
- os: ubuntu-20.04
targetos: linux
targetarch: amd64
- os: ubuntu-18.04
- os: ubuntu-20.04
targetos: linux
targetarch: i386
# TODO enable and test ref_vk for it too
# - os: ubuntu-aarch64-20.04
# targetos: linux
# targetarch: aarch64
# - os: ubuntu-18.04
# targetos: android
# targetarch: 32
# - os: ubuntu-18.04
# targetos: android
# targetarch: 64
# - os: ubuntu-20.04
# targetos: android
# targetarch: 32
# - os: ubuntu-20.04
# targetos: android
# targetarch: 64
# - os: ubuntu-18.04
# targetos: motomagx
# targetarch: armv6
# - os: ubuntu-20.04
# targetos: motomagx
# targetarch: armv6
# - os: ubuntu-20.04
# targetos: nswitch
# targetarch: arm64
# - os: ubuntu-20.04
# targetos: psvita
# targetarch: armv7hf
- os: windows-latest
targetos: win32
targetarch: amd64
@ -41,33 +56,84 @@ jobs:
targetos: win32
targetarch: i386
env:
SDL_VERSION: 2.0.14
VULKAN_SDK_VERSION: 1.2.176.1
SDL_VERSION: 2.26.2
VULKAN_SDK_VERSION: 1.3.239
GH_CPU_ARCH: ${{ matrix.targetarch }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ANDROID_SDK_TOOLS_VER: 4333796
UPLOADTOOL_ISPRERELEASE: true
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
submodules: recursive
- name: Checkout xash-extras
uses: actions/checkout@v2
with:
repository: FWGS/xash-extras
path: xash-extras
- name: Install dependencies
run: bash scripts/gha/deps_${{ matrix.targetos }}.sh
- name: Build engine
run: bash scripts/gha/build_${{ matrix.targetos }}.sh
- name: Upload engine (prereleases)
run: bash scripts/continious_upload.sh artifacts/*
- name: Upload engine (artifacts)
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: artifact-${{ matrix.targetos }}-${{ matrix.targetarch }}
path: artifacts/*
# See https://github.com/w23/xash3d-fwgs/issues/430
# flatpak:
# name: "Flatpak"
# runs-on: ubuntu-latest
# strategy:
# matrix:
# include:
# - app: su.xash.Engine.Compat.i386
# container:
# image: bilelmoussaoui/flatpak-github-actions:freedesktop-22.08
# options: --privileged
# env:
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# UPLOADTOOL_ISPRERELEASE: true
# steps:
# - name: Checkout
# uses: actions/checkout@v3
# with:
# submodules: recursive
# - name: Build flatpak (Compat.i386)
# uses: FWGS/flatpak-github-actions/flatpak-builder@v5
# with:
# bundle: ${{ matrix.app }}.flatpak
# manifest-path: scripts/flatpak/${{ matrix.app }}.yml
# - name: Upload engine (prereleases)
# run: bash scripts/continious_upload.sh ${{ matrix.app }}.flatpak
# Completely disable uplodaing, as it does not make any sense for Vulkan branch for now
# release:
# name: "Upload releases"
# runs-on: ubuntu-latest
# needs: [build, flatpak]
# if: ${{ github.event_name == 'push' }}
# steps:
# - name: Remove old release
# uses: FWGS/delete-tag-and-release@v0.2.1-dev
# with:
# tag_name: ${{ github.ref_name == 'master' && 'continuous' || format('continuous-{0}', github.ref_name) }}
# delete_release: true
# github_token: ${{ secrets.GITHUB_TOKEN }}
# - name: Fetch artifacts
# uses: actions/download-artifact@v3.0.1
# with:
# path: artifacts/
# - name: Repackage binaries and allow GitHub to process removed release for few seconds
# run: |
# cd artifacts/
# for i in artifact-* su.xash.Engine.*; do
# mv "$i"/* .
# rm -rf "$i"
# done
# ls -R .
# cd ../
# sleep 20s
# - name: Upload new release
# uses: FWGS/action-gh-release@v0.1.15
# with:
# name: Xash3D FWGS Continuous ${{ github.ref_name }} Build
# tag_name: ${{ github.ref_name == 'master' && 'continuous' || format('continuous-{0}', github.ref_name) }}
# prerelease: true
# token: ${{ secrets.GITHUB_TOKEN }}
# files: artifacts/*
# draft: false

16
.github/workflows/for_ignored.yml vendored Normal file
View File

@ -0,0 +1,16 @@
name: Pass through for ignored files
on:
push:
paths:
- '**.md'
- 'ref/vk/data/**'
pull_request:
paths:
- '**.md'
- 'ref/vk/data/**'
jobs:
check:
runs-on: ubuntu-20.04
steps:
- name: Always pass
run: echo "OK"

7
.gitignore vendored
View File

@ -60,6 +60,7 @@ Makefile.dep
ALL_BUILD.*
INSTALL.*
ZERO_CHECK.*
CMakeLists.txt
# Visual Studio
*.obj
@ -216,7 +217,7 @@ publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
@ -338,3 +339,7 @@ core
*.code-workspace
.history/*
.cache/*
enc_temp_folder/
# KDevelop4
*.kdev4

19
.gitmodules vendored
View File

@ -1,16 +1,21 @@
[submodule "mainui"]
path = mainui
url = https://github.com/zgdump/mainui_cpp
branch = vk_menu
path = 3rdparty/mainui
url = https://github.com/FWGS/mainui_cpp
[submodule "ref_gl/nanogl"]
path = ref_gl/nanogl
path = 3rdparty/nanogl
url = https://github.com/FWGS/nanogl
[submodule "ref_gl/gl-wes-v2"]
path = ref_gl/gl-wes-v2
path = 3rdparty/gl-wes-v2
url = https://github.com/FWGS/gl-wes-v2
[submodule "ref_gl/gl4es"]
path = ref_gl/gl4es
path = 3rdparty/gl4es/gl4es
url = https://github.com/ptitSeb/gl4es
[submodule "vgui_support"]
path = vgui_support
path = 3rdparty/vgui_support
url = https://github.com/FWGS/vgui_support
[submodule "opus"]
path = 3rdparty/opus/opus
url = https://github.com/xiph/opus
[submodule "3rdparty/xash-extras"]
path = 3rdparty/extras/xash-extras
url = https://github.com/FWGS/xash-extras

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

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

1
3rdparty/extras/xash-extras vendored Submodule

@ -0,0 +1 @@
Subproject commit 853f633be18892499a86e7f57fecf34640bd64f2

1
3rdparty/gl-wes-v2 vendored Submodule

@ -0,0 +1 @@
Subproject commit 7ba4631bf5e921284100d10923b6980af66d98e8

1
3rdparty/gl4es/gl4es vendored Submodule

@ -0,0 +1 @@
Subproject commit 5226f5f9370eebe874dae0525ad5d878a3b66faf

24
3rdparty/gl4es/wscript vendored Normal file
View File

@ -0,0 +1,24 @@
#! /usr/bin/env python
# encoding: utf-8
import os
def options(opt):
pass
def configure(conf):
if not conf.path.find_dir('gl4es') or not conf.path.find_dir('gl4es/src'):
conf.fatal('Can\'t find gl4es submodule. Run `git submodule update --init --recursive`.')
return
def build(bld):
gl4es_srcdir = bld.path.find_node('gl4es/src')
bld.stlib(source = gl4es_srcdir.ant_glob(['gl/*.c', 'gl/*/*.c', 'glx/hardext.c']),
target = 'gl4es',
features = 'c',
includes = ['gl4es/src', 'gl4es/src/gl', 'gl4es/src/glx', 'gl4es/include'],
defines = ['NOX11', 'NO_GBM', 'NO_INIT_CONSTRUCTOR', 'DEFAULT_ES=2', 'NOEGL', 'EXTERNAL_GETPROCADDRESS=GL4ES_GetProcAddress', 'NO_LOADER', 'STATICLIB'],
cflags = ['-w', '-fvisibility=hidden', '-std=gnu99'],
subsystem = bld.env.MSVC_SUBSYSTEM,
export_includes = '.')

1
3rdparty/mainui vendored Submodule

@ -0,0 +1 @@
Subproject commit e456555cf159d2e858694b53fa92717c84e8870e

1
3rdparty/nanogl vendored Submodule

@ -0,0 +1 @@
Subproject commit 6b6a947ee0c32abceea3e111364b0225af36df61

1
3rdparty/opus/opus vendored Submodule

@ -0,0 +1 @@
Subproject commit 8cf872a186b96085b1bb3a547afd598354ebeb87

40
3rdparty/opus/wscript vendored Normal file
View File

@ -0,0 +1,40 @@
#! /usr/bin/env python
# encoding: utf-8
import os
def options(opt):
pass
def configure(conf):
if not conf.path.find_dir('opus') or not conf.path.find_dir('opus/src'):
conf.fatal('Can\'t find opus submodule. Run `git submodule update --init --recursive`.')
return
# TODO: ARM/x86 intrinsics detection
# TODO: maybe call autotools/cmake/meson instead?
def build(bld):
sources = bld.path.ant_glob([
'opus/src/*.c',
'opus/celt/*.c',
'opus/silk/*.c',
'opus/silk/float/*.c'
], excl = [
'opus/src/repacketizer_demo.c',
'opus/src/opus_demo.c',
'opus/src/opus_compare.c',
'opus/celt/opus_custom_demo.c'
])
includes = ['opus/include/', 'opus/celt/', 'opus/silk/', 'opus/silk/float/']
defines = ['USE_ALLOCA', 'OPUS_BUILD', 'FLOAT_APPROX', 'PACKAGE_VERSION="1.3.1"', 'CUSTOM_MODES']
bld.stlib(
source = sources,
target = 'opus',
features = 'c',
includes = includes,
defines = defines,
subsystem = bld.env.MSVC_SUBSYSTEM,
export_includes = ['opus/include/']
)

1
3rdparty/vgui_support vendored Submodule

@ -0,0 +1 @@
Subproject commit 521cf5cb6c3ee0804e5478d8858ec3fba67c1377

View File

@ -1,3 +1,42 @@
# Specific instructions for this fork
## Introduction
1. This fork's only concern is the `ref_vk` Vulkan/RT renderer. Engine and other renderers issues and functionality are absolutely out of scope, unless directly and specifically related to `ref_vk`.
2. Primary focus is Ray Tracing with PBR materials. "Traditional" (triangle rasterization) mode is low proirity and has quite a few known issues and deficiencies.
3. The primary development branch is `vulkan`, it should contain the latest working and stable code. Other branches (including `master`) are not supported.
4. Check out the upstream xash3d-fwgs CONTRIBUTING.md too.
## Reporting issues
1. Precondition: you're supposed to know how to build and run stuff manually. It is not ready to be used by non-developers.
2. This is a very actively developing project. There are lots of known issues. Search them first.
3. Run with `-dev 2 -log -vkdebug -vkvalidate -vkverboselogs` and provide `engine.log`.
4. Specify detailed steps to reproduce. A savefile might be helpful too.
5. Although it is deducible from the log, provide the following information explicitly: map, location, OS, GPU, driver version.
6. Attach a screenshot if possible (i.e. if it is not a crash at init time)
## Contributing code
We are very glad to hear that you want to help. And there are certainly quite a few issues that could be worked on in parallel.
The renderer code is being mostly written as a for-fun-only hobby project by a single person who has neither mental capacity nor time to make and maintain a comprehensive documentation or development structure.
Making it a collaboration effort with multiple active participants would require a completely different approach to development, communication, and progress tracking. We might or might not be able to get there eventually.
That said, we are still happy to hear that you'd like to help. Your involvement might be instrumental to reorganize and allow more collaborators.
Strongly suggested checklist for contributing anything, **before you start writing any code that you'd like to land here**:
1. Find an existing issue (e.g. with `good first issue` label), or suggest your own.
2. Let us know that you'd want to work on it, e.g. by leaving a comment on it. **Why:** any given issue might be stale, no longer relevant, being actively worked on as part of something else, or conflicting with some other approach being deliberated.
3. Work with us on a design review for the issue. **Why:** this is live C codebase, it is rather fragile and is constantly changing. There are no good practices or stable building blocks. It is also a bit idiosyncratic in places. We just know more context about where are we going to, and where we might be heading. You might also get into surprising conflicts with things that we're working on. There are unfortunately no stable scaffolding or guardrails that would allow for easy independent collaboration yet. Working on a design review means that we'll suggest a compatible way of doing things, and will schedule our work to minimize conflicts with yours.
4. Open a draft PR as early as possible, even if it is not ready yet. That way we can coordinate effort, suggest things and anwer any questions.
## Code and PR
1. Do not worry that much about code style. Be reasonable, try to either imitate the surrounding code (which has no strict style yet), or follow upstream recommendations listed below under `Code style` section.
2. Try to limit your changes, e.g. don't re-format lines which are not crucial to your change.
3. Ping us in the PR if you're not hearing any feedback for a couple of days. I'm usually way too busy *with life* to be on the internets all the time, but a little nudge might be able to allocate some attention.
---------------------------------------------
# UPSTREAM XASH3D-FWGS CONTRIBUTING.md FOLLOWS
---------------------------------------------
## If you are reporting bugs
1. Check you are using latest version. You can build latest Xash3D FWGS for yourself, look to README.md.

View File

@ -0,0 +1,17 @@
# Bug-compatibility in Xash3D FWGS
Xash3D FWGS has special mode for games that rely on original engine bugs.
In this mode, we emulate the behaviour of selected functions that may help running mods relying on engine bugs, but enabling them by default may break majority of other games.
At this time, we only have implemented GoldSrc bug-compatibility. It can be enabled with `-bugcomp` command line switch.
## GoldSrc bug-compatibility
### Emulated bugs
* `pfnPEntityOfEntIndex` in GoldSrc returns NULL for last player due to incorrect player index comparison
### Games and mods that require this
* Counter-Strike: Condition Zero - Deleted Scenes

View File

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

View File

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

24
Documentation/donate.md Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

112
Documentation/gameinfo.md Normal file
View File

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

View File

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

View File

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

View File

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

49
Documentation/psvita.md Normal file
View File

@ -0,0 +1,49 @@
## PlayStation Vita port
### Prerequisites
1. Make sure your PSVita is [set up to run homebrew applications](https://vita.hacks.guide/).
2. Install [kubridge](https://github.com/TheOfficialFloW/kubridge/releases/) by copying `kubridge.suprx` to your taiHEN plugins folder (usually `ux0:/tai`) and add it to your `config.txt`, for example:
```
*KERNEL
ux0:tai/kubridge.skprx
```
3. Install `libshacccg.suprx` by following [this guide](https://cimmerian.gitbook.io/vita-troubleshooting-guide/shader-compiler/extract-libshacccg.suprx).
### Installation
1. If you have an old vitaXash3D install, remove it.
2. Get `xash3d-fwgs-psvita.7z` from the latest [automatic build](https://github.com/FWGS/xash3d-fwgs/releases/tag/continuous).
3. Install `xash.vpk` from the 7z archive onto your PSVita.
4. Copy the `data` directory from the 7z archive to the root of your PSVita's SD card.
5. Copy the valve folder and any other mod folders from your Half-Life install to `ux0:/data/xash3d/` (you can use other mountpoints instead of `ux0`). **Do not overwrite anything.**
### Build instructions
1. Install [VitaSDK](https://vitasdk.org/).
2. Build and install [vitaGL](https://github.com/Rinnegatamante/vitaGL):
```
git clone https://github.com/Rinnegatamante/vitaGL.git
make -C vitaGL NO_TEX_COMBINER=1 HAVE_UNFLIPPED_FBOS=1 HAVE_PTHREAD=1 SINGLE_THREADED_GC=1 MATH_SPEEDHACK=1 DRAW_SPEEDHACK=1 HAVE_CUSTOM_HEAP=1 -j2 install
```
3. Build and install [vita-rtld](https://github.com/fgsfdsfgs/vita-rtld):
```
git clone https://github.com/fgsfdsfgs/vita-rtld.git && cd vita-rtld
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make -j2 install
```
4. Build and install [this SDL2 fork](https://github.com/Northfear/SDL) with vitaGL integration:
```
git clone https://github.com/Northfear/SDL.git && cd SDL
mkdir build && cd build
cmake -DCMAKE_TOOLCHAIN_FILE=${VITASDK}/share/vita.toolchain.cmake -DCMAKE_BUILD_TYPE=Release -DVIDEO_VITA_VGL=ON ..
make -j2 install
```
5. Use `waf`:
```
./waf configure -T release --psvita
./waf build
```
6. Copy all the resulting `.so` files into a single folder:
```
./waf install --destdir=xash3d
```
7. `xash.vpk` is located in `build/engine/`.

View File

@ -2,31 +2,32 @@
[![GitHub Actions Status](https://github.com/w23/xash3d-fwgs/actions/workflows/c-cpp.yml/badge.svg)](https://github.com/w23/xash3d-fwgs/actions/workflows/c-cpp.yml)
## TL;DR
- ![image](https://github.com/w23/xash3d-fwgs/assets/321361/12200b56-df80-4d33-b433-71f5690fb4f5)
- This fork adds Vulkan renderer to Xash3D-FWGS engine.
- This is work-in-progress. It is in very early stages and is not ready for unsupervised usage.
- This is work-in-progress. It is in early stages and is not ready for unsupervised usage.
- Vulkan renderer targets two different modes:
- Traditional rasterizer. It is intended to produce pixel-perfect identical frames to existing GL renderer as possible.
- Ray tracing. It implements real time path traced global illumination lighting with PBR materials. It will look noticeably different from original game.
- It is intended to be merged back into upstream/master when it gets mature and stable enough.
- It primarily focuses Half-Life 1 game. Mods compatibility is not being considered at this time. This may change with maturity of the new renderer.
- Ray tracing requires 64-bit build. 32-bit drivers do not expose vulkan ray tracing extensions.
- For more information, check out the [wiki](https://github.com/w23/xash3d-fwgs/wiki).
- [Page on Mod DB](https://www.moddb.com/mods/half-life-rtx) (screenshots, etc).
## Current status
- Not ready for any use.
- See Issues and [ref_vk/TODO.md](ref_vk/TODO.md)
- Traditional rasterizer works with some issues.
- See [issues](https://github.com/w23/xash3d-fwgs/issues) and [project](https://github.com/users/w23/projects/2/views/12)
- Traditional rasterizer mostly works:
- Works on Windows and Linux with any Vulkan GPU (and at some point it worked on Raspberry Pi 4 even).
- It is slower than OpenGL renderer (1. I suck at Vulkan. 2. No visibility culling is performed).
- Some features are not implemented yet: most of blending modes, some studio models features, sprites, beams, decals, tri api, etc)
- Some features are not implemented yet, like decals, dynamic lighting is different and way off, etc.
- Ray tracer mostly works too, with dynamic GI and stuff.
- It misses roughly the same set of features as traditional rasterizer (code is the same for the most part).
- It also requires material remaster (i.e. newer textures for PBR parameters) and missing RAD files for most of the game maps. Work on these haven't been started yet.
- It also requires material remaster (i.e. newer textures for PBR parameters) and missing RAD files for most of the game maps.
- Works under both Windows and Linux.
- Works on both AMD and Nvidia GPUs.
- If you feel adventurous, you can follow [build instructions](https://github.com/w23/xash3d-fwgs/wiki/64-bit-build-on-Windows). Note that they might be slightly out of date, kek.
- Works on Steam Deck with _interactive framerates_.
- If you feel adventurous, you can follow [build instructions](https://github.com/w23/xash3d-fwgs/wiki/How-to-build-a-64bit). Note that they might be slightly out of date, kek.
## Follow development
This project is 99.999% developed live on stream. I'm not a graphcis programmer, and have no idea what I'm doing. I'm essentially learning Vulkan, game engine renderer development, linear algebra, and ray tracing techniques while getting hands dirty with this. This is all for your amusement.
This project is 99% developed live on stream. I'm not a graphics programmer, and have no idea what I'm doing. I'm essentially learning Vulkan, game engine renderer development, linear algebra, and ray tracing techniques while getting hands dirty with this. This is all for your amusement.
You can watch me making a fool of myself publicly here:
- [Archive playlist on YouTube/floba23](https://www.youtube.com/playlist?list=PLP0z1CQXyu5CrDa522FklxbOC0SM_Manl)
@ -38,39 +39,36 @@ Regular upstream Xash3D README.md follows.
---
# 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/) \
[![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 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.
Read more about Xash3D on ModDB: https://www.moddb.com/engines/xash3d-engine
```
Xash3D FWGS is a heavily modified fork of an original [Xash3D Engine](https://www.moddb.com/engines/xash3d-engine) by Unkle Mike.
## Donate
[![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
* HLSDK 2.4 support.
* Crossplatform: supported x86 and ARM on Windows/Linux/BSD/Android. ([see docs for more info](Documentation/ports.md))
* Modern compilers support: say no more to MSVC6.
* Better multiplayer support: multiple master servers, headless dedicated server.
* Mobility API: allows better game integration on mobile devices(vibration, touch controls)
* Different input methods: touch, gamepad and classic mouse & keyboard.
* Steam Half-Life (HLSDK 2.4) support.
* Crossplatform and modern compilers support: supports Windows, Linux, BSD & Android on x86 & ARM and [many more](Documentation/ports.md).
* Better multiplayer support: multiple master servers, headless dedicated server, voice chat and IPv6 support.
* Multiple renderers support: OpenGL, GLESv1, GLESv2 and Software.
* Advanced virtual filesystem: `.pk3` and `.pk3dir` support, compatibility with GoldSrc FS module, fast case-insensitivity emulation for crossplatform.
* 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.
* Multiple renderers support: OpenGL, GLESv1, GLESv2, Software
* A set of small improvements, without broken compatibility.
## Planned fork features
* Virtual Reality support and game API
* Voice support
* Vulkan renderer
* External VGUI support module.
* PNG & KTX2 image format support.
* [A set of small improvements](Documentation/), without broken compatibility.
## Installation & Running
0) Get Xash3D FWGS binaries: you can use [testing](https://github.com/FWGS/xash3d-fwgs/releases/tag/continuous) build or you can compile engine from source code.
1) Copy engine binaries to some directory.
2) Copy `valve` directory from [Half-Life](https://store.steampowered.com/app/70/HalfLife/) to directory with engine binaries.
If your CPU is NOT x86 compatible or you're running 64-bit version of the engine, you may want to compile [Half-Life SDK](https://github.com/FWGS/hlsdk-xash3d).
If your CPU is NOT x86 compatible or you're running 64-bit version of the engine, you may want to compile [Half-Life SDK](https://github.com/FWGS/hlsdk-portable).
This repository contains our fork of HLSDK and restored source code for some of the mods. Not all of them, of course.
You still needed to copy `valve` directory as all game resources located there.
3) Run the main executable (`xash3d.exe` or AppImage).
@ -89,10 +87,10 @@ NOTE: NEVER USE GitHub's ZIP ARCHIVES. GitHub doesn't include external dependenc
### Prerequisites
If your CPU is x86 compatible, we are building 32-bit code by default. This was dont for keeping compatibility with Steam releases of Half-Life and based on it's engine games.
If your CPU is x86 compatible, we are building 32-bit code by default. This was done to maintain compatibility with Steam releases of Half-Life and based on it's engine games.
Even if Xash3D FWGS does support targetting 64-bit, you can't load games without recompiling them from source code!
If your CPU is NOT x86 compatible or you decided build 64-bit version of engine, you may want to compile [Half-Life SDK](https://github.com/FWGS/hlsdk-xash3d).
If your CPU is NOT x86 compatible or you decided build 64-bit version of engine, you may want to compile [Half-Life SDK](https://github.com/FWGS/hlsdk-portable).
This repository contains our fork of HLSDK and restored source code for some of the mods. Not all of them, of course.
#### Windows (Visual Studio)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

24
common/synctype.h Normal file
View File

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

View File

@ -4,12 +4,17 @@
#include "build.h"
#if XASH_IRIX
#include <port.h>
#endif
#if XASH_WIN32
#include <wchar.h> // off_t
#endif // _WIN32
#include <sys/types.h> // off_t
#include STDINT_H
#include <assert.h>
typedef unsigned char byte;
typedef int sound_t;
@ -22,7 +27,12 @@ typedef byte rgba_t[4]; // unsigned byte colorpack
typedef byte rgb_t[3]; // unsigned byte colorpack
typedef vec_t matrix3x4[3][4];
typedef vec_t matrix4x4[4][4];
#if XASH_64BIT
typedef uint32_t poolhandle_t;
#else
typedef void* poolhandle_t;
#endif
#undef true
#undef false
@ -40,12 +50,14 @@ typedef uint64_t longtime_t;
#define MAX_SERVERINFO_STRING 512 // server handles too many settings. expand to 1024?
#define MAX_LOCALINFO_STRING 32768 // localinfo used on server and not sended to the clients
#define MAX_SYSPATH 1024 // system filepath
#define MAX_VA_STRING 1024 // string length returned by va()
#define MAX_PRINT_MSG 8192 // how many symbols can handle single call of Con_Printf or Con_DPrintf
#define MAX_TOKEN 2048 // parse token length
#define MAX_MODS 512 // environment games that engine can keep visible
#define MAX_USERMSG_LENGTH 2048 // don't modify it's relies on a client-side definitions
#define BIT( n ) ( 1U << ( n ))
#define BIT64( n ) ( 1ULL << ( n ))
#define GAMMA ( 2.2f ) // Valve Software gamma
#define INVGAMMA ( 1.0f / 2.2f ) // back to 1.0
#define TEXGAMMA ( 0.9f ) // compensate dim textures
@ -75,16 +87,19 @@ typedef uint64_t longtime_t;
#endif
#define _format(x) __attribute__((format(printf, x, x+1)))
#define NORETURN __attribute__((noreturn))
#define NONNULL __attribute__((nonnull))
#elif defined(_MSC_VER)
#define EXPORT __declspec( dllexport )
#define GAME_EXPORT
#define _format(x)
#define NORETURN
#define NONNULL
#else
#define EXPORT
#define GAME_EXPORT
#define _format(x)
#define NORETURN
#define NONNULL
#endif
#if ( __GNUC__ >= 3 )
@ -103,6 +118,11 @@ typedef uint64_t longtime_t;
#define likely(x) (x)
#endif
#if defined( static_assert ) // C11 static_assert
#define STATIC_ASSERT static_assert
#else
#define STATIC_ASSERT( x, y ) extern int _static_assert_##__LINE__[( x ) ? 1 : -1]
#endif
#ifdef XASH_BIG_ENDIAN
#define LittleLong(x) (((int)(((x)&255)<<24)) + ((int)((((x)>>8)&255)<<16)) + ((int)(((x)>>16)&255)<<8) + (((x) >> 24)&255))
@ -161,6 +181,7 @@ typedef struct dll_info_s
} dll_info_t;
typedef void (*setpair_t)( const char *key, const void *value, const void *buffer, void *numpairs );
typedef void *(*pfnCreateInterface_t)( const char *, int * );
// config strings are a general means of communication from
// 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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

File diff suppressed because it is too large Load Diff

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -27,9 +27,10 @@ struct ref_state_s
HINSTANCE hInstance;
ref_interface_t dllFuncs;
// depends on build configuration
int numRenderers;
string shortNames[DEFAULT_RENDERERS_LEN];
string readableNames[DEFAULT_RENDERERS_LEN];
const char **shortNames;
const char **readableNames;
};
extern struct ref_state_s ref;
@ -40,14 +41,14 @@ void R_GetTextureParms( int *w, int *h, int texnum );
#define REF_GET_PARM( parm, arg ) ref.dllFuncs.RefGetParm( (parm), (arg) )
#define GL_LoadTextureInternal( name, pic, flags ) ref.dllFuncs.GL_LoadTextureFromBuffer( (name), (pic), (flags), false )
#define GL_UpdateTextureInternal( name, pic, flags ) ref.dllFuncs.GL_LoadTextureFromBuffer( (name), (pic), (flags), true )
#define R_GetBuiltinTexture( name ) ref.dllFuncs.GL_LoadTexture( (name), 0, 0, 0 )
#define R_GetBuiltinTexture( name ) ref.dllFuncs.GL_FindTexture( (name) )
void GL_RenderFrame( const struct ref_viewpass_s *rvp );
// common engine and renderer cvars
extern convar_t *r_decals;
extern convar_t *r_adjust_fov;
extern convar_t *gl_clear;
extern convar_t r_decals;
extern convar_t r_adjust_fov;
extern convar_t gl_clear;
qboolean R_Init( void );
void R_Shutdown( void );

View File

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

View File

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

View File

@ -159,7 +159,7 @@ void S_UpdateSoundFade( void )
}
// spline it.
f = SimpleSpline( f );
f = -( cos( M_PI * f ) - 1 ) / 2;
f = bound( 0.0f, f, 1.0f );
soundfade.percent = soundfade.initial_percent * f;
@ -197,6 +197,65 @@ qboolean SND_FStreamIsPlaying( sfx_t *sfx )
return false;
}
/*
=================
SND_GetChannelTimeLeft
TODO: this function needs to be removed after whole sound subsystem rewrite
=================
*/
static int SND_GetChannelTimeLeft( const channel_t *ch )
{
int remaining;
if( ch->pMixer.finished || !ch->sfx || !ch->sfx->cache )
return 0;
if( ch->isSentence ) // sentences are special, count all remaining words
{
int i;
if( !ch->currentWord )
return 0;
// current word
remaining = ch->currentWord->forcedEndSample - ch->currentWord->sample;
// here we count all remaining words, stopping if no sfx or sound file is available
// see VOX_LoadWord
for( i = ch->wordIndex + 1; i < ARRAYSIZE( ch->words ); i++ )
{
wavdata_t *sc;
int end;
// don't continue with broken sentences
if( !ch->words[i].sfx )
break;
if( !( sc = S_LoadSound( ch->words[i].sfx )))
break;
end = ch->words[i].end;
if( end )
remaining += sc->samples * 0.01f * end;
else remaining += sc->samples;
}
}
else
{
int curpos;
int samples;
// handle position looping
samples = ch->sfx->cache->samples;
curpos = S_ConvertLoopedPosition( ch->sfx->cache, ch->pMixer.sample, ch->use_loop );
remaining = bound( 0, samples - curpos, samples );
}
return remaining;
}
/*
=================
SND_PickDynamicChannel
@ -246,11 +305,7 @@ channel_t *SND_PickDynamicChannel( int entnum, int channel, sfx_t *sfx, qboolean
continue;
// try to pick the sound with the least amount of data left to play
timeleft = 0;
if( ch->sfx )
{
timeleft = 1; // ch->end - paintedtime
}
timeleft = SND_GetChannelTimeLeft( ch );
if( timeleft < life_left )
{
@ -533,8 +588,6 @@ void S_StartSound( const vec3_t pos, int ent, int chan, sound_t handle, float fv
// spatialize
memset( target_chan, 0, sizeof( *target_chan ));
pitch *= (sys_timescale.value + 1) / 2;
VectorCopy( pos, target_chan->origin );
target_chan->staticsound = ( ent == 0 ) ? true : false;
target_chan->use_loop = (flags & SND_STOP_LOOPING) ? false : true;
@ -1129,7 +1182,7 @@ static uint S_RawSamplesStereo( portable_samplepair_t *rawsamples, uint rawend,
S_RawEntSamples
===================
*/
static void S_RawEntSamples( int entnum, uint samples, uint rate, word width, word channels, const byte *data, int snd_vol )
void S_RawEntSamples( int entnum, uint samples, uint rate, word width, word channels, const byte *data, int snd_vol )
{
rawchan_t *ch;
@ -1239,36 +1292,6 @@ void S_StreamAviSamples( void *Avi, int entnum, float fvol, float attn, float sy
}
}
/*
===================
S_GetRawSamplesLength
===================
*/
uint S_GetRawSamplesLength( int entnum )
{
rawchan_t *ch;
if( !( ch = S_FindRawChannel( entnum, false )))
return 0;
return ch->s_rawend <= paintedtime ? 0 : (float)(ch->s_rawend - paintedtime) * DMA_MSEC_PER_SAMPLE;
}
/*
===================
S_ClearRawChannel
===================
*/
void S_ClearRawChannel( int entnum )
{
rawchan_t *ch;
if( !( ch = S_FindRawChannel( entnum, false )))
return;
ch->s_rawend = 0;
}
/*
===================
S_FreeIdleRawChannels
@ -1288,6 +1311,9 @@ static void S_FreeIdleRawChannels( void )
if( ch->s_rawend >= paintedtime )
continue;
if ( ch->entnum > 0 )
SND_ForceCloseMouth( ch->entnum );
if(( paintedtime - ch->s_rawend ) / SOUND_DMA_SPEED >= S_RAW_SOUND_IDLE_SEC )
{
@ -1786,8 +1812,12 @@ void S_Music_f( void )
for( i = 0; i < 2; i++ )
{
const char *intro_path = va( "media/%s.%s", intro, ext[i] );
const char *main_path = va( "media/%s.%s", main, ext[i] );
char intro_path[MAX_VA_STRING];
char main_path[MAX_VA_STRING];
char track_path[MAX_VA_STRING];
Q_snprintf( intro_path, sizeof( intro_path ), "media/%s.%s", intro, ext[i] );
Q_snprintf( main_path, sizeof( main_path ), "media/%s.%s", main, ext[i] );
if( FS_FileExists( intro_path, false ) && FS_FileExists( main_path, false ))
{
@ -1795,7 +1825,10 @@ void S_Music_f( void )
S_StartBackgroundTrack( intro, main, 0, false );
break;
}
else if( FS_FileExists( va( "media/%s.%s", track, ext[i] ), false ))
Q_snprintf( track_path, sizeof( track_path ), "media/%s.%s", track, ext[i] );
if( FS_FileExists( track_path, false ))
{
// single non-looped theme
S_StartBackgroundTrack( track, NULL, 0, false );
@ -1850,7 +1883,7 @@ S_SoundInfo_f
*/
void S_SoundInfo_f( void )
{
Con_Printf( "Audio: DirectSound\n" );
Con_Printf( "Audio backend: %s\n", dma.backendName );
Con_Printf( "%5d channel(s)\n", 2 );
Con_Printf( "%5d samples\n", dma.samples );
Con_Printf( "%5d bits/sample\n", 16 );
@ -1860,6 +1893,33 @@ void S_SoundInfo_f( void )
S_PrintBackgroundTrackState ();
}
/*
=================
S_VoiceRecordStart_f
=================
*/
void S_VoiceRecordStart_f( void )
{
if( cls.state != ca_active || cls.legacymode )
return;
Voice_RecordStart();
}
/*
=================
S_VoiceRecordStop_f
=================
*/
void S_VoiceRecordStop_f( void )
{
if( cls.state != ca_active || !Voice_IsRecording() )
return;
CL_AddVoiceToDatagram();
Voice_RecordStop();
}
/*
================
S_Init
@ -1894,11 +1954,12 @@ qboolean S_Init( void )
Cmd_AddCommand( "soundlist", S_SoundList_f, "display loaded sounds" );
Cmd_AddCommand( "s_info", S_SoundInfo_f, "print sound system information" );
Cmd_AddCommand( "s_fade", S_SoundFade_f, "fade all sounds then stop all" );
Cmd_AddCommand( "+voicerecord", Cmd_Null_f, "start voice recording (non-implemented)" );
Cmd_AddCommand( "-voicerecord", Cmd_Null_f, "stop voice recording (non-implemented)" );
Cmd_AddCommand( "+voicerecord", S_VoiceRecordStart_f, "start voice recording" );
Cmd_AddCommand( "-voicerecord", S_VoiceRecordStop_f, "stop voice recording" );
Cmd_AddCommand( "spk", S_SayReliable_f, "reliable play a specified sententce" );
Cmd_AddCommand( "speak", S_Say_f, "playing a specified sententce" );
dma.backendName = "None";
if( !SNDDMA_Init( ) )
{
Con_Printf( "Audio: sound system can't be initialized\n" );

View File

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

View File

@ -24,17 +24,7 @@ void SND_InitMouth( int entnum, int entchannel )
{
if(( entchannel == CHAN_VOICE || entchannel == CHAN_STREAM ) && entnum > 0 )
{
cl_entity_t *clientEntity;
// init mouth movement vars
clientEntity = CL_GetEntityByIndex( entnum );
if( clientEntity )
{
clientEntity->mouth.mouthopen = 0;
clientEntity->mouth.sndcount = 0;
clientEntity->mouth.sndavg = 0;
}
SND_ForceInitMouth( entnum );
}
}
@ -42,15 +32,7 @@ void SND_CloseMouth( channel_t *ch )
{
if( ch->entchannel == CHAN_VOICE || ch->entchannel == CHAN_STREAM )
{
cl_entity_t *clientEntity;
clientEntity = CL_GetEntityByIndex( ch->entnum );
if( clientEntity )
{
// shut mouth
clientEntity->mouth.mouthopen = 0;
}
SND_ForceCloseMouth( ch->entnum );
}
}
@ -150,3 +132,68 @@ void SND_MoveMouth16( channel_t *ch, wavdata_t *pSource, int count )
pMouth->sndcount = 0;
}
}
void SND_ForceInitMouth( int entnum )
{
cl_entity_t *clientEntity;
clientEntity = CL_GetEntityByIndex( entnum );
if( clientEntity )
{
clientEntity->mouth.mouthopen = 0;
clientEntity->mouth.sndavg = 0;
clientEntity->mouth.sndcount = 0;
}
}
void SND_ForceCloseMouth( int entnum )
{
cl_entity_t *clientEntity;
clientEntity = CL_GetEntityByIndex( entnum );
if( clientEntity )
clientEntity->mouth.mouthopen = 0;
}
void SND_MoveMouthRaw( rawchan_t *ch, portable_samplepair_t *pData, int count )
{
cl_entity_t *clientEntity;
mouth_t *pMouth = NULL;
int savg, data;
int scount = 0;
uint i;
clientEntity = CL_GetEntityByIndex( ch->entnum );
if( !clientEntity ) return;
pMouth = &clientEntity->mouth;
if( pData == NULL )
return;
i = 0;
scount = pMouth->sndcount;
savg = 0;
while ( i < count && scount < CAVGSAMPLES )
{
data = pData[i].left; // mono sound anyway
data = ( bound( -32767, data, 0x7ffe ) >> 8 );
savg += abs( data );
i += 80 + ( (byte)data & 0x1F );
scount++;
}
pMouth->sndavg += savg;
pMouth->sndcount = (byte)scount;
if ( pMouth->sndcount >= CAVGSAMPLES )
{
pMouth->mouthopen = pMouth->sndavg / CAVGSAMPLES;
pMouth->sndavg = 0;
pMouth->sndcount = 0;
}
}

View File

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

View File

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

View File

@ -113,10 +113,11 @@ typedef struct snd_format_s
typedef struct
{
snd_format_t format;
int samples; // mono samples in buffer
int samplepos; // in mono samples
byte *buffer;
int samples; // mono samples in buffer
int samplepos; // in mono samples
byte *buffer;
qboolean initialized; // sound engine is active
const char *backendName;
} dma_t;
#include "vox.h"
@ -202,7 +203,7 @@ typedef struct
#define MAX_DYNAMIC_CHANNELS (60 + NUM_AMBIENTS)
#define MAX_CHANNELS (256 + MAX_DYNAMIC_CHANNELS) // Scourge Of Armagon has too many static sounds on hip2m4.bsp
#define MAX_RAW_CHANNELS 16
#define MAX_RAW_CHANNELS 48
#define MAX_RAW_SAMPLES 8192
extern sound_t ambient_sfx[NUM_AMBIENTS];
@ -218,7 +219,6 @@ extern dma_t dma;
extern convar_t s_musicvolume;
extern convar_t s_lerping;
extern convar_t *dsp_off;
extern convar_t s_test; // cvar to testify new effects
extern convar_t s_samplecount;
extern convar_t snd_mute_losefocus;
@ -271,11 +271,10 @@ int S_GetCurrentStaticSounds( soundlist_t *pout, int size );
int S_GetCurrentDynamicSounds( soundlist_t *pout, int size );
sfx_t *S_GetSfxByHandle( sound_t handle );
rawchan_t *S_FindRawChannel( int entnum, qboolean create );
void S_RawEntSamples( int entnum, uint samples, uint rate, word width, word channels, const byte *data, int snd_vol );
void S_RawSamples( uint samples, uint rate, word width, word channels, const byte *data, int entnum );
void S_StopSound( int entnum, int channel, const char *soundname );
void S_UpdateFrame( struct ref_viewpass_s *rvp );
uint S_GetRawSamplesLength( int entnum );
void S_ClearRawChannel( int entnum );
void S_StopAllSounds( qboolean ambient );
void S_FreeSounds( void );
@ -283,9 +282,12 @@ void S_FreeSounds( void );
// s_mouth.c
//
void SND_InitMouth( int entnum, int entchannel );
void SND_ForceInitMouth( int entnum );
void SND_MoveMouth8( channel_t *ch, wavdata_t *pSource, int count );
void SND_MoveMouth16( channel_t *ch, wavdata_t *pSource, int count );
void SND_MoveMouthRaw( rawchan_t *ch, portable_samplepair_t *pData, int count );
void SND_CloseMouth( channel_t *ch );
void SND_ForceCloseMouth( int entnum );
//
// s_stream.c
@ -301,6 +303,7 @@ void S_FadeMusicVolume( float fadePercent );
//
int S_ZeroCrossingAfter( wavdata_t *pWaveData, int sample );
int S_ZeroCrossingBefore( wavdata_t *pWaveData, int sample );
int S_ConvertLoopedPosition( wavdata_t *pSource, int samplePosition, qboolean use_loop );
int S_GetOutputData( wavdata_t *pSource, void **pData, int samplePosition, int sampleCount, qboolean use_loop );
void S_SetSampleStart( channel_t *pChan, wavdata_t *pSource, int newPosition );
void S_SetSampleEnd( channel_t *pChan, wavdata_t *pSource, int newEndPosition );

View File

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

View File

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

View File

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

View File

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

View File

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

635
engine/client/voice.c Normal file
View File

@ -0,0 +1,635 @@
/*
voice.c - voice chat implementation
Copyright (C) 2022 Velaron
Copyright (C) 2022 SNMetamorph
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.
*/
#define CUSTOM_MODES 1 // required to correctly link with Opus Custom
#include <opus_custom.h>
#include "common.h"
#include "client.h"
#include "voice.h"
voice_state_t voice = { 0 };
CVAR_DEFINE_AUTO( voice_enable, "1", FCVAR_PRIVILEGED|FCVAR_ARCHIVE, "enable voice chat" );
CVAR_DEFINE_AUTO( voice_loopback, "0", FCVAR_PRIVILEGED, "loopback voice back to the speaker" );
CVAR_DEFINE_AUTO( voice_scale, "1.0", FCVAR_PRIVILEGED|FCVAR_ARCHIVE, "incoming voice volume scale" );
CVAR_DEFINE_AUTO( voice_avggain, "0.5", FCVAR_PRIVILEGED|FCVAR_ARCHIVE, "automatic voice gain control (average)" );
CVAR_DEFINE_AUTO( voice_maxgain, "5.0", FCVAR_PRIVILEGED|FCVAR_ARCHIVE, "automatic voice gain control (maximum)" );
CVAR_DEFINE_AUTO( voice_inputfromfile, "0", FCVAR_PRIVILEGED, "input voice from voice_input.wav" );
static void Voice_ApplyGainAdjust( int16_t *samples, int count );
/*
===============================================================================
OPUS INTEGRATION
===============================================================================
*/
/*
=========================
Voice_InitOpusDecoder
=========================
*/
static qboolean Voice_InitOpusDecoder( void )
{
int err;
voice.width = sizeof( opus_int16 );
voice.samplerate = VOICE_OPUS_CUSTOM_SAMPLERATE;
voice.frame_size = VOICE_OPUS_CUSTOM_FRAME_SIZE;
voice.custom_mode = opus_custom_mode_create( SOUND_44k, voice.frame_size, &err );
if( !voice.custom_mode )
{
Con_Printf( S_ERROR "Can't create Opus Custom mode: %s\n", opus_strerror( err ));
return false;
}
voice.decoder = opus_custom_decoder_create( voice.custom_mode, VOICE_PCM_CHANNELS, &err );
if( !voice.decoder )
{
Con_Printf( S_ERROR "Can't create Opus encoder: %s\n", opus_strerror( err ));
return false;
}
return true;
}
/*
=========================
Voice_InitOpusEncoder
=========================
*/
static qboolean Voice_InitOpusEncoder( int quality )
{
int err;
voice.encoder = opus_custom_encoder_create( voice.custom_mode, VOICE_PCM_CHANNELS, &err );
if( !voice.encoder )
{
Con_Printf( S_ERROR "Can't create Opus encoder: %s\n", opus_strerror( err ));
return false;
}
switch( quality )
{
case 1: // 6 kbps
opus_custom_encoder_ctl( voice.encoder, OPUS_SET_BITRATE( 6000 ));
break;
case 2: // 12 kbps
opus_custom_encoder_ctl( voice.encoder, OPUS_SET_BITRATE( 12000 ));
break;
case 4: // 64 kbps
opus_custom_encoder_ctl( voice.encoder, OPUS_SET_BITRATE( 64000 ));
break;
case 5: // 96 kbps
opus_custom_encoder_ctl( voice.encoder, OPUS_SET_BITRATE( 96000 ));
break;
default: // 36 kbps
opus_custom_encoder_ctl( voice.encoder, OPUS_SET_BITRATE( 36000 ));
break;
}
return true;
}
/*
=========================
Voice_ShutdownOpusDecoder
=========================
*/
static void Voice_ShutdownOpusDecoder( void )
{
if( voice.decoder )
{
opus_custom_decoder_destroy( voice.decoder );
voice.decoder = NULL;
}
}
/*
=========================
Voice_ShutdownOpusEncoder
=========================
*/
static void Voice_ShutdownOpusEncoder( void )
{
if( voice.encoder )
{
opus_custom_encoder_destroy( voice.encoder );
voice.encoder = NULL;
}
if( voice.custom_mode )
{
opus_custom_mode_destroy( voice.custom_mode );
voice.custom_mode = NULL;
}
}
/*
=========================
Voice_GetOpusCompressedData
=========================
*/
static uint Voice_GetOpusCompressedData( byte *out, uint maxsize, uint *frames )
{
uint ofs = 0, size = 0;
uint frame_size_bytes = voice.frame_size * voice.width;
if( voice.input_file )
{
uint numbytes;
double updateInterval, curtime = Sys_DoubleTime();
updateInterval = curtime - voice.start_time;
voice.start_time = curtime;
numbytes = updateInterval * voice.samplerate * voice.width * VOICE_PCM_CHANNELS;
numbytes = Q_min( numbytes, voice.input_file->size - voice.input_file_pos );
numbytes = Q_min( numbytes, sizeof( voice.input_buffer ) - voice.input_buffer_pos );
memcpy( voice.input_buffer + voice.input_buffer_pos, voice.input_file->buffer + voice.input_file_pos, numbytes );
voice.input_buffer_pos += numbytes;
voice.input_file_pos += numbytes;
}
if( !voice.input_file )
VoiceCapture_Lock( true );
for( ofs = 0; voice.input_buffer_pos - ofs >= frame_size_bytes && ofs <= voice.input_buffer_pos; ofs += frame_size_bytes )
{
int bytes;
#if 1
if( !voice.input_file )
{
// adjust gain before encoding, but only for input from voice
Voice_ApplyGainAdjust((opus_int16*)(voice.input_buffer + ofs), voice.frame_size);
}
#endif
bytes = opus_custom_encode( voice.encoder, (const opus_int16 *)( voice.input_buffer + ofs ),
voice.frame_size, out + size + sizeof( uint16_t ), maxsize );
if( bytes > 0 )
{
// write compressed frame size
*((uint16_t *)&out[size]) = bytes;
size += bytes + sizeof( uint16_t );
maxsize -= bytes + sizeof( uint16_t );
(*frames)++;
}
else
{
Con_Printf( S_ERROR "%s: failed to encode frame: %s\n", __func__, opus_strerror( bytes ));
}
}
// did we compress anything? update counters
if( ofs )
{
fs_offset_t remaining = voice.input_buffer_pos - ofs;
// move remaining samples to the beginning of buffer
memmove( voice.input_buffer, voice.input_buffer + ofs, remaining );
voice.input_buffer_pos = remaining;
}
if( !voice.input_file )
VoiceCapture_Lock( false );
return size;
}
/*
===============================================================================
VOICE CHAT INTEGRATION
===============================================================================
*/
/*
=========================
Voice_ApplyGainAdjust
=========================
*/
static void Voice_ApplyGainAdjust( int16_t *samples, int count )
{
float gain, modifiedMax;
int average, adjustedSample, blockOffset = 0;
for( ;; )
{
int i, localMax = 0, localSum = 0;
int blockSize = Q_min( count - ( blockOffset + voice.autogain.block_size ), voice.autogain.block_size );
if( blockSize < 1 )
break;
for( i = 0; i < blockSize; ++i )
{
int sample = samples[blockOffset + i];
int absSample = abs( sample );
if( absSample > localMax )
localMax = absSample;
localSum += absSample;
gain = voice.autogain.current_gain + i * voice.autogain.gain_multiplier;
adjustedSample = Q_min( SHRT_MAX, Q_max(( int )( sample * gain ), SHRT_MIN ));
samples[blockOffset + i] = adjustedSample;
}
if( blockOffset % voice.autogain.block_size == 0 )
{
average = localSum / blockSize;
modifiedMax = average + ( localMax - average ) * voice_avggain.value;
voice.autogain.current_gain = voice.autogain.next_gain * voice_scale.value;
voice.autogain.next_gain = Q_min( (float)SHRT_MAX / modifiedMax, voice_maxgain.value ) * voice_scale.value;
voice.autogain.gain_multiplier = ( voice.autogain.next_gain - voice.autogain.current_gain ) / ( voice.autogain.block_size - 1 );
}
blockOffset += blockSize;
}
}
/*
=========================
Voice_Status
Notify user dll aboit voice transmission
=========================
*/
static void Voice_Status( int entindex, qboolean bTalking )
{
if( cls.state == ca_active && clgame.dllFuncs.pfnVoiceStatus )
clgame.dllFuncs.pfnVoiceStatus( entindex, bTalking );
}
/*
=========================
Voice_StatusTimeout
Waits few milliseconds and if there was no
voice transmission, sends notification
=========================
*/
static void Voice_StatusTimeout( voice_status_t *status, int entindex, double frametime )
{
if( status->talking_ack )
{
status->talking_timeout += frametime;
if( status->talking_timeout > 0.2 )
{
status->talking_ack = false;
Voice_Status( entindex, false );
}
}
}
/*
=========================
Voice_StatusAck
Sends notification to user dll and
zeroes timeouts for this client
=========================
*/
void Voice_StatusAck( voice_status_t *status, int playerIndex )
{
if( !status->talking_ack )
Voice_Status( playerIndex, true );
status->talking_ack = true;
status->talking_timeout = 0.0;
}
/*
=========================
Voice_IsRecording
=========================
*/
qboolean Voice_IsRecording( void )
{
return voice.is_recording;
}
/*
=========================
Voice_RecordStop
=========================
*/
void Voice_RecordStop( void )
{
if( voice.input_file )
{
FS_FreeSound( voice.input_file );
voice.input_file = NULL;
}
VoiceCapture_Activate( false );
voice.is_recording = false;
Voice_Status( VOICE_LOCALCLIENT_INDEX, false );
voice.input_buffer_pos = 0;
memset( voice.input_buffer, 0, sizeof( voice.input_buffer ));
}
/*
=========================
Voice_RecordStart
=========================
*/
void Voice_RecordStart( void )
{
Voice_RecordStop();
if( voice_inputfromfile.value )
{
voice.input_file = FS_LoadSound( "voice_input.wav", NULL, 0 );
if( voice.input_file )
{
Sound_Process( &voice.input_file, voice.samplerate, voice.width, SOUND_RESAMPLE );
voice.input_file_pos = 0;
voice.start_time = Sys_DoubleTime();
voice.is_recording = true;
}
else
{
FS_FreeSound( voice.input_file );
voice.input_file = NULL;
}
}
if( !Voice_IsRecording() )
voice.is_recording = VoiceCapture_Activate( true );
if( Voice_IsRecording() )
Voice_Status( VOICE_LOCALCLIENT_INDEX, true );
}
/*
=========================
Voice_Disconnect
We're disconnected from server
stop recording and notify user dlls
=========================
*/
void Voice_Disconnect( void )
{
int i;
Voice_RecordStop();
if( voice.local.talking_ack )
{
Voice_Status( VOICE_LOOPBACK_INDEX, false );
voice.local.talking_ack = false;
}
for( i = 0; i < MAX_CLIENTS; i++ )
{
if( voice.players_status[i].talking_ack )
{
Voice_Status( i, false );
voice.players_status[i].talking_ack = false;
}
}
}
/*
=========================
Voice_StartChannel
Feed the decoded data to engine sound subsystem
=========================
*/
static void Voice_StartChannel( uint samples, byte *data, int entnum )
{
SND_ForceInitMouth( entnum );
S_RawEntSamples( entnum, samples, voice.samplerate, voice.width, VOICE_PCM_CHANNELS, data, 255 );
}
/*
=========================
Voice_AddIncomingData
Received encoded voice data, decode it
=========================
*/
void Voice_AddIncomingData( int ent, const byte *data, uint size, uint frames )
{
int samples = 0;
int ofs = 0;
if( !voice.decoder )
return;
// decode frame by frame
for( ;; )
{
int frame_samples;
uint16_t compressed_size;
// no compressed size mark
if( ofs + sizeof( uint16_t ) > size )
break;
compressed_size = *(const uint16_t *)(data + ofs);
ofs += sizeof( uint16_t );
// no frame data
if( ofs + compressed_size > size )
break;
frame_samples = opus_custom_decode( voice.decoder, data + ofs, compressed_size,
(opus_int16*)voice.decompress_buffer + samples, voice.frame_size );
ofs += compressed_size;
samples += frame_samples;
}
if( samples > 0 )
Voice_StartChannel( samples, voice.decompress_buffer, ent );
}
/*
=========================
CL_AddVoiceToDatagram
Encode our voice data and send it to server
=========================
*/
void CL_AddVoiceToDatagram( void )
{
uint size, frames = 0;
if( cls.state != ca_active || !Voice_IsRecording() || !voice.encoder )
return;
size = Voice_GetOpusCompressedData( voice.output_buffer, sizeof( voice.output_buffer ), &frames );
if( size > 0 && MSG_GetNumBytesLeft( &cls.datagram ) >= size + 32 )
{
MSG_BeginClientCmd( &cls.datagram, clc_voicedata );
MSG_WriteByte( &cls.datagram, voice_loopback.value != 0 );
MSG_WriteByte( &cls.datagram, frames );
MSG_WriteShort( &cls.datagram, size );
MSG_WriteBytes( &cls.datagram, voice.output_buffer, size );
}
}
/*
=========================
Voice_RegisterCvars
Register voice related cvars and commands
=========================
*/
void Voice_RegisterCvars( void )
{
Cvar_RegisterVariable( &voice_enable );
Cvar_RegisterVariable( &voice_loopback );
Cvar_RegisterVariable( &voice_scale );
Cvar_RegisterVariable( &voice_avggain );
Cvar_RegisterVariable( &voice_maxgain );
Cvar_RegisterVariable( &voice_inputfromfile );
}
/*
=========================
Voice_Shutdown
Completely shutdown the voice subsystem
=========================
*/
static void Voice_Shutdown( void )
{
int i;
Voice_RecordStop();
Voice_ShutdownOpusEncoder();
Voice_ShutdownOpusDecoder();
VoiceCapture_Shutdown();
if( voice.local.talking_ack )
Voice_Status( VOICE_LOOPBACK_INDEX, false );
for( i = 0; i < MAX_CLIENTS; i++ )
{
if( voice.players_status[i].talking_ack )
Voice_Status( i, false );
}
memset( &voice, 0, sizeof( voice ));
}
/*
=========================
Voice_Idle
Run timeout for all clients
=========================
*/
void Voice_Idle( double frametime )
{
int i;
if( FBitSet( voice_enable.flags, FCVAR_CHANGED ) && !voice_enable.value )
{
Voice_Shutdown();
return;
}
// update local player status first
Voice_StatusTimeout( &voice.local, VOICE_LOOPBACK_INDEX, frametime );
for( i = 0; i < MAX_CLIENTS; i++ )
Voice_StatusTimeout( &voice.players_status[i], i, frametime );
}
/*
=========================
Voice_Init
Initialize the voice subsystem
=========================
*/
qboolean Voice_Init( const char *pszCodecName, int quality )
{
if( !voice_enable.value )
return false;
if( Q_strcmp( pszCodecName, VOICE_OPUS_CUSTOM_CODEC ))
{
Con_Printf( S_ERROR "Server requested unsupported codec: %s\n", pszCodecName );
return false;
}
// reinitialize only if codec parameters are different
if( !Q_strcmp( voice.codec, pszCodecName ) && voice.quality == quality )
return true;
Voice_Shutdown();
voice.autogain.block_size = 128;
if( !Voice_InitOpusDecoder( ))
{
// no reason to init encoder and open audio device
// if we can't hear other players
Con_Printf( S_ERROR "Voice chat disabled.\n" );
Voice_Shutdown();
return false;
}
// we can hear others players, so it's fine to fail now
voice.initialized = true;
Q_strncpy( voice.codec, pszCodecName, sizeof( voice.codec ));
if( !Voice_InitOpusEncoder( quality ))
{
Con_Printf( S_WARN "Other players will not be able to hear you.\n" );
return false;
}
voice.quality = quality;
if( !VoiceCapture_Init( ))
Con_Printf( S_WARN "No microphone is available.\n" );
return true;
}

104
engine/client/voice.h Normal file
View File

@ -0,0 +1,104 @@
/*
voice.h - voice chat implementation
Copyright (C) 2022 Velaron
Copyright (C) 2022 SNMetamorph
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 VOICE_H
#define VOICE_H
#include "common.h"
#include "protocol.h" // MAX_CLIENTS
#include "sound.h"
typedef struct OpusCustomEncoder OpusCustomEncoder;
typedef struct OpusCustomDecoder OpusCustomDecoder;
typedef struct OpusCustomMode OpusCustomMode;
#define VOICE_LOOPBACK_INDEX (-2)
#define VOICE_LOCALCLIENT_INDEX (-1)
#define VOICE_PCM_CHANNELS 1 // always mono
// never change these parameters when using opuscustom
#define VOICE_OPUS_CUSTOM_SAMPLERATE SOUND_44k
// must follow opus custom requirements
// also be divisible with MAX_RAW_SAMPLES
#define VOICE_OPUS_CUSTOM_FRAME_SIZE 1024
#define VOICE_OPUS_CUSTOM_CODEC "opus_custom_44k_512"
// a1ba: do not change, we don't have any re-encoding support now
#define VOICE_DEFAULT_CODEC VOICE_OPUS_CUSTOM_CODEC
typedef struct voice_status_s
{
qboolean talking_ack;
double talking_timeout;
} voice_status_t;
typedef struct voice_state_s
{
string codec;
int quality;
qboolean initialized;
qboolean is_recording;
double start_time;
voice_status_t local;
voice_status_t players_status[MAX_CLIENTS];
// opus stuff
OpusCustomMode *custom_mode;
OpusCustomEncoder *encoder;
OpusCustomDecoder *decoder;
// audio info
uint width;
uint samplerate;
uint frame_size; // in samples
// buffers
byte input_buffer[MAX_RAW_SAMPLES];
byte output_buffer[MAX_RAW_SAMPLES];
byte decompress_buffer[MAX_RAW_SAMPLES];
fs_offset_t input_buffer_pos; // in bytes
// input from file
wavdata_t *input_file;
fs_offset_t input_file_pos; // in bytes
// automatic gain control
struct {
int block_size;
float current_gain;
float next_gain;
float gain_multiplier;
} autogain;
} voice_state_t;
extern voice_state_t voice;
void CL_AddVoiceToDatagram( void );
void Voice_RegisterCvars( void );
qboolean Voice_Init( const char *pszCodecName, int quality );
void Voice_Idle( double frametime );
qboolean Voice_IsRecording( void );
void Voice_RecordStop( void );
void Voice_RecordStart( void );
void Voice_Disconnect( void );
void Voice_AddIncomingData( int ent, const byte *data, uint size, uint frames );
void Voice_StatusAck( voice_status_t *status, int playerIndex );
#endif // VOICE_H

View File

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

View File

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

View File

@ -29,7 +29,7 @@ typedef struct
int maxsize;
} cmdbuf_t;
qboolean cmd_wait;
int cmd_wait;
cmdbuf_t cmd_text, filteredcmd_text;
byte cmd_text_buf[MAX_CMD_BUFFER];
byte filteredcmd_text_buf[MAX_CMD_BUFFER];
@ -120,6 +120,18 @@ void Cbuf_AddText( const char *text )
Cbuf_AddTextToBuffer( &cmd_text, text );
}
void Cbuf_AddTextf( const char *fmt, ... )
{
va_list va;
char buf[MAX_VA_STRING];
va_start( va, fmt );
Q_vsnprintf( buf, sizeof( buf ), fmt, va );
va_end( va );
Cbuf_AddText( buf );
}
/*
============
Cbuf_AddFilteredText
@ -173,6 +185,14 @@ void Cbuf_ExecuteCommandsFromBuffer( cmdbuf_t *buf, qboolean isPrivileged, int c
while( buf->cursize )
{
if( cmd_wait > 0 )
{
// skip out while text still remains in buffer,
// leaving it for next frame
cmd_wait--;
break;
}
// limit amount of commands that can be issued
if( cmdsToExecute >= 0 )
{
@ -237,14 +257,6 @@ void Cbuf_ExecuteCommandsFromBuffer( cmdbuf_t *buf, qboolean isPrivileged, int c
// execute the command line
Cmd_ExecuteStringWithPrivilegeCheck( line, isPrivileged );
if( cmd_wait )
{
// skip out while text still remains in buffer,
// leaving it for next frame
cmd_wait = false;
break;
}
}
}
@ -360,7 +372,13 @@ bind g "cmd use rocket ; +attack ; wait ; -attack ; cmd use blaster"
*/
void Cmd_Wait_f( void )
{
cmd_wait = true;
if ( Cmd_Argc() > 1 )
{
const char *arg = Cmd_Argv( 1 );
cmd_wait = atoi( arg );
}
cmd_wait = Q_max( cmd_wait, 1 );
}
/*
@ -535,7 +553,7 @@ int GAME_EXPORT Cmd_Argc( void )
Cmd_Argv
============
*/
const char *Cmd_Argv( int arg )
const char *GAME_EXPORT Cmd_Argv( int arg )
{
if((uint)arg >= cmd_argc )
return "";
@ -547,7 +565,7 @@ const char *Cmd_Argv( int arg )
Cmd_Args
============
*/
const char *Cmd_Args( void )
const char *GAME_EXPORT Cmd_Args( void )
{
return cmd_args;
}
@ -984,7 +1002,7 @@ static void Cmd_ExecuteStringWithPrivilegeCheck( const char *text, qboolean isPr
cmd_condlevel = 0;
// cvar value substitution
if( CVAR_TO_BOOL( cmd_scripting ))
if( cmd_scripting.value && isPrivileged )
{
while( *text )
{
@ -1150,13 +1168,13 @@ void Cmd_ForwardToServer( void )
str[0] = 0;
if( Q_stricmp( Cmd_Argv( 0 ), "cmd" ))
{
Q_strcat( str, Cmd_Argv( 0 ));
Q_strcat( str, " " );
Q_strncat( str, Cmd_Argv( 0 ), sizeof( str ));
Q_strncat( str, " ", sizeof( str ));
}
if( Cmd_Argc() > 1 )
Q_strcat( str, Cmd_Args( ));
else Q_strcat( str, "\n" );
Q_strncat( str, Cmd_Args( ), sizeof( str ));
else Q_strncat( str, "\n", sizeof( str ));
MSG_WriteString( &cls.netchan.message, str );
}
@ -1171,17 +1189,21 @@ void Cmd_List_f( void )
{
cmd_t *cmd;
int i = 0;
const char *match;
size_t matchlen = 0;
const char *match = NULL;
if( Cmd_Argc() > 1 ) match = Cmd_Argv( 1 );
else match = NULL;
if( Cmd_Argc() > 1 )
{
match = Cmd_Argv( 1 );
matchlen = Q_strlen( match );
}
for( cmd = cmd_functions; cmd; cmd = cmd->next )
{
if( cmd->name[0] == '@' )
continue; // never show system cmds
if( match && !Q_stricmpext( match, cmd->name ))
if( match && !Q_strnicmpext( match, cmd->name, matchlen ))
continue;
Con_Printf( " %-*s ^3%s^7\n", 32, cmd->name, cmd->desc );
@ -1250,21 +1272,21 @@ static void Cmd_Apropos_f( void )
cmdalias_t *alias;
const char *partial;
int count = 0;
qboolean ispattern;
char buf[MAX_VA_STRING];
if( Cmd_Argc() > 1 )
{
partial = Cmd_Args();
}
else
if( Cmd_Argc() < 2 )
{
Msg( "apropos what?\n" );
return;
}
ispattern = partial && Q_strpbrk( partial, "*?" );
if( !ispattern )
partial = va( "*%s*", partial );
partial = Cmd_Args();
if( !Q_strpbrk( partial, "*?" ))
{
Q_snprintf( buf, sizeof( buf ), "*%s*", partial );
partial = buf;
}
for( var = (convar_t*)Cvar_GetList(); var; var = var->next )
{
@ -1341,7 +1363,7 @@ inserts escape sequences
void Cmd_Escape( char *newCommand, const char *oldCommand, int len )
{
int c;
int scripting = CVAR_TO_BOOL( cmd_scripting );
int scripting = cmd_scripting.value;
while( (c = *oldCommand++) && len > 1 )
{
@ -1391,8 +1413,8 @@ void Cmd_Init( void )
#endif // XASH_DEDICATED
Cmd_AddRestrictedCommand( "alias", Cmd_Alias_f, "create a script function. Without arguments show the list of all alias" );
Cmd_AddRestrictedCommand( "unalias", Cmd_UnAlias_f, "remove a script function" );
Cmd_AddCommand( "if", Cmd_If_f, "compare and set condition bits" );
Cmd_AddCommand( "else", Cmd_Else_f, "invert condition bit" );
Cmd_AddRestrictedCommand( "if", Cmd_If_f, "compare and set condition bits" );
Cmd_AddRestrictedCommand( "else", Cmd_Else_f, "invert condition bit" );
#if defined(XASH_HASHED_VARS)
Cmd_AddCommand( "basecmd_stats", BaseCmd_Stats_f, "print info about basecmd usage" );

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