Merge origin/master into ref_dll

This commit is contained in:
Alibek Omarov 2019-03-20 02:38:13 +03:00
commit 121c72c9e0
15 changed files with 666 additions and 96 deletions

58
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,58 @@
## 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.
4. Describe which OS and architecture you are using.
6. Attach screenshot if it will help clarify the situation.
## If you are contributing code
### Which branch?
* We recommend using `master` branch.
### Third-party libraries
* Philosophy of any Xash Project by Uncle Mike: don't be bloated. We follow it too.
* There is allowed only these libraries, if there is a REAL reason to use library and library is crossplatform. 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.
### 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 at least compile everywhere.
| OS | Macro |
| -- | ----- |
| Linux | `defined(__linux__)` |
| FreeBSD | `defined(__FreeBSD__)` |
| NetBSD | `defined(__NetBSD__)` |
| OpenBSD | `defined(__OpenBSD__)` |
| OS X/iOS | `defined(__APPLE__)` and TargetConditionals macros |
| Windows | `defined(_WIN32)` |
| Android | `defined(__ANDROID__)` |
| Emscripten | `defined(__EMSCRIPTEN__)` |
### Code style
* This project uses mixed Quake's and HLSDK's C/C++ code style convention.
* In short:
* Use spaces in parenthesis.
* Only tabs for indentation.
* Any brace must have it's own line.
* Short blocks, if statements and loops on single line are allowed.
* 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:
`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.

79
README.md Normal file
View File

@ -0,0 +1,79 @@
# Xash3D FWGS Engine
[![Build Status](https://api.travis-ci.org/FWGS/xash3d-fwgs.svg?branch=master)](https://travis-ci.org/FWGS/xash3d-fwgs) [![Discord Server](https://img.shields.io/discord/355697768582610945.svg)](https://discord.gg/TbnHcVb)
Xash3D FWGS is a fork of Xash3D Engine by Unkle Mike with extended features and crossplatform.
```
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
```
Latest release build: https://github.com/FWGS/xash3d-fwgs/releases/latest
Latest development build: https://github.com/FWGS/xash3d-deploy/tree/newengine-latest
## Fork features
* HLSDK 2.4 support.
* Crossplatform: officially supported x86 and ARM on Windows/Linux/BSD/macOS/Android/iOS/Haiku.
* 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.
* TrueType font rendering, as a part of mainui_cpp.
* A set of small improvements, without broken compatibility.
## Planned fork features
* Virtual Reality support and game API(in development!)
* Voice support
* Multiple renderers support(OpenGL, GLES, Vulkan, software)
## Contributing
* Before sending an issue, check if someone already reported your issue. Make sure you're following "How To Ask Questions The Smart Way" guide by Eric Steven Raymond. Read more: http://www.catb.org/~esr/faqs/smart-questions.html
* Before sending a PR, check if you followed our coding guide in CODING_STYLE.md file.
## Build instructions
We are using Waf build system. If you have some Waf-related questions, I recommend you to read https://waf.io/book/
If you're stuck somewhere and you need a clear example, read `.travis.yml` and `scripts/build*.sh`.
### Prerequisites
#### Windows(Visual Studio)
* Install Visual Studio.
* Install latest [Python](https://python.org) **OR** run `cinst python.install` if you have Chocolatey.
* Install latest [Git](https://git-scm.com/download/win) **OR** run `cinst git.install` if you have Chocolatey.
* Download [SDL2](https://libsdl.org/download-2.0.php) development package for Visual Studio.
* Clone this repository: `git clone --recursive https://github.com/FWGS/xash3d-fwgs`.
* Clone `vgui-dev` repository: `git clone https://github.com/FWGS/vgui-dev`.
* Make sure you have at least 12GB of free space to store all build-time dependencies: ~10GB for Visual Studio, 300 MB for Git, 100 MB for Python and other.
#### Linux
NOTE: Make sure you're OK with targetting 32-bit.
Even if Xash3D FWGS does support targetting 64-bit, you can't load games without recompiling them from source code!
* **Gentoo**: TODO
* **Debian**: TODO
* **ArchLinux**: `<AUR Helper> -S xash3d-git`
### Building
#### Windows(Visual Studio)
0) Open command line
1) Navigate to `xash3d-fwgs` directory.
2) Carefully examine which build options are available: `waf --help`
3) Configure build: `waf configure --build-type=release --sdl2=c:/path/to/SDL2 --vgui=c:/path/to/vgui-dev --prefix=c:/path/to/any/output/directory`
4) Compile: `waf build`
5) Install: `waf install`
#### Linux
0) Examine which build options are available: `./waf --help`
1) Configure build: `./waf configure --build-type=release --vgui=vgui-dev`
2) Compile: `./waf build`
3) Install(optional): `./waf install`
## Running
0) Copy libraries and main executable somewhere, if you're skipped installation stage.
1) Copy game files to same directory
2) Run `xash3d.exe`/`xash3d.sh`/`xash3d` depending on which platform you're using.
For additional info, run Xash3D with `-help` command line key.

95
common/mathlib.h Normal file
View File

@ -0,0 +1,95 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* Use, distribution, and modification of this source code and/or resulting
* object code is restricted to non-commercial enhancements to products from
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
// mathlib.h
#include <math.h>
typedef float vec_t;
typedef vec_t vec2_t[2];
typedef vec_t vec3_t[3];
typedef vec_t vec4_t[4]; // x,y,z,w
#ifndef M_PI
#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h
#endif
struct mplane_s;
extern vec3_t vec3_origin;
extern int nanmask;
#define IS_NAN(x) (((*(int *)&x)&nanmask)==nanmask)
#ifndef VECTOR_H
#define DotProduct(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2])
#endif
#define VectorSubtract(a,b,c) {(c)[0]=(a)[0]-(b)[0];(c)[1]=(a)[1]-(b)[1];(c)[2]=(a)[2]-(b)[2];}
#define VectorAdd(a,b,c) {(c)[0]=(a)[0]+(b)[0];(c)[1]=(a)[1]+(b)[1];(c)[2]=(a)[2]+(b)[2];}
#define VectorCopy(a,b) {(b)[0]=(a)[0];(b)[1]=(a)[1];(b)[2]=(a)[2];}
#define VectorClear(a) {(a)[0]=0.0;(a)[1]=0.0;(a)[2]=0.0;}
void VectorMA (const vec3_t veca, float scale, const vec3_t vecb, vec3_t vecc);
vec_t _DotProduct (vec3_t v1, vec3_t v2);
void _VectorSubtract (vec3_t veca, vec3_t vecb, vec3_t out);
void _VectorAdd (vec3_t veca, vec3_t vecb, vec3_t out);
void _VectorCopy (vec3_t in, vec3_t out);
int VectorCompare (const vec3_t v1, const vec3_t v2);
float Length (const vec3_t v);
void CrossProduct (const vec3_t v1, const vec3_t v2, vec3_t cross);
float VectorNormalize (vec3_t v); // returns vector length
void VectorInverse (vec3_t v);
void VectorScale (const vec3_t in, vec_t scale, vec3_t out);
void R_ConcatRotations (float in1[3][3], float in2[3][3], float out[3][3]);
void R_ConcatTransforms (float in1[3][4], float in2[3][4], float out[3][4]);
void AngleVectors (const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up);
void AngleVectorsTranspose (const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up);
#define AngleIVectors AngleVectorsTranspose
void AngleMatrix (const vec3_t angles, float (*matrix)[4] );
void AngleIMatrix (const vec3_t angles, float (*matrix)[4] );
void VectorTransform (const vec3_t in1, float in2[3][4], vec3_t out);
void NormalizeAngles( vec3_t angles );
void InterpolateAngles( vec3_t start, vec3_t end, vec3_t output, float frac );
float AngleBetweenVectors( const vec3_t v1, const vec3_t v2 );
void VectorMatrix( vec3_t forward, vec3_t right, vec3_t up);
void VectorAngles( const vec3_t forward, vec3_t angles );
int InvertMatrix( const float * m, float *out );
int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct mplane_s *plane);
float anglemod(float a);
#define BOX_ON_PLANE_SIDE(emins, emaxs, p) \
(((p)->type < 3)? \
( \
((p)->dist <= (emins)[(p)->type])? \
1 \
: \
( \
((p)->dist >= (emaxs)[(p)->type])?\
2 \
: \
3 \
) \
) \
: \
BoxOnPlaneSide( (emins), (emaxs), (p)))

View File

@ -797,7 +797,7 @@ void CL_WritePacket( void )
newcmds = ( cls.netchan.outgoing_sequence - cls.lastoutgoingcommand );
// put an upper/lower bound on this
newcmds = bound( 0, newcmds, MAX_TOTAL_CMDS );
newcmds = bound( 0, newcmds, cls.legacymode?MAX_LEGACY_TOTAL_CMDS:MAX_TOTAL_CMDS );
if( cls.state == ca_connected ) newcmds = 0;
MSG_WriteByte( &buf, newcmds );

View File

@ -260,5 +260,6 @@ extern const char *clc_strings[clc_lastmsg+1];
#define MAX_LEGACY_WEAPON_BITS 5
#define MAX_LEGACY_MODEL_BITS 11
#define MAX_LEGACY_SERVERS 32
#define MAX_LEGACY_TOTAL_CMDS 28 // magic number from old engine's sv_client.c
#endif//NET_PROTOCOL_H

View File

@ -9,17 +9,16 @@ from fwgslib import get_subproject_name
top = '.'
def options(opt):
opt.load('sdl2')
opt.add_option(
'--enable-bsp2', action = 'store_true', dest = 'SUPPORT_BSP2_FORMAT', default = False,
help = 'build engine with BSP2 map support(recommended for Quake, breaks compability!)')
opt.add_option(
'--single-binary', action = 'store_true', dest = 'SINGLE_BINARY', default = None,
help = 'build single "xash" binary instead of xash.dll/libxash.so (default for dedicated)')
opt.add_option(
grp = opt.add_option_group('Engine options')
grp.add_option(
'--enable-bsp2', action = 'store_true', dest = 'SUPPORT_BSP2_FORMAT', default = False,
help = 'build engine with BSP2 map support(recommended for Quake, breaks compatibility!)')
grp.add_option(
'--stdin-input', action = 'store_true', dest = 'USE_SELECT', default = None,
help = 'enable console input from stdin (default for dedicated)')
opt.load('sdl2')
def configure(conf):
# check for dedicated server build
@ -35,10 +34,7 @@ def configure(conf):
conf.fatal('SDL2 not availiable! If you want to build dedicated server, specify --dedicated')
conf.env.append_unique('DEFINES', 'XASH_SDL')
if conf.options.SINGLE_BINARY == None:
conf.options.SINGLE_BINARY = conf.options.DEDICATED # We don't need game launcher on dedicated
conf.env.SINGLE_BINARY = conf.options.SINGLE_BINARY
if conf.options.SINGLE_BINARY:
if conf.env.SINGLE_BINARY:
conf.env.append_unique('DEFINES', 'SINGLE_BINARY')
if conf.options.USE_SELECT == None:

View File

@ -10,22 +10,13 @@ from fwgslib import get_subproject_name
top = '.'
def options(opt):
# stub
return
def configure(conf):
if conf.env.SINGLE_BINARY:
return
# check for dedicated server build
if not conf.env.DEDICATED:
if conf.env.DEST_OS == 'win32':
conf.load('winres')
if conf.env.DEST_OS == 'win32':
conf.load('winres')
def build(bld):
if bld.env.SINGLE_BINARY:
return
bld.load_envs()
bld.env = bld.all_envs[get_subproject_name(bld)]

2
mainui

@ -1 +1 @@
Subproject commit 33e6e585e875d91ae44b22d5425f1c38f2413741
Subproject commit 9acf8b75d9d167ac63efd6db8f35c42a2d325082

View File

@ -885,7 +885,7 @@ _inline qboolean R_HasLightmap( void )
if( RI.currententity )
{
if( RI.currententity->curstate.effects & EF_FULLBRIGHT )
return; // disabled by user
return false; // disabled by user
// check for rendermode
switch( RI.currententity->curstate.rendermode )
@ -1586,7 +1586,13 @@ void R_DrawBrushModel( cl_entity_t *e )
GL_SetupFogColorForSurfaces ();
if( e->curstate.rendermode == kRenderTransAdd )
{
R_AllowFog( false );
allow_vbo = false;
}
if( e->curstate.rendermode == kRenderTransColor || e->curstate.rendermode == kRenderTransTexture )
allow_vbo = false;
psurf = &clmodel->surfaces[clmodel->firstmodelsurface];
num_sorted = 0;
@ -1961,7 +1967,7 @@ void R_GenerateVBO()
// prepare decal array
pglGenBuffersARB( 1, &vbos.decaldata->decalvbo );
pglBindBufferARB( GL_ARRAY_BUFFER_ARB, vbos.decaldata->decalvbo );
pglBufferDataARB( GL_ARRAY_BUFFER_ARB, sizeof( vbovertex_t ) * DECAL_VERTS_CUT * MAX_RENDER_DECALS, vbos.decaldata->decalarray, GL_STATIC_DRAW_ARB );
pglBufferDataARB( GL_ARRAY_BUFFER_ARB, sizeof( vbovertex_t ) * DECAL_VERTS_CUT * MAX_RENDER_DECALS, vbos.decaldata->decalarray, GL_DYNAMIC_DRAW_ARB );
// preallocate dlight arrays
vbos.dlight_index = Mem_Calloc( vbos.mempool, maxindex * sizeof( unsigned short ) * 6 );
@ -1973,10 +1979,10 @@ void R_GenerateVBO()
{
pglGenBuffersARB( 1, &vbos.dlight_vbo );
pglBindBufferARB( GL_ARRAY_BUFFER_ARB, vbos.dlight_vbo );
pglBufferDataARB( GL_ARRAY_BUFFER_ARB, sizeof( vec2_t ) * (int)(vbos.arraylist->next?USHRT_MAX + 1:vbos.arraylist->array_len + 1) , vbos.dlight_tc, GL_DYNAMIC_DRAW_ARB );
pglBufferDataARB( GL_ARRAY_BUFFER_ARB, sizeof( vec2_t ) * (int)(vbos.arraylist->next?USHRT_MAX + 1:vbos.arraylist->array_len + 1) , vbos.dlight_tc, GL_STREAM_DRAW_ARB );
pglGenBuffersARB( 1, &vbos.decal_dlight_vbo );
pglBindBufferARB( GL_ARRAY_BUFFER_ARB, vbos.decal_dlight_vbo );
pglBufferDataARB( GL_ARRAY_BUFFER_ARB, sizeof( vbos.decal_dlight ), vbos.decal_dlight, GL_DYNAMIC_DRAW_ARB );
pglBufferDataARB( GL_ARRAY_BUFFER_ARB, sizeof( vbos.decal_dlight ), vbos.decal_dlight, GL_STREAM_DRAW_ARB );
}

View File

@ -113,13 +113,22 @@ typedef struct
// playermodels
player_model_t player_models[MAX_CLIENTS];
// drawelements renderer
vec3_t arrayverts[MAXSTUDIOVERTS];
vec2_t arraycoord[MAXSTUDIOVERTS];
unsigned short arrayelems[MAXSTUDIOVERTS*6];
GLubyte arraycolor[MAXSTUDIOVERTS][4];
uint numverts;
uint numelems;
} studio_draw_state_t;
// studio-related cvars
cvar_t *r_studio_sort_textures;
cvar_t *r_drawviewmodel;
static cvar_t *r_studio_sort_textures;
static cvar_t *r_drawviewmodel;
cvar_t *cl_righthand = NULL;
cvar_t *cl_himodels;
static cvar_t *cl_himodels;
static cvar_t *r_studio_drawelements;
static r_studio_interface_t *pStudioDraw;
static studio_draw_state_t g_studio; // global studio state
@ -146,6 +155,7 @@ void R_StudioInit( void )
cl_himodels = gEngfuncs.Cvar_Get( "cl_himodels", "1", FCVAR_ARCHIVE, "draw high-resolution player models in multiplayer" );
r_studio_sort_textures = gEngfuncs.Cvar_Get( "r_studio_sort_textures", "0", FCVAR_ARCHIVE, "change draw order for additive meshes" );
r_drawviewmodel = gEngfuncs.Cvar_Get( "r_drawviewmodel", "1", 0, "draw firstperson weapon model" );
r_studio_drawelements = gEngfuncs.Cvar_Get( "r_studio_drawelements", "1", FCVAR_ARCHIVE, "use glDrawElements for studiomodels" );
Matrix3x4_LoadIdentity( g_studio.rotationmatrix );
r_glowshellfreq = gEngfuncs.Cvar_Get( "r_glowshellfreq", "2.2", 0, "glowing shell frequency update" );
@ -1706,7 +1716,7 @@ R_LightLambert
====================
*/
void R_LightLambert( vec4_t light[MAX_LOCALLIGHTS], vec3_t normal, vec3_t color )
void R_LightLambert( vec4_t light[MAX_LOCALLIGHTS], vec3_t normal, vec3_t color, byte *out )
{
vec3_t finalLight;
vec3_t localLight;
@ -1744,7 +1754,53 @@ void R_LightLambert( vec4_t light[MAX_LOCALLIGHTS], vec3_t normal, vec3_t color
}
}
pglColor4f( finalLight[0], finalLight[1], finalLight[2], tr.blend );
out[0] = finalLight[0] * 255;
out[1] = finalLight[1] * 255;
out[2] = finalLight[2] * 255;
}
static void R_StudioSetColorBegin(short *ptricmds, vec3_t *pstudionorms )
{
float *lv = (float *)g_studio.lightvalues[ptricmds[1]];
rgba_t color;
if( g_studio.numlocallights )
{
color[3] = tr.blend * 255;
R_LightLambert( g_studio.lightpos[ptricmds[0]], pstudionorms[ptricmds[1]], lv, color );
pglColor4ubv( color );
}
else
{
if( RI.currententity->curstate.rendermode == kRenderTransColor )
{
color[3] = tr.blend * 255;
VectorCopy( (byte*)&RI.currententity->curstate.rendercolor, color );
pglColor4ubv( color );
}
else pglColor4f( lv[0], lv[1], lv[2], tr.blend );
}
}
static void R_StudioSetColorArray(short *ptricmds, vec3_t *pstudionorms, byte *color )
{
float *lv = (float *)g_studio.lightvalues[ptricmds[1]];
color[3] = tr.blend * 255;
if( g_studio.numlocallights )
R_LightLambert( g_studio.lightpos[ptricmds[0]], pstudionorms[ptricmds[1]], lv, color );
else
{
if( RI.currententity->curstate.rendermode == kRenderTransColor )
VectorCopy( (byte*)&RI.currententity->curstate.rendercolor, color );
else
{
color[0] = lv[0] * 255;
color[1] = lv[1] * 255;
color[2] = lv[2] * 255;
}
}
}
/*
@ -1917,11 +1973,8 @@ _inline void R_StudioDrawNormalMesh( short *ptricmds, vec3_t *pstudionorms, floa
for( ; i > 0; i--, ptricmds += 4 )
{
lv = (float *)g_studio.lightvalues[ptricmds[1]];
R_StudioSetColorBegin( ptricmds, pstudionorms );
if( g_studio.numlocallights )
R_LightLambert( g_studio.lightpos[ptricmds[0]], pstudionorms[ptricmds[1]], lv );
else pglColor4f( lv[0], lv[1], lv[2], tr.blend );
pglTexCoord2f( ptricmds[2] * s, ptricmds[3] * t );
pglVertex3fv( g_studio.verts[ptricmds[0]] );
}
@ -1953,10 +2006,7 @@ _inline void R_StudioDrawFloatMesh( short *ptricmds, vec3_t *pstudionorms )
for( ; i > 0; i--, ptricmds += 4 )
{
lv = (float *)g_studio.lightvalues[ptricmds[1]];
if( g_studio.numlocallights )
R_LightLambert( g_studio.lightpos[ptricmds[0]], pstudionorms[ptricmds[1]], lv );
else pglColor4f( lv[0], lv[1], lv[2], tr.blend );
R_StudioSetColorBegin( ptricmds, pstudionorms );
pglTexCoord2f( HalfToFloat( ptricmds[2] ), HalfToFloat( ptricmds[3] ));
pglVertex3fv( g_studio.verts[ptricmds[0]] );
}
@ -1992,10 +2042,13 @@ _inline void R_StudioDrawChromeMesh( short *ptricmds, vec3_t *pstudionorms, floa
{
if( glowShell )
{
color24 *clr = &RI.currententity->curstate.rendercolor;
idx = g_studio.normaltable[ptricmds[0]];
av = g_studio.verts[ptricmds[0]];
lv = g_studio.norms[ptricmds[0]];
VectorMA( av, scale, lv, vert );
pglColor4ub( clr->r, clr->g, clr->b, 255 );
pglTexCoord2f( g_studio.chrome[idx][0] * s, g_studio.chrome[idx][1] * t );
pglVertex3fv( vert );
}
@ -2003,9 +2056,7 @@ _inline void R_StudioDrawChromeMesh( short *ptricmds, vec3_t *pstudionorms, floa
{
idx = ptricmds[1];
lv = (float *)g_studio.lightvalues[ptricmds[1]];
if( g_studio.numlocallights )
R_LightLambert( g_studio.lightpos[ptricmds[0]], pstudionorms[ptricmds[1]], lv );
else pglColor4f( lv[0], lv[1], lv[2], tr.blend );
R_StudioSetColorBegin( ptricmds, pstudionorms );
pglTexCoord2f( g_studio.chrome[idx][0] * s, g_studio.chrome[idx][1] * t );
pglVertex3fv( g_studio.verts[ptricmds[0]] );
}
@ -2015,6 +2066,220 @@ _inline void R_StudioDrawChromeMesh( short *ptricmds, vec3_t *pstudionorms, floa
}
}
_inline int R_StudioBuildIndices( qboolean tri_strip, int vertexState )
{
// build in indices
if( vertexState++ < 3 )
{
g_studio.arrayelems[g_studio.numelems++] = g_studio.numverts;
}
else if( tri_strip )
{
// flip triangles between clockwise and counter clockwise
if( vertexState & 1 )
{
// draw triangle [n-2 n-1 n]
g_studio.arrayelems[g_studio.numelems++] = g_studio.numverts - 2;
g_studio.arrayelems[g_studio.numelems++] = g_studio.numverts - 1;
g_studio.arrayelems[g_studio.numelems++] = g_studio.numverts;
}
else
{
// draw triangle [n-1 n-2 n]
g_studio.arrayelems[g_studio.numelems++] = g_studio.numverts - 1;
g_studio.arrayelems[g_studio.numelems++] = g_studio.numverts - 2;
g_studio.arrayelems[g_studio.numelems++] = g_studio.numverts;
}
}
else
{
// draw triangle fan [0 n-1 n]
g_studio.arrayelems[g_studio.numelems++] = g_studio.numverts - ( vertexState - 1 );
g_studio.arrayelems[g_studio.numelems++] = g_studio.numverts - 1;
g_studio.arrayelems[g_studio.numelems++] = g_studio.numverts;
}
return vertexState;
}
/*
===============
R_StudioDrawNormalMesh
generic path
===============
*/
_inline void R_StudioBuildArrayNormalMesh( short *ptricmds, vec3_t *pstudionorms, float s, float t )
{
float *lv;
int i;
float alpha = tr.blend;
while( i = *( ptricmds++ ))
{
int vertexState = 0;
qboolean tri_strip = true;
if( i < 0 )
{
tri_strip = false;
i = -i;
}
for( ; i > 0; i--, ptricmds += 4 )
{
GLubyte *cl;
cl = g_studio.arraycolor[g_studio.numverts];
lv = (float *)g_studio.lightvalues[ptricmds[1]];
vertexState = R_StudioBuildIndices( tri_strip, vertexState );
R_StudioSetColorArray( ptricmds, pstudionorms, cl );
g_studio.arraycoord[g_studio.numverts][0] = ptricmds[2] * s;
g_studio.arraycoord[g_studio.numverts][1] = ptricmds[3] * t;
VectorCopy( g_studio.verts[ptricmds[0]], g_studio.arrayverts[g_studio.numverts] );
g_studio.numverts++;
}
}
}
/*
===============
R_StudioDrawNormalMesh
generic path
===============
*/
_inline void R_StudioBuildArrayFloatMesh( short *ptricmds, vec3_t *pstudionorms )
{
float *lv;
int i;
float alpha = tr.blend;
while( i = *( ptricmds++ ))
{
int vertexState = 0;
qboolean tri_strip = true;
if( i < 0 )
{
tri_strip = false;
i = -i;
}
for( ; i > 0; i--, ptricmds += 4 )
{
GLubyte *cl;
cl = g_studio.arraycolor[g_studio.numverts];
lv = (float *)g_studio.lightvalues[ptricmds[1]];
vertexState = R_StudioBuildIndices( tri_strip, vertexState );
R_StudioSetColorArray( ptricmds, pstudionorms, cl );
g_studio.arraycoord[g_studio.numverts][0] = HalfToFloat( ptricmds[2] );
g_studio.arraycoord[g_studio.numverts][1] = HalfToFloat( ptricmds[3] );
VectorCopy( g_studio.verts[ptricmds[0]], g_studio.arrayverts[g_studio.numverts] );
g_studio.numverts++;
}
}
}
/*
===============
R_StudioDrawNormalMesh
generic path
===============
*/
_inline void R_StudioBuildArrayChromeMesh( short *ptricmds, vec3_t *pstudionorms, float s, float t, float scale )
{
float *lv, *av;
int i, idx;
qboolean glowShell = (scale > 0.0f) ? true : false;
vec3_t vert;
float alpha = tr.blend;
while( i = *( ptricmds++ ))
{
int vertexState = 0;
qboolean tri_strip = true;
if( i < 0 )
{
tri_strip = false;
i = -i;
}
for( ; i > 0; i--, ptricmds += 4 )
{
GLubyte *cl;
cl = g_studio.arraycolor[g_studio.numverts];
lv = (float *)g_studio.lightvalues[ptricmds[1]];
vertexState = R_StudioBuildIndices( tri_strip, vertexState );
if( glowShell )
{
idx = g_studio.normaltable[ptricmds[0]];
av = g_studio.verts[ptricmds[0]];
lv = g_studio.norms[ptricmds[0]];
cl[0] = RI.currententity->curstate.rendercolor.r;
cl[1] = RI.currententity->curstate.rendercolor.g;
cl[2] = RI.currententity->curstate.rendercolor.b;
cl[3] = 255;
VectorMA( av, scale, lv, vert );
VectorCopy( vert, g_studio.arrayverts[g_studio.numverts] );
}
else
{
idx = ptricmds[1];
R_StudioSetColorArray( ptricmds, pstudionorms, cl );
VectorCopy( g_studio.verts[ptricmds[0]], g_studio.arrayverts[g_studio.numverts] );
}
g_studio.arraycoord[g_studio.numverts][0] = g_studio.chrome[idx][0] * s;
g_studio.arraycoord[g_studio.numverts][1] = g_studio.chrome[idx][1] * t;
g_studio.numverts++;
}
}
}
_inline void R_StudioDrawArrays( uint startverts, uint startelems )
{
pglEnableClientState( GL_VERTEX_ARRAY );
pglVertexPointer( 3, GL_FLOAT, 12, g_studio.arrayverts );
pglEnableClientState( GL_TEXTURE_COORD_ARRAY );
pglTexCoordPointer( 2, GL_FLOAT, 0, g_studio.arraycoord );
if( !( g_nForceFaceFlags & STUDIO_NF_CHROME ) )
{
pglEnableClientState( GL_COLOR_ARRAY );
pglColorPointer( 4, GL_UNSIGNED_BYTE, 0, g_studio.arraycolor );
}
#if !defined XASH_NANOGL || defined XASH_WES && defined __EMSCRIPTEN__ // WebGL need to know array sizes
if( pglDrawRangeElements )
pglDrawRangeElements( GL_TRIANGLES, startverts, g_studio.numverts,
g_studio.numelems - startelems, GL_UNSIGNED_SHORT, &g_studio.arrayelems[startelems] );
else
#endif
pglDrawElements( GL_TRIANGLES, g_studio.numelems - startelems, GL_UNSIGNED_SHORT, &g_studio.arrayelems[startelems] );
pglDisableClientState( GL_VERTEX_ARRAY );
pglDisableClientState( GL_TEXTURE_COORD_ARRAY );
if( !( g_nForceFaceFlags & STUDIO_NF_CHROME ) )
pglDisableClientState( GL_COLOR_ARRAY );
}
/*
===============
R_StudioDrawPoints
@ -2037,6 +2302,9 @@ static void R_StudioDrawPoints( void )
if( !m_pStudioHeader ) return;
g_studio.numverts = g_studio.numelems = 0;
// safety bounding the skinnum
m_skinnum = bound( 0, RI.currententity->curstate.skin, ( m_pStudioHeader->numskinfamilies - 1 ));
ptexture = (mstudiotexture_t *)((byte *)m_pStudioHeader + m_pStudioHeader->textureindex);
@ -2134,6 +2402,8 @@ static void R_StudioDrawPoints( void )
for( j = 0; j < m_pSubModel->nummesh; j++ )
{
float oldblend = tr.blend;
uint startArrayVerts = g_studio.numverts;
uint startArrayElems = g_studio.numelems;
short *ptricmds;
float s, t;
@ -2167,11 +2437,24 @@ static void R_StudioDrawPoints( void )
R_StudioSetupSkin( m_pStudioHeader, pskinref[pmesh->skinref] );
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 );
if( CVAR_TO_BOOL(r_studio_drawelements) )
{
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 );
}
if( FBitSet( g_nFaceFlags, STUDIO_NF_MASKED ))
{

View File

@ -7,7 +7,9 @@ cd $TRAVIS_BUILD_DIR
export CC="ccache i686-w64-mingw32-gcc"
export CXX="ccache i686-w64-mingw32-g++"
export CFLAGS="-static-libgcc -no-pthread"
export CXXFLAGS="-static-libgcc -static-libstdc++"
export CXXFLAGS="-static-libgcc -static-libstdc++ -no-pthread"
export LDFLAGS="-static-libgcc -static-libstdc++ -no-pthread"
export LINKFLAGS="-static-libgcc -static-libstdc++ -no-pthread"
export WINRC="i686-w64-mingw32-windres"
rm -rf build # clean build directory
./waf configure --sdl2=$TRAVIS_BUILD_DIR/SDL2_mingw/i686-w64-mingw32/ --disable-vgui --build-type=debug --verbose || die # can't compile VGUI support on MinGW, due to differnet C++ ABI

View File

@ -14,13 +14,12 @@
import os
def options(opt):
opt.add_option(
'--sdl2', action='store', type='string', dest = 'SDL2_PATH', default = None,
help = 'SDL2 path to build(required for Windows)')
grp = opt.add_option_group('SDL2 options')
grp.add_option('--sdl2', action='store', dest = 'SDL2_PATH', default = None,
help = 'path to precompiled SDL2 library(required for Windows)')
opt.add_option(
'--skip-sdl2-sanity-check', action='store_false', default = True, dest='SDL2_SANITY_CHECK',
help = 'Skip checking SDL2 sanity')
grp.add_option('--skip-sdl2-sanity-check', action='store_false', default = True, dest='SDL2_SANITY_CHECK',
help = 'skip checking SDL2 sanity')
def my_dirname(path):
# really dumb, will not work with /path/framework//, but still enough

View File

@ -111,7 +111,7 @@ class Android:
def options(opt):
android = opt.add_option_group('Android options')
android.add_option('--android', action='store', type='string', dest='ANDROID_OPTS', default=None,
android.add_option('--android', action='store', dest='ANDROID_OPTS', default=None,
help='enable building for android, format: --android=<arch>,<toolchain>,<api>, example: --android=arm,4.9,26')
def configure(conf):

View File

@ -9,24 +9,20 @@ from fwgslib import get_subproject_name
top = '.'
def options(opt):
opt.add_option(
'--vgui', action = 'store', type='string', dest = 'VGUI_DEV',
grp = opt.add_option_group('VGUI options')
grp.add_option('--vgui', action = 'store', dest = 'VGUI_DEV',
help = 'path to vgui-dev repo', default='' )
opt.add_option(
'--disable-vgui', action = 'store_true', dest = 'NO_VGUI',
grp.add_option('--disable-vgui', action = 'store_true', dest = 'NO_VGUI',
help = 'disable vgui_support', default=False )
opt.add_option(
'--skip-vgui-sanity-check', action = 'store_false', dest = 'VGUI_SANITY_CHECK',
help = 'Skip checking VGUI sanity', default=True )
# stub
grp.add_option('--skip-vgui-sanity-check', action = 'store_false', dest = 'VGUI_SANITY_CHECK',
help = 'skip checking VGUI sanity', default=True )
return
def configure(conf):
conf.env.NO_VGUI = conf.options.NO_VGUI
if conf.options.DEDICATED or conf.options.NO_VGUI:
if conf.options.NO_VGUI:
return
conf.start_msg('Configuring VGUI by provided path')
@ -75,7 +71,7 @@ def build(bld):
bld.load_envs()
bld.env = bld.all_envs[get_subproject_name(bld)]
if bld.env.DEDICATED or bld.env.NO_VGUI:
if bld.env.NO_VGUI:
return
libs = []

118
wscript
View File

@ -13,35 +13,73 @@ import fwgslib
VERSION = '0.99'
APPNAME = 'xash3d-fwgs'
SUBDIRS = [ 'public', 'engine', 'game_launch', 'vgui_support', 'ref_gl' ]
top = '.'
class Subproject:
name = ''
dedicated = True # if true will be ignored when building dedicated server
singlebin = False # if true will be ignored when singlebinary is set
ignore = False # if true will be ignored, set by user request
def __init__(self, name, dedicated=True, singlebin=False):
self.name = name
self.dedicated = dedicated
self.singlebin = singlebin
SUBDIRS = [
Subproject('public', dedicated=False),
Subproject('engine', dedicated=False),
Subproject('game_launch', singlebin=True),
Subproject('ref_gl'),
Subproject('mainui'),
Subproject('vgui_support'),
]
def subdirs():
return map(lambda x: x.name, SUBDIRS)
def options(opt):
grp = opt.add_option_group('Common options')
grp.add_option('--build-type', action='store', dest='BUILD_TYPE', default = None,
help = 'build type: debug, release or none(custom flags)')
grp.add_option('--dedicated', action = 'store_true', dest = 'DEDICATED', default = False,
help = 'build Xash Dedicated Server(XashDS)')
grp.add_option( '--single-binary', action = 'store_true', dest = 'SINGLE_BINARY', default = False,
help = 'build single "xash" binary instead of xash.dll/libxash.so (forced for dedicated)')
grp.add_option('--64bits', action = 'store_true', dest = 'ALLOW64', default = False,
help = 'allow targetting 64-bit engine')
grp.add_option('--win-style-install', action = 'store_true', dest = 'WIN_INSTALL', default = False,
help = 'install like Windows build, ignore prefix, useful for development')
grp.add_option('--enable-bsp2', action = 'store_true', dest = 'SUPPORT_BSP2_FORMAT', default = False,
help = 'build engine and renderers with BSP2 map support(recommended for Quake, breaks compability!)')
grp.add_option('--skip-subprojects', action='store', dest = 'SKIP_SUBDIRS', default=None,
help = 'don\'t recurse into specified subprojects. Current subdirs: ' + str(subdirs()))
for i in SUBDIRS:
if not os.path.isfile(os.path.join(i.name, 'wscript')):
# HACKHACK: this way we get warning message right in the help
# so this just becomes more noticeable
opt.add_option_group('Cannot find wscript in ' + i.name + '. You probably missed submodule update')
else: opt.recurse(i.name)
opt.load('xcompile compiler_cxx compiler_c sdl2')
if sys.platform == 'win32':
opt.load('msvc msvs')
opt.add_option(
'--build-type', action='store', type='string', dest='BUILD_TYPE', default = None,
help = 'build type: debug, release or none(custom flags)')
def set_ignored_subdirs(subdirs):
for i in SUBDIRS:
if i.ignore:
continue
opt.add_option(
'--dedicated', action = 'store_true', dest = 'DEDICATED', default = False,
help = 'build Xash Dedicated Server(XashDS)')
opt.add_option(
'--64bits', action = 'store_true', dest = 'ALLOW64', default = False,
help = 'allow targetting 64-bit engine')
opt.add_option(
'--win-style-install', action = 'store_true', dest = 'WIN_INSTALL', default = False,
help = 'install like Windows build, ignore prefix, useful for development')
opt.add_option(
'--enable-bsp2', action = 'store_true', dest = 'SUPPORT_BSP2_FORMAT', default = False,
help = 'build engine and renderers with BSP2 map support(recommended for Quake, breaks compability!)')
opt.recurse(SUBDIRS)
if i.name in subdirs:
i.ignore = True
def configure(conf):
conf.start_msg('Build type')
@ -53,6 +91,11 @@ def configure(conf):
conf.fatal('Invalid build type. Valid are "debug", "release" or "none"')
conf.end_msg(conf.options.BUILD_TYPE)
# skip some subdirectories, if requested
if conf.options.SKIP_SUBDIRS:
skip_subdirs = conf.options.SKIP_SUBDIRS.split(',')
set_ignored_subdirs(skip_subdirs)
# Force XP compability, all build targets should add
# subsystem=bld.env.MSVC_SUBSYSTEM
# TODO: wrapper around bld.stlib, bld.shlib and so on?
@ -104,6 +147,8 @@ def configure(conf):
linker_flags, conf.options.BUILD_TYPE, conf.env.COMPILER_CC))
conf.env.DEDICATED = conf.options.DEDICATED
# we don't need game launcher on dedicated
conf.env.SINGLE_BINARY = conf.options.SINGLE_BINARY or conf.env.DEDICATED
if conf.env.DEST_OS == 'linux':
conf.check_cc( lib='dl' )
@ -135,13 +180,32 @@ def configure(conf):
conf.env.append_unique('DEFINES', 'XASH_BUILD_COMMIT="{0}"'.format(conf.env.GIT_VERSION if conf.env.GIT_VERSION else 'notset'))
for i in SUBDIRS:
conf.setenv(i, conf.env) # derive new env from global one
conf.env.ENVNAME = i
conf.msg(msg='--> ' + i, result='in progress', color='BLUE')
if conf.env.SINGLE_BINARY and i.singlebin:
continue
if conf.env.DEDICATED and i.dedicated:
continue
if i.ignore:
continue
conf.setenv(i.name, conf.env) # derive new env from global one
conf.env.ENVNAME = i.name
conf.msg(msg='--> ' + i.name, result='in progress', color='BLUE')
# configure in standalone env
conf.recurse(i)
conf.msg(msg='<-- ' + i, result='done', color='BLUE')
conf.recurse(i.name)
conf.msg(msg='<-- ' + i.name, result='done', color='BLUE')
conf.setenv('')
def build(bld):
bld.recurse(SUBDIRS)
for i in SUBDIRS:
if bld.env.SINGLE_BINARY and i.singlebin:
continue
if bld.env.DEDICATED and i.dedicated:
continue
if i.ignore:
continue
bld.recurse(i.name)