mirror of
https://github.com/FWGS/xash3d-fwgs.git
synced 2026-08-05 11:35:05 +08:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
46add4784b | ||
|
|
fe62e61aa4 | ||
|
|
de74ce9767 | ||
|
|
8c89579c35 | ||
|
|
18dddaf1a5 | ||
|
|
d3bcdc6c06 | ||
|
|
c0a40f6e03 | ||
|
|
e3e459bb67 | ||
|
|
badda6c585 | ||
|
|
db68b7c6e7 | ||
|
|
841b2bcf5a | ||
|
|
a5fb74eb8f | ||
|
|
31d44f85a7 | ||
|
|
24f8525fad | ||
|
|
04fbe1a356 |
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -46,6 +46,3 @@
|
||||
[submodule "3rdparty/mbedtls/mbedtls"]
|
||||
path = 3rdparty/mbedtls/mbedtls
|
||||
url = https://github.com/FWGS/mbedtls-releases.git
|
||||
[submodule "3rdparty/freevgui"]
|
||||
path = 3rdparty/freevgui
|
||||
url = https://github.com/FWGS/freevgui.git
|
||||
|
||||
1
3rdparty/freevgui
vendored
1
3rdparty/freevgui
vendored
Submodule 3rdparty/freevgui deleted from 8bf71dba02
2
3rdparty/library_suffix
vendored
2
3rdparty/library_suffix
vendored
Submodule 3rdparty/library_suffix updated: a35ac9c12e...e9fc14307b
2
3rdparty/nanogl
vendored
2
3rdparty/nanogl
vendored
Submodule 3rdparty/nanogl updated: 6c8aeca5e6...7f654d2de2
2
3rdparty/vgui_support
vendored
2
3rdparty/vgui_support
vendored
Submodule 3rdparty/vgui_support updated: aa31f43b57...d2aaec107d
@@ -1,53 +1,55 @@
|
||||
## If you are reporting bugs
|
||||
|
||||
1. Check you are using latest version. You can build latest Xash3D FWGS for yourself, look to README.md.
|
||||
2. Check open issues is your bug is already reported and closed issues if it reported and fixed. Don't send bug if it's already reported.
|
||||
3. Re-run engine with `-dev 2 -log` arguments, reproduce bug and post engine.log which can be found in your working directory.
|
||||
3. Describe steps to reproduce bug.
|
||||
1. Check that you are using the latest version. To build the latest Xash3D FWGS, look at README.md.
|
||||
2. Check the open issues to make sure your bug is not already reported and closed issues if it reported and fixed. Don't send a bug if it's already been reported.
|
||||
3. Re-run engine with `-dev 2 -log` arguments, then reproduce the bug and post `engine.log` which can be found in your working directory.
|
||||
3. Describe the steps to reproduce the bug.
|
||||
4. Describe which OS and architecture you are using.
|
||||
6. Attach screenshot if it will help clarify the situation.
|
||||
6. Attach a screenshot if it will help clarify the situation.
|
||||
|
||||
## If you are contributing code
|
||||
|
||||
### Which branch?
|
||||
|
||||
* We recommend using `master` branch.
|
||||
* We recommend using the `master` branch.
|
||||
|
||||
### Third-party libraries
|
||||
|
||||
* Philosophy of any Xash Project by Uncle Mike: don't be bloated. We follow it too.
|
||||
* Adding new library is allowed only if there is a REAL reason to use it. It's will be nice, if you will leave a possibility to remove new dependency at build-time.
|
||||
* Adding new dependencies for Waf Build System is not welcomed.
|
||||
* The philosophy of any Xash Project by Uncle Mike: don't be bloated. We follow it too.
|
||||
* Adding new libraries are allowed only if there is a REAL reason to use it. It will be nice, if you leave a possibility to remove the new dependency at build-time.
|
||||
* Adding new dependencies for the Waf Build System is not welcomed.
|
||||
|
||||
### Portability level
|
||||
|
||||
* Xash3D have it's own crt library. It's recommended to use it. It most cases it's just a wrappers around standart C library.
|
||||
* If your feature need platform-specific code, move it to `engine/platform` and try to implement to every supported OS and every supported compiler or at least leave a stubs.
|
||||
* You must put it under appopriate macro. It's a rule: Xash3D FWGS must compile everywhere. For list of platforms we support, refer to public/build.h file.
|
||||
* Xash3D has it's own crt library. It's recommended to use it. In most cases it's just a wrapper around the standard C library.
|
||||
* If your feature needs platform-specific code, move it to `engine/platform` and try to implement every supported OS and every supported compiler or at least leave a stub.
|
||||
* You must put it under the appropriate macro. It's a rule: Xash3D FWGS must compile everywhere. For list of platforms we support, refer to `public/build.h`.
|
||||
|
||||
### Code style
|
||||
|
||||
* This project uses mixed Quake's and HLSDK's C/C++ code style convention.
|
||||
* This project uses a mix of Quake's and HLSDK's C/C++ code style convention.
|
||||
* In short:
|
||||
* Use spaces in parenthesis, but not when two parentheses are consecutive.
|
||||
* Only tabs for indentation.
|
||||
* Use only tabs for indentation.
|
||||
* Any brace must have it's own line.
|
||||
* Short blocks, if statements and loops on single line are allowed.
|
||||
* Use short blocks, if statements and loops on single line are allowed.
|
||||
* Prefer generic utilities from libpublic over rolling your own.
|
||||
* Avoid magic numbers.
|
||||
* While macros are powerful, it's better to avoid overusing them.
|
||||
* If you unsure, try to mimic code style from anywhere else of engine source code.
|
||||
* **ANY** commit message should start from declaring a tags, in format:
|
||||
* If you are unsure, try to mimic the code style from anywhere else in the engine source code.
|
||||
* **ANY** commit message should start from declaring tags, in the format:
|
||||
|
||||
`tag: added some bugs`
|
||||
|
||||
`tag: subtag: fixed some features`
|
||||
|
||||
Tags can be any: subsystem, simple feature name or even just a filename, without extension.
|
||||
Just keep them always same, it helps keep history clean and commit messages short.
|
||||
The tags can be a:
|
||||
* subsystem
|
||||
* simple feature name or even just a filename, without the extension.
|
||||
Just always keep them the same because it helps keep the commit history clean and messages short.
|
||||
|
||||
## LLM-based tools usage.
|
||||
|
||||
While we wouldn't recommend using any LLM-based (also misleadingly called AI) tools, we understand that they are here to stay.
|
||||
|
||||
Whether you're reporting bug or contributing the code, you take complete authorship and responsibility over provided content and the same rules will apply to you as for everybody else, so validate the bug report or the patch before sending it.
|
||||
Whether you're reporting a bug or contributing to the code, you will take complete authorship and responsibility over the provided content, and the same rules will apply to you as for everybody else, so validate the bug report or the patch it before sending it.
|
||||
|
||||
@@ -65,11 +65,14 @@ Available on GamerLab - http://gamer-lab.com/eng/code_mods_goldsrc/Half-Life_2D_
|
||||
## Gang Wars
|
||||
Mirrored on github - https://github.com/nekonomicon/gw1.45src
|
||||
|
||||
## Go-mod
|
||||
## Go-Mod
|
||||
Versions 2.0 and 3.0, available in mod archives on ModDB - https://www.moddb.com/mods/go-mod/downloads
|
||||
|
||||
Version 3.0, mirrored on github - https://github.com/nekonomicon/Go-mod30
|
||||
|
||||
## Go-Mod: Reborn
|
||||
Official github repository - https://github.com/LambdaLuke87/Go-Mod-Reborn-Lite-Build
|
||||
|
||||
## GT mod
|
||||
Available on GamerLab - http://gamer-lab.com/eng/code_mods_goldsrc/GT_mod_(Polnie_ishodniki)
|
||||
|
||||
@@ -112,6 +115,13 @@ Mirrored on github - https://github.com/solidi/hl-mods/tree/master/pong
|
||||
## Half-Life: Quest Mode
|
||||
Available on cs-mapping.com.ua - https://old.cs-mapping.com.ua/forum/showthread.php?t=38030
|
||||
|
||||
## Half-Life: Sum
|
||||
Original Version: Branch **sum_orig** in halflife-featureful - https://github.com/FreeSlave/halflife-featureful/tree/sum_orig
|
||||
|
||||
Version 2022: Branch **sum_2022** in halflife-featureful - https://github.com/FreeSlave/halflife-featureful/tree/sum_2022
|
||||
|
||||
Current Version: Branch **sum** in halflife-featureful - https://github.com/FreeSlave/halflife-featureful/tree/sum
|
||||
|
||||
## Half-Life: Top-Down
|
||||
Official gitlab repository - https://gitlab.com/Sockman/hltopdown
|
||||
|
||||
@@ -254,6 +264,12 @@ Mirrored on github - https://github.com/a1batross/XashXT_original
|
||||
|
||||
[Logic&Trick's](https://github.com/LogicAndTrick) mirror - https://files.logic-and-trick.com/#/Half-Life/Mods/Spirit%20of%20Half-Life
|
||||
|
||||
## Yet another PS2 Half-Life port
|
||||
Official github repository - https://github.com/supadupaplex/ya-ps2hl-dll
|
||||
|
||||
## Zombie Panic!
|
||||
Official github repository - https://github.com/Monochrome-Inc/ZombiePanic-HL
|
||||
|
||||
## 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
|
||||
|
||||
@@ -461,5 +477,8 @@ Branch **dmc** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/d
|
||||
## Xen-Warrior
|
||||
Branch **sohl1.2** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/sohl1.2
|
||||
|
||||
## Yet another PS2 Half-Life port
|
||||
Branch **ps2hl** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/ps2hl
|
||||
|
||||
## Zombie-X
|
||||
Branch **zombie-x** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/zombie-x
|
||||
|
||||
@@ -1072,127 +1072,137 @@ To run this mod on specific platforms you may be need to compile libraries from
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **sci** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
35. **[Half-Life: TopDown](https://www.moddb.com/mods/half-life-top-downs)**
|
||||
35. **[Half-Life: Sum](https://www.moddb.com/mods/half-life-sum)**
|
||||
|
||||
This mod already supports x86 Linux.
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **sum** branch of [halflife-featureful](https://github.com/FreeSlave/halflife-featureful).
|
||||
|
||||
36. **[Half-Life: TopDown](https://www.moddb.com/mods/half-life-top-downs)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **topdown** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
36. **[Half-Life: Urbicide](https://www.moddb.com/mods/half-life-urbicide)**
|
||||
37. **[Half-Life: Urbicide](https://www.moddb.com/mods/half-life-urbicide)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **hl_urbicide** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
37. **[Half-Life: Visitors](https://www.moddb.com/mods/half-life-visitors)**
|
||||
38. **[Half-Life: Visitors](https://www.moddb.com/mods/half-life-visitors)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **visitors** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
38. **[Half-Rats: Parasomnia](https://www.moddb.com/mods/half-rats-parasomnia/downloads/half-rats-parasomnia-v10b-steamlinux)**
|
||||
39. **[Half-Rats: Parasomnia](https://www.moddb.com/mods/half-rats-parasomnia/downloads/half-rats-parasomnia-v10b-steamlinux)**
|
||||
|
||||
This mod already supports x86 Linux.
|
||||
|
||||
Support for other platforms may be available later.
|
||||
|
||||
39. **[Half-Screwed: Death and Rebirth](https://www.moddb.com/mods/half-screwed)**
|
||||
40. **[Half-Screwed: Death and Rebirth](https://www.moddb.com/mods/half-screwed)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **half-screwed** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
40. **[Half-Secret](https://www.moddb.com/mods/half-secret)**
|
||||
41. **[Half-Secret](https://www.moddb.com/mods/half-secret)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **half-secret** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
41. **[Natural Selection](https://www.moddb.com/mods/natural-selection)**
|
||||
42. **[Mortal Kombat](https://www.moddb.com/mods/hl-mortal-kombat)**
|
||||
|
||||
This mod already supports Android and x86 Linux.
|
||||
|
||||
43. **[Natural Selection](https://www.moddb.com/mods/natural-selection)**
|
||||
|
||||
This mod already supports x86 Linux.
|
||||
|
||||
Support for other platforms may be available later.
|
||||
|
||||
42. **[Night at the Office](https://www.moddb.com/mods/night-at-the-office)**
|
||||
44. **[Night at the Office](https://www.moddb.com/mods/night-at-the-office)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **noffice** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
43. **[Paranoia](https://www.moddb.com/mods/paranoia)**
|
||||
45. **[Paranoia](https://www.moddb.com/mods/paranoia)**
|
||||
|
||||
*Support temporary abandoned*
|
||||
|
||||
[Source code](https://github.com/FWGS/paranoia_toolkit).
|
||||
|
||||
44. **[Poke646](https://poke646.com/)**
|
||||
46. **[Poke646](https://poke646.com/)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **poke646** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
45. **[Poke646: Vendetta](https://poke646.com/)**
|
||||
47. **[Poke646: Vendetta](https://poke646.com/)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **poke646_vendetta** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
46. [PrimeXT](https://snmetamorph.github.io/PrimeXT/)
|
||||
48. [PrimeXT](https://snmetamorph.github.io/PrimeXT/)
|
||||
|
||||
*It's modding SDK*
|
||||
|
||||
[Source code](https://github.com/SNMetamorph/PrimeXT)
|
||||
|
||||
47. **[Quake Remake](https://www.moddb.com/games/quake-remake)**
|
||||
49. **[Quake Remake](https://www.moddb.com/games/quake-remake)**
|
||||
|
||||
*Support was fully abandoned due Quake Wrapper release.*
|
||||
|
||||
[Actual source code](https://github.com/FWGS/quakeremake)
|
||||
|
||||
48. **[Rebellion](https://www.moddb.com/mods/rebellion1)**
|
||||
50. **[Rebellion](https://www.moddb.com/mods/rebellion1)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **rebellion** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
49. **[Residual Life](https://www.moddb.com/mods/hl-residual-life)**
|
||||
51. **[Residual Life](https://www.moddb.com/mods/hl-residual-life)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **residual_point** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
50. **[Residual Point](https://www.moddb.com/mods/hl-residual-point)**
|
||||
52. **[Residual Point](https://www.moddb.com/mods/hl-residual-point)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **residual_point** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
51. **[Ricochet](https://store.steampowered.com/app/60/Ricochet/)**
|
||||
53. **[Ricochet](https://store.steampowered.com/app/60/Ricochet/)**
|
||||
|
||||
This mod already supports x86 Linux.
|
||||
|
||||
Support for other platforms may be available later.
|
||||
|
||||
52. [Sewer](https://www.moddb.com/games/half-life/addons/sewer-beta)
|
||||
54. [Sewer](https://www.moddb.com/games/half-life/addons/sewer-beta)
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **sewer_beta** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
53. [Spirit of Half-Life 1.2](https://www.moddb.com/mods/spirit-of-half-life)
|
||||
55. [Spirit of Half-Life 1.2](https://www.moddb.com/mods/spirit-of-half-life)
|
||||
|
||||
*It's modding SDK*
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **sohl1.2** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
54. **[Swiss Cheese Halloween](https://www.moddb.com/mods/half-life-halloween-mod)**
|
||||
56. **[Swiss Cheese Halloween](https://www.moddb.com/mods/half-life-halloween-mod)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **halloween** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
55. **[Team Fortress Classic](https://store.steampowered.com/app/20/Team_Fortress_Classic/)**
|
||||
57. **[Team Fortress Classic](https://store.steampowered.com/app/20/Team_Fortress_Classic/)**
|
||||
|
||||
This mod already supports x86 Linux.
|
||||
|
||||
Currently, only source code of [client part](https://github.com/Velaron/tf15-client) is available.
|
||||
|
||||
56. **[The Gate](https://www.moddb.com/mods/the-gate)**
|
||||
58. **[The Gate](https://www.moddb.com/mods/the-gate)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **thegate** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
57. **[The Last Bullet](https://www.moddb.com/mods/the-last-bullet-update)**
|
||||
59. **[The Last Bullet](https://www.moddb.com/mods/the-last-bullet-update)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **fwgs** branch of [The-Last-Bullet-Updated-Code](https://github.com/GT-Project-Cat/The-Last-Bullet-Updated-Code).
|
||||
|
||||
58. **[They Hunger: Trilogy](https://www.moddb.com/mods/they-hunger)**
|
||||
60. **[They Hunger: Trilogy](https://www.moddb.com/mods/they-hunger)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **theyhunger** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
59. **[ThreeWave CTF](https://www.moddb.com/games/deathmatch-classic/downloads/threewave-ctf)**
|
||||
61. **[ThreeWave CTF](https://www.moddb.com/games/deathmatch-classic/downloads/threewave-ctf)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **dmc** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
60. **[Times of Troubles](https://www.moddb.com/mods/times-of-troubles)**
|
||||
62. **[Times of Troubles](https://www.moddb.com/mods/times-of-troubles)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **tot** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
61. [XashXT](https://csm.dev/threads/xashxt-0-65-rev-4-release-stable.38319/)
|
||||
63. [XashXT](https://csm.dev/threads/xashxt-0-65-rev-4-release-stable.38319/)
|
||||
|
||||
*It's modding SDK*
|
||||
|
||||
@@ -1200,19 +1210,23 @@ To run this mod on specific platforms you may be need to compile libraries from
|
||||
|
||||
[Source code](https://github.com/FWGS/XashXT-FWGS/)
|
||||
|
||||
62. **[X-Half-Life DeathMatch](https://www.moddb.com/mods/xdm)**
|
||||
64. **[X-Half-Life DeathMatch](https://www.moddb.com/mods/xdm)**
|
||||
|
||||
This mod already supports x86 Linux.
|
||||
|
||||
Support for other platforms may be available later.
|
||||
|
||||
63. **[Xen-Warrior](https://www.moddb.com/mods/xen-warrior)**
|
||||
65. **[Xen-Warrior](https://www.moddb.com/mods/xen-warrior)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **sohl1.2** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
Don't forget to enable XENWARRIOR build option!!!
|
||||
|
||||
64. [Zombie-X](https://www.moddb.com/mods/zombie-x-10-final)
|
||||
66. **[Yet another PS2 Half-Life port](https://www.moddb.com/mods/yet-another-ps2-half-life-pc-port)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **ps2hl** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
67. [Zombie-X](https://www.moddb.com/mods/zombie-x-10-final)
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **zombie-x** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
|
||||
@@ -15,14 +15,13 @@ GNU General Public License for more details.
|
||||
|
||||
#include "build.h"
|
||||
#include <inttypes.h>
|
||||
#if XASH_LINUX
|
||||
#include <fcntl.h>
|
||||
#if !XASH_WIN32
|
||||
#include <dirent.h>
|
||||
#else
|
||||
#include <io.h>
|
||||
#endif
|
||||
#include "common.h"
|
||||
#include "client.h"
|
||||
#include "platform/platform.h"
|
||||
|
||||
/*
|
||||
==========================================================
|
||||
@@ -97,8 +96,6 @@ IDENTIFICATION
|
||||
#define MAXBITS_GEN 30
|
||||
#define MAXBITS_CHECK MAXBITS_GEN + 6
|
||||
|
||||
static qboolean ID_ProcessFile( bloomfilter_t *value, const char *path );
|
||||
|
||||
static void ID_BloomFilter_f( void )
|
||||
{
|
||||
bloomfilter_t value = 0;
|
||||
@@ -203,84 +200,6 @@ static qboolean ID_ProcessCPUInfo( bloomfilter_t *value )
|
||||
return true;
|
||||
}
|
||||
|
||||
static qboolean ID_ValidateNetDevice( const char *dev )
|
||||
{
|
||||
const char *prefix = "/sys/class/net";
|
||||
|
||||
// These devices are fake, their mac address is generated each boot, while assign_type is 0
|
||||
if( !Q_strnicmp( dev, "ccmni", sizeof( "ccmni" ) ) ||
|
||||
!Q_strnicmp( dev, "ifb", sizeof( "ifb" ) ) )
|
||||
return false;
|
||||
|
||||
byte *pfile = FS_LoadDirectFile( va( "%s/%s/addr_assign_type", prefix, dev ), NULL );
|
||||
|
||||
// if NULL, it may be old kernel
|
||||
if( pfile )
|
||||
{
|
||||
int assignType = Q_atoi( (char*)pfile );
|
||||
|
||||
Mem_Free( pfile );
|
||||
|
||||
// check is MAC address is constant
|
||||
if( assignType != 0 )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int ID_ProcessNetDevices( bloomfilter_t *value )
|
||||
{
|
||||
const char *prefix = "/sys/class/net";
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
int count = 0;
|
||||
|
||||
if( !( dir = opendir( prefix ) ) )
|
||||
return 0;
|
||||
|
||||
while( ( entry = readdir( dir ) ) && BloomFilter_Weight( *value ) < MAXBITS_GEN )
|
||||
{
|
||||
if( !Q_strcmp( entry->d_name, "." ) || !Q_strcmp( entry->d_name, ".." ) )
|
||||
continue;
|
||||
|
||||
if( !ID_ValidateNetDevice( entry->d_name ) )
|
||||
continue;
|
||||
|
||||
count += ID_ProcessFile( value, va( "%s/%s/address", prefix, entry->d_name ) );
|
||||
}
|
||||
closedir( dir );
|
||||
return count;
|
||||
}
|
||||
|
||||
static int ID_CheckNetDevices( bloomfilter_t value )
|
||||
{
|
||||
const char *prefix = "/sys/class/net";
|
||||
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
int count = 0;
|
||||
bloomfilter_t filter = 0;
|
||||
|
||||
if( !( dir = opendir( prefix ) ) )
|
||||
return 0;
|
||||
|
||||
while( ( entry = readdir( dir ) ) )
|
||||
{
|
||||
if( !Q_strcmp( entry->d_name, "." ) || !Q_strcmp( entry->d_name, ".." ) )
|
||||
continue;
|
||||
|
||||
if( !ID_ValidateNetDevice( entry->d_name ) )
|
||||
continue;
|
||||
|
||||
if( ID_ProcessFile( &filter, va( "%s/%s/address", prefix, entry->d_name ) ) )
|
||||
count += ( value & filter ) == filter, filter = 0;
|
||||
}
|
||||
|
||||
closedir( dir );
|
||||
return count;
|
||||
}
|
||||
|
||||
static void ID_TestCPUInfo_f( void )
|
||||
{
|
||||
bloomfilter_t value = 0;
|
||||
@@ -291,8 +210,6 @@ static void ID_TestCPUInfo_f( void )
|
||||
Msg( "Could not get serial\n" );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static qboolean ID_ProcessFile( bloomfilter_t *value, const char *path )
|
||||
{
|
||||
int fd = open( path, O_RDONLY );
|
||||
@@ -322,7 +239,6 @@ static qboolean ID_ProcessFile( bloomfilter_t *value, const char *path )
|
||||
return true;
|
||||
}
|
||||
|
||||
#if !XASH_WIN32
|
||||
static int ID_ProcessFiles( bloomfilter_t *value, const char *prefix, const char *postfix )
|
||||
{
|
||||
DIR *dir;
|
||||
@@ -365,7 +281,94 @@ static int ID_CheckFiles( bloomfilter_t value, const char *prefix, const char *p
|
||||
closedir( dir );
|
||||
return count;
|
||||
}
|
||||
#else
|
||||
#endif // XASH_LINUX
|
||||
|
||||
#if XASH_POSIX
|
||||
#define MAX_NETDEVICES 16
|
||||
|
||||
static qboolean ID_IsReservedMAC( uint64_t mac )
|
||||
{
|
||||
byte first = ( mac >> 40 ) & 0xff;
|
||||
|
||||
// no address at all
|
||||
if( mac == 0 )
|
||||
return true;
|
||||
|
||||
// group and local bits of the first octet, see https://www.rfc-editor.org/rfc/rfc9542#section-2.1.1
|
||||
if( FBitSet( first, 0x01 ) || FBitSet( first, 0x02 ))
|
||||
return true;
|
||||
|
||||
// IANA OUI, see https://www.iana.org/assignments/ethernet-numbers/ethernet-numbers.xhtml and https://www.rfc-editor.org/rfc/rfc9568#section-7.3
|
||||
if(( mac >> 24 ) == 0x00005e )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void ID_FormatMAC( char *out, size_t size, uint64_t mac )
|
||||
{
|
||||
// format exactly like /sys/class/net/ */address contents, so ids generated by older versions stay valid
|
||||
Q_snprintf( out, size, "%02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
(uint)(( mac >> 40 ) & 0xffu ),
|
||||
(uint)(( mac >> 32 ) & 0xffu ),
|
||||
(uint)(( mac >> 24 ) & 0xffu ),
|
||||
(uint)(( mac >> 16 ) & 0xffu ),
|
||||
(uint)(( mac >> 8 ) & 0xffu ),
|
||||
(uint)( mac & 0xffu ));
|
||||
}
|
||||
|
||||
static int ID_ProcessNetDevices( bloomfilter_t *value )
|
||||
{
|
||||
uint64_t macs[MAX_NETDEVICES];
|
||||
int total = Posix_GetNetDeviceAddresses( macs, MAX_NETDEVICES );
|
||||
int count = 0;
|
||||
|
||||
for( int i = 0; i < total && BloomFilter_Weight( *value ) < MAXBITS_GEN; i++ )
|
||||
{
|
||||
char buf[32];
|
||||
|
||||
if( ID_IsReservedMAC( macs[i] ))
|
||||
continue;
|
||||
|
||||
ID_FormatMAC( buf, sizeof( buf ), macs[i] );
|
||||
|
||||
if( !ID_VerifyHEX( buf ))
|
||||
continue;
|
||||
|
||||
*value |= BloomFilter_ProcessStr( buf );
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static int ID_CheckNetDevices( bloomfilter_t value )
|
||||
{
|
||||
uint64_t macs[MAX_NETDEVICES];
|
||||
int total = Posix_GetNetDeviceAddresses( macs, MAX_NETDEVICES );
|
||||
int count = 0;
|
||||
|
||||
for( int i = 0; i < total; i++ )
|
||||
{
|
||||
char buf[32];
|
||||
|
||||
if( ID_IsReservedMAC( macs[i] ))
|
||||
continue;
|
||||
|
||||
ID_FormatMAC( buf, sizeof( buf ), macs[i] );
|
||||
|
||||
if( !ID_VerifyHEX( buf ))
|
||||
continue;
|
||||
|
||||
bloomfilter_t filter = BloomFilter_ProcessStr( buf );
|
||||
count += ( value & filter ) == filter;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
#endif // XASH_POSIX
|
||||
|
||||
#if XASH_WIN32
|
||||
static int ID_GetKeyData( HKEY hRootKey, char *subKey, char *value, LPBYTE data, DWORD cbData )
|
||||
{
|
||||
HKEY hKey;
|
||||
@@ -539,6 +542,17 @@ static bloomfilter_t ID_GenerateRawId( void )
|
||||
|
||||
count += ID_ProcessCPUInfo( &value );
|
||||
count += ID_ProcessFiles( &value, "/sys/block", "device/cid" );
|
||||
#endif
|
||||
#if XASH_OSX
|
||||
char buf[64];
|
||||
|
||||
if( Apple_GetSerialNumber( buf, sizeof( buf )))
|
||||
{
|
||||
value |= BloomFilter_ProcessStr( buf );
|
||||
count++;
|
||||
}
|
||||
#endif
|
||||
#if XASH_POSIX
|
||||
count += ID_ProcessNetDevices( &value );
|
||||
#endif
|
||||
#if XASH_WIN32
|
||||
@@ -587,12 +601,26 @@ static uint ID_CheckRawId( bloomfilter_t filter )
|
||||
}
|
||||
|
||||
#endif // !XASH_ANDROID
|
||||
count += ID_CheckNetDevices( filter );
|
||||
count += ID_CheckFiles( filter, "/sys/block", "device/cid" );
|
||||
if( ID_ProcessCPUInfo( &value ) )
|
||||
count += (filter & value) == value;
|
||||
#endif
|
||||
|
||||
#if XASH_OSX
|
||||
char buf[64];
|
||||
|
||||
if( Apple_GetSerialNumber( buf, sizeof( buf )))
|
||||
{
|
||||
value = BloomFilter_ProcessStr( buf );
|
||||
count += (filter & value) == value;
|
||||
value = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if XASH_POSIX
|
||||
count += ID_CheckNetDevices( filter );
|
||||
#endif
|
||||
|
||||
#if XASH_WIN32
|
||||
count += ID_CheckWMIC( filter, L"wmic path win32_physicalmedia get SerialNumber" );
|
||||
count += ID_CheckWMIC( filter, L"wmic bios get serialnumber" );
|
||||
|
||||
@@ -731,69 +731,77 @@ Image_SaveWAD
|
||||
*/
|
||||
qboolean Image_SaveWAD( const char *name, rgbdata_t *pix )
|
||||
{
|
||||
byte *mip1_data = NULL, *mip2_data = NULL, *mip3_data = NULL;
|
||||
byte grad_palette[256 * 3];
|
||||
file_t *f;
|
||||
dwadinfo_t header =
|
||||
{
|
||||
.ident = IDWAD3HEADER,
|
||||
.numlumps = 1,
|
||||
};
|
||||
mip_t miptex;
|
||||
long infotableofs;
|
||||
dlumpinfo_t lump;
|
||||
fs_offset_t pad;
|
||||
qboolean result = false;
|
||||
int lump_type = ( pix->flags & IMAGE_GRADIENT_DECAL ) ? TYP_PALETTE : TYP_MIPTEX;
|
||||
short palette_size = 256;
|
||||
int infotableofs32 = 0;
|
||||
|
||||
if( !pix || !pix->buffer )
|
||||
return false;
|
||||
|
||||
const byte *palette = pix->palette ? pix->palette : (const byte *)image.palette;
|
||||
const int lump_type = ( pix->flags & IMAGE_GRADIENT_DECAL ) ? TYP_PALETTE : TYP_MIPTEX;
|
||||
|
||||
int m0size = pix->width * pix->height;
|
||||
int m1size = m0size / 4;
|
||||
int m2size = m0size / 16;
|
||||
int m3size = m0size / 64;
|
||||
|
||||
mip1_data = (byte *)Mem_Malloc( host.imagepool, m1size );
|
||||
mip2_data = (byte *)Mem_Malloc( host.imagepool, m2size );
|
||||
mip3_data = (byte *)Mem_Malloc( host.imagepool, m3size );
|
||||
if( !mip1_data || !mip2_data || !mip3_data )
|
||||
goto cleanup;
|
||||
byte *mip1_data = Mem_Malloc( host.imagepool, m1size );
|
||||
byte *mip2_data = Mem_Malloc( host.imagepool, m2size );
|
||||
byte *mip3_data = Mem_Malloc( host.imagepool, m3size );
|
||||
if( !mip1_data || !mip2_data || !mip3_data ) // Mem_Malloc never returns NULL, but keep this check anyway
|
||||
{
|
||||
Mem_Free( mip1_data );
|
||||
Mem_Free( mip2_data );
|
||||
Mem_Free( mip3_data );
|
||||
return false;
|
||||
}
|
||||
|
||||
Image_GenerateMipmaps( pix->buffer, pix->width, pix->height, mip1_data, mip2_data, mip3_data );
|
||||
|
||||
memset( &miptex, 0, sizeof( mip_t ));
|
||||
Q_strncpy( miptex.name, "{LOGO", sizeof( miptex.name ));
|
||||
miptex.width = pix->width;
|
||||
miptex.height = pix->height;
|
||||
miptex.offsets[0] = sizeof( mip_t );
|
||||
miptex.offsets[1] = miptex.offsets[0] + m0size;
|
||||
miptex.offsets[2] = miptex.offsets[1] + m1size;
|
||||
miptex.offsets[3] = miptex.offsets[2] + m2size;
|
||||
|
||||
f = FS_Open( name, "wb", false );
|
||||
file_t *f = FS_Open( name, "wb", false );
|
||||
if( !f )
|
||||
goto cleanup;
|
||||
{
|
||||
Mem_Free( mip1_data );
|
||||
Mem_Free( mip2_data );
|
||||
Mem_Free( mip3_data );
|
||||
return false;
|
||||
}
|
||||
|
||||
le_struct_swap( dwadinfo_swap, &header );
|
||||
FS_Write( f, &header, sizeof( header ));
|
||||
{
|
||||
dwadinfo_t header =
|
||||
{
|
||||
.ident = IDWAD3HEADER,
|
||||
.numlumps = 1,
|
||||
};
|
||||
le_struct_swap( dwadinfo_swap, &header );
|
||||
FS_Write( f, &header, sizeof( header ));
|
||||
}
|
||||
|
||||
mip_t miptex = {
|
||||
.name = "{LOGO",
|
||||
.width = pix->width,
|
||||
.height = pix->height,
|
||||
.offsets[0] = sizeof( mip_t ),
|
||||
.offsets[1] = sizeof( mip_t ) + m0size,
|
||||
.offsets[2] = sizeof( mip_t ) + m0size + m1size,
|
||||
.offsets[3] = sizeof( mip_t ) + m0size + m1size + m2size,
|
||||
};
|
||||
le_struct_swap( mip_swap, &miptex );
|
||||
FS_Write( f, &miptex, sizeof( mip_t ));
|
||||
le_struct_swap( mip_swap, &miptex );
|
||||
|
||||
FS_Write( f, pix->buffer, m0size );
|
||||
FS_Write( f, mip1_data, m1size );
|
||||
FS_Write( f, mip2_data, m2size );
|
||||
FS_Write( f, mip3_data, m3size );
|
||||
palette_size = LittleShort( palette_size );
|
||||
FS_Write( f, &palette_size, sizeof( short ));
|
||||
|
||||
{
|
||||
short palette_size = LittleShort( 256 );
|
||||
FS_Write( f, &palette_size, sizeof( short ));
|
||||
}
|
||||
|
||||
const byte *palette = pix->palette ? pix->palette : (const byte *)image.palette;
|
||||
|
||||
if( lump_type == TYP_PALETTE )
|
||||
{
|
||||
const byte *frontColorPtr = palette + 255 * 3;
|
||||
byte grad_palette[256 * 3];
|
||||
for( int i = 0; i < 256; ++i )
|
||||
{
|
||||
float t = i / 255.0f;
|
||||
@@ -809,34 +817,37 @@ qboolean Image_SaveWAD( const char *name, rgbdata_t *pix )
|
||||
}
|
||||
|
||||
// padding up to a multiple of 4
|
||||
pad = (( FS_Tell( f ) + 3 ) & ~3 ) - FS_Tell( f );
|
||||
fs_offset_t pad = (( FS_Tell( f ) + 3 ) & ~3 ) - FS_Tell( f );
|
||||
for( int i = 0; i < pad; ++i )
|
||||
FS_Write( f, (const void *)&(char){0}, 1 );
|
||||
{
|
||||
byte x = 0;
|
||||
FS_Write( f, &x, 1 );
|
||||
}
|
||||
|
||||
infotableofs = FS_Tell( f );
|
||||
memset( &lump, 0, sizeof( lump ));
|
||||
lump.filepos = sizeof( dwadinfo_t );
|
||||
lump.disksize = (int)( miptex.offsets[3] + m3size + sizeof( short ) + 256 * 3 );
|
||||
lump.size = lump.disksize;
|
||||
lump.type = (char)lump_type;
|
||||
lump.attribs = 0;
|
||||
Q_strncpy( lump.name, "tempdecal", sizeof( lump.name ));
|
||||
le_struct_swap( dlumpinfo_swap, &lump );
|
||||
FS_Write( f, &lump, sizeof( lump ));
|
||||
fs_offset_t infotableofs = FS_Tell( f );
|
||||
|
||||
{
|
||||
dlumpinfo_t lump =
|
||||
{
|
||||
.filepos = sizeof( dwadinfo_t ),
|
||||
.disksize = (int)( miptex.offsets[3] + m3size + sizeof( short ) + 256 * 3 ),
|
||||
.size = (int)( miptex.offsets[3] + m3size + sizeof( short ) + 256 * 3 ),
|
||||
.type = (char)lump_type,
|
||||
.attribs = 0,
|
||||
.name = "tempdecal",
|
||||
};
|
||||
le_struct_swap( dlumpinfo_swap, &lump );
|
||||
FS_Write( f, &lump, sizeof( lump ));
|
||||
}
|
||||
|
||||
FS_Seek( f, offsetof( dwadinfo_t, infotableofs ), SEEK_SET );
|
||||
infotableofs32 = LittleLong((int)infotableofs );
|
||||
int infotableofs32 = LittleLong((int)infotableofs );
|
||||
FS_Write( f, &infotableofs32, sizeof( int ));
|
||||
|
||||
FS_Close( f );
|
||||
result = true;
|
||||
|
||||
cleanup:
|
||||
if( mip1_data )
|
||||
Mem_Free( mip1_data );
|
||||
if( mip2_data )
|
||||
Mem_Free( mip2_data );
|
||||
if( mip3_data )
|
||||
Mem_Free( mip3_data );
|
||||
return result;
|
||||
Mem_Free( mip1_data );
|
||||
Mem_Free( mip2_data );
|
||||
Mem_Free( mip3_data );
|
||||
return true;
|
||||
}
|
||||
|
||||
50
engine/platform/apple/id_apple.c
Normal file
50
engine/platform/apple/id_apple.c
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
id_apple.c - macOS hardware serial id source
|
||||
Copyright (C) 2026 Xash3D FWGS Contributors
|
||||
|
||||
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 "platform/platform.h"
|
||||
#include <AvailabilityMacros.h>
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <IOKit/IOKitLib.h>
|
||||
|
||||
// kIOMasterPortDefault was renamed to kIOMainPortDefault in macOS 12 SDK
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED < 120000
|
||||
#define kIOMainPortDefault kIOMasterPortDefault
|
||||
#endif
|
||||
|
||||
static qboolean Apple_GetPlatformExpertProperty( CFStringRef key, char *out, size_t size )
|
||||
{
|
||||
io_service_t service = IOServiceGetMatchingService( kIOMainPortDefault, IOServiceMatching( "IOPlatformExpertDevice" ));
|
||||
|
||||
if( !service )
|
||||
return false;
|
||||
|
||||
qboolean ret = false;
|
||||
CFTypeRef prop = IORegistryEntryCreateCFProperty( service, key, kCFAllocatorDefault, 0 );
|
||||
|
||||
if( prop )
|
||||
{
|
||||
if( CFGetTypeID( prop ) == CFStringGetTypeID() && CFStringGetCString( (CFStringRef)prop, out, size, kCFStringEncodingUTF8 ))
|
||||
ret = true;
|
||||
CFRelease( prop );
|
||||
}
|
||||
|
||||
IOObjectRelease( service );
|
||||
return ret;
|
||||
}
|
||||
|
||||
qboolean Apple_GetSerialNumber( char *out, size_t size )
|
||||
{
|
||||
return Apple_GetPlatformExpertProperty( CFSTR( "IOPlatformSerialNumber" ), out, size );
|
||||
}
|
||||
@@ -69,6 +69,12 @@ void IOS_LaunchDialog( void );
|
||||
void Posix_Daemonize( void );
|
||||
void Posix_SetupSigtermHandling( void );
|
||||
char *Posix_Input( void );
|
||||
// returns the number of stable network device MAC addresses, each packed into low 48 bits
|
||||
int Posix_GetNetDeviceAddresses( uint64_t *addresses, int max );
|
||||
#endif
|
||||
|
||||
#if XASH_OSX
|
||||
qboolean Apple_GetSerialNumber( char *out, size_t size );
|
||||
#endif
|
||||
|
||||
#if XASH_SDL
|
||||
|
||||
141
engine/platform/posix/id_posix.c
Normal file
141
engine/platform/posix/id_posix.c
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
id_posix.c - network device enumeration for unique id generation
|
||||
Copyright (C) 2026 Xash3D FWGS contributors
|
||||
|
||||
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 "platform/platform.h"
|
||||
|
||||
#if XASH_LINUX
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static qboolean Posix_ValidateNetDevice( const char *dev )
|
||||
{
|
||||
const char *prefix = "/sys/class/net";
|
||||
|
||||
// These devices are fake, their mac address is generated each boot, while assign_type is 0
|
||||
if( !Q_strnicmp( dev, "ccmni", sizeof( "ccmni" ) - 1 ) || !Q_strnicmp( dev, "ifb", sizeof( "ifb" ) - 1 ))
|
||||
return false;
|
||||
|
||||
byte *pfile = FS_LoadDirectFile( va( "%s/%s/addr_assign_type", prefix, dev ), NULL );
|
||||
|
||||
// if NULL, it may be old kernel
|
||||
if( pfile )
|
||||
{
|
||||
int assignType = Q_atoi( (char*)pfile );
|
||||
|
||||
Mem_Free( pfile );
|
||||
|
||||
// check is MAC address is constant
|
||||
if( assignType != 0 )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int Posix_GetNetDeviceAddresses( uint64_t *addresses, int max )
|
||||
{
|
||||
const char *prefix = "/sys/class/net";
|
||||
DIR *dir = opendir( prefix );
|
||||
struct dirent *entry;
|
||||
int count = 0;
|
||||
|
||||
if( !dir )
|
||||
return 0;
|
||||
|
||||
while(( entry = readdir( dir )) && count < max )
|
||||
{
|
||||
if( !Q_strcmp( entry->d_name, "." ) || !Q_strcmp( entry->d_name, ".." ))
|
||||
continue;
|
||||
|
||||
if( !Posix_ValidateNetDevice( entry->d_name ))
|
||||
continue;
|
||||
|
||||
int fd = open( va( "%s/%s/address", prefix, entry->d_name ), O_RDONLY );
|
||||
|
||||
if( fd < 0 )
|
||||
continue;
|
||||
|
||||
char buffer[64];
|
||||
int ret = read( fd, buffer, sizeof( buffer ) - 1 );
|
||||
|
||||
close( fd );
|
||||
|
||||
if( ret <= 0 )
|
||||
continue;
|
||||
|
||||
buffer[ret] = 0;
|
||||
|
||||
uint mac[6];
|
||||
char term = 0;
|
||||
|
||||
if( sscanf( buffer, "%02x:%02x:%02x:%02x:%02x:%02x%c", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5], &term ) < 6 )
|
||||
continue;
|
||||
|
||||
// skip malformed or long address devices, we only need MAC addresses and they're always 48-bit
|
||||
if( term != '\n' && term != '\0' )
|
||||
continue;
|
||||
|
||||
addresses[count] = ((uint64_t)mac[0] << 40) | ((uint64_t)mac[1] << 32) | ((uint64_t)mac[2] << 24) | ((uint64_t)mac[3] << 16) | ((uint64_t)mac[4] << 8) | (uint64_t)mac[5];
|
||||
count++;
|
||||
}
|
||||
|
||||
closedir( dir );
|
||||
return count;
|
||||
}
|
||||
#elif XASH_APPLE || XASH_FREEBSD || XASH_NETBSD || XASH_OPENBSD
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
|
||||
int Posix_GetNetDeviceAddresses( uint64_t *addresses, int max )
|
||||
{
|
||||
struct ifaddrs *ifaddr;
|
||||
int count = 0;
|
||||
|
||||
if( getifaddrs( &ifaddr ) < 0 )
|
||||
return 0;
|
||||
|
||||
for( struct ifaddrs *ifa = ifaddr; ifa != NULL && count < max; ifa = ifa->ifa_next )
|
||||
{
|
||||
if( !ifa->ifa_addr || ifa->ifa_addr->sa_family != AF_LINK )
|
||||
continue;
|
||||
|
||||
if( FBitSet( ifa->ifa_flags, IFF_LOOPBACK | IFF_POINTOPOINT ))
|
||||
continue;
|
||||
|
||||
const struct sockaddr_dl *sdl = (const struct sockaddr_dl *)ifa->ifa_addr;
|
||||
|
||||
if( sdl->sdl_alen != 6 )
|
||||
continue;
|
||||
|
||||
const byte *mac = (const byte *)LLADDR( sdl );
|
||||
|
||||
addresses[count] = ((uint64_t)mac[0] << 40) | ((uint64_t)mac[1] << 32) | ((uint64_t)mac[2] << 24) | ((uint64_t)mac[3] << 16) | ((uint64_t)mac[4] << 8) | (uint64_t)mac[5];
|
||||
count++;
|
||||
}
|
||||
|
||||
freeifaddrs( ifaddr );
|
||||
return count;
|
||||
}
|
||||
#else
|
||||
int Posix_GetNetDeviceAddresses( uint64_t *addresses, int max )
|
||||
{
|
||||
Con_Reportf( S_WARN "%s: implement me!\n", __func__ );
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -705,4 +705,23 @@ int SV_LightForEntity( edict_t *pEdict );
|
||||
//
|
||||
void SV_SourceQuery_HandleConnnectionlessPacket( const char *c, netadr_t from, sizebuf_t *msg );
|
||||
|
||||
static inline qboolean SV_CheckGroupOp( int op, int groupinfo, int mask )
|
||||
{
|
||||
if( op == GROUP_OP_AND && !FBitSet( groupinfo, mask ))
|
||||
return false;
|
||||
|
||||
if( op == GROUP_OP_NAND && FBitSet( groupinfo, mask ))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline qboolean SV_CheckGroupTrace( const edict_t *e1, const edict_t *e2 )
|
||||
{
|
||||
if( e1->v.groupinfo && e2->v.groupinfo )
|
||||
return SV_CheckGroupOp( svs.groupop, e1->v.groupinfo, e2->v.groupinfo );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif//SERVER_H
|
||||
|
||||
@@ -435,14 +435,8 @@ static int SV_Multicast( int dest, const vec3_t origin, const edict_t *ent, qboo
|
||||
if( filter && cl == sv.current_client && FBitSet( sv.current_client->flags, FCL_PREDICT_MOVEMENT ))
|
||||
continue;
|
||||
|
||||
if( SV_IsValidEdict( ent ) && ent->v.groupinfo && cl->edict->v.groupinfo )
|
||||
{
|
||||
if( svs.groupop == GROUP_OP_AND && !FBitSet( cl->edict->v.groupinfo, ent->v.groupinfo ))
|
||||
continue;
|
||||
|
||||
if( svs.groupop == GROUP_OP_NAND && FBitSet( cl->edict->v.groupinfo, ent->v.groupinfo ))
|
||||
continue;
|
||||
}
|
||||
if( SV_IsValidEdict( ent ) && !SV_CheckGroupTrace( ent, cl->edict ))
|
||||
continue;
|
||||
|
||||
if( !SV_CheckClientVisiblity( cl, mask ))
|
||||
continue;
|
||||
@@ -4123,14 +4117,8 @@ void GAME_EXPORT SV_PlaybackEventFull( int flags, const edict_t *pInvoker, word
|
||||
if( cl->state != cs_spawned || !cl->edict || FBitSet( cl->flags, FCL_FAKECLIENT ))
|
||||
continue;
|
||||
|
||||
if( SV_IsValidEdict( pInvoker ) && pInvoker->v.groupinfo && cl->edict->v.groupinfo )
|
||||
{
|
||||
if( svs.groupop == GROUP_OP_AND && !FBitSet( cl->edict->v.groupinfo, pInvoker->v.groupinfo ))
|
||||
continue;
|
||||
|
||||
if( svs.groupop == GROUP_OP_NAND && FBitSet( cl->edict->v.groupinfo, pInvoker->v.groupinfo ))
|
||||
continue;
|
||||
}
|
||||
if( SV_IsValidEdict( pInvoker ) && !SV_CheckGroupTrace( pInvoker, cl->edict ))
|
||||
continue;
|
||||
|
||||
if( SV_IsValidEdict( pInvoker ))
|
||||
{
|
||||
|
||||
@@ -60,6 +60,47 @@ Utility functions
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
/*
|
||||
================
|
||||
SV_CheckVelocity
|
||||
================
|
||||
*/
|
||||
void SV_CheckVelocity( edict_t *ent )
|
||||
{
|
||||
float wishspd;
|
||||
float maxspd;
|
||||
|
||||
// bound velocity
|
||||
for( int i = 0; i < 3; i++ )
|
||||
{
|
||||
if( IS_NAN( ent->v.velocity[i] ))
|
||||
{
|
||||
if( sv_check_errors.value )
|
||||
Con_Printf( "Got a NaN velocity on %s\n", SV_GetString( ent->v.classname ));
|
||||
ent->v.velocity[i] = 0.0f;
|
||||
}
|
||||
|
||||
if( IS_NAN( ent->v.origin[i] ))
|
||||
{
|
||||
if( sv_check_errors.value )
|
||||
Con_Printf( "Got a NaN origin on %s\n", SV_GetString( ent->v.classname ));
|
||||
ent->v.origin[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
wishspd = DotProduct( ent->v.velocity, ent->v.velocity );
|
||||
maxspd = sv_maxvelocity.value * sv_maxvelocity.value * 1.73f; // half-diagonal
|
||||
|
||||
if( wishspd > maxspd )
|
||||
{
|
||||
wishspd = sqrt( wishspd );
|
||||
if( sv_check_errors.value )
|
||||
Con_Printf( "Got a velocity too high on %s ( %.2f > %.2f )\n", SV_GetString( ent->v.classname ), wishspd, sqrt( maxspd ));
|
||||
wishspd = sv_maxvelocity.value / wishspd;
|
||||
VectorScale( ent->v.velocity, wishspd, ent->v.velocity );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
SV_CheckAllEnts
|
||||
@@ -110,47 +151,6 @@ static void SV_CheckAllEnts( void )
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
SV_CheckVelocity
|
||||
================
|
||||
*/
|
||||
void SV_CheckVelocity( edict_t *ent )
|
||||
{
|
||||
float wishspd;
|
||||
float maxspd;
|
||||
|
||||
// bound velocity
|
||||
for( int i = 0; i < 3; i++ )
|
||||
{
|
||||
if( IS_NAN( ent->v.velocity[i] ))
|
||||
{
|
||||
if( sv_check_errors.value )
|
||||
Con_Printf( "Got a NaN velocity on %s\n", SV_GetString( ent->v.classname ));
|
||||
ent->v.velocity[i] = 0.0f;
|
||||
}
|
||||
|
||||
if( IS_NAN( ent->v.origin[i] ))
|
||||
{
|
||||
if( sv_check_errors.value )
|
||||
Con_Printf( "Got a NaN origin on %s\n", SV_GetString( ent->v.classname ));
|
||||
ent->v.origin[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
wishspd = DotProduct( ent->v.velocity, ent->v.velocity );
|
||||
maxspd = sv_maxvelocity.value * sv_maxvelocity.value * 1.73f; // half-diagonal
|
||||
|
||||
if( wishspd > maxspd )
|
||||
{
|
||||
wishspd = sqrt( wishspd );
|
||||
if( sv_check_errors.value )
|
||||
Con_Printf( "Got a velocity too high on %s ( %.2f > %.2f )\n", SV_GetString( ent->v.classname ), wishspd, sqrt( maxspd ));
|
||||
wishspd = sv_maxvelocity.value / wishspd;
|
||||
VectorScale( ent->v.velocity, wishspd, ent->v.velocity );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
SV_UpdateBaseVelocity
|
||||
@@ -158,26 +158,20 @@ SV_UpdateBaseVelocity
|
||||
*/
|
||||
void SV_UpdateBaseVelocity( edict_t *ent )
|
||||
{
|
||||
if( ent->v.flags & FL_ONGROUND )
|
||||
{
|
||||
edict_t *groundentity = ent->v.groundentity;
|
||||
if( !FBitSet( ent->v.flags, FL_ONGROUND ))
|
||||
return;
|
||||
|
||||
if( SV_IsValidEdict( groundentity ))
|
||||
{
|
||||
// On conveyor belt that's moving?
|
||||
if( groundentity->v.flags & FL_CONVEYOR )
|
||||
{
|
||||
vec3_t new_basevel;
|
||||
const edict_t *groundentity = ent->v.groundentity;
|
||||
|
||||
VectorScale( groundentity->v.movedir, groundentity->v.speed, new_basevel );
|
||||
if( ent->v.flags & FL_BASEVELOCITY )
|
||||
VectorAdd( new_basevel, ent->v.basevelocity, new_basevel );
|
||||
if( !SV_IsValidEdict( groundentity ) || !FBitSet( groundentity->v.flags, FL_CONVEYOR ))
|
||||
return;
|
||||
|
||||
ent->v.flags |= FL_BASEVELOCITY;
|
||||
VectorCopy( new_basevel, ent->v.basevelocity );
|
||||
}
|
||||
}
|
||||
}
|
||||
if( FBitSet( ent->v.flags, FL_BASEVELOCITY ))
|
||||
VectorMA( ent->v.basevelocity, groundentity->v.speed, groundentity->v.movedir, ent->v.basevelocity );
|
||||
else
|
||||
VectorScale( groundentity->v.movedir, groundentity->v.speed, ent->v.basevelocity );
|
||||
|
||||
ent->v.flags |= FL_BASEVELOCITY;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -189,18 +183,15 @@ returns true if the entity is in solid currently
|
||||
*/
|
||||
static qboolean SV_TestEntityPosition( edict_t *ent, edict_t *blocker )
|
||||
{
|
||||
qboolean monsterClip = FBitSet( ent->v.flags, FL_MONSTERCLIP ) ? true : false;
|
||||
trace_t trace;
|
||||
|
||||
if( FBitSet( ent->v.flags, FL_CLIENT|FL_FAKECLIENT ))
|
||||
{
|
||||
// to avoid falling through tracktrain update client mins\maxs here
|
||||
if( FBitSet( ent->v.flags, FL_DUCKING ))
|
||||
SV_SetMinMaxSize( ent, host.player_mins[1], host.player_maxs[1], true );
|
||||
else SV_SetMinMaxSize( ent, host.player_mins[0], host.player_maxs[0], true );
|
||||
int hull = FBitSet( ent->v.flags, FL_DUCKING ) ? 1 : 0;
|
||||
SV_SetMinMaxSize( ent, host.player_mins[hull], host.player_maxs[hull], true );
|
||||
}
|
||||
|
||||
trace = SV_Move( ent->v.origin, ent->v.mins, ent->v.maxs, ent->v.origin, MOVE_NORMAL, ent, monsterClip );
|
||||
qboolean monsterClip = FBitSet( ent->v.flags, FL_MONSTERCLIP ) ? true : false;
|
||||
trace_t trace = SV_Move( ent->v.origin, ent->v.mins, ent->v.maxs, ent->v.origin, MOVE_NORMAL, ent, monsterClip );
|
||||
|
||||
if( SV_IsValidEdict( blocker ) && SV_IsValidEdict( trace.ent ))
|
||||
{
|
||||
@@ -212,6 +203,25 @@ static qboolean SV_TestEntityPosition( edict_t *ent, edict_t *blocker )
|
||||
return trace.startsolid;
|
||||
}
|
||||
|
||||
static qboolean SV_TryThink( edict_t *ent, double frametime, double time )
|
||||
{
|
||||
float thinktime = ent->v.nextthink;
|
||||
if( thinktime <= 0.0f || thinktime > ( time + frametime ))
|
||||
return false;
|
||||
|
||||
// don't let things stay in the past.
|
||||
// it is possible to start that way
|
||||
// by a trigger with a local time.
|
||||
if( thinktime < time )
|
||||
thinktime = time;
|
||||
|
||||
ent->v.nextthink = 0.0f;
|
||||
svgame.globals->time = thinktime;
|
||||
svgame.dllFuncs.pfnThink( ent );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
SV_RunThink
|
||||
@@ -224,21 +234,10 @@ Returns false if the entity removed itself.
|
||||
*/
|
||||
static qboolean SV_RunThink( edict_t *ent )
|
||||
{
|
||||
float thinktime;
|
||||
|
||||
if( !FBitSet( ent->v.flags, FL_KILLME ))
|
||||
{
|
||||
thinktime = ent->v.nextthink;
|
||||
if( thinktime <= 0.0f || thinktime > (sv.time + sv.frametime))
|
||||
if( !SV_TryThink( ent, sv.frametime, sv.time ))
|
||||
return true;
|
||||
|
||||
if( thinktime < sv.time )
|
||||
thinktime = sv.time; // don't let things stay in the past.
|
||||
// it is possible to start that way
|
||||
// by a trigger with a local time.
|
||||
ent->v.nextthink = 0.0f;
|
||||
svgame.globals->time = thinktime;
|
||||
svgame.dllFuncs.pfnThink( ent );
|
||||
}
|
||||
|
||||
if( FBitSet( ent->v.flags, FL_KILLME ))
|
||||
@@ -259,25 +258,13 @@ Returns false if the entity removed itself.
|
||||
*/
|
||||
qboolean SV_PlayerRunThink( edict_t *ent, float frametime, double time )
|
||||
{
|
||||
float thinktime;
|
||||
|
||||
if( svgame.physFuncs.SV_PlayerThink )
|
||||
return svgame.physFuncs.SV_PlayerThink( ent, frametime, time );
|
||||
|
||||
if( !FBitSet( ent->v.flags, FL_KILLME|FL_DORMANT ))
|
||||
{
|
||||
thinktime = ent->v.nextthink;
|
||||
if( thinktime <= 0.0f || thinktime > (time + frametime))
|
||||
if( !SV_TryThink( ent, frametime, time ))
|
||||
return true;
|
||||
|
||||
if( thinktime < time )
|
||||
thinktime = time; // don't let things stay in the past.
|
||||
// it is possible to start that way
|
||||
// by a trigger with a local time.
|
||||
|
||||
ent->v.nextthink = 0.0f;
|
||||
svgame.globals->time = thinktime;
|
||||
svgame.dllFuncs.pfnThink( ent );
|
||||
}
|
||||
|
||||
if( FBitSet( ent->v.flags, FL_KILLME ))
|
||||
@@ -297,17 +284,11 @@ void SV_Impact( edict_t *e1, edict_t *e2, trace_t *trace )
|
||||
{
|
||||
svgame.globals->time = sv.time;
|
||||
|
||||
if(( e1->v.flags|e2->v.flags ) & FL_KILLME )
|
||||
if( FBitSet( e1->v.flags|e2->v.flags, FL_KILLME ))
|
||||
return;
|
||||
|
||||
if( e1->v.groupinfo && e2->v.groupinfo )
|
||||
{
|
||||
if( svs.groupop == GROUP_OP_AND && !FBitSet( e1->v.groupinfo, e2->v.groupinfo ))
|
||||
return;
|
||||
|
||||
if( svs.groupop == GROUP_OP_NAND && FBitSet( e1->v.groupinfo, e2->v.groupinfo ))
|
||||
return;
|
||||
}
|
||||
if( !SV_CheckGroupTrace( e1, e2 ))
|
||||
return;
|
||||
|
||||
if( e1->v.solid != SOLID_NOT )
|
||||
{
|
||||
|
||||
@@ -205,10 +205,7 @@ static void SV_AddLinksToPmove( areanode_t *node, const vec3_t pmove_mins, const
|
||||
|
||||
if( check->v.groupinfo != 0 )
|
||||
{
|
||||
if( svs.groupop == GROUP_OP_AND && !FBitSet( check->v.groupinfo, pl->v.groupinfo ))
|
||||
continue;
|
||||
|
||||
if( svs.groupop == GROUP_OP_NAND && FBitSet( check->v.groupinfo, pl->v.groupinfo ))
|
||||
if( !SV_CheckGroupOp( svs.groupop, check->v.groupinfo, pl->v.groupinfo ))
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -977,9 +974,9 @@ void SV_RunCmd( sv_client_t *cl, usercmd_t *ucmd, int random_seed )
|
||||
// touch other objects
|
||||
for( int i = 0; i < svgame.pmove->numtouch; i++ )
|
||||
{
|
||||
pmtrace_t *pmtrace = &svgame.pmove->touchindex[i];
|
||||
edict_t *touch = SV_EdictNum( svgame.pmove->physents[pmtrace->ent].info );
|
||||
trace_t trace;
|
||||
pmtrace_t *pmtrace = &svgame.pmove->touchindex[i];
|
||||
edict_t *touch = SV_EdictNum( svgame.pmove->physents[pmtrace->ent].info );
|
||||
trace_t trace;
|
||||
|
||||
VectorCopy( pmtrace->deltavelocity, clent->v.velocity );
|
||||
PM_ConvertTrace( &trace, pmtrace, touch );
|
||||
|
||||
@@ -522,14 +522,8 @@ static void SV_TouchLinks( edict_t *ent, areanode_t *node )
|
||||
if( touch == ent || touch->v.solid != SOLID_TRIGGER ) // disabled ?
|
||||
continue;
|
||||
|
||||
if( touch->v.groupinfo && ent->v.groupinfo )
|
||||
{
|
||||
if( svs.groupop == GROUP_OP_AND && !FBitSet( touch->v.groupinfo, ent->v.groupinfo ))
|
||||
continue;
|
||||
|
||||
if( svs.groupop == GROUP_OP_NAND && FBitSet( touch->v.groupinfo, ent->v.groupinfo ))
|
||||
continue;
|
||||
}
|
||||
if( !SV_CheckGroupTrace( touch, ent ))
|
||||
continue;
|
||||
|
||||
if( !BoundsIntersect( ent->v.absmin, ent->v.absmax, touch->v.absmin, touch->v.absmax ))
|
||||
continue;
|
||||
@@ -725,10 +719,7 @@ static void SV_WaterLinks( const vec3_t origin, int *pCont, areanode_t *node )
|
||||
|
||||
if( touch->v.groupinfo )
|
||||
{
|
||||
if( svs.groupop == GROUP_OP_AND && !FBitSet( touch->v.groupinfo, svs.groupmask ))
|
||||
continue;
|
||||
|
||||
if( svs.groupop == GROUP_OP_NAND && FBitSet( touch->v.groupinfo, svs.groupmask ))
|
||||
if( !SV_CheckGroupOp( svs.groupop, touch->v.groupinfo, svs.groupmask ))
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1101,14 +1092,8 @@ static qboolean SV_ClipToEntity( edict_t *touch, moveclip_t *clip )
|
||||
trace_t trace;
|
||||
model_t *mod;
|
||||
|
||||
if( touch->v.groupinfo && SV_IsValidEdict( clip->passedict ) && clip->passedict->v.groupinfo != 0 )
|
||||
{
|
||||
if( svs.groupop == GROUP_OP_AND && !FBitSet( touch->v.groupinfo, clip->passedict->v.groupinfo ))
|
||||
return true;
|
||||
|
||||
if( svs.groupop == GROUP_OP_NAND && FBitSet( touch->v.groupinfo, clip->passedict->v.groupinfo ))
|
||||
return true;
|
||||
}
|
||||
if( SV_IsValidEdict( clip->passedict ) && !SV_CheckGroupTrace( touch, clip->passedict ))
|
||||
return true;
|
||||
|
||||
if( touch == clip->passedict || touch->v.solid == SOLID_NOT )
|
||||
return true;
|
||||
|
||||
@@ -26,7 +26,12 @@ int main(int argc, char **argv)
|
||||
}
|
||||
'''
|
||||
|
||||
frameworks = ['Foundation', 'UIKit', 'QuartzCore', 'GameController', 'SystemConfiguration', 'CFNetwork', 'AVFoundation', 'CoreGraphics']
|
||||
def get_frameworks(env):
|
||||
if env.IOS:
|
||||
return ['Foundation', 'UIKit', 'QuartzCore', 'GameController', 'SystemConfiguration', 'CFNetwork', 'AVFoundation', 'CoreGraphics']
|
||||
if env.DEST_OS == 'darwin':
|
||||
return ['IOKit', 'CoreFoundation']
|
||||
return []
|
||||
|
||||
@TaskGen.extension('.m')
|
||||
def m_hook(self, node):
|
||||
@@ -124,9 +129,8 @@ def configure(conf):
|
||||
if not conf.env.DEST_OS in ['win32', 'android']:
|
||||
conf.check_pthreads(mode='c')
|
||||
|
||||
if conf.env.IOS:
|
||||
for i in frameworks :
|
||||
conf.check(features='c cprogram', framework=i, uselib_store=i, msg='Checking for %s framework' % i)
|
||||
for i in get_frameworks(conf.env):
|
||||
conf.check(features='c cprogram', framework=i, uselib_store=i, msg='Checking for %s framework' % i)
|
||||
|
||||
conf.define('ENGINE_DLL', 1)
|
||||
|
||||
@@ -179,6 +183,8 @@ def build(bld):
|
||||
source += bld.path.ant_glob('platform/ios/*.c')
|
||||
source += bld.path.ant_glob('platform/ios/*.m')
|
||||
includes += bld.path.ant_glob('platform/ios')
|
||||
elif bld.env.DEST_OS == 'darwin':
|
||||
source += bld.path.ant_glob('platform/apple/*.c')
|
||||
|
||||
# include sources for optional features
|
||||
if bld.get_define('XASH_CUSTOM_SWAP'):
|
||||
@@ -206,6 +212,7 @@ def build(bld):
|
||||
]
|
||||
else: # POSIX
|
||||
libs += ['M', 'RT', 'PTHREAD', 'ASOUND', 'HAIKU', 'MAGX', 'LOG', 'SOCKET']
|
||||
libs += get_frameworks(bld.env)
|
||||
if not bld.env.STATIC:
|
||||
libs += ['DL']
|
||||
|
||||
@@ -274,7 +281,6 @@ def build(bld):
|
||||
install_path = bld.env.LIBDIR
|
||||
|
||||
if bld.env.IOS:
|
||||
libs += frameworks
|
||||
defines += ['XASH_SDLMAIN=1']
|
||||
|
||||
if bld.env.DEST_OS in ['nswitch', 'psvita', 'emscripten']:
|
||||
|
||||
@@ -736,6 +736,7 @@ extern convar_t r_vbo_detail;
|
||||
extern convar_t r_vbo_overbrightmode;
|
||||
extern convar_t r_studio_sort_textures;
|
||||
extern convar_t r_studio_drawelements;
|
||||
extern convar_t r_studio_builtin_renderer;
|
||||
extern convar_t r_shadows;
|
||||
extern convar_t r_ripple;
|
||||
extern convar_t r_ripple_updatetime;
|
||||
|
||||
@@ -1149,6 +1149,7 @@ static void GL_InitCommands( void )
|
||||
gEngfuncs.Cvar_RegisterVariable( &r_traceglow );
|
||||
gEngfuncs.Cvar_RegisterVariable( &r_studio_sort_textures );
|
||||
gEngfuncs.Cvar_RegisterVariable( &r_studio_drawelements );
|
||||
gEngfuncs.Cvar_RegisterVariable( &r_studio_builtin_renderer );
|
||||
gEngfuncs.Cvar_RegisterVariable( &r_ripple );
|
||||
gEngfuncs.Cvar_RegisterVariable( &r_ripple_updatetime );
|
||||
gEngfuncs.Cvar_RegisterVariable( &r_ripple_spawntime );
|
||||
|
||||
@@ -122,6 +122,7 @@ typedef struct
|
||||
// studio-related cvars
|
||||
CVAR_DEFINE_AUTO( r_studio_sort_textures, "0", FCVAR_GLCONFIG, "change draw order for additive meshes" );
|
||||
CVAR_DEFINE_AUTO( r_studio_drawelements, "1", FCVAR_GLCONFIG, "use glDrawElements for studiomodels" );
|
||||
CVAR_DEFINE_AUTO( r_studio_builtin_renderer, "0", 0, "use built-in studio model renderer instead of the one provided by client library (debugging)" );
|
||||
static cvar_t *cl_righthand = NULL;
|
||||
|
||||
static r_studio_interface_t *pStudioDraw;
|
||||
@@ -1904,6 +1905,43 @@ static void R_StudioDrawArrays( uint startverts, uint startelems )
|
||||
pglDisableClientState( GL_COLOR_ARRAY );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_StudioSubmitMesh
|
||||
|
||||
===============
|
||||
*/
|
||||
static void R_StudioSubmitMesh( short *ptricmds, vec3_t *pstudionorms, float s, float t, float shellscale, int tesslevel )
|
||||
{
|
||||
if( tesslevel > 0 )
|
||||
{
|
||||
// R_StudioDrawTruformMesh( ptricmds, pstudionorms, s, t, shellscale, tesslevel );
|
||||
}
|
||||
else if( r_studio_drawelements.value )
|
||||
{
|
||||
uint startArrayVerts = g_studio.numverts;
|
||||
uint startArrayElems = g_studio.numelems;
|
||||
|
||||
if( FBitSet( g_nFaceFlags, STUDIO_NF_CHROME ))
|
||||
R_StudioBuildArrayChromeMesh( ptricmds, pstudionorms, s, t, shellscale );
|
||||
else if( FBitSet( g_nFaceFlags, STUDIO_NF_UV_COORDS ))
|
||||
R_StudioBuildArrayFloatMesh( ptricmds, pstudionorms );
|
||||
else
|
||||
R_StudioBuildArrayNormalMesh( ptricmds, pstudionorms, s, t );
|
||||
|
||||
R_StudioDrawArrays( startArrayVerts, startArrayElems );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( FBitSet( g_nFaceFlags, STUDIO_NF_CHROME ))
|
||||
R_StudioDrawChromeMesh( ptricmds, pstudionorms, s, t, shellscale );
|
||||
else if( FBitSet( g_nFaceFlags, STUDIO_NF_UV_COORDS ))
|
||||
R_StudioDrawFloatMesh( ptricmds, pstudionorms );
|
||||
else
|
||||
R_StudioDrawNormalMesh( ptricmds, pstudionorms, s, t );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_StudioDrawPoints
|
||||
@@ -2040,8 +2078,6 @@ static void R_StudioDrawPoints( void )
|
||||
for( int j = 0; j < m_pSubModel->nummesh; j++ )
|
||||
{
|
||||
float oldblend = tr.blend;
|
||||
uint startArrayVerts = g_studio.numverts;
|
||||
uint startArrayElems = g_studio.numelems;
|
||||
|
||||
pmesh = g_studio.meshes[j].mesh;
|
||||
short *ptricmds = (short *)((byte *)m_pStudioHeader + pmesh->triindex);
|
||||
@@ -2073,24 +2109,7 @@ static void R_StudioDrawPoints( void )
|
||||
|
||||
R_StudioSetupSkin( m_pStudioHeader, pskinref[pmesh->skinref] );
|
||||
|
||||
if( r_studio_drawelements.value )
|
||||
{
|
||||
if( FBitSet( g_nFaceFlags, STUDIO_NF_CHROME ))
|
||||
R_StudioBuildArrayChromeMesh( ptricmds, pstudionorms, s, t, shellscale );
|
||||
else if( FBitSet( g_nFaceFlags, STUDIO_NF_UV_COORDS ))
|
||||
R_StudioBuildArrayFloatMesh( ptricmds, pstudionorms );
|
||||
else R_StudioBuildArrayNormalMesh( ptricmds, pstudionorms, s, t );
|
||||
|
||||
R_StudioDrawArrays( startArrayVerts, startArrayElems );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( FBitSet( g_nFaceFlags, STUDIO_NF_CHROME ))
|
||||
R_StudioDrawChromeMesh( ptricmds, pstudionorms, s, t, shellscale );
|
||||
else if( FBitSet( g_nFaceFlags, STUDIO_NF_UV_COORDS ))
|
||||
R_StudioDrawFloatMesh( ptricmds, pstudionorms );
|
||||
else R_StudioDrawNormalMesh( ptricmds, pstudionorms, s, t );
|
||||
}
|
||||
R_StudioSubmitMesh( ptricmds, pstudionorms, s, t, shellscale, 0 );
|
||||
|
||||
if( FBitSet( g_nFaceFlags, STUDIO_NF_MASKED ))
|
||||
{
|
||||
@@ -3192,6 +3211,12 @@ static void R_StudioDrawModelInternal( cl_entity_t *e, int flags )
|
||||
R_StudioDrawPlayer( flags, &e->curstate );
|
||||
else R_StudioDrawModel( flags );
|
||||
}
|
||||
else if( unlikely( r_studio_builtin_renderer.value ))
|
||||
{
|
||||
if( e->player )
|
||||
R_StudioDrawPlayer( flags, R_StudioGetPlayerState( e->index - 1 ));
|
||||
else R_StudioDrawModel( flags );
|
||||
}
|
||||
else
|
||||
{
|
||||
// select the properly method
|
||||
|
||||
@@ -955,6 +955,7 @@ extern convar_t sw_texfilt;
|
||||
extern convar_t r_traceglow;
|
||||
extern convar_t sw_noalphabrushes;
|
||||
extern convar_t r_studio_sort_textures;
|
||||
extern convar_t r_studio_builtin_renderer;
|
||||
|
||||
extern struct qfrustum_s
|
||||
{
|
||||
|
||||
@@ -1341,6 +1341,7 @@ qboolean GAME_EXPORT R_Init( void )
|
||||
#endif
|
||||
gEngfuncs.Cvar_RegisterVariable( &r_novis );
|
||||
gEngfuncs.Cvar_RegisterVariable( &r_studio_sort_textures );
|
||||
gEngfuncs.Cvar_RegisterVariable( &r_studio_builtin_renderer );
|
||||
|
||||
r_temppool = Mem_AllocPool( "ref_soft zone" );
|
||||
|
||||
|
||||
@@ -105,6 +105,7 @@ typedef struct
|
||||
|
||||
// studio-related cvars
|
||||
CVAR_DEFINE_AUTO( r_studio_sort_textures, "0", FCVAR_GLCONFIG, "change draw order for additive meshes" );
|
||||
CVAR_DEFINE_AUTO( r_studio_builtin_renderer, "0", 0, "use built-in studio model renderer instead of the one provided by client library (debugging)" );
|
||||
static cvar_t *cl_righthand = NULL;
|
||||
|
||||
static r_studio_interface_t *pStudioDraw;
|
||||
@@ -2822,6 +2823,13 @@ static void R_StudioDrawModelInternal( cl_entity_t *e, int flags )
|
||||
else
|
||||
R_StudioDrawModel( flags );
|
||||
}
|
||||
else if( unlikely( r_studio_builtin_renderer.value ))
|
||||
{
|
||||
if( e->player )
|
||||
R_StudioDrawPlayer( flags, R_StudioGetPlayerState( e->index - 1 ));
|
||||
else
|
||||
R_StudioDrawModel( flags );
|
||||
}
|
||||
else
|
||||
{
|
||||
// select the properly method
|
||||
|
||||
97
scripts/waifulib/vgui.py
Normal file
97
scripts/waifulib/vgui.py
Normal file
@@ -0,0 +1,97 @@
|
||||
#! /usr/bin/env python
|
||||
# encoding: utf-8
|
||||
# mittorn, 2018
|
||||
|
||||
from waflib.Configure import conf
|
||||
from waflib import Logs
|
||||
import os
|
||||
|
||||
VGUI_SUPPORTED_OS = ['win32', 'darwin', 'linux']
|
||||
|
||||
VGUI_FRAGMENT = '''#include <VGUI.h>
|
||||
int main() { return 0; }'''
|
||||
|
||||
def options(opt):
|
||||
grp = opt.add_option_group('VGUI options')
|
||||
|
||||
vgui_dev_path = os.path.join(opt.path.path_from(opt.root), 'vgui-dev')
|
||||
|
||||
grp.add_option('--vgui', action = 'store', dest = 'VGUI_DEV', default=vgui_dev_path,
|
||||
help = 'path to vgui-dev repo [default: %(default)s]')
|
||||
|
||||
grp.add_option('--enable-unsupported-vgui', action = 'store_true', dest = 'ENABLE_UNSUPPORTED_VGUI', default=False,
|
||||
help = 'ignore all checks and allow link against anything [default: %(default)s]')
|
||||
|
||||
grp.add_option('--skip-vgui-sanity-check', action = 'store_false', dest = 'VGUI_SANITY_CHECK', default=True,
|
||||
help = 'skip checking VGUI sanity [default: %(default)s]' )
|
||||
return
|
||||
|
||||
@conf
|
||||
def check_vgui(conf):
|
||||
if not conf.options.ENABLE_UNSUPPORTED_VGUI:
|
||||
conf.start_msg('Does this architecture support VGUI?')
|
||||
|
||||
if conf.env.DEST_CPU != 'x86':
|
||||
conf.end_msg('no')
|
||||
Logs.warn('vgui is not supported on this CPU: ' + str(conf.env.DEST_CPU))
|
||||
return False
|
||||
else: conf.end_msg('yes')
|
||||
|
||||
conf.start_msg('Does this OS support VGUI?')
|
||||
if conf.env.DEST_OS not in VGUI_SUPPORTED_OS:
|
||||
conf.end_msg('no')
|
||||
Logs.warn('vgui is not supported on this OS: ' + str(conf.env.DEST_OS))
|
||||
return False
|
||||
else: conf.end_msg('yes')
|
||||
|
||||
conf.start_msg('Does this toolchain able to link VGUI?')
|
||||
if conf.env.DEST_OS == 'win32' and conf.env.COMPILER_CXX != 'msvc':
|
||||
conf.end_msg('no')
|
||||
# we have ABI incompatibility ONLY on MinGW
|
||||
Logs.warn('vgui can\'t be linked with MinGW')
|
||||
return False
|
||||
else: conf.end_msg('yes')
|
||||
|
||||
conf.start_msg('Configuring VGUI by provided path')
|
||||
vgui_dev = conf.options.VGUI_DEV
|
||||
|
||||
libpath = os.path.abspath(os.path.join(vgui_dev, 'lib'))
|
||||
|
||||
if conf.env.DEST_OS == 'win32':
|
||||
conf.env.LIB_VGUI = ['vgui']
|
||||
libpath = os.path.join(libpath, 'win32_vc6')
|
||||
if conf.env.DEST_CPU != 'x86':
|
||||
# for 32-bit x86 it's expected to be under win32_vc6
|
||||
# for others, it's expected to be under win32_vc6 subdirectory matching CPU arch (x86_64 for 64-bit CPUs)
|
||||
libpath = os.path.join(libpath, conf.env.DEST_CPU)
|
||||
conf.env.LIBPATH_VGUI = [libpath]
|
||||
elif conf.env.DEST_OS == 'linux':
|
||||
conf.env.LIB_VGUI = [':vgui.so']
|
||||
if conf.env.DEST_CPU != 'x86':
|
||||
libpath = os.path.join(libpath, conf.env.DEST_CPU)
|
||||
conf.env.LIBPATH_VGUI = [libpath]
|
||||
elif conf.env.DEST_OS == 'darwin':
|
||||
if conf.env.DEST_CPU != 'x86':
|
||||
conf.env.LDFLAGS_VGUI = [os.path.join(libpath, conf.env.DEST_CPU, 'vgui.dylib')]
|
||||
else:
|
||||
conf.env.LDFLAGS_VGUI = [os.path.join(libpath, 'vgui.dylib')]
|
||||
else:
|
||||
# TODO: figure out what to do here
|
||||
conf.env.LIB_VGUI = ['vgui']
|
||||
conf.env.LIBPATH_VGUI = [os.path.join(libpath, conf.env.DEST_OS, conf.env.DEST_CPU)]
|
||||
|
||||
conf.env.INCLUDES_VGUI = [os.path.abspath(os.path.join(vgui_dev, 'include'))]
|
||||
|
||||
conf.env.HAVE_VGUI = 1
|
||||
conf.end_msg('yes: {0}, {1}, {2}'.format(conf.env.LIB_VGUI, conf.env.LIBPATH_VGUI, conf.env.INCLUDES_VGUI))
|
||||
|
||||
if conf.env.HAVE_VGUI and conf.options.VGUI_SANITY_CHECK:
|
||||
try:
|
||||
conf.check_cxx(fragment=VGUI_FRAGMENT,
|
||||
msg = 'Checking for library VGUI sanity',
|
||||
use = 'VGUI',
|
||||
execute = False)
|
||||
except conf.errors.ConfigurationError:
|
||||
conf.fatal("Can't compile simple program. Check your path to vgui-dev repository.")
|
||||
|
||||
return True
|
||||
3
wscript
3
wscript
@@ -127,7 +127,6 @@ SUBDIRS = [
|
||||
Subproject('3rdparty/opusfile', lambda x: x.env.CLIENT and not x.env.HAVE_SYSTEM_OPUSFILE),
|
||||
Subproject('3rdparty/maintui', lambda x: x.env.CLIENT and x.env.TUI),
|
||||
Subproject('3rdparty/mainui', lambda x: x.env.CLIENT and x.env.DEST_OS != 'android'),
|
||||
Subproject('3rdparty/freevgui', lambda x: x.env.CLIENT),
|
||||
Subproject('3rdparty/vgui_support', lambda x: x.env.CLIENT),
|
||||
Subproject('3rdparty/MultiEmulator',lambda x: x.env.CLIENT),
|
||||
# Subproject('3rdparty/freevgui', lambda x: x.env.CLIENT),
|
||||
@@ -366,6 +365,7 @@ def configure(conf):
|
||||
'-Werror=duplicated-cond',
|
||||
'-Werror=format=2',
|
||||
'-Werror=free-nonheap-object',
|
||||
'-Werror=init-self',
|
||||
'-Werror=implicit-fallthrough=2',
|
||||
'-Werror=logical-op',
|
||||
'-Werror=nonnull',
|
||||
@@ -386,7 +386,6 @@ def configure(conf):
|
||||
|
||||
# unstable diagnostics, may cause false positives
|
||||
'-Walloc-zero',
|
||||
'-Winit-self',
|
||||
'-Wmisleading-indentation',
|
||||
'-Wmismatched-dealloc',
|
||||
'-Wstringop-overflow',
|
||||
|
||||
Reference in New Issue
Block a user