Compare commits

...

21 Commits

Author SHA1 Message Date
Alibek Omarov
0cf571602c ref: common: wscript: fix psvita build 2026-04-13 12:48:55 +05:00
Alibek Omarov
a125f90d12 ref: soft: fix build 2026-04-13 10:00:15 +05:00
Alibek Omarov
313cda5478 ref: add GL_ResampleTexture to libref_common 2026-04-12 23:30:08 +05:00
Alibek Omarov
fc4e7eb18b ref: move remaining light functions to libref_common 2026-04-12 23:18:31 +05:00
Alibek Omarov
0836519b2d ref: gl: refactor R_LightVec 2026-04-12 23:06:43 +05:00
Alibek Omarov
5eeb250907 ref: common: add R_PushDlightsForBmodel 2026-04-12 22:44:55 +05:00
Alibek Omarov
2e579d0dd3 ref: move R_PushDlights and R_MarkLights to ref_common 2026-04-12 22:38:43 +05:00
Alibek Omarov
8cd40db261 ref: move RunLightstyles to ref_common 2026-04-12 22:12:50 +05:00
Alibek Omarov
9d03959196 engine: move sprite texture loading back to engine, only leave rendering for renderer 2026-04-12 17:29:45 +05:00
Alibek Omarov
acd3b0258d ref: common: move malloc and GL_InitRandomTable 2026-04-12 16:10:48 +05:00
Alibek Omarov
0b49e60c22 ref: common: draft new static library, containing shared code for ref_gl and ref_soft 2026-04-12 15:52:33 +05:00
Alibek Omarov
6719443d99 engine: draft new RefAPI 14: remove reserved functions from render api, remove CL_AddCustomBeam 2026-04-12 15:25:19 +05:00
a1batross
5f6577df2e engine: client: don't allow con_fontscale lower than 1
Prevents possible division by zero
2026-04-12 14:50:58 +05:00
Sergey Degtyar
e87f307ac1 engine: image: fix blue halo around sprays 2026-04-10 15:00:02 +05:00
Владислав Сухов
7e015a268b engine: client: in_joy: implement per-axis gyroscope deadzone support 2026-04-10 14:59:30 +05:00
TheEVolk
a679c53111 engine: client: add cvar sv_voice_singleplayer flag FCVAR_SERVER 2026-04-10 14:58:46 +05:00
TheEVolk
9e8d248044 engine: client: voice api 2026-04-10 14:58:46 +05:00
Alibek Omarov
055d646225 ref: gl: merge refactoring changes from litwater branch 2026-04-09 11:43:47 +05:00
ksagameng
a2514b6916 platform: ios: Remove FTP server as latest apple clang broke it 2026-04-09 10:25:18 +05:00
ksagameng
0ac5e78040 scripts: ios: Modify script to work with dylib loading changes 2026-04-09 10:25:18 +05:00
ksagameng
a82221e3df engine: platform: No more lib_ios, use FS_FindLibaray to load dylibs instead 2026-04-09 10:25:18 +05:00
90 changed files with 1285 additions and 7593 deletions

View File

@@ -134,7 +134,7 @@ To build you should clone [SDL](https://github.com/libsdl-org/SDL) from `SDL2` b
0) (optional) Examine which build options are available: `./waf --help`.
1) Configure build: `./waf configure --ios --enable-bundled-deps --sdl2 (path/to/SDL2.framework)`, set `--ios-simulator` instead of `--ios` if you want to build for simulator.
2) Compile `./waf build`.
3) Navigate to `build` and copy your compiled SDL2.framework there, then add your client dylibs to `build/ios/cl_dlls` and any other dylibs to `build/ios/dlls` (You can also run `scripts/ios/buildhlsdk.sh` instead to automatically create an ipa with hlsdk dylibs)
3) Navigate to `build` and copy your compiled SDL2.framework there, then add your game dylibs to `build/ios/libs/(gamedir)/(dlls/cl_dlls)`(You can also run `scripts/ios/buildhlsdk.sh` instead to automatically create an ipa with hlsdk dylibs)
4) Run `scripts/ios/createipa.sh` to create an installable ipa
### Running tests

View File

@@ -116,6 +116,8 @@ typedef enum
IMAGE_MULTILAYER = BIT(8), // to differentiate from 3D texture
IMAGE_ONEBIT_ALPHA = BIT(9), // binary alpha
IMAGE_QUAKEPAL = BIT(10), // image has quake1 palette
IMAGE_PREMULTIPLIED = BIT(11),
IMAGE_PLAYERDECAL = BIT(12), // loaded with IL_LOAD_PLAYER_DECAL (custom player spray)
// Image_Process manipulation flags
IMAGE_FLIP_X = BIT(16), // flip the image by width

View File

@@ -101,7 +101,7 @@ typedef enum
TF_TEXTURE_3D = (1<<20), // this is GL_TEXTURE_3D
TF_ATLAS_PAGE = (1<<21), // bit who indicate lightmap page or deluxemap page
TF_ALPHACONTRAST = (1<<22), // special texture mode for A2C
// reserved
TF_PREMULTIPLIED = (1<<23), // RGBA was stored premultiplied (HL gradient / indexalpha)
// reserved
TF_IMG_UPLOADED = (1<<25), // this is set for first time when called glTexImage, otherwise it will be call glTexSubImage
TF_ARB_FLOAT = (1<<26), // float textures

View File

@@ -159,11 +159,22 @@ typedef struct snd_globals_s
qboolean have_ambient_sfx;
} snd_globals_t;
typedef struct voice_audio_info_s
{
uint width;
uint samplerate;
uint frame_size; // in samples
} voice_audio_info_t;
// API from engine to client (client calls these)
typedef struct sound_api_s
{
qboolean (*CL_GetEntitySpatialization)( channel_t *ch );
sfx_t* (*S_GetSfxByHandle)( sound_t handle );
qboolean (*CL_GetEntitySpatialization)( channel_t *ch );
sfx_t* (*S_GetSfxByHandle)( sound_t handle );
// Voice extensions
void (*pfnS_RawEntSamples)( int entnum, uint samples, uint rate, word width, word channels, const byte *data, int snd_vol, float attn );
void (*pfnSND_ForceInitMouth)( int entnum );
voice_audio_info_t (*pfnVoice_GetAudioInfo)( void );
} sound_api_t;
// Callbacks from client to engine (engine calls these when custom sound is active)

View File

@@ -82,6 +82,7 @@ typedef struct cldll_func_s
void (*pfnLookEvent)( float relyaw, float relpitch );
// Sound API
int (*pfnGetSoundInterface)( int version, const sound_api_t *api, sound_interface_t *callback );
int (*pfnVoice_StartChannel)( int samples, byte *data, int entnum );
} cldll_func_t;
#endif//CDLL_EXP_H

View File

@@ -981,15 +981,8 @@ qboolean CL_AddVisibleEntity( cl_entity_t *ent, int entityType )
if( !draw_player )
return false;
if( entityType == ET_BEAM )
{
ref.dllFuncs.CL_AddCustomBeam( ent );
return true;
}
else if( !ref.dllFuncs.R_AddEntity( ent, entityType ))
{
if( !ref.dllFuncs.R_AddEntity( ent, entityType ))
return false;
}
// because pTemp->entity.curstate.effects
// is already occupied by FTENT_FLICKER

View File

@@ -105,7 +105,8 @@ static const dllfunc_t cdll_new_exports[] = // allowed only in SDK 2.3 and high
{ "IN_ClientTouchEvent", (void **)&clgame.dllFuncs.pfnTouchEvent}, // Xash3D FWGS ext
{ "IN_ClientMoveEvent", (void **)&clgame.dllFuncs.pfnMoveEvent}, // Xash3D FWGS ext
{ "IN_ClientLookEvent", (void **)&clgame.dllFuncs.pfnLookEvent}, // Xash3D FWGS ext
{ "HUD_GetSoundInterface", (void **)&clgame.dllFuncs.pfnGetSoundInterface }, // Xash3D ext
{ "HUD_GetSoundInterface", (void **)&clgame.dllFuncs.pfnGetSoundInterface }, // Xash3D FWGS ext
{ "Voice_StartChannel", (void **)&clgame.dllFuncs.pfnVoice_StartChannel }, // Xash3D FWGS ext
};
static void pfnSPR_DrawHoles( int frame, int x, int y, const wrect_t *prc );
@@ -373,13 +374,13 @@ static void SPR_DrawGeneric( int frame, float x, float y, float width, float hei
int w, h;
// assume we get sizes from image
ref.dllFuncs.R_GetSpriteParms( &w, &h, NULL, frame, clgame.ds.pSprite );
R_GetSpriteParms( &w, &h, NULL, frame, clgame.ds.pSprite );
width = w;
height = h;
}
texnum = ref.dllFuncs.R_GetSpriteTexture( clgame.ds.pSprite, frame );
texnum = R_GetSpriteTexture( clgame.ds.pSprite, frame );
if( prc )
{
@@ -1423,7 +1424,7 @@ int EXPORT pfnSPR_Frames( HSPRITE hPic )
{
int numFrames = 0;
ref.dllFuncs.R_GetSpriteParms( NULL, NULL, &numFrames, 0, CL_GetSpritePointer( hPic ));
R_GetSpriteParms( NULL, NULL, &numFrames, 0, CL_GetSpritePointer( hPic ));
return numFrames;
}
@@ -1438,7 +1439,7 @@ static int GAME_EXPORT pfnSPR_Height( HSPRITE hPic, int frame )
{
int sprHeight = 0;
ref.dllFuncs.R_GetSpriteParms( NULL, &sprHeight, NULL, frame, CL_GetSpritePointer( hPic ));
R_GetSpriteParms( NULL, &sprHeight, NULL, frame, CL_GetSpritePointer( hPic ));
return sprHeight;
}
@@ -1453,7 +1454,7 @@ static int GAME_EXPORT pfnSPR_Width( HSPRITE hPic, int frame )
{
int sprWidth = 0;
ref.dllFuncs.R_GetSpriteParms( &sprWidth, NULL, NULL, frame, CL_GetSpritePointer( hPic ));
R_GetSpriteParms( &sprWidth, NULL, NULL, frame, CL_GetSpritePointer( hPic ));
return sprWidth;
}
@@ -3323,7 +3324,7 @@ int TriSpriteTexture( model_t *pSpriteModel, int frame )
{
int gl_texturenum;
if(( gl_texturenum = ref.dllFuncs.R_GetSpriteTexture( pSpriteModel, frame )) <= 0 )
if(( gl_texturenum = R_GetSpriteTexture( pSpriteModel, frame )) <= 0 )
return 0;
ref.dllFuncs.GL_Bind( XASH_TEXTURE0, gl_texturenum );

360
engine/client/cl_sprite.c Normal file
View File

@@ -0,0 +1,360 @@
/*
cl_sprite.c - sprite loading
Copyright (C) 2010 Uncle Mike
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#include "common.h"
#include "client.h"
#include "sprite.h"
#include "ref_common.h"
static char sprite_name[MAX_QPATH];
static char group_suffix[8];
static uint r_texFlags = 0;
static int sprite_version;
/*
================
R_GetSpriteFrame
assume pModel is valid
================
*/
mspriteframe_t *R_GetSpriteFrame( const model_t *pModel, int frame, float yaw )
{
msprite_t *psprite;
mspritegroup_t *pspritegroup;
mspriteframe_t *pspriteframe = NULL;
float *pintervals, fullinterval;
int i, numframes;
float targettime;
if( !pModel )
return NULL;
psprite = pModel->cache.data;
if( frame < 0 )
{
frame = 0;
}
else if( frame >= psprite->numframes )
{
if( frame > psprite->numframes )
Con_Printf( S_WARN "%s: no such frame %d (%s)\n", __func__, frame, pModel->name );
frame = psprite->numframes - 1;
}
if( psprite->frames[frame].type == SPR_SINGLE )
{
pspriteframe = psprite->frames[frame].frameptr;
}
else if( psprite->frames[frame].type == SPR_GROUP )
{
pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr;
pintervals = pspritegroup->intervals;
numframes = pspritegroup->numframes;
fullinterval = pintervals[numframes - 1];
// when loading in Mod_LoadSpriteGroup, we guaranteed all interval values
// are positive, so we don't have to worry about division by zero
targettime = cl.time - ((int)( cl.time / fullinterval )) * fullinterval;
for( i = 0; i < ( numframes - 1 ); i++ )
{
if( pintervals[i] > targettime )
break;
}
pspriteframe = pspritegroup->frames[i];
}
else if( psprite->frames[frame].type == FRAME_ANGLED )
{
int angleframe = (int)( Q_rint(( refState.viewangles[1] - yaw + 45.0f ) / 360 * 8 ) - 4 ) & 7;
// e.g. doom-style sprite monsters
pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr;
pspriteframe = pspritegroup->frames[angleframe];
}
return pspriteframe;
}
void R_GetSpriteParms( int *frameWidth, int *frameHeight, int *numFrames, int currentFrame, const model_t *pSprite )
{
mspriteframe_t *pFrame;
if( !pSprite || pSprite->type != mod_sprite )
return;
pFrame = R_GetSpriteFrame( pSprite, currentFrame, 0.0f );
if( frameWidth )
*frameWidth = pFrame->width;
if( frameHeight )
*frameHeight = pFrame->height;
if( numFrames )
*numFrames = pSprite->numframes;
}
int R_GetSpriteTexture( const model_t *m_pSpriteModel, int frame )
{
if( !m_pSpriteModel || m_pSpriteModel->type != mod_sprite || !m_pSpriteModel->cache.data )
return 0;
return R_GetSpriteFrame( m_pSpriteModel, frame, 0.0f )->gl_texturenum;
}
static void Mod_SpriteTextureReplacementReport( const char *modelname, int gl_texturenum, const char *foundpath )
{
if( host_allow_materials.value != 2.0f )
return;
if( gl_texturenum > 0 )
Con_Printf( "Looking for %s tex replacement..." S_GREEN "OK (%s)\n", modelname, foundpath );
else if( gl_texturenum < 0 )
Con_Printf( "Looking for %s tex replacement..." S_YELLOW "MISS (%s)\n", modelname, foundpath );
else
Con_Printf( "Looking for %s tex replacement..." S_RED "FAIL (%s)\n", modelname, foundpath );
}
static qboolean Mod_SpriteSearchForTextureReplacement( char *out, size_t size, const char *modelname, const char *fmt, ... )
{
va_list ap;
int ret;
va_start( ap, fmt );
ret = Q_vsnprintf( out, size, fmt, ap );
va_end( ap );
if( ret < 0 )
{
Mod_SpriteTextureReplacementReport( modelname, -1, "overflow" );
return false;
}
if( FS_FileExists( out, false ))
return true;
Mod_SpriteTextureReplacementReport( modelname, -1, out );
return false;
}
static const byte *Mod_SpriteLoadFrame( model_t *mod, const void *pin, mspriteframe_t **ppframe, int num )
{
dspriteframe_t pinframe;
mspriteframe_t *pspriteframe;
int gl_texturenum = 0;
char texname[128];
int bytes = 1;
memcpy( &pinframe, pin, sizeof( dspriteframe_t ));
if( sprite_version == SPRITE_VERSION_32 )
bytes = 4;
// build unique frame name
if( FBitSet( mod->flags, MODEL_CLIENT )) // it's a HUD sprite
{
Q_snprintf( texname, sizeof( texname ), "#HUD/%s(%s:%i%i).spr", sprite_name, group_suffix, num / 10, num % 10 );
gl_texturenum = ref.dllFuncs.GL_LoadTexture( texname, pin, pinframe.width * pinframe.height * bytes, r_texFlags );
}
else
{
// partial HD-textures support
if( Mod_AllowMaterials( ))
{
if( Mod_SpriteSearchForTextureReplacement( texname, sizeof( texname ), sprite_name, "materials/%s/%s%i%i.tga", sprite_name, group_suffix, num / 10, num % 10 ))
{
gl_texturenum = ref.dllFuncs.GL_LoadTexture( texname, NULL, 0, r_texFlags );
Mod_SpriteTextureReplacementReport( sprite_name, gl_texturenum, texname );
}
}
if( gl_texturenum == 0 )
{
Q_snprintf( texname, sizeof( texname ), "#%s(%s:%i%i).spr", sprite_name, group_suffix, num / 10, num % 10 );
gl_texturenum = ref.dllFuncs.GL_LoadTexture( texname, pin, pinframe.width * pinframe.height * bytes, r_texFlags );
}
}
// setup frame description
pspriteframe = Mem_Malloc( mod->mempool, sizeof( mspriteframe_t ));
pspriteframe->width = pinframe.width;
pspriteframe->height = pinframe.height;
pspriteframe->up = pinframe.origin[1];
pspriteframe->left = pinframe.origin[0];
pspriteframe->down = pinframe.origin[1] - pinframe.height;
pspriteframe->right = pinframe.width + pinframe.origin[0];
pspriteframe->gl_texturenum = gl_texturenum;
*ppframe = pspriteframe;
return (const byte *)pin + sizeof( dspriteframe_t ) + pinframe.width * pinframe.height * bytes;
}
static const byte *Mod_SpriteLoadGroup( model_t *mod, const void *pin, mspriteframe_t **ppframe, int framenum )
{
const dspritegroup_t *pingroup;
mspritegroup_t *pspritegroup;
const dspriteinterval_t *pin_intervals;
float *poutintervals;
int i, groupsize, numframes;
const void *ptemp;
pingroup = (const dspritegroup_t *)pin;
numframes = pingroup->numframes;
groupsize = sizeof( mspritegroup_t ) + ( numframes - 1 ) * sizeof( pspritegroup->frames[0] );
pspritegroup = Mem_Calloc( mod->mempool, groupsize );
pspritegroup->numframes = numframes;
*ppframe = (mspriteframe_t *)pspritegroup;
pin_intervals = (const dspriteinterval_t *)( pingroup + 1 );
poutintervals = Mem_Calloc( mod->mempool, numframes * sizeof( float ));
pspritegroup->intervals = poutintervals;
for( i = 0; i < numframes; i++ )
{
*poutintervals = pin_intervals->interval;
if( *poutintervals <= 0.0f )
*poutintervals = 1.0f; // set error value
poutintervals++;
pin_intervals++;
}
ptemp = (const void *)pin_intervals;
for( i = 0; i < numframes; i++ )
{
ptemp = Mod_SpriteLoadFrame( mod, ptemp, &pspritegroup->frames[i], framenum * 10 + i );
}
return ptemp;
}
void Mod_SpriteLoadTextures( model_t *mod, const void *buffer )
{
const dsprite_t *pin = buffer;
const short *numi = NULL;
const byte *pframetype;
msprite_t *psprite = mod->cache.data;
int i;
if( pin->version == SPRITE_VERSION_Q1 || pin->version == SPRITE_VERSION_32 )
numi = NULL;
else if( pin->version == SPRITE_VERSION_HL )
numi = (const short *)((const byte *)buffer + sizeof( dsprite_hl_t ));
r_texFlags = mod->numtexinfo;
sprite_version = pin->version;
Q_strncpy( sprite_name, mod->name, sizeof( sprite_name ));
COM_StripExtension( sprite_name );
if( numi == NULL )
{
rgbdata_t *pal;
pal = FS_LoadImage( "#id.pal", (byte *)&i, 768 );
pframetype = (const byte *)buffer + sizeof( dsprite_q1_t );
FS_FreeImage( pal );
}
else if( *numi <= 256 )
{
const byte *src = (const byte *)( numi + 1 );
rgbdata_t *pal;
size_t pal_bytes = *numi * 3;
// install palette
switch( psprite->texFormat )
{
case SPR_INDEXALPHA:
pal = FS_LoadImage( "#gradient.pal", src, pal_bytes );
break;
case SPR_ALPHTEST:
pal = FS_LoadImage( "#masked.pal", src, pal_bytes );
break;
default:
pal = FS_LoadImage( "#texgamma.pal", src, pal_bytes );
break;
}
pframetype = (const byte *)( src + pal_bytes );
FS_FreeImage( pal );
}
else
{
Con_DPrintf( S_ERROR "%s has wrong number of palette colors %i (should be less or equal than 256)\n", mod->name, *numi );
return;
}
if( mod->numframes < 1 )
return;
for( i = 0; i < mod->numframes; i++ )
{
frametype_t frametype;
dframetype_t dframetype;
memcpy( &dframetype, pframetype, sizeof( dframetype ));
frametype = dframetype.type;
psprite->frames[i].type = (spriteframetype_t)frametype;
switch( frametype )
{
case FRAME_SINGLE:
Q_strncpy( group_suffix, "frame", sizeof( group_suffix ));
pframetype = Mod_SpriteLoadFrame( mod, pframetype + sizeof( dframetype_t ), &psprite->frames[i].frameptr, i );
break;
case FRAME_GROUP:
Q_strncpy( group_suffix, "group", sizeof( group_suffix ));
pframetype = Mod_SpriteLoadGroup( mod, pframetype + sizeof( dframetype_t ), &psprite->frames[i].frameptr, i );
break;
case FRAME_ANGLED:
Q_strncpy( group_suffix, "angle", sizeof( group_suffix ));
pframetype = Mod_SpriteLoadGroup( mod, pframetype + sizeof( dframetype_t ), &psprite->frames[i].frameptr, i );
break;
}
if( pframetype == NULL )
break;
}
}
void Mod_SpriteUnloadTextures( void *data )
{
msprite_t *psprite = data;
int i;
if( !data )
return;
// release all textures
for( i = 0; i < psprite->numframes; i++ )
{
if( !psprite->frames[i].frameptr )
continue;
if( psprite->frames[i].type == SPR_SINGLE )
{
ref.dllFuncs.GL_FreeTexture( psprite->frames[i].frameptr->gl_texturenum );
}
else
{
mspritegroup_t *pspritegroup = (mspritegroup_t *)psprite->frames[i].frameptr;
int j;
for( j = 0; j < pspritegroup->numframes; j++ )
{
if( pspritegroup->frames[j] )
ref.dllFuncs.GL_FreeTexture( pspritegroup->frames[j]->gl_texturenum );
}
}
}
}

View File

@@ -972,6 +972,13 @@ void SCR_DrawPos( void );
void SCR_DrawEnts( void );
void SCR_DrawUserCmd( void );
//
// cl_sprite.c
//
mspriteframe_t *R_GetSpriteFrame( const model_t *pModel, int frame, float yaw );
void R_GetSpriteParms( int *frameWidth, int *frameHeight, int *numFrames, int currentFrame, const model_t *pSprite );
int R_GetSpriteTexture( const model_t *m_pSpriteModel, int frame );
//
// cl_netgraph.c
//

View File

@@ -2164,8 +2164,11 @@ void Con_RunConsole( void )
con.vislines = con.showlines;
}
if( FBitSet( con_charset.flags|con_fontscale.flags|con_fontnum.flags|cl_charset.flags|con_oldfont.flags, FCVAR_CHANGED ))
if( FBitSet( con_charset.flags|con_fontscale.flags|con_fontnum.flags|cl_charset.flags|con_oldfont.flags, FCVAR_CHANGED ))
{
if( con_fontscale.value < 1.0f )
Cvar_DirectSet( &con_fontscale, "1" );
// update codepage parameters
if( !Q_stricmp( con_charset.string, "cp1251" ))
{

View File

@@ -65,6 +65,9 @@ static CVAR_DEFINE_AUTO( joy_calibrated, "0", FCVAR_READ_ONLY, "tells whether cu
static CVAR_DEFINE_AUTO( joy_gyro_pitch, "1.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "gyroscope sensitivity for looking up and down" );
static CVAR_DEFINE_AUTO( joy_gyro_yaw, "1.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "gyroscope sensitivity for turning left and right" );
static CVAR_DEFINE_AUTO( joy_gyro_roll, "0.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "gyroscope sensitivity when tilting the device sideways" );
static CVAR_DEFINE_AUTO( joy_gyro_pitch_deadzone, "0.5", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "gyroscope pitch axis deadzone (deg/s)" );
static CVAR_DEFINE_AUTO( joy_gyro_yaw_deadzone, "0.5", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "gyroscope yaw axis deadzone (deg/s)" );
static CVAR_DEFINE_AUTO( joy_gyro_roll_deadzone, "0.5", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "gyroscope roll axis deadzone (deg/s)" );
static CVAR_DEFINE_AUTO( joy_debug, "0", 0, "visualize gamepad axes and buttons" );
// stores the latest instantaneous gyroscope rotation rates (in rad/s) from platform input
@@ -343,6 +346,13 @@ void Joy_FinalizeMove( float *fw, float *side, float *dpitch, float *dyaw )
float yaw_speed = joy_gyro_speed[1] * ( 180.0f / M_PI );
float roll_speed = joy_gyro_speed[2] * ( 180.0f / M_PI );
if( fabs( pitch_speed ) < joy_gyro_pitch_deadzone.value )
pitch_speed = 0.0f;
if( fabs( yaw_speed ) < joy_gyro_yaw_deadzone.value )
yaw_speed = 0.0f;
if( fabs( roll_speed ) < joy_gyro_roll_deadzone.value )
roll_speed = 0.0f;
*dpitch -= joy_gyro_pitch.value * pitch_speed * host.realframetime;
*dyaw += joy_gyro_yaw.value * yaw_speed * host.realframetime;
*dyaw += joy_gyro_roll.value * roll_speed * host.realframetime;
@@ -467,6 +477,12 @@ void Joy_DrawDebug( void )
if( joy_have_gyro.value )
{
static const char *gyronames[3] = { "GYRO P", "GYRO Y", "GYRO R" };
static const convar_t *const gyro_deadzone[3] =
{
&joy_gyro_pitch_deadzone,
&joy_gyro_yaw_deadzone,
&joy_gyro_roll_deadzone,
};
for( int i = 0; i < 3; i++ )
{
@@ -485,10 +501,22 @@ void Joy_DrawDebug( void )
float filled = fval * halfbar_w;
ref.dllFuncs.FillRGBA( kRenderTransTexture, center + Q_min( 0, filled ), y, fabs( filled ), bar_h, bar_fillcolor[0], bar_fillcolor[1], bar_fillcolor[2], bar_fillcolor[3] );
// deadzone in deg/s; display scale is +-5 rad/s
float fthreshold = gyro_deadzone[i]->value * ( M_PI / 180.0f ) / 5.0f;
fthreshold = bound( 0.0f, fthreshold, 1.0f );
if( fthreshold > 0.0f )
{
float thresh_x = fthreshold * halfbar_w;
ref.dllFuncs.FillRGBA( kRenderTransTexture, center - thresh_x, y, thresh_x * 2, bar_h, 180, 40, 40, 120 );
ref.dllFuncs.FillRGBA( kRenderTransTexture, center + thresh_x, y, 1, bar_h, 255, 200, 0, 220 );
ref.dllFuncs.FillRGBA( kRenderTransTexture, center - thresh_x, y, 1, bar_h, 255, 200, 0, 220 );
}
// mark the center
ref.dllFuncs.FillRGBA( kRenderTransTexture, center, y, 1, bar_h, 180, 180, 180, 220 );
// gyro doesn't have deadzones or prevval like axes
// gyro doesn't have prevval like axes
y += bar_h + 2;
}
}
@@ -572,6 +600,11 @@ void Joy_Init( void )
Cvar_RegisterVariable( &joy_gyro_pitch );
Cvar_RegisterVariable( &joy_gyro_yaw );
Cvar_RegisterVariable( &joy_gyro_roll );
Cvar_RegisterVariable( &joy_gyro_pitch_deadzone );
Cvar_RegisterVariable( &joy_gyro_yaw_deadzone );
Cvar_RegisterVariable( &joy_gyro_roll_deadzone );
Cvar_RegisterVariable( &joy_debug );
// renamed from -nojoy to -noenginejoy to not conflict with

View File

@@ -465,6 +465,7 @@ static const ref_api_t gEngfuncs =
&g_fsapi,
R_GetWindowHandle,
R_GetSpriteFrame,
};
static void R_UnloadProgs( void )

View File

@@ -1287,7 +1287,7 @@ uint S_RawSamplesStereo( portable_samplepair_t *rawsamples, uint rawend, uint ma
S_RawEntSamples
===================
*/
void S_RawEntSamples( int entnum, uint samples, uint rate, word width, word channels, const byte *data, int snd_vol )
void S_RawEntSamples( int entnum, uint samples, uint rate, word width, word channels, const byte *data, int snd_vol, float attn )
{
rawchan_t *ch;
@@ -1298,7 +1298,7 @@ void S_RawEntSamples( int entnum, uint samples, uint rate, word width, word chan
return;
ch->master_vol = snd_vol;
ch->dist_mult = (ATTN_NONE / SND_CLIP_DISTANCE);
ch->dist_mult = (attn / SND_CLIP_DISTANCE);
ch->s_rawend = S_RawSamplesStereo( ch->rawsamples, ch->s_rawend, ch->max_samples, samples, rate, width, channels, data );
ch->leftvol = ch->rightvol = snd_vol;
}
@@ -1938,6 +1938,9 @@ static void S_VoiceRecordStop_f( void )
static const sound_api_t gSoundAPI = {
CL_GetEntitySpatialization,
S_GetSfxByHandle,
S_RawEntSamples,
SND_ForceInitMouth,
Voice_GetAudioInfo,
};
/*

View File

@@ -253,7 +253,7 @@ void S_StreamBackgroundTrack( void )
{
// add to raw buffer
int music_vol = (int)(255.0f * S_GetMusicVolume());
S_RawEntSamples( S_RAW_SOUND_BACKGROUNDTRACK, fileSamples, info->rate, info->width, info->channels, raw, music_vol );
S_RawEntSamples( S_RAW_SOUND_BACKGROUNDTRACK, fileSamples, info->rate, info->width, info->channels, raw, music_vol, ATTN_NONE );
}
else
{

View File

@@ -111,7 +111,7 @@ int S_GetCurrentDynamicSounds( soundlist_t *pout, int size );
sfx_t *S_GetSfxByHandle( sound_t handle );
rawchan_t *S_FindRawChannel( int entnum, qboolean create );
uint S_RawSamplesStereo( portable_samplepair_t *rawsamples, uint rawend, uint max_samples, uint samples, uint rate, word width, word channels, const byte *data );
void S_RawEntSamples( int entnum, uint samples, uint rate, word width, word channels, const byte *data, int snd_vol );
void S_RawEntSamples( int entnum, uint samples, uint rate, word width, word channels, const byte *data, int snd_vol, float attn );
void S_StopSound( int entnum, int channel, const char *soundname );
void S_UpdateFrame( struct ref_viewpass_s *rvp );
void S_StopAllSounds( qboolean ambient );

View File

@@ -939,8 +939,14 @@ Feed the decoded data to engine sound subsystem
*/
static void Voice_StartChannel( uint samples, byte *data, int entnum )
{
if( clgame.dllFuncs.pfnVoice_StartChannel != NULL )
{
if( clgame.dllFuncs.pfnVoice_StartChannel( samples, data, entnum ))
return;
}
SND_ForceInitMouth( entnum );
S_RawEntSamples( entnum, samples, voice.samplerate, voice.width, VOICE_PCM_CHANNELS, data, bound( 0, 255 * voice_scale.value, 255 ));
S_RawEntSamples( entnum, samples, voice.samplerate, voice.width, VOICE_PCM_CHANNELS, data, bound( 0, 255 * voice_scale.value, 255 ), ATTN_NONE );
Voice_Status( entnum, true );
}
@@ -1194,3 +1200,13 @@ qboolean Voice_Init( const char *pszCodecName, int quality, qboolean preinit )
voice.initialized = true;
return true;
}
voice_audio_info_t Voice_GetAudioInfo( void )
{
voice_audio_info_t info;
info.width = voice.width;
info.samplerate = voice.samplerate;
info.frame_size = voice.frame_size;
return info;
}

View File

@@ -131,5 +131,6 @@ void Voice_Disconnect( void );
void Voice_AddIncomingData( int ent, const byte *data, uint size, uint frames );
void Voice_StopChannel( int entnum );
void Voice_LoopbackAck( void ); // sends VOICE_LOOPBACK_INDEX to client, gets disabled on timeout
voice_audio_info_t Voice_GetAudioInfo( void );
#endif // VOICE_H

View File

@@ -320,6 +320,11 @@ static qboolean FS_DetermineReadOnlyRootDirectory( char *out, size_t size )
return true;
}
#if XASH_IOS
Q_strncpy( out, IOS_GetExecDir(), size );
return true;
#endif
return false;
}

View File

@@ -173,6 +173,9 @@ static MALLOC_LIKE( FS_FreeImage, 1 ) rgbdata_t *ImagePack( const char *name )
Image_ReportLookupsCount( name );
if( Image_CheckFlag( IL_LOAD_PLAYER_DECAL ))
SetBits( image.flags, IMAGE_PLAYERDECAL );
// clear any force flags
image.force_flags = 0;

View File

@@ -250,6 +250,8 @@ qboolean Image_LoadSPR( const char *name, const byte *buffer, fs_offset_t filesi
SetBits( image.flags, IMAGE_ONEBIT_ALPHA );
// intentionally fallthrough
case LUMP_GRADIENT:
SetBits( image.flags, IMAGE_HAS_ALPHA );
break;
case LUMP_QUAKE1:
SetBits( image.flags, IMAGE_HAS_ALPHA );
break;

View File

@@ -2014,7 +2014,7 @@ static void Mod_SetupSubmodels( model_t *mod, dbspmodel_t *bmod )
SetBits( mod->flags, MODEL_HAS_ORIGIN );
#ifdef HACKS_RELATED_HLMODS
// c2a1 doesn't have origin brush it's just placed at center of the level
if( !Q_stricmp( name, "maps/c2a1.bsp" ) && ( i == 11 ))
if( i == 11 && !Q_stricmp( name, "maps/c2a1.bsp" ))
SetBits( mod->flags, MODEL_HAS_ORIGIN );
#endif
}

View File

@@ -197,6 +197,8 @@ void Mod_ClearStudioCache( void );
// mod_sprite.c
//
void Mod_LoadSpriteModel( model_t *mod, const void *buffer, size_t buffersize, qboolean *loaded );
#endif
void Mod_SpriteLoadTextures( model_t *mod, const void *buffer );
void Mod_SpriteUnloadTextures( void *data );
#endif
#endif//MOD_LOCAL_H

View File

@@ -17,9 +17,6 @@ GNU General Public License for more details.
#include "common.h"
#include "sprite.h"
#include "studio.h"
#if !XASH_DEDICATED
#include "ref_common.h"
#endif // XASH_DEDICATED
#include "mod_local.h"
@@ -147,4 +144,8 @@ void Mod_LoadSpriteModel( model_t *mod, const void *buffer, size_t buffersize, q
psprite->numframes = 0;
return;
}
#if !XASH_DEDICATED
Mod_SpriteLoadTextures( mod, buffer );
#endif
}

View File

@@ -88,6 +88,22 @@ static void Mod_Modellist_f( void )
Con_Printf( "\n" );
}
static void Mod_UnloadRenderData( model_t *mod )
{
#if !XASH_DEDICATED
switch( mod->type )
{
case mod_sprite:
Mod_SpriteUnloadTextures( mod->cache.data );
break;
default:
break;
}
ref.dllFuncs.Mod_ProcessRenderData( mod, false, NULL, 0 );
#endif
}
/*
================
Mod_FreeUserData
@@ -107,12 +123,10 @@ static void Mod_FreeUserData( model_t *mod )
svgame.physFuncs.Mod_ProcessUserData( mod, false, NULL );
}
}
#if !XASH_DEDICATED
else
{
ref.dllFuncs.Mod_ProcessRenderData( mod, false, NULL, 0 );
Mod_UnloadRenderData( mod );
}
#endif
}
/*

View File

@@ -168,6 +168,8 @@ typedef struct physics_interface_s
void *(*SV_HullForBsp)( edict_t *ent, const float *mins, const float *maxs, float *offset );
// handle player custom think function
int (*SV_PlayerThink)( edict_t *ent, float frametime, double time );
// voice data
qboolean (*pfnVoiceData)( int client, uint frames, uint size, qboolean loopback, const char *received );
} physics_interface_t;
#endif//PHYSINT_H

View File

@@ -1,282 +0,0 @@
//
// AsyncSocket.h
//
// This class is in the public domain.
// Originally created by Dustin Voss on Wed Jan 29 2003.
// Updated and maintained by Deusty Designs and the Mac development community.
//
// http://code.google.com/p/cocoaasyncsocket/
//
#import <Foundation/Foundation.h>
@class AsyncSocket;
@class AsyncReadPacket;
@class AsyncWritePacket;
extern NSString *const AsyncSocketException;
extern NSString *const AsyncSocketErrorDomain;
enum AsyncSocketError
{
AsyncSocketCFSocketError = kCFSocketError, // From CFSocketError enum.
AsyncSocketNoError = 0, // Never used.
AsyncSocketCanceledError, // onSocketWillConnect: returned NO.
AsyncSocketReadMaxedOutError, // Reached set maxLength without completing
AsyncSocketReadTimeoutError,
AsyncSocketWriteTimeoutError
};
typedef enum AsyncSocketError AsyncSocketError;
@interface NSObject (AsyncSocketDelegate)
/**
* In the event of an error, the socket is closed.
* You may call "unreadData" during this call-back to get the last bit of data off the socket.
* When connecting, this delegate method may be called
* before"onSocket:didAcceptNewSocket:" or "onSocket:didConnectToHost:".
**/
- (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err;
/**
* Called when a socket disconnects with or without error. If you want to release a socket after it disconnects,
* do so here. It is not safe to do that during "onSocket:willDisconnectWithError:".
**/
- (void)onSocketDidDisconnect:(AsyncSocket *)sock;
/**
* Called when a socket accepts a connection. Another socket is spawned to handle it. The new socket will have
* the same delegate and will call "onSocket:didConnectToHost:port:".
**/
- (void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket;
/**
* Called when a new socket is spawned to handle a connection. This method should return the run-loop of the
* thread on which the new socket and its delegate should operate. If omitted, [NSRunLoop currentRunLoop] is used.
**/
- (NSRunLoop *)onSocket:(AsyncSocket *)sock wantsRunLoopForNewSocket:(AsyncSocket *)newSocket;
/**
* Called when a socket is about to connect. This method should return YES to continue, or NO to abort.
* If aborted, will result in AsyncSocketCanceledError.
*
* If the connectToHost:onPort:error: method was called, the delegate will be able to access and configure the
* CFReadStream and CFWriteStream as desired prior to connection.
*
* If the connectToAddress:error: method was called, the delegate will be able to access and configure the
* CFSocket and CFSocketNativeHandle (BSD socket) as desired prior to connection. You will be able to access and
* configure the CFReadStream and CFWriteStream in the onSocket:didConnectToHost:port: method.
**/
- (BOOL)onSocketWillConnect:(AsyncSocket *)sock;
/**
* Called when a read stream is closed. This method should return YES, if you
* want to close the socket of the stream, or NO then the socket won't be closed.
* This was added for the workaround to solve the issue of firefox and os-x finder,
* which seem to close a read stream for ftp's list command.
* 'iosftpserver' returns YES only when the socket is for FTP::STORE command.
**/
- (BOOL)onReadStreamEnded:(AsyncSocket *)sock;
/**
* Called when a socket connects and is ready for reading and writing.
* The host parameter will be an IP address, not a DNS name.
**/
- (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port;
/**
* Called when a socket has completed reading the requested data into memory.
* Not called if there is an error.
**/
- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag;
/**
* Called when a socket has read in data, but has not yet completed the read.
* This would occur if using readToData: or readToLength: methods.
* It may be used to for things such as updating progress bars.
**/
- (void)onSocket:(AsyncSocket *)sock didReadPartialDataOfLength:(CFIndex)partialLength tag:(long)tag;
/**
* Called when a socket has completed writing the requested data. Not called if there is an error.
**/
- (void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag;
@end
@interface AsyncSocket : NSObject
{
CFSocketRef theSocket; // IPv4 accept or connect socket
CFSocketRef theSocket6; // IPv6 accept or connect socket
CFReadStreamRef theReadStream;
CFWriteStreamRef theWriteStream;
CFRunLoopSourceRef theSource; // For theSocket
CFRunLoopSourceRef theSource6; // For theSocket6
CFRunLoopRef theRunLoop;
CFSocketContext theContext;
NSMutableArray *theReadQueue;
AsyncReadPacket *theCurrentRead;
NSTimer *theReadTimer;
NSMutableData *partialReadBuffer;
NSMutableArray *theWriteQueue;
AsyncWritePacket *theCurrentWrite;
NSTimer *theWriteTimer;
id theDelegate;
Byte theFlags;
long theUserData;
}
- (id)init;
- (id)initWithDelegate:(id)delegate;
- (id)initWithDelegate:(id)delegate userData:(long)userData;
/* String representation is long but has no "\n". */
- (NSString *)description;
/**
* Use "canSafelySetDelegate" to see if there is any pending business (reads and writes) with the current delegate
* before changing it. It is, of course, safe to change the delegate before connecting or accepting connections.
**/
- (id)delegate;
- (BOOL)canSafelySetDelegate;
- (void)setDelegate:(id)delegate;
/* User data can be a long, or an id or void * cast to a long. */
- (long)userData;
- (void)setUserData:(long)userData;
/* Don't use these to read or write. And don't close them, either! */
- (CFSocketRef)getCFSocket;
- (CFReadStreamRef)getCFReadStream;
- (CFWriteStreamRef)getCFWriteStream;
/**
* Once one of these methods is called, the AsyncSocket instance is locked in, and the rest can't be called without
* disconnecting the socket first. If the attempt times out or fails, these methods either return NO or
* call "onSocket:willDisconnectWithError:" and "onSockedDidDisconnect:".
**/
- (BOOL)acceptOnPort:(UInt16)port error:(NSError **)errPtr;
- (BOOL)acceptOnAddress:(NSString *)hostaddr port:(UInt16)port error:(NSError **)errPtr;
- (BOOL)connectToHost:(NSString *)hostname onPort:(UInt16)port error:(NSError **)errPtr;
- (BOOL)connectToAddress:(NSData *)remoteAddr error:(NSError **)errPtr;
/**
* Disconnects immediately. Any pending reads or writes are dropped.
**/
- (void)disconnect;
/**
* Disconnects after all pending writes have completed.
* After calling this, the read and write methods (including "readDataWithTimeout:tag:") will do nothing.
* The socket will disconnect even if there are still pending reads.
**/
- (void)disconnectAfterWriting;
/* Returns YES if the socket and streams are open, connected, and ready for reading and writing. */
- (BOOL)isConnected;
/**
* Returns the local or remote host and port to which this socket is connected, or nil and 0 if not connected.
* The host will be an IP address.
**/
- (NSString *)connectedHost;
- (UInt16)connectedPort;
- (NSString *)localHost;
- (UInt16)localPort;
- (BOOL)isIPv4;
- (BOOL)isIPv6;
// The readData and writeData methods won't block. To not time out, use a negative time interval.
// If they time out, "onSocket:disconnectWithError:" is called. The tag is for your convenience.
// You can use it as an array index, step number, state id, pointer, etc., just like the socket's user data.
/**
* This will read a certain number of bytes into memory, and call the delegate method when those bytes have been read.
* If there is an error, partially read data is lost.
* If the length is 0, this method does nothing and the delegate is not called.
**/
- (void)readDataToLength:(CFIndex)length withTimeout:(NSTimeInterval)timeout tag:(long)tag;
/**
* This reads bytes until (and including) the passed "data" parameter, which acts as a separator.
* The bytes and the separator are returned by the delegate method.
*
* If you pass nil or zero-length data as the "data" parameter,
* the method will do nothing, and the delegate will not be called.
*
* To read a line from the socket, use the line separator (e.g. CRLF for HTTP, see below) as the "data" parameter.
* Note that this method is not character-set aware, so if a separator can occur naturally as part of the encoding for
* a character, the read will prematurely end.
**/
- (void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag;
/**
* Same as readDataToData:withTimeout:tag, with the additional restriction that the amount of data read
* may not surpass the given maxLength (specified in bytes).
*
* If you pass a maxLength parameter that is less than the length of the data parameter,
* the method will do nothing, and the delegate will not be called.
*
* If the max length is surpassed, it is treated the same as a timeout - the socket is closed.
*
* Pass -1 as maxLength if no length restriction is desired, or simply use the readDataToData:withTimeout:tag method.
**/
- (void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout maxLength:(CFIndex)length tag:(long)tag;
/**
* Reads the first available bytes that become available on the socket.
**/
- (void)readDataWithTimeout:(NSTimeInterval)timeout tag:(long)tag;
/* Writes data to the socket, and calls the delegate when finished.
*
* If you pass in nil or zero-length data, this method does nothing and the delegate will not be called.
**/
- (void)writeData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag;
/**
* Returns progress of current read or write, from 0.0 to 1.0, or NaN if no read/write (use isnan() to check).
* "tag", "done" and "total" will be filled in if they aren't NULL.
**/
- (float)progressOfReadReturningTag:(long *)tag bytesDone:(CFIndex *)done total:(CFIndex *)total;
- (float)progressOfWriteReturningTag:(long *)tag bytesDone:(CFIndex *)done total:(CFIndex *)total;
/**
* For handling readDataToData requests, data is necessarily read from the socket in small increments.
* The performance can be improved by allowing AsyncSocket to read larger chunks at a time and
* store any overflow in a small internal buffer.
* This is termed pre-buffering, as some data may be read for you before you ask for it.
* If you use readDataToData a lot, enabling pre-buffering may offer a small performance improvement.
*
* Pre-buffering is disabled by default. You must explicitly enable it to turn it on.
*
* Note: If your protocol negotiates upgrades to TLS (as opposed to using TLS from the start), you should
* consider how, if at all, pre-buffering could affect the TLS negotiation sequence.
* This is because TLS runs atop TCP, and requires sending/receiving a TLS handshake over the TCP socket.
* If the negotiation sequence is poorly designed, pre-buffering could potentially pre-read part of the TLS handshake,
* thus causing TLS to fail. In almost all cases, especially when implementing a formalized protocol, this will never
* be a hazard.
**/
- (void)enablePreBuffering;
/**
* In the event of an error, this method may be called during onSocket:willDisconnectWithError: to read
* any data that's left on the socket.
**/
- (NSData *)unreadData;
/* A few common line separators, for use with "readDataToData:withTimeout:tag:". */
+ (NSData *)CRLFData; // 0x0D0A
+ (NSData *)CRData; // 0x0D
+ (NSData *)LFData; // 0x0A
+ (NSData *)ZeroData; // 0x00
@end

File diff suppressed because it is too large Load Diff

View File

@@ -1,129 +0,0 @@
/*
iosFtpServer
Copyright (C) 2008 Richard Dearlove ( monsta )
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#import <UIKit/UIKit.h>
#import "AsyncSocket.h"
#import "FtpDataConnection.h"
#import "FtpDefines.h"
#include <sys/time.h>
#include <time.h>
@class FtpServer;
@interface FtpConnection : NSObject {
AsyncSocket *connectionSocket; // Socket for this particular connection
FtpServer *server; // pointer to Server object
AsyncSocket *dataListeningSocket; // Socket to listen for a data connection to spawn on <-- think this is now redundant
AsyncSocket *dataSocket; // duplicates the listening socket - remove listening socket from code when working - which seems to be the case.
FtpDataConnection *dataConnection; // instance handling spawned data connection socket
NSArray *msgComponents; // The Message rcvd broken into an array
UInt16 dataPort;
int transferMode;
NSMutableArray *queuedData;
NSString *currentUser; // The current user for this connection
NSString *currentDir; // The current directory for this connection
NSString *currentFile; // File that is about to be uploaded
NSFileHandle *currentFileHandle; // File handle of what to save
NSString *rnfrFilename; // rnfr
}
-(id)initWithAsyncSocket:(AsyncSocket*)newSocket forServer:(id)myServer ;
#pragma mark STATE
@property(readwrite)int transferMode;
@property(readwrite, retain ) NSString *currentFile;
@property(readwrite, retain ) NSString *currentDir;
@property(readwrite, retain ) NSString *rnfrFilename;
-(NSString*)connectionAddress;
#pragma mark ASYNCSOCKET DATACONN
-(BOOL)openDataSocket:(int)portNumber;
-(int)choosePasvDataPort;
-(BOOL)onSocketWillConnect:(AsyncSocket *)sock;
-(void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket;
#pragma mark ASYNCSOCKET FTPCLIENT CONNECTION
-(void)onSocket:(AsyncSocket*)sock didReadData:(NSData*)data withTag:(long)tag;
-(void)onSocket:(AsyncSocket*)sock didWriteDataWithTag:(long)tag;
-(void)sendMessage:(NSString*)ftpMessage; // calls FC writedata
-(void)sendDataString:(NSString*)dataString; // calls FDC writedata
-(void)sendData:(NSMutableData*)data;
-(void)didReceiveDataWritten; // notification that FDC wrote data
-(void)didReceiveDataRead; // notification that FDC read data ie a transfer
-(void)didFinishReading; // Called at the closing == end of a data connection from the client we presume
#pragma mark PROCESS
-(void)processDataRead:(NSData*)data;
-(void)processCommand;
#pragma mark COMMANDS
-(void)doQuit:(id)sender arguments:(NSArray*)arguments;
-(void)doUser:(id)sender arguments:(NSArray*)arguments;
-(void)doPass:(id)sender arguments:(NSArray*)arguments;
-(void)doStat:(id)sender arguments:(NSArray*)arguments;
-(void)doFeat:(id)sender arguments:(NSArray*)arguments;
-(void)doList:(id)sender arguments:(NSArray*)arguments;
-(void)doPwd:(id)sender arguments:(NSArray*)arguments;
-(void)doNoop:(id)sender arguments:(NSArray*)arguments;
-(void)doSyst:(id)sender arguments:(NSArray*)arguments;
-(void)doLprt:(id)sender arguments:(NSArray*)arguments;
-(void)doPasv:(id)sender arguments:(NSArray*)arguments;
-(void)doEpsv:(id)sender arguments:(NSArray*)arguments;
-(void)doPort:(id)sender arguments:(NSArray*)arguments;
-(void)doNlst:(id)sender arguments:(NSArray*)arguments;
-(void)doStor:(id)sender arguments:(NSArray*)arguments;
-(void)doRetr:(id)sender arguments:(NSArray*)arguments;
-(void)doDele:(id)sender arguments:(NSArray*)arguments;
-(void)doMlst:(id)sender arguments:(NSArray*)arguments;
-(void)doSize:(id)sender arguments:(NSArray*)arguments;
-(void)doMkdir:(id)sender arguments:(NSArray*)arguments;
-(void)doCdUp:(id)sender arguments:(NSArray*)arguments;
-(void)doRnfr:(id)sender arguments:(NSArray*)arguments;
-(void)doRnto:(id)sender arguments:(NSArray*)arguments;
#pragma mark UTITILITES
-(NSString*)makeFilePathFrom:(NSString*)filename;
-(unsigned long long)fileSize:(NSString*)filePath;
-(NSString*)fileNameFromArgs:(NSArray*)arguments;
- (Boolean)changedCurrentDirectoryTo:(NSString *)newDirectory;
-(Boolean)canChangeDirectoryTo:(NSString *)testDirectory;
- (Boolean)accessibleFilePath:(NSString*)filePath; // check filepath exists and is in basedir ( if set )
- (Boolean)validNewFilePath:(NSString*)filePath;
- (NSString *)visibleCurrentDir;
-(NSString *)rootedPath:(NSString*)path;
@end

File diff suppressed because it is too large Load Diff

View File

@@ -1,54 +0,0 @@
/*
iosFtpServer
Copyright (C) 2008 Richard Dearlove ( monsta )
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#import <UIKit/UIKit.h>
#import "AsyncSocket.h"
#import "FtpDefines.h"
@class FtpConnection;
@interface FtpDataConnection : NSObject {
AsyncSocket *dataSocket;
FtpConnection *ftpConnection; // connection which generated data socket we are tied to
AsyncSocket *dataListeningSocket;
id dataConnection;
NSMutableData *receivedData;
int connectionState;
}
-(id)initWithAsyncSocket:(AsyncSocket*)newSocket forConnection:(id)aConnection withQueuedData:(NSMutableArray*)queuedData;
-(void)writeString:(NSString*)dataString;
-(void)writeData:(NSMutableData*)data;
-(void)writeQueuedData:(NSMutableArray*)queuedData;
-(void)closeConnection;
#pragma mark ASYNCSOCKET DELEGATES
-(BOOL)onSocketWillConnect:(AsyncSocket *)sock;
-(void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket;
-(void)onSocket:(AsyncSocket*)sock didReadData:(NSData*)data withTag:(long)tag;
-(void)onSocket:(AsyncSocket*)sock didWriteDataWithTag:(long)tag;
-(void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err;
@property (readonly) NSMutableData *receivedData;
@property (readwrite) int connectionState;
@end

View File

@@ -1,192 +0,0 @@
/*
iosFtpServer
Copyright (C) 2008 Richard Dearlove ( monsta )
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#import "FtpDataConnection.h"
#import "FtpConnection.h"
@implementation FtpDataConnection
@synthesize receivedData;
@synthesize connectionState;
// ----------------------------------------------------------------------------------------------------------
-(id)initWithAsyncSocket:(AsyncSocket*)newSocket forConnection:(id)aConnection withQueuedData:(NSMutableArray*)queuedData
// ----------------------------------------------------------------------------------------------------------
{
self = [super init ];
if (self)
{
dataSocket = [newSocket retain ]; // Hang onto the socket that was generated - the FDC is retained by FC
ftpConnection = aConnection;
[ dataSocket setDelegate:self ];
if ( [queuedData count ] )
{
NSLog(@"FC:Write Queued Data");
[self writeQueuedData:queuedData ];
[ queuedData removeAllObjects ]; // Clear out queue
}
// [ dataSocket readDataToData:[AsyncSocket CRLFData] withTimeout:READ_TIMEOUT tag:FTP_CLIENT_REQUEST ];
[ dataSocket readDataWithTimeout:READ_TIMEOUT tag:FTP_CLIENT_REQUEST ];
dataListeningSocket = nil;
receivedData = nil; // [[ NSMutableData alloc ] init ] 12/nov/08 - no need for this. rcd is just a pointer
connectionState = clientQuiet; // Nothing coming through
}
return self;
}
// ----------------------------------------------------------------------------------------------------------
-(void)dealloc
// ----------------------------------------------------------------------------------------------------------
{
[dataSocket release];
[dataListeningSocket release];
[dataConnection release];
// [receivedData release];
[super dealloc];
}
// ----------------------------------------------------------------------------------------------------------
-(void)writeString:(NSString*)dataString
// ----------------------------------------------------------------------------------------------------------
{
NSLog(@"FDC:writeStringData");
NSMutableData *data = [[ dataString dataUsingEncoding:NSUTF8StringEncoding ] mutableCopy]; // Autoreleased
[ data appendData:[AsyncSocket CRLFData] ];
[ dataSocket writeData:data withTimeout:READ_TIMEOUT tag:FTP_CLIENT_REQUEST ];
[ dataSocket readDataWithTimeout:READ_TIMEOUT tag:FTP_CLIENT_REQUEST ];
}
// ----------------------------------------------------------------------------------------------------------
-(void)writeData:(NSMutableData*)data
// ----------------------------------------------------------------------------------------------------------
{
NSLog(@"FDC:writeData");
// [ data appendData:[AsyncSocket CRLFData] ]; // Add on CRLF to end of data - as Windows Explorer needs it
connectionState = clientReceiving; // We hope
[ dataSocket writeData:data withTimeout:READ_TIMEOUT tag:FTP_CLIENT_REQUEST ];
[ dataSocket readDataWithTimeout:READ_TIMEOUT tag:FTP_CLIENT_REQUEST ];
}
// ----------------------------------------------------------------------------------------------------------
-(void)writeQueuedData:(NSMutableArray*)queuedData
// ----------------------------------------------------------------------------------------------------------
{
for (NSMutableData* data in queuedData) {
[self writeData:data ];
}
}
// ----------------------------------------------------------------------------------------------------------
-(void)closeConnection
// ----------------------------------------------------------------------------------------------------------
{
NSLog(@"FDC:closeConnection");
[ dataSocket disconnect ];
}
#pragma mark ASYNCSOCKET DELEGATES
// ----------------------------------------------------------------------------------------------------------
-(BOOL)onSocketWillConnect:(AsyncSocket *)sock
// ----------------------------------------------------------------------------------------------------------
{
NSLog(@"FDC:onSocketWillConnect");
[ dataSocket readDataWithTimeout:READ_TIMEOUT tag:0 ];
return YES;
}
// ----------------------------------------------------------------------------------------------------------
-(void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket
// ----------------------------------------------------------------------------------------------------------
{
// This shouldnt happen - we should be connected already - and havent set up a listening socket
NSLog(@"FDC:New Connection -- shouldn't be called");
}
// ----------------------------------------------------------------------------------------------------------
-(void)onSocket:(AsyncSocket*)sock didReadData:(NSData*)data withTag:(long)tag
// ----------------------------------------------------------------------------------------------------------
{
NSLog(@"FDC:didReadData");
// [ dataSocket readDataToData:[AsyncSocket CRLFData] withTimeout:READ_TIMEOUT tag:FTP_CLIENT_REQUEST ]; // continue reading
[ dataSocket readDataWithTimeout:READ_TIMEOUT tag:FTP_CLIENT_REQUEST ];
NSMutableData *mutdata = [data mutableCopy];
receivedData = [ mutdata retain]; // make autoreleased copy of data
// notify connection data came through, ( will write data for us )
[ftpConnection didReceiveDataRead ]; // notify, the connection, so it knows to write the data
[ receivedData release ]; // let go, not our business anymore
connectionState = clientSent;
}
// ----------------------------------------------------------------------------------------------------------
-(void)onSocket:(AsyncSocket*)sock didWriteDataWithTag:(long)tag
// ----------------------------------------------------------------------------------------------------------
{
NSLog(@"FDC:didWriteData");
[ ftpConnection didReceiveDataWritten ]; // notify that we are finished writing
// [ dataSocket readDataToData:[AsyncSocket CRLFData] withTimeout:READ_TIMEOUT tag:FTP_CLIENT_REQUEST ]; // continue reading
[ dataSocket readDataWithTimeout:READ_TIMEOUT tag:FTP_CLIENT_REQUEST ];
}
// ----------------------------------------------------------------------------------------------------------
-(void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err
// ----------------------------------------------------------------------------------------------------------
{
NSLog(@"FDC:willDisconnect");
// if we were writing and there's no error, then it must be the end of file
if ( connectionState == clientSending )
{
NSLog(@"FDC::did FinishReading");
// hopefully this is the end of the connection. not sure how we can tell
}
else
{
NSLog(@"FDC: we werent expecting this as we never set clientSending prob late coming up");
}
[ ftpConnection didFinishReading ]; // its over, please send the message
}
- (BOOL)onReadStreamEnded:(AsyncSocket*)sock
{
NSLog( @"FDC: onReadStreamEnded %d(clientSending is %d)", connectionState, clientSending );
if ( connectionState == clientSent ||
connectionState == clientSending ) return YES;
return NO;
}
@end

View File

@@ -1,15 +0,0 @@
enum {
pasvftp=0,epsvftp,portftp,lprtftp, eprtftp
};
#define DATASTR(args) [ args dataUsingEncoding:NSUTF8StringEncoding ]
#define SERVER_PORT 20000
#define READ_TIMEOUT -1
#define FTP_CLIENT_REQUEST 0
enum {
clientSending=0, clientReceiving=1, clientQuiet=2,clientSent=3
};

View File

@@ -1,72 +0,0 @@
/*
iosFtpServer
Copyright (C) 2008 Richard Dearlove ( monsta )
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#import <UIKit/UIKit.h>
#import "AsyncSocket.h"
#import "FtpDefines.h"
#import "FtpConnection.h"
#import "list.h"
@interface FtpServer : NSObject {
AsyncSocket *listenSocket;
NSMutableArray *connectedSockets;
id server;
id notificationObject;
int portNumber;
id delegate;
NSMutableArray *connections;
NSDictionary *commands;
NSString *baseDir;
Boolean changeRoot; // Change root to virtual root ( basedir )
int clientEncoding; // FTP client encoding type
}
- (id)initWithPort:(unsigned)serverPort withDir:(NSString *)aDirectory notifyObject:(id)sender;
- (void)stopFtpServer;
#pragma mark ASYNCSOCKET DELEGATES
- (void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket;
- (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port;
#pragma mark NOTIFICATIONS
- (void)didReceiveFileListChanged;
#pragma mark CONNECTIONS
- (void)closeConnection:(id)theConnection;
- (NSString *)createList:(NSString *)directoryPath;
@property (readwrite, retain) AsyncSocket *listenSocket;
@property (readwrite, retain) NSMutableArray *connectedSockets;
@property (readwrite, retain) id server;
@property (readwrite, retain) id notificationObject;
@property (readwrite) int portNumber;
@property (readwrite, retain) id delegate;
@property (readwrite, retain) NSMutableArray *connections;
@property (readwrite, retain) NSDictionary *commands;
@property (readwrite, retain) NSString *baseDir;
@property (readwrite) Boolean changeRoot;
@property (readwrite) int clientEncoding;
@end

View File

@@ -1,198 +0,0 @@
/*
iosFtpServer
Copyright (C) 2008 Richard Dearlove ( monsta )
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
// 11/02/08 changes to made to allow stopping of the server. Also added a bit of code to show users IP address.
// Cleaned up the code to make the retains and releases a bit more obvious... mostly programming style preferences.
// Added a stop Ftp server method to be called from where ever it was start. See iphoneLibTestViewController.m to see how I was calling it.
// Most users wouldn't want the server to continue to run once the transfers are done.
#import "FtpServer.h"
@implementation FtpServer
@synthesize listenSocket, connectedSockets, server, notificationObject, portNumber, delegate, commands, baseDir, connections;
@synthesize clientEncoding;
@synthesize changeRoot;
// ----------------------------------------------------------------------------------------------------------
- (id)initWithPort:(unsigned)serverPort withDir:(NSString*)aDirectory notifyObject:(id)sender
// ----------------------------------------------------------------------------------------------------------
{
if( self = [super init] ) {
NSError *error = nil;
self.notificationObject = sender;
// Load up commands
NSString *plistPath = [[ NSBundle mainBundle ] pathForResource:@"ftp_commands" ofType:@"plist"];
if ( ! [ [ NSFileManager defaultManager ] fileExistsAtPath:plistPath ] )
{
NSLog(@"ftp_commands.plist missing");
}
commands = [ [ NSDictionary alloc ] initWithContentsOfFile:plistPath];
// Clear out connections list
NSMutableArray *myConnections = [[NSMutableArray alloc] init];
self.connections = myConnections;
[myConnections release];
// Create a socket
self.portNumber = serverPort;
AsyncSocket *myListenSocket = [[AsyncSocket alloc] initWithDelegate:self];
self.listenSocket = myListenSocket;
[myListenSocket release];
NSLog(@"Listening on %u", portNumber);
[listenSocket acceptOnPort:serverPort error:&error]; // start lisetning on this port.
NSMutableArray *myConnectedSockets = [[NSMutableArray alloc] initWithCapacity:1];
self.connectedSockets = myConnectedSockets;
[myConnectedSockets release];
// Set directory - have to do this because on iphone, some directories arent what they report back as, so need real path it resolves to, CHECKME - might be an easier way
NSFileManager *fileManager = [ NSFileManager defaultManager ];
NSString *expandedPath = [ aDirectory stringByStandardizingPath ];
// CHANGE TO NEW DIRECTORY & GET SYSTEM FILE PATH ( no .. etc )
if ([ fileManager changeCurrentDirectoryPath:expandedPath ]) // try changing to directory
{
self.baseDir = [[ fileManager currentDirectoryPath ] copy] ; // Gets the real path. CHECKME.
// self.baseDir = @"/Users"; // REMOVEME - added for testing 7/6/10
}
else
{
self.baseDir = aDirectory; // shouldnt get to this line really
}
self.changeRoot = false; // true if you want them to be sandboxed/chrooted into the basedir
// the default client encoding is UTF8
self.clientEncoding = NSUTF8StringEncoding;
}
return self;
}
// ----------------------------------------------------------------------------------------------------------
-(void)stopFtpServer
// ----------------------------------------------------------------------------------------------------------
{
if(listenSocket)[listenSocket disconnect];
[connectedSockets removeAllObjects];
[connections removeAllObjects];
}
#pragma mark ASYNCSOCKET DELEGATES
// ----------------------------------------------------------------------------------------------------------
- (void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket
// ----------------------------------------------------------------------------------------------------------
{
FtpConnection *newConnection = [[[ FtpConnection alloc ] initWithAsyncSocket:newSocket forServer:self] autorelease]; // Create an ftp connection
[ connections addObject:newConnection ]; // Add this to our list of connections
NSLog(@"FS:didAcceptNewSocket port:%i", [sock localPort]);
if ([sock localPort] == portNumber )
{
NSLog(@"Connection on Server Port");
}
else
{
// must be a data comms port
// spawn a data comms port
// look for the connection with the same port
// and attach it
NSLog(@"--ERROR %i, %i", [sock localPort],portNumber);
}
}
// ----------------------------------------------------------------------------------------------------------
- (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port
// ----------------------------------------------------------------------------------------------------------
{
NSLog(@"FtpServer:didConnectToHost port:%i", [sock localPort]);
}
#pragma mark NOTIFICATIONS
// ----------------------------------------------------------------------------------------------------------
-(void)didReceiveFileListChanged
// ----------------------------------------------------------------------------------------------------------
{
if ([notificationObject respondsToSelector:@selector(didReceiveFileListChanged)])
[notificationObject didReceiveFileListChanged ];
}
#pragma mark CONNECTIONS
// ----------------------------------------------------------------------------------------------------------
- (void)closeConnection:(id)theConnection
// ----------------------------------------------------------------------------------------------------------
{
// Search through connections for this one - and delete
// this should release it - and delloc
[connections removeObject:theConnection ];
}
// ----------------------------------------------------------------------------------------------------------
-(NSString*)createList:(NSString*)directoryPath
// ----------------------------------------------------------------------------------------------------------
{
return createList(directoryPath);
}
// ----------------------------------------------------------------------------------------------------------
- (void)dealloc
// ----------------------------------------------------------------------------------------------------------
{
if(listenSocket)
{
[listenSocket disconnect];
[listenSocket release];
}
[connectedSockets release];
[notificationObject release];
[connections release];
[commands release];
[baseDir release];
[super dealloc];
}
@end

View File

@@ -1,26 +0,0 @@
//
// networkController.h
// DiddyDJ
//
// Created by Richard Dearlove on 21/10/2008.
// Copyright 2008 DiddySoft. All rights reserved.
//
#import <UIKit/UIKit.h>
#import <SystemConfiguration/SystemConfiguration.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <ifaddrs.h>
@interface NetworkController : NSObject {
}
+ (NSString *)localWifiIPAddress;
+ (NSString *) localIPAddress;
+ (BOOL)addressFromString:(NSString *)IPAddress address:(struct sockaddr_in *)address;
+ (NSString *) getIPAddressForHost: (NSString *) theHost;
+ (BOOL) hostAvailable: (NSString *) theHost;
+ (BOOL) connectedToNetwork;
@end

View File

@@ -1,184 +0,0 @@
//
// networkController.m
//
// Created by Richard Dearlove on 21/10/2008.
// Copyright 2008 DiddySoft. All rights reserved.
//
#import "NetworkController.h"
@implementation NetworkController
// Return the localized IP address
// ----------------------------------------------------------------------------------------------------------
+ (NSString *)localWifiIPAddress
// ----------------------------------------------------------------------------------------------------------
{
NSString *address = @"error";
struct ifaddrs *interfaces = NULL;
struct ifaddrs *temp_addr = NULL;
int success = 0;
// retrieve the current interfaces - returns 0 on success
success = getifaddrs(&interfaces);
if (success == 0)
{
// Loop through linked list of interfaces
temp_addr = interfaces;
while(temp_addr != NULL)
{
if(temp_addr->ifa_addr->sa_family == AF_INET)
{
// Check if interface is en0 which is the wifi connection on the iPhone
if([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"])
{
// Get NSString from C String
address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
}
}
temp_addr = temp_addr->ifa_next;
}
}
// Free memory
freeifaddrs(interfaces);
return address;
}
// ----------------------------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------------------------
+ (NSString *) localIPAddress
// ----------------------------------------------------------------------------------------------------------
{
char baseHostName[255];
gethostname(baseHostName, 255);
// Adjust for iPhone -- add .local to the host name
char hn[255];
sprintf(hn, "%s.local", baseHostName);
struct hostent *host = gethostbyname(hn);
if (host == NULL)
{
herror("resolv");
return NULL;
}
else {
struct in_addr **list = (struct in_addr **)host->h_addr_list;
return [NSString stringWithCString:inet_ntoa(*list[0])];
}
return NULL;
}
// ----------------------------------------------------------------------------------------------------------
+ (BOOL)addressFromString:(NSString *)IPAddress address:(struct sockaddr_in *)address
// ----------------------------------------------------------------------------------------------------------
{
if (!IPAddress || ![IPAddress length]) {
return NO;
}
memset((char *) address, sizeof(struct sockaddr_in), 0);
address->sin_family = AF_INET;
address->sin_len = sizeof(struct sockaddr_in);
int conversionResult = inet_aton([IPAddress UTF8String], &address->sin_addr);
if (conversionResult == 0) {
NSAssert1(conversionResult != 1, @"Failed to convert the IP address string into a sockaddr_in: %@", IPAddress);
return NO;
}
return YES;
}
// ----------------------------------------------------------------------------------------------------------
+ (NSString *) getIPAddressForHost: (NSString *) theHost
// ----------------------------------------------------------------------------------------------------------
{
struct hostent *host = gethostbyname([theHost UTF8String]);
if (host == NULL) {
herror("resolv");
return NULL;
}
struct in_addr **list = (struct in_addr **)host->h_addr_list;
NSString *addressString = [NSString stringWithCString:inet_ntoa(*list[0])];
return addressString;
}
// ----------------------------------------------------------------------------------------------------------
+ (BOOL) hostAvailable: (NSString *) theHost
// ----------------------------------------------------------------------------------------------------------
{
NSString *addressString = [self getIPAddressForHost:theHost];
if (!addressString)
{
printf("Error recovering IP address from host name\n");
return NO;
}
struct sockaddr_in address;
BOOL gotAddress = [self addressFromString:addressString address:&address];
if (!gotAddress)
{
printf("Error recovering sockaddr address from %s\n", [addressString UTF8String]);
return NO;
}
SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&address);
SCNetworkReachabilityFlags flags;
BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);
CFRelease(defaultRouteReachability);
if (!didRetrieveFlags)
{
printf("Error. Could not recover network reachability flags\n");
return NO;
}
BOOL isReachable = flags & kSCNetworkFlagsReachable;
return isReachable ? YES : NO;;
}
// ----------------------------------------------------------------------------------------------------------
+ (BOOL) connectedToNetwork
// ----------------------------------------------------------------------------------------------------------
{
// Create zero addy
struct sockaddr_in zeroAddress;
bzero(&zeroAddress, sizeof(zeroAddress));
zeroAddress.sin_len = sizeof(zeroAddress);
zeroAddress.sin_family = AF_INET;
// Recover reachability flags
SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress);
CFRelease(defaultRouteReachability);
SCNetworkReachabilityFlags flags;
BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);
if (!didRetrieveFlags)
{
printf("Error. Could not recover network reachability flags\n");
return 0;
}
BOOL isReachable = flags & kSCNetworkFlagsReachable;
BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired;
// BOOL isEDGE = flags & kSCNetworkReachabilityFlagsIsWWAN;
return (isReachable && !needsConnection) ? YES : NO;
}
@end

View File

@@ -1,64 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>ack</key>
<string>doAck:</string>
<key>cdup</key>
<string>doCdUp:</string>
<key>cwd</key>
<string>doCwd:</string>
<key>dele</key>
<string>doDele:</string>
<key>eprt</key>
<string>doEprt:</string>
<key>epsv</key>
<string>doEpsv:</string>
<key>feat</key>
<string>doFeat:</string>
<key>list</key>
<string>doList:</string>
<key>lprt</key>
<string>doLprt:</string>
<key>mkd</key>
<string>doMkdir:</string>
<key>mlst</key>
<string>doMlst:</string>
<key>nlst</key>
<string>doList:</string>
<key>noop</key>
<string>doNoop:</string>
<key>opts</key>
<string>doOpts:</string>
<key>pass</key>
<string>doPass:</string>
<key>pasv</key>
<string>doPasv:</string>
<key>port</key>
<string>doPort:</string>
<key>pwd</key>
<string>doPwd:</string>
<key>quit</key>
<string>doQuit:</string>
<key>retr</key>
<string>doRetr:</string>
<key>rmd</key>
<string>doDele:</string>
<key>rnfr</key>
<string>doRnfr:</string>
<key>rnto</key>
<string>doRnto:</string>
<key>size</key>
<string>doSize:</string>
<key>stat</key>
<string>doStat:</string>
<key>stor</key>
<string>doStor:</string>
<key>syst</key>
<string>doSyst:</string>
<key>type</key>
<string>doType:</string>
<key>user</key>
<string>doUser:</string>
</dict>
</plist>

View File

@@ -17,7 +17,6 @@
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import "FtpServer.h"
#include <sys/stat.h>
#include "dlfcn.h"
@@ -78,36 +77,22 @@ const char *IOS_GetDocsDir(void)
}
}
UIBackgroundTaskIdentifier task;
FtpServer *server = NULL;
void IOS_StartBackgroundTask(void)
const char *IOS_GetExecDir(void)
{
if( !server ) return;
if( task != UIBackgroundTaskInvalid )
return;
UIApplication* app = [UIApplication sharedApplication];
static const char *dir = NULL;
task = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:task];
task = UIBackgroundTaskInvalid;
}];
if( dir )
return dir;
// Start the long-running task and return immediately.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UIBackgroundTaskIdentifier local = task;
// do not keep "zombie" tasks
while( 1 )
sleep(1);
NSString *executableDirctory = [[NSBundle mainBundle] bundlePath];
[app endBackgroundTask:local];
task = UIBackgroundTaskInvalid;
});
dir = [executableDirctory fileSystemRepresentation];
NSLog(@"IOS_GetDocsDir: %s", dir);
return dir;
}
#define SETTINGS_MAGIC 111
typedef struct settings_s
@@ -188,8 +173,6 @@ void IOS_LaunchDialog( void )
UIScrollView *scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 300, 200)];
UISwitch *ftpswitch = [[UISwitch alloc] initWithFrame:CGRectMake(210,60,80,30)];
UILabel *argstitle = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 300, 30)];
[argstitle setText:@"Command-line arguments:"];
@@ -197,12 +180,6 @@ void IOS_LaunchDialog( void )
[args setBackgroundColor:[[UIColor alloc] initWithRed:1 green:1 blue:1 alpha:1]];
if(isdark) [args setBackgroundColor:[[UIColor alloc] initWithRed:0 green:0 blue:0 alpha:1]];
UILabel *ftptitle = [[UILabel alloc] initWithFrame:CGRectMake(0, 60, 200, 30)];
[ftptitle setText:@"FTP Server"];
UITextField *port = [[UITextField alloc] initWithFrame:CGRectMake(110, 60, 100, 30)];
UITextField *suffix = [[UITextField alloc] initWithFrame:CGRectMake(140, 90, 160, 30 )];
[suffix setBackgroundColor:[[UIColor alloc] initWithRed:1 green:1 blue:1 alpha:1]];
@@ -214,9 +191,6 @@ void IOS_LaunchDialog( void )
[scroll addSubview:argstitle];
[scroll addSubview:args];
[scroll addSubview:suffix];
[scroll addSubview:ftpswitch];
[scroll addSubview:ftptitle];
[scroll addSubview:port];
[scroll addSubview:suffixtitle];
settingsfile = fopen( settingspath, "rb" );
@@ -225,14 +199,11 @@ void IOS_LaunchDialog( void )
settings.args[1023] = 0;
settings.suffix[31] = 0;
[args setText:@(settings.args)];
[port setText:[NSString stringWithFormat:@"%u", settings.port]];
[suffix setText:@(settings.suffix)];
ftpswitch.on = settings.ftpserver;
}
else
{
[args setText:@"-dev 2 -log"];
[port setText:@"21135"];
}
scroll.contentSize=CGSizeMake(250, 200);
@@ -248,10 +219,8 @@ void IOS_LaunchDialog( void )
if( (settingsfile = fopen( settingspath, "wb" )) )
{
settings.ftpserver = ftpswitch.on;
strlcpy(settings.args, [args.text UTF8String], 1024);
strlcpy(settings.suffix, [suffix.text UTF8String], 32 );
settings.port = [port.text intValue];
settings.magic = 111;
fwrite(&settings, sizeof(settings), 1, settingsfile);
@@ -263,25 +232,6 @@ void IOS_LaunchDialog( void )
exit(0);
}
if( ftpswitch.on )
{
button = -1;
[[[UIAlertView alloc] initWithTitle:@"Xash3D" message:[NSString stringWithFormat:@"Started FTP server on port %@", port.text] delegate:delegate cancelButtonTitle:@"Ok" otherButtonTitles:nil] show];
server = [[ FtpServer alloc ] initWithPort:[port.text integerValue] withDir:@(docsDir) notifyObject:nil ];
IOS_StartBackgroundTask();
@autoreleasepool {
while( button == -1 ) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
IOS_StartBackgroundTask(); // keep running
}
}
}
NSArray *argv = [ args.text componentsSeparatedByString:@" " ];
int count = [argv count];
@@ -299,11 +249,8 @@ void IOS_LaunchDialog( void )
alert.delegate = nil;
[ftpswitch release];
[ftptitle release];
[args release];
[argstitle release];
[port release];
[suffix release];
[suffixtitle release];

View File

@@ -1,95 +0,0 @@
/*
ios_lib.c - dynamic library code for iOS
Copyright (C) 2017-2018 mittorn
This program is free software: you can redistribute it and/sor 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 <string.h>
#include <unistd.h>
#include <SDL.h>
#include <dlfcn.h>
#include <sys/stat.h>
#include "crtlib.h"
#include "library.h"
#include "platform/ios/lib_ios.h"
#include "common.h"
const char *g_szLibrarySuffix;
static void *IOS_LoadLibraryInternal( const char *dllname )
{
void *pHandle;
char path[MAX_SYSPATH];
Q_snprintf( path, sizeof( path ), "%s%s", SDL_GetBasePath(), dllname );
pHandle = dlopen( path, RTLD_LAZY );
if( !pHandle )
COM_PushLibraryError(dlerror( ));
return pHandle;
}
static qboolean IOS_LibraryExistsInternal( const char *name )
{
struct stat buf;
char path[MAX_SYSPATH];
Q_snprintf( path, sizeof( path ), "%s%s", SDL_GetBasePath(), name );
return stat( path, &buf ) == 0;
}
static const char *IOS_GetLibraryPostfix( void )
{
if( g_szLibrarySuffix )
return g_szLibrarySuffix;
return Q_strcmp( host.default_gamedir, FS_Gamedir( )) ? FS_Gamedir( ) : "";
}
static void IOS_PrepareGameLibraryPath( const char *dllname, char *out, size_t outsize )
{
string strippedname;
Q_strncpy( strippedname, dllname, sizeof( strippedname ));
COM_StripExtension( strippedname );
Q_snprintf( out, outsize, "%s_%s.dylib", strippedname, IOS_GetLibraryPostfix( ));
}
void *IOS_LoadLibrary( const char *dllname )
{
// filesystem_stdio is a special case, as engine won't work correctly without it
// but it's always located at known path
if( !Q_strcmp( dllname, "filesystem_stdio.dylib" ))
return IOS_LoadLibraryInternal( dllname );
string name;
char *pHandle;
IOS_PrepareGameLibraryPath( dllname, name, sizeof( name ));
pHandle = IOS_LoadLibraryInternal( name );
if( !pHandle )
pHandle = IOS_LoadLibraryInternal( dllname );
return pHandle;
}
qboolean IOS_LibraryExists( const char *dllname )
{
string name;
IOS_PrepareGameLibraryPath( dllname, name, sizeof( name ));
return IOS_LibraryExistsInternal( name ) || IOS_LibraryExistsInternal( dllname );
}

View File

@@ -1,26 +0,0 @@
/*
ios_lib.h - dynamic library code for iOS
Copyright (C) 2017-2018 mittorn
This program is free software: you can redistribute it and/sor modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#pragma once
#if TARGET_OS_IPHONE
#ifndef IOS_LIB_H
#define IOS_LIB_H
#define Platform_POSIX_LoadLibrary( x ) IOS_LoadLibrary(( x ))
void *IOS_LoadLibrary( const char *dllname );
qboolean IOS_LibraryExists( const char *name );
#endif // IOS_LIB_H
#endif // TARGET_OS_IPHONE

View File

@@ -1,29 +0,0 @@
/*
iosFtpServer
Copyright (C) 2008 Richard Dearlove ( monsta )
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#import <Foundation/Foundation.h>
#pragma mark LS replacement
NSString* createList(NSString* directoryPath);
#pragma mark Supporting Functions
int filesinDirectory(NSString* filePath );
NSMutableString* int2BinString(int x);
NSMutableString *byte2String(int x );
NSMutableString *bin2perms(NSString *binaryValue);

View File

@@ -1,202 +0,0 @@
/*
iosFtpServer
Copyright (C) 2008 Richard Dearlove ( monsta )
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#import "list.h"
// ----------------------------------------------------------------------------------------------------------
NSString* createList(NSString* directoryPath)
// ----------------------------------------------------------------------------------------------------------
{
NSFileManager *fileManager = [ NSFileManager defaultManager ];
NSDictionary *fileAttributes;
NSError *error;
NSString* fileType;
NSNumber* filePermissions;
long fileSubdirCount;
NSString* fileOwner;
NSString* fileGroup;
NSNumber* fileSize;
NSDate* fileModified;
NSString* fileDateFormatted;
NSDateFormatter* dateFormatter = [[[ NSDateFormatter alloc ] init ] autorelease ];
BOOL fileIsDirectory;
NSMutableString* returnString= [ NSMutableString new ];
NSString* formattedString;
NSString* binaryString;
[returnString appendString:@"\r\n"];
NSDirectoryEnumerator *dirEnum = [fileManager enumeratorAtPath:directoryPath];
NSString *filePath;
NSString* firstChar;
NSString* fullFilePath;
[dateFormatter setDateFormat:@"MMM dd HH:mm"];
NSLocale *englishLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en"];
[dateFormatter setLocale:englishLocale];
[englishLocale release];
NSLog(@"Get LS for %@", directoryPath );
int numberOfFiles = 0;
while (filePath = [dirEnum nextObject]) {
firstChar = [ filePath substringToIndex:1 ];
[dirEnum skipDescendents ]; // don't go down that recursive road
if ( ![ firstChar isEqualToString:@"."] ) // dont show hidden files
{
fullFilePath = [directoryPath stringByAppendingPathComponent:filePath];
fileAttributes = [ fileManager attributesOfItemAtPath:fullFilePath error:&error ];
fileType = [ fileAttributes valueForKey:NSFileType ];
filePermissions = [ fileAttributes valueForKey:NSFilePosixPermissions ];
fileSubdirCount = filesinDirectory(fullFilePath);
fileOwner = [ fileAttributes valueForKey:NSFileOwnerAccountName ];
fileGroup = [ fileAttributes valueForKey:NSFileGroupOwnerAccountName ];
fileSize = [ fileAttributes valueForKey:NSFileSize ];
fileModified = [ fileAttributes valueForKey:NSFileModificationDate ];
fileDateFormatted = [ dateFormatter stringFromDate:fileModified ];
fileIsDirectory = (fileType == NSFileTypeDirectory );
fileSubdirCount = fileSubdirCount <1 ? 1 : fileSubdirCount;
binaryString = int2BinString([filePermissions unsignedLongValue]) ;
binaryString = [ binaryString substringFromIndex:7 ];// snip off the front
formattedString = [ NSString stringWithFormat:@"%@%@ %5i %12@ %12@ %10qu %@ %@", fileIsDirectory ? @"d" : @"-" ,bin2perms(binaryString),fileSubdirCount, fileOwner, fileGroup, [fileSize unsignedLongLongValue], fileDateFormatted , filePath ];
[ returnString appendString:formattedString ];
[ returnString appendString:@"\n" ];
numberOfFiles++;
}
}
[returnString insertString: [NSString stringWithFormat:@"total %d", numberOfFiles] atIndex:0];
// NSLog(returnString );
return [returnString autorelease]; // FIXME - release count
}
// ----------------------------------------------------------------------------------------------------------
int filesinDirectory(NSString* filePath )
// ----------------------------------------------------------------------------------------------------------
{
int no_files =0;
NSFileManager *fileManager = [ NSFileManager defaultManager ];
NSDirectoryEnumerator *dirEnum = [fileManager enumeratorAtPath:filePath];
while (filePath = [dirEnum nextObject]) {
[dirEnum skipDescendents ]; // don't want children
no_files++;
}
return no_files;
}
// ----------------------------------------------------------------------------------------------------------
NSMutableString* int2BinString(int x)
// ----------------------------------------------------------------------------------------------------------
{
NSMutableString *returnString = [[ NSMutableString alloc ] init];
int hi, lo;
hi=(x>>8) & 0xff;
lo=x&0xff;
[ returnString appendString:byte2String(hi) ];
[ returnString appendString:byte2String(lo) ];
return [ returnString autorelease ];
}
// ----------------------------------------------------------------------------------------------------------
NSMutableString *byte2String(int x )
// ----------------------------------------------------------------------------------------------------------
{
NSMutableString *returnString = [[ NSMutableString alloc ]init];
int n;
for(n=0; n<8; n++)
{
if((x & 0x80) !=0)
{
[ returnString appendString:@"1"];
}
else
{
[ returnString appendString:@"0"];
}
x = x<<1;
}
return [returnString autorelease];
}
// ----------------------------------------------------------------------------------------------------------
NSMutableString *bin2perms(NSString *binaryValue)
// ----------------------------------------------------------------------------------------------------------
{
NSMutableString *returnString = [[ NSMutableString alloc ] init];
NSRange subStringRange;
subStringRange.length = 1;
NSString *replaceWithChar;
for (int n=0; n < [binaryValue length]; n++)
{
subStringRange.location = n;
// take the char
// if pos = 0, 3,6
if ( n == 0 || n == 3 || n ==6)
{
replaceWithChar = @"r";
}
if ( n == 1 || n == 4 || n ==7)
{
replaceWithChar = @"w";
}
if ( n == 2 || n == 5 || n ==7)
{
replaceWithChar = @"x";
}
if ( [[binaryValue substringWithRange:subStringRange ] isEqualToString:@"1" ] )
{
[ returnString appendString:replaceWithChar ];
}
else
{
[ returnString appendString:@"-" ];
}
}
return [ returnString autorelease ];
}

View File

@@ -41,11 +41,11 @@ void Platform_SetStatus( const char *status );
qboolean Platform_DebuggerPresent( void );
// legacy iOS port functions
#if TARGET_OS_IOS
#if XASH_IOS
int IOS_GetArgs( char ***argv );
const char *IOS_GetDocsDir( void );
const char *IOS_GetExecDir( void );
void IOS_LaunchDialog( void );
#include "platform/ios/lib_ios.h"
#endif // TARGET_OS_IOS
#if XASH_WIN32 || XASH_LINUX
@@ -212,9 +212,7 @@ static inline void Sys_RestoreCrashHandler( void )
static inline qboolean Platform_LibraryExists( const char *name, qboolean gamedironly )
{
#if XASH_IOS
return IOS_LibraryExists( name );
#elif XASH_ANDROID
#if XASH_ANDROID
// sorry, unimplemented
return false;
#else

View File

@@ -36,7 +36,6 @@ GNU General Public License for more details.
#include "filesystem.h"
#include "server.h"
#include "platform/android/lib_android.h"
#include "platform/ios/lib_ios.h"
#ifdef XASH_NO_LIBDL
void *dlsym( void *handle, const char *symbol )

View File

@@ -248,13 +248,6 @@ static void SDLash_ActiveEvent( int gain )
}
else
{
#if TARGET_OS_IPHONE
{
// Keep running if ftp server enabled
void IOS_StartBackgroundTask( void );
IOS_StartBackgroundTask();
}
#endif
host.status = HOST_NOFOCUS;
if( cls.key_dest == key_game )

View File

@@ -19,11 +19,11 @@ GNU General Public License for more details.
#include <stdarg.h>
#include "com_image.h"
#include "vgui_api.h"
#include "const.h"
#include "com_model.h"
#include "cl_entity.h"
#include "render_api.h"
#include "triangleapi.h"
#include "const.h"
#include "cl_entity.h"
#include "com_model.h"
#include "studio.h"
#include "r_efx.h"
#include "filesystem.h"
@@ -62,7 +62,9 @@ GNU General Public License for more details.
// 11. Added size argument to Mod_ProcessRenderData
// 12. Added Image_CalcImageSize
// 13. Removed ignore_flags argument from GetCvarPointer
#define REF_API_VERSION 13
// 14. Removed reserved functions, they are leftover from RenderAPI
// Removed CL_AddCustomBeam, it's now handled through R_AddEntity
#define REF_API_VERSION 14
#define TF_SKY (TF_SKYSIDE|TF_NOMIPMAP|TF_ALLOW_NEAREST)
#define TF_FONT (TF_NOMIPMAP|TF_CLAMP|TF_ALLOW_NEAREST)
@@ -90,10 +92,10 @@ GNU General Public License for more details.
#define MODEL_CLIENT BIT( 30 ) // client sprite
// goes into world.flags
#define FWORLD_SKYSPHERE BIT( 0 )
#define FWORLD_CUSTOM_SKYBOX BIT( 1 )
#define FWORLD_WATERALPHA BIT( 2 )
#define FWORLD_HAS_DELUXEMAP BIT( 3 )
#define FWORLD_SKYSPHERE BIT( 0 )
#define FWORLD_CUSTOM_SKYBOX BIT( 1 )
#define FWORLD_WATERALPHA BIT( 2 )
#define FWORLD_HAS_DELUXEMAP BIT( 3 )
// special rendermode for screenfade modulate
// (probably will be expanded at some point)
@@ -499,6 +501,9 @@ typedef struct ref_api_s
// for abstracting the engine's rendering
ref_window_type_t (*R_GetWindowHandle)( void **handle, ref_window_type_t type );
// sprites
struct mspriteframe_s *(*R_GetSpriteFrame)( const struct model_s *pModel, int frame, float yaw );
} ref_api_t;
struct mip_s;
@@ -533,7 +538,6 @@ typedef struct ref_interface_s
void (*GL_SetRenderMode)( int renderMode );
qboolean (*R_AddEntity)( struct cl_entity_s *clent, int type );
void (*CL_AddCustomBeam)( cl_entity_t *pEnvBeam );
void (*R_ProcessEntData)( qboolean allocate, cl_entity_t *entities, unsigned int max_entities );
void (*R_Flush)( unsigned int flush_flags );
@@ -577,9 +581,6 @@ typedef struct ref_interface_s
void (*GL_SubdivideSurface)( model_t *mod, msurface_t *fa );
void (*CL_RunLightStyles)( lightstyle_t *ls );
// sprites
void (*R_GetSpriteParms)( int *frameWidth, int *frameHeight, int *numFrames, int currentFrame, const model_t *pSprite );
int (*R_GetSpriteTexture)( const model_t *m_pSpriteModel, int frame );
// model management
// flags ignored for everything except spritemodels
@@ -632,8 +633,6 @@ typedef struct ref_interface_s
void (*GL_TextureTarget)( unsigned int target ); // change texture unit mode without bind texture
void (*GL_TexCoordArrayMode)( unsigned int texmode );
void (*GL_UpdateTexSize)( int texnum, int width, int height, int depth ); // recalc statistics
void (*GL_Reserved0)( void ); // for potential interface expansion without broken compatibility
void (*GL_Reserved1)( void );
// Misc renderer functions
void (*GL_DrawParticles)( const struct ref_viewpass_s *rvp, qboolean trans_pass, float frametime );

View File

@@ -406,6 +406,7 @@ extern convar_t sv_wateralpha;
extern convar_t sv_wateramp;
extern convar_t sv_voiceenable;
extern convar_t sv_voicequality;
extern convar_t sv_voice_singleplayer;
extern convar_t sv_maxvelocity;
extern convar_t sv_stepsize;
extern convar_t sv_skyname;

View File

@@ -3571,7 +3571,16 @@ static void SV_ParseVoiceData( sv_client_t *cl, sizebuf_t *msg )
MSG_ReadBytes( msg, received, size );
if( !sv_voiceenable.value || svs.maxclients <= 1 || cl->state != cs_spawned )
if( !sv_voiceenable.value || cl->state != cs_spawned )
return;
if( svgame.physFuncs.pfnVoiceData != NULL )
{
if( svgame.physFuncs.pfnVoiceData( client, frames, size, loopback, received ))
return;
}
if( svs.maxclients <= 1 && sv_voice_singleplayer.value == 0.0f )
return;
for( i = 0; i < svs.maxclients; i++ )

View File

@@ -463,7 +463,7 @@ static void SV_CreateBaseline( void )
int delta_type;
int entnum;
if( svs.maxclients > 1 )
if( svs.maxclients > 1 || sv_voice_singleplayer.value )
SV_WriteVoiceCodec( &sv.signon );
if( FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ))

View File

@@ -124,6 +124,7 @@ static CVAR_DEFINE_AUTO( violence_agibs, "1", 0, "show alien gib entities" );
// voice chat
CVAR_DEFINE_AUTO( sv_voiceenable, "1", FCVAR_ARCHIVE|FCVAR_SERVER, "enable voice support" );
CVAR_DEFINE_AUTO( sv_voicequality, "3", FCVAR_ARCHIVE, "voice chat quality level, from 0 to 5, higher is better" );
CVAR_DEFINE_AUTO( sv_voice_singleplayer, "0", FCVAR_ARCHIVE|FCVAR_SERVER, "enable voice subsystem in singleplayer games (maxclients == 1)" );
// enttools
CVAR_DEFINE_AUTO( sv_enttools_enable, "0", FCVAR_ARCHIVE|FCVAR_PROTECTED, "enable powerful and dangerous entity tools" );
@@ -975,6 +976,7 @@ void SV_Init( void )
Cvar_RegisterVariable( &sv_voiceenable );
Cvar_RegisterVariable( &sv_voicequality );
Cvar_RegisterVariable( &sv_voice_singleplayer );
Cvar_RegisterVariable( &sv_trace_messages );
Cvar_RegisterVariable( &sv_enttools_enable );
Cvar_RegisterVariable( &sv_enttools_maxfire );

91
ref/common/ref_common.h Normal file
View File

@@ -0,0 +1,91 @@
/*
ref_common.h - shared renderer code
Copyright (C) 2010 Uncle Mike
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#ifndef REF_COMMON_H
#define REF_COMMON_H
#include "xash3d_mathlib.h"
#include "ref_api.h"
//
// ref_context.c
//
extern ref_api_t gEngfuncs;
extern ref_globals_t *gpGlobals;
extern ref_client_t *gp_cl;
extern ref_host_t *gp_host;
extern const ref_interface_t gReffuncs;
DECLARE_ENGINE_SHARED_CVAR_LIST()
#define Assert( x ) if( !( x )) gEngfuncs.Host_Error( "assert failed at %s:%i\n", __FILE__, __LINE__ )
#define ENGINE_GET_PARM_ (*gEngfuncs.EngineGetParm)
#define ENGINE_GET_PARM( parm ) ENGINE_GET_PARM_( (parm), 0 )
extern uint16_t rtable[MOD_FRAMES][MOD_FRAMES];
void GL_InitRandomTable( void );
void _Mem_Free( void *data, const char *filename, int fileline );
void *_Mem_Alloc( poolhandle_t poolptr, size_t size, qboolean clear, const char *filename, int fileline )
ALLOC_CHECK( 2 ) MALLOC_LIKE( _Mem_Free, 1 ) WARN_UNUSED_RESULT;
void *_Mem_Realloc( poolhandle_t poolptr, void *memptr, size_t size, qboolean clear, const char *filename, int fileline )
ALLOC_CHECK( 3 ) WARN_UNUSED_RESULT;
#define Mem_Malloc( pool, size ) _Mem_Alloc( pool, size, false, __FILE__, __LINE__ )
#define Mem_Calloc( pool, size ) _Mem_Alloc( pool, size, true, __FILE__, __LINE__ )
#define Mem_Realloc( pool, ptr, size ) _Mem_Realloc( pool, ptr, size, true, __FILE__, __LINE__ )
#define Mem_Free( mem ) _Mem_Free( mem, __FILE__, __LINE__ )
#define Mem_AllocPool( name ) gEngfuncs._Mem_AllocPool( name, __FILE__, __LINE__ )
#define Mem_FreePool( pool ) gEngfuncs._Mem_FreePool( pool, __FILE__, __LINE__ )
#define Mem_EmptyPool( pool ) gEngfuncs._Mem_EmptyPool( pool, __FILE__, __LINE__ )
extern dlight_t *gp_dlights;
extern int g_lightstylevalue[MAX_LIGHTSTYLES];
extern poolhandle_t r_temppool;
//
// ref_common cvars
//
extern convar_t r_dlight_virtual_radius;
extern convar_t r_lighting_extended;
//
// ref_math.c
//
void Matrix4x4_Concat( matrix4x4 out, const matrix4x4 in1, const matrix4x4 in2 );
void Matrix4x4_ConcatTranslate( matrix4x4 out, float x, float y, float z );
void Matrix4x4_ConcatRotate( matrix4x4 out, float angle, float x, float y, float z );
void Matrix4x4_CreateProjection( matrix4x4 out, float xMax, float xMin, float yMax, float yMin, float zNear, float zFar );
void Matrix4x4_CreateOrtho( matrix4x4 m, float xLeft, float xRight, float yBottom, float yTop, float zNear, float zFar );
void Matrix4x4_CreateModelview( matrix4x4 out );
void Matrix4x4_ToArrayFloatGL( const matrix4x4 in, float out[16] );
//
// ref_light.c
//
void CL_RunLightStyles( lightstyle_t *ls );
void R_PushDlightsForBmodel( model_t *model, int framecount, const matrix4x4 object_matrix );
int R_PushDlights( model_t *model, int framecount );
colorVec R_LightVec( const vec3_t start, const vec3_t end, vec3_t lspot, vec3_t lvec );
colorVec R_LightPoint( const vec3_t p0 );
void R_UpdateSurfaceCachedLight( msurface_t *surf );
//
// ref_image.c
//
byte *GL_ResampleTexture( const byte *source, int in_w, int in_h, int out_w, int out_h, qboolean isNormalMap );
#endif // REF_COMMON_H

81
ref/common/ref_context.c Normal file
View File

@@ -0,0 +1,81 @@
/*
ref_context.c - shared renderer context
Copyright (C) 2018 a1batross
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 "ref_common.h"
#include "com_strings.h"
DEFINE_ENGINE_SHARED_CVAR_LIST()
ref_api_t gEngfuncs;
ref_globals_t *gpGlobals;
ref_client_t *gp_cl;
ref_host_t *gp_host;
uint16_t rtable[MOD_FRAMES][MOD_FRAMES];
dlight_t *gp_dlights;
int g_lightstylevalue[MAX_LIGHTSTYLES];
poolhandle_t r_temppool;
void _Mem_Free( void *data, const char *filename, int fileline )
{
gEngfuncs._Mem_Free( data, filename, fileline );
}
void *_Mem_Alloc( poolhandle_t poolptr, size_t size, qboolean clear, const char *filename, int fileline )
{
return gEngfuncs._Mem_Alloc( poolptr, size, clear, filename, fileline );
}
void *_Mem_Realloc( poolhandle_t poolptr, void *memptr, size_t size, qboolean clear, const char *filename, int fileline )
{
return gEngfuncs._Mem_Realloc( poolptr, memptr, size, clear, filename, fileline );
}
void GL_InitRandomTable( void )
{
int tu, tv;
for( tu = 0; tu < MOD_FRAMES; tu++ )
{
for( tv = 0; tv < MOD_FRAMES; tv++ )
{
rtable[tu][tv] = gEngfuncs.COM_RandomLong( 0, 0x7FFF );
}
}
gEngfuncs.COM_SetRandomSeed( 0 );
}
int EXPORT GetRefAPI( int version, ref_interface_t *funcs, ref_api_t *engfuncs, ref_globals_t *globals );
int EXPORT GetRefAPI( int version, ref_interface_t *funcs, ref_api_t *engfuncs, ref_globals_t *globals )
{
if( version != REF_API_VERSION )
return 0;
// fill in our callbacks
*funcs = gReffuncs;
gEngfuncs = *engfuncs;
gpGlobals = globals;
gp_cl = (ref_client_t *)ENGINE_GET_PARM( PARM_GET_CLIENT_PTR );
gp_host = (ref_host_t *)ENGINE_GET_PARM( PARM_GET_HOST_PTR );
gp_dlights = (dlight_t *)ENGINE_GET_PARM( PARM_GET_DLIGHTS_PTR );
RETRIEVE_ENGINE_SHARED_CVAR_LIST();
gEngfuncs.Cvar_RegisterVariable( &r_dlight_virtual_radius );
gEngfuncs.Cvar_RegisterVariable( &r_lighting_extended );
return REF_API_VERSION;
}

108
ref/common/ref_image.c Normal file
View File

@@ -0,0 +1,108 @@
/*
ref_image.c - shared image code
Copyright (C) 2010 Uncle Mike
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#include "ref_common.h"
#include "xash3d_mathlib.h"
/*
================
GL_ResampleTexture
Assume input buffer is RGBA
=================
*/
byte *GL_ResampleTexture( const byte *source, int inWidth, int inHeight, int outWidth, int outHeight, qboolean isNormalMap )
{
uint frac, fracStep;
uint *in = (uint *)source;
uint p1[0x1000], p2[0x1000];
byte *pix1, *pix2, *pix3, *pix4;
uint *out, *inRow1, *inRow2;
static byte *scaledImage = NULL; // pointer to a scaled image
vec3_t normal;
int i, x, y;
if( !source ) return NULL;
scaledImage = Mem_Realloc( r_temppool, scaledImage, outWidth * outHeight * 4 );
fracStep = inWidth * 0x10000 / outWidth;
out = (uint *)scaledImage;
frac = fracStep >> 2;
for( i = 0; i < outWidth; i++ )
{
p1[i] = 4 * (frac >> 16);
frac += fracStep;
}
frac = (fracStep >> 2) * 3;
for( i = 0; i < outWidth; i++ )
{
p2[i] = 4 * (frac >> 16);
frac += fracStep;
}
if( isNormalMap )
{
for( y = 0; y < outHeight; y++, out += outWidth )
{
inRow1 = in + inWidth * (int)(((float)y + 0.25f) * inHeight / outHeight);
inRow2 = in + inWidth * (int)(((float)y + 0.75f) * inHeight / outHeight);
for( x = 0; x < outWidth; x++ )
{
pix1 = (byte *)inRow1 + p1[x];
pix2 = (byte *)inRow1 + p2[x];
pix3 = (byte *)inRow2 + p1[x];
pix4 = (byte *)inRow2 + p2[x];
normal[0] = MAKE_SIGNED( pix1[0] ) + MAKE_SIGNED( pix2[0] ) + MAKE_SIGNED( pix3[0] ) + MAKE_SIGNED( pix4[0] );
normal[1] = MAKE_SIGNED( pix1[1] ) + MAKE_SIGNED( pix2[1] ) + MAKE_SIGNED( pix3[1] ) + MAKE_SIGNED( pix4[1] );
normal[2] = MAKE_SIGNED( pix1[2] ) + MAKE_SIGNED( pix2[2] ) + MAKE_SIGNED( pix3[2] ) + MAKE_SIGNED( pix4[2] );
if( !VectorNormalizeLength( normal ))
VectorSet( normal, 0.5f, 0.5f, 1.0f );
((byte *)(out+x))[0] = 128 + (byte)(127.0f * normal[0]);
((byte *)(out+x))[1] = 128 + (byte)(127.0f * normal[1]);
((byte *)(out+x))[2] = 128 + (byte)(127.0f * normal[2]);
((byte *)(out+x))[3] = 255;
}
}
}
else
{
for( y = 0; y < outHeight; y++, out += outWidth )
{
inRow1 = in + inWidth * (int)(((float)y + 0.25f) * inHeight / outHeight);
inRow2 = in + inWidth * (int)(((float)y + 0.75f) * inHeight / outHeight);
for( x = 0; x < outWidth; x++ )
{
pix1 = (byte *)inRow1 + p1[x];
pix2 = (byte *)inRow1 + p2[x];
pix3 = (byte *)inRow2 + p1[x];
pix4 = (byte *)inRow2 + p2[x];
((byte *)(out+x))[0] = (pix1[0] + pix2[0] + pix3[0] + pix4[0]) >> 2;
((byte *)(out+x))[1] = (pix1[1] + pix2[1] + pix3[1] + pix4[1]) >> 2;
((byte *)(out+x))[2] = (pix1[2] + pix2[2] + pix3[2] + pix4[2]) >> 2;
((byte *)(out+x))[3] = (pix1[3] + pix2[3] + pix3[3] + pix4[3]) >> 2;
}
}
}
return scaledImage;
}

View File

@@ -1,5 +1,5 @@
/*
gl_rlight.c - dynamic and static lights
ref_light.c - shared light code
Copyright (C) 2010 Uncle Mike
This program is free software: you can redistribute it and/or modify
@@ -13,19 +13,13 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#include "gl_local.h"
#include "pm_local.h"
#include "studio.h"
#include "ref_common.h"
#include "xash3d_mathlib.h"
#include "ref_params.h"
#include "pm_local.h"
/*
=============================================================================
CVAR_DEFINE_AUTO( r_dlight_virtual_radius, "3", FCVAR_GLCONFIG, "increase dlight radius virtually by this amount" );
CVAR_DEFINE_AUTO( r_lighting_extended, "1", FCVAR_GLCONFIG, "allow to get lighting from world and bmodels" );
DYNAMIC LIGHTS
=============================================================================
*/
/*
==================
CL_RunLightStyles
@@ -34,16 +28,17 @@ CL_RunLightStyles
*/
void CL_RunLightStyles( lightstyle_t *ls )
{
const model_t *world = gp_cl->models[1];
int i;
float frametime = (gp_cl->time - gp_cl->oldtime);
float frametime = gp_cl->time - gp_cl->oldtime;
if( !WORLDMODEL )
if( !world )
return;
if( !WORLDMODEL->lightdata )
if( r_fullbright->value || !world->lightdata )
{
for( i = 0; i < MAX_LIGHTSTYLES; i++ )
tr.lightstylevalue[i] = 256 * 256;
g_lightstylevalue[i] = 256 * 256;
return;
}
@@ -59,13 +54,13 @@ void CL_RunLightStyles( lightstyle_t *ls )
if( !ls[i].length )
{
tr.lightstylevalue[i] = 256;
g_lightstylevalue[i] = 256;
continue;
}
else if( ls[i].length == 1 )
{
// single length style so don't bother interpolating
tr.lightstylevalue[i] = ( ls[i].map[0] ) * 22;
g_lightstylevalue[i] = ls[i].map[0] * 22;
continue;
}
@@ -73,7 +68,7 @@ void CL_RunLightStyles( lightstyle_t *ls )
if( !ls[i].interp || !cl_lightstyle_lerping->value )
{
tr.lightstylevalue[i] = ls[i].map[flight%ls[i].length] * 22;
g_lightstylevalue[i] = ls[i].map[flight % ls[i].length] * 22;
continue;
}
@@ -90,7 +85,7 @@ void CL_RunLightStyles( lightstyle_t *ls )
k = ls[i].map[clight % ls[i].length];
l += (float)( k * 22.0f ) * lerpfrac;
tr.lightstylevalue[i] = (int)l;
g_lightstylevalue[i] = (int)l;
}
}
@@ -99,44 +94,39 @@ void CL_RunLightStyles( lightstyle_t *ls )
R_MarkLights
=============
*/
void R_MarkLights( const dlight_t *light, int bit, const mnode_t *node )
static void R_MarkLights( const dlight_t *light, int bit, const mnode_t *node, model_t *model, int dlightframecount )
{
const float virtual_radius = light->radius * Q_max( 1.0f, r_dlight_virtual_radius.value );
const float maxdist = light->radius * light->radius;
float dist;
int i;
int firstsurface, numsurfaces;
start:
if( !node || node->contents < 0 )
return;
dist = PlaneDiff( light->origin, node->plane );
float dist = PlaneDiff( light->origin, node->plane );
if( dist > virtual_radius )
{
node = node_child( node, 0, RI.currentmodel );
node = node_child( node, 0, model );
goto start;
}
if( dist < -virtual_radius )
{
node = node_child( node, 1, RI.currentmodel );
node = node_child( node, 1, model );
goto start;
}
const float dist_sq = dist * dist;
// mark the polygons
firstsurface = node_firstsurface( node, RI.currentmodel );
numsurfaces = node_numsurfaces( node, RI.currentmodel );
int firstsurface = node_firstsurface( node, model );
int numsurfaces = node_numsurfaces( node, model );
for( i = 0; i < numsurfaces && dist_sq < maxdist; i++ )
for( int i = 0; i < numsurfaces && dist_sq < maxdist; i++ )
{
vec3_t impact;
float s, t, l;
msurface_t *surf = &RI.currentmodel->surfaces[firstsurface + i];
msurface_t *surf = &model->surfaces[firstsurface + i];
const mextrasurf_t *info = surf->info;
if( surf->plane->type < 3 )
@@ -162,16 +152,17 @@ start:
if( s * s + t * t + dist_sq >= maxdist )
continue;
if( surf->dlightframe != tr.dlightframecount )
if( surf->dlightframe != dlightframecount )
{
surf->dlightbits = bit;
surf->dlightframe = tr.dlightframecount;
surf->dlightframe = dlightframecount;
}
else surf->dlightbits |= bit;
}
R_MarkLights( light, bit, node_child( node, 0, RI.currentmodel ));
R_MarkLights( light, bit, node_child( node, 1, RI.currentmodel ));
R_MarkLights( light, bit, node_child( node, 0, model ), model, dlightframecount );
node = node_child( node, 1, model );
goto start;
}
/*
@@ -179,31 +170,40 @@ start:
R_PushDlights
=============
*/
void R_PushDlights( void )
int R_PushDlights( model_t *model, int framecount )
{
int i;
if( !model )
return framecount;
tr.dlightframecount = tr.framecount;
RI.currententity = CL_GetEntityByIndex( 0 );
// no world -- no dlights
if( !RI.currententity )
return;
RI.currentmodel = RI.currententity->model;
for( i = 0; i < MAX_DLIGHTS; i++ )
for( int i = 0; i < MAX_DLIGHTS; i++ )
{
dlight_t *l = &tr.dlights[i];
const dlight_t *l = &gp_dlights[i];
if( l->die < gp_cl->time || !l->radius )
continue;
if( GL_FrustumCullSphere( &RI.frustum, l->origin, l->radius, 15 ))
R_MarkLights( l, 1 << i, model->nodes, model, framecount );
}
return framecount;
}
void R_PushDlightsForBmodel( model_t *model, int framecount, const matrix4x4 object_matrix )
{
for( int i = 0; i < MAX_DLIGHTS; i++ )
{
dlight_t *l = &gp_dlights[i];
if( l->die < gp_cl->time || !l->radius )
continue;
R_MarkLights( l, 1<<i, RI.currentmodel->nodes );
vec3_t oldorigin;
VectorCopy( l->origin, oldorigin );
Matrix4x4_VectorITransform( object_matrix, oldorigin, l->origin );
R_MarkLights( l, 1 << i, model->nodes + model->hulls[0].firstclipnode, model, framecount );
VectorCopy( oldorigin, l->origin );
}
}
@@ -225,18 +225,7 @@ R_RecursiveLightPoint
*/
static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f, float p2f, colorVec *cv, const vec3_t start, const vec3_t end )
{
float front, back, frac, midf;
int i, map, side, size;
float ds, dt, s, t;
int sample_size;
color24 *lm, *dm;
mextrasurf_t *info;
msurface_t *surf;
mtexinfo_t *tex;
matrix3x4 tbn;
vec3_t mid;
int firstsurface, numsurfaces;
start:
// didn't hit anything
if( !node || node->contents < 0 )
{
@@ -244,21 +233,23 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
return false;
}
firstsurface = node_firstsurface( node, model );
numsurfaces = node_numsurfaces( node, model );
// calculate mid point
front = PlaneDiff( start, node->plane );
back = PlaneDiff( end, node->plane );
float front = PlaneDiff( start, node->plane );
float back = PlaneDiff( end, node->plane );
side = front < 0;
int side = front < 0;
if(( back < 0 ) == side )
return R_RecursiveLightPoint( model, node_child( node, side, model ), p1f, p2f, cv, start, end );
{
node = node_child( node, side, model );
goto start;
}
frac = front / ( front - back );
float frac = front / ( front - back );
vec3_t mid;
VectorLerp( start, frac, end, mid );
midf = p1f + ( p2f - p1f ) * frac;
float midf = p1f + ( p2f - p1f ) * frac;
// co down front side
if( R_RecursiveLightPoint( model, node_child( node, side, model ), p1f, midf, cv, start, mid ))
@@ -271,27 +262,27 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
}
// check for impact on this node
surf = model->surfaces + firstsurface;
int firstsurface = node_firstsurface( node, model );
int numsurfaces = node_numsurfaces( node, model );
VectorCopy( mid, g_trace_lightspot );
for( i = 0; i < numsurfaces; i++, surf++ )
for( int i = 0; i < numsurfaces; i++ )
{
int smax, tmax;
tex = surf->texinfo;
info = surf->info;
const msurface_t *surf = &model->surfaces[firstsurface + i];
const mextrasurf_t *info = surf->info;
if( FBitSet( surf->flags, SURF_DRAWTILED ))
continue; // no lightmaps
s = DotProduct( mid, info->lmvecs[0] ) + info->lmvecs[0][3];
t = DotProduct( mid, info->lmvecs[1] ) + info->lmvecs[1][3];
float s = DotProduct( mid, info->lmvecs[0] ) + info->lmvecs[0][3];
float t = DotProduct( mid, info->lmvecs[1] ) + info->lmvecs[1][3];
if( s < info->lightmapmins[0] || t < info->lightmapmins[1] )
continue;
ds = s - info->lightmapmins[0];
dt = t - info->lightmapmins[1];
float ds = s - info->lightmapmins[0];
float dt = t - info->lightmapmins[1];
if ( ds > info->lightextents[0] || dt > info->lightextents[1] )
continue;
@@ -301,21 +292,25 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
if( !surf->samples )
return true;
sample_size = gEngfuncs.Mod_SampleSizeForFace( surf );
smax = (info->lightextents[0] / sample_size) + 1;
tmax = (info->lightextents[1] / sample_size) + 1;
int sample_size = gEngfuncs.Mod_SampleSizeForFace( surf );
int smax = (info->lightextents[0] / sample_size) + 1;
int tmax = (info->lightextents[1] / sample_size) + 1;
ds /= sample_size;
dt /= sample_size;
lm = surf->samples + Q_rint( dt ) * smax + Q_rint( ds );
g_trace_fraction = midf;
size = smax * tmax;
dm = NULL;
const color24 *lm = surf->samples + Q_rint( dt ) * smax + Q_rint( ds );
const color24 *dm = NULL;
matrix3x4 tbn;
if( surf->info->deluxemap )
{
vec3_t faceNormal;
dm = surf->info->deluxemap + Q_rint( dt ) * smax + Q_rint( ds );
if( FBitSet( surf->flags, SURF_PLANEBACK ))
VectorNegate( surf->plane->normal, faceNormal );
else VectorCopy( surf->plane->normal, faceNormal );
@@ -333,12 +328,13 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
VectorNormalize( tbn[0] );
VectorNormalize( tbn[1] );
VectorNormalize( tbn[2] );
dm = surf->info->deluxemap + Q_rint( dt ) * smax + Q_rint( ds );
}
for( map = 0; map < MAXLIGHTMAPS && surf->styles[map] != 255; map++ )
int size = smax * tmax;
for( int map = 0; map < MAXLIGHTMAPS && surf->styles[map] != 255; map++ )
{
uint scale = tr.lightstylevalue[surf->styles[map]];
uint scale = g_lightstylevalue[surf->styles[map]];
cv->r += lm->r * scale;
cv->g += lm->g * scale;
@@ -368,83 +364,75 @@ static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f,
/*
=================
R_LightVec
R_LightVecInternal
check bspmodels to get light from
=================
*/
static colorVec R_LightVecInternal( const vec3_t start, const vec3_t end, vec3_t lspot, vec3_t lvec )
{
float last_fraction;
int i, maxEnts = 1;
colorVec light, cv;
if( lspot )
VectorClear( lspot );
if( lspot ) VectorClear( lspot );
if( lvec ) VectorClear( lvec );
if( lvec )
VectorClear( lvec );
if( WORLDMODEL && WORLDMODEL->lightdata )
if( !gp_cl->models[1] || !gp_cl->models[1]->lightdata )
return (colorVec){ 255, 255, 255, 0 };
float last_fraction = 1.0f;
int max_ents = r_lighting_extended.value ? MAX_PHYSENTS : 1; // get light from bmodels too
colorVec light = { 0 };
// check all the bsp-models
for( int i = 0; i < max_ents; i++ )
{
light.r = light.g = light.b = light.a = 0;
last_fraction = 1.0f;
const physent_t *pe = gEngfuncs.EV_GetPhysent( i );
// get light from bmodels too
if( r_lighting_extended.value )
maxEnts = MAX_PHYSENTS;
if( !pe )
break;
// check all the bsp-models
for( i = 0; i < maxEnts; i++ )
if( !pe->model || pe->model->type != mod_brush )
continue; // skip non-bsp models
mnode_t *pnodes = &pe->model->nodes[pe->model->hulls[0].firstclipnode];
vec3_t offset, start_l, end_l;
VectorSubtract( pe->model->hulls[0].clip_mins, vec3_origin, offset );
VectorAdd( offset, pe->origin, offset );
VectorSubtract( start, offset, start_l );
VectorSubtract( end, offset, end_l );
// rotate start and end into the models frame of reference
if( !VectorIsNull( pe->angles ))
{
physent_t *pe = gEngfuncs.EV_GetPhysent( i );
vec3_t offset, start_l, end_l;
mnode_t *pnodes;
matrix4x4 matrix;
if( !pe )
break;
if( !pe->model || pe->model->type != mod_brush )
continue; // skip non-bsp models
pnodes = &pe->model->nodes[pe->model->hulls[0].firstclipnode];
VectorSubtract( pe->model->hulls[0].clip_mins, vec3_origin, offset );
VectorAdd( offset, pe->origin, offset );
VectorSubtract( start, offset, start_l );
VectorSubtract( end, offset, end_l );
// rotate start and end into the models frame of reference
if( !VectorIsNull( pe->angles ))
{
Matrix4x4_CreateFromEntity( matrix, pe->angles, offset, 1.0f );
Matrix4x4_VectorITransform( matrix, start, start_l );
Matrix4x4_VectorITransform( matrix, end, end_l );
}
VectorClear( g_trace_lightspot );
VectorClear( g_trace_lightvec );
g_trace_fraction = 1.0f;
if( !R_RecursiveLightPoint( pe->model, pnodes, 0.0f, 1.0f, &cv, start_l, end_l ))
continue; // didn't hit anything
if( g_trace_fraction < last_fraction )
{
if( lspot ) VectorCopy( g_trace_lightspot, lspot );
if( lvec ) VectorNormalize2( g_trace_lightvec, lvec );
light.r = Q_min(( cv.r >> 8 ), 255 );
light.g = Q_min(( cv.g >> 8 ), 255 );
light.b = Q_min(( cv.b >> 8 ), 255 );
last_fraction = g_trace_fraction;
if(( light.r + light.g + light.b ) != 0 )
break; // we get light now
}
matrix4x4 matrix;
Matrix4x4_CreateFromEntity( matrix, pe->angles, offset, 1.0f );
Matrix4x4_VectorITransform( matrix, start, start_l );
Matrix4x4_VectorITransform( matrix, end, end_l );
}
VectorClear( g_trace_lightspot );
VectorClear( g_trace_lightvec );
g_trace_fraction = 1.0f;
colorVec cv;
if( !R_RecursiveLightPoint( pe->model, pnodes, 0.0f, 1.0f, &cv, start_l, end_l ))
continue; // didn't hit anything
if( g_trace_fraction < last_fraction )
{
if( lspot ) VectorCopy( g_trace_lightspot, lspot );
if( lvec ) VectorNormalize2( g_trace_lightvec, lvec );
light.r = Q_min(( cv.r >> 8 ), 255 );
light.g = Q_min(( cv.g >> 8 ), 255 );
light.b = Q_min(( cv.b >> 8 ), 255 );
last_fraction = g_trace_fraction;
if(( light.r + light.g + light.b ) != 0 )
break; // we get light now
}
}
else
{
light.r = light.g = light.b = 255;
light.a = 0;
}
return light;
@@ -459,7 +447,7 @@ check bspmodels to get light from
*/
colorVec R_LightVec( const vec3_t start, const vec3_t end, vec3_t lspot, vec3_t lvec )
{
colorVec light = R_LightVecInternal( start, end, lspot, lvec );
colorVec light = R_LightVecInternal( start, end, lspot, lvec );
if( r_lighting_extended.value && lspot != NULL && lvec != NULL )
{
@@ -480,9 +468,20 @@ light from floor
*/
colorVec R_LightPoint( const vec3_t p0 )
{
vec3_t p1;
vec3_t p1;
VectorSet( p1, p0[0], p0[1], p0[2] - 2048.0f );
return R_LightVec( p0, p1, NULL, NULL );
}
/*
================
R_SetCacheState
================
*/
void R_UpdateSurfaceCachedLight( msurface_t *surf )
{
for( int i = 0; i < MAXLIGHTMAPS && surf->styles[i] != 255; i++ )
surf->cached_light[i] = g_lightstylevalue[surf->styles[i]];
}

View File

@@ -1,5 +1,5 @@
/*
gl_rmath.c - renderer mathlib
ref_math.c - renderer mathlib
Copyright (C) 2010 Uncle Mike
This program is free software: you can redistribute it and/or modify
@@ -13,8 +13,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#include "r_local.h"
#include "xash3d_mathlib.h"
#include "ref_common.h"
/*
========================================================================
@@ -99,7 +98,27 @@ void Matrix4x4_CreateModelview( matrix4x4 out )
out[1][2] = 1.0f;
}
void Matrix4x4_CreateTranslate( matrix4x4 out, float x, float y, float z )
void Matrix4x4_ToArrayFloatGL( const matrix4x4 in, float out[16] )
{
out[ 0] = in[0][0];
out[ 1] = in[1][0];
out[ 2] = in[2][0];
out[ 3] = in[3][0];
out[ 4] = in[0][1];
out[ 5] = in[1][1];
out[ 6] = in[2][1];
out[ 7] = in[3][1];
out[ 8] = in[0][2];
out[ 9] = in[1][2];
out[10] = in[2][2];
out[11] = in[3][2];
out[12] = in[0][3];
out[13] = in[1][3];
out[14] = in[2][3];
out[15] = in[3][3];
}
static void Matrix4x4_CreateTranslate( matrix4x4 out, float x, float y, float z )
{
out[0][0] = 1.0f;
out[0][1] = 0.0f;
@@ -119,7 +138,7 @@ void Matrix4x4_CreateTranslate( matrix4x4 out, float x, float y, float z )
out[3][3] = 1.0f;
}
void Matrix4x4_CreateRotate( matrix4x4 out, float angle, float x, float y, float z )
static void Matrix4x4_CreateRotate( matrix4x4 out, float angle, float x, float y, float z )
{
float len, c, s;

27
ref/common/wscript Normal file
View File

@@ -0,0 +1,27 @@
#! /usr/bin/env python
# encoding: utf-8
def options(opt):
pass
def configure(conf):
pass
def build(bld):
use = ['engine_includes', 'sdk_includes', 'werror']
# FIXME: figure out why psvita needs it and how can we avoid it
if bld.env.DEST_OS == 'psvita':
bld.env.CFLAGS_cstlib.remove('-fno-PIC')
bld.env.CFLAGS += ['-fPIC']
else:
use += ['public']
bld.stlib(source = bld.path.ant_glob('*.c'),
target = 'ref_common',
includes = '.',
export_includes = '.',
defines = 'REF_DLL=1',
use = use,
subsystem = bld.env.MSVC_SUBSYSTEM
)

View File

@@ -684,7 +684,7 @@ static void R_AliasDynamicLight( cl_entity_t *ent, alight_t *plight )
for( lnum = 0; lnum < MAX_DLIGHTS; lnum++ )
{
const dlight_t *dl = &tr.dlights[lnum];
const dlight_t *dl = &gp_dlights[lnum];
if( dl->die < g_alias.time || !r_dynamic->value )
continue;

View File

@@ -151,28 +151,6 @@ qboolean R_BeamCull( const vec3_t start, const vec3_t end, qboolean pvsOnly )
return true;
}
/*
================
CL_AddCustomBeam
Add the beam that encoded as custom entity
================
*/
void CL_AddCustomBeam( cl_entity_t *pEnvBeam )
{
if( tr.draw_list->num_beam_entities >= MAX_VISIBLE_PACKET )
{
gEngfuncs.Con_Printf( S_ERROR "Too many beams %d!\n", tr.draw_list->num_beam_entities );
return;
}
if( pEnvBeam )
{
tr.draw_list->beam_entities[tr.draw_list->num_beam_entities] = pEnvBeam;
tr.draw_list->num_beam_entities++;
}
}
/*
==============================================================

View File

@@ -22,20 +22,7 @@ GNU General Public License for more details.
#include "gl4es/include/gl4esinit.h"
#endif
ref_api_t gEngfuncs;
ref_globals_t *gpGlobals;
ref_client_t *gp_cl;
ref_host_t *gp_host;
void _Mem_Free( void *data, const char *filename, int fileline )
{
gEngfuncs._Mem_Free( data, filename, fileline );
}
void *_Mem_Alloc( poolhandle_t poolptr, size_t size, qboolean clear, const char *filename, int fileline )
{
return gEngfuncs._Mem_Alloc( poolptr, size, clear, filename, fileline );
}
static void R_ClearScreen( void )
{
@@ -132,7 +119,6 @@ static void Mod_UnloadTextures( model_t *mod )
Mod_BrushUnloadTextures( mod );
break;
case mod_sprite:
Mod_SpriteUnloadTextures( mod->cache.data );
break;
default:
Assert( 0 );
@@ -159,7 +145,7 @@ static qboolean Mod_ProcessRenderData( model_t *mod, qboolean create, const byte
loaded = true;
break;
case mod_sprite:
Mod_LoadSpriteModel( mod, buf, &loaded, mod->numtexinfo );
loaded = true;
break;
case mod_alias:
Mod_LoadAliasModel( mod, buf, &loaded );
@@ -228,7 +214,7 @@ static int GL_RefGetParm( int parm, int arg )
return glState.activeTMU;
case PARM_LIGHTSTYLEVALUE:
arg = bound( 0, arg, MAX_LIGHTSTYLES - 1 );
return tr.lightstylevalue[arg];
return g_lightstylevalue[arg];
case PARM_MAX_IMAGE_UNITS:
return GL_MaxTextureUnits();
case PARM_REBUILD_GAMMA:
@@ -427,7 +413,7 @@ static const char *R_GetConfigName( void )
return "opengl";
}
static const ref_interface_t gReffuncs =
const ref_interface_t gReffuncs =
{
R_Init,
R_Shutdown,
@@ -452,7 +438,6 @@ static const ref_interface_t gReffuncs =
GL_SetRenderMode,
R_AddEntity,
CL_AddCustomBeam,
R_ProcessEntData,
R_Flush,
@@ -487,8 +472,6 @@ static const ref_interface_t gReffuncs =
GL_SubdivideSurface,
CL_RunLightStyles,
R_GetSpriteParms,
R_GetSpriteTexture,
Mod_ProcessRenderData,
Mod_StudioLoadTextures,
@@ -531,8 +514,6 @@ static const ref_interface_t gReffuncs =
GL_TextureTarget,
GL_SetTexCoordArrayMode,
GL_UpdateTexSize,
NULL,
NULL,
CL_DrawParticlesExternal,
R_LightVec,
@@ -564,19 +545,3 @@ static const ref_interface_t gReffuncs =
VGUI_UploadTextureBlock,
};
int EXPORT GetRefAPI( int version, ref_interface_t *funcs, ref_api_t *engfuncs, ref_globals_t *globals );
int EXPORT GetRefAPI( int version, ref_interface_t *funcs, ref_api_t *engfuncs, ref_globals_t *globals )
{
if( version != REF_API_VERSION )
return 0;
// fill in our callbacks
*funcs = gReffuncs;
gEngfuncs = *engfuncs;
gpGlobals = globals;
gp_cl = (ref_client_t *)ENGINE_GET_PARM( PARM_GET_CLIENT_PTR );
gp_host = (ref_host_t *)ENGINE_GET_PARM( PARM_GET_HOST_PTR );
return REF_API_VERSION;
}

View File

@@ -868,6 +868,10 @@ void DrawSingleDecal( decal_t *pDecal, msurface_t *fa )
GL_Bind( XASH_TEXTURE0, pDecal->texture );
if( FBitSet( R_GetTexture( pDecal->texture )->flags, TF_PREMULTIPLIED ))
pglBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA );
else pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
pglBegin( GL_POLYGON );
for( i = 0; i < numVerts; i++, v += VERTEXSIZE )

View File

@@ -29,34 +29,6 @@ void R_GetTextureParms( int *w, int *h, int texnum )
if( h ) *h = glt->srcHeight;
}
/*
=============
R_GetSpriteParms
same as GetImageParms but used
for sprite models
=============
*/
void R_GetSpriteParms( int *frameWidth, int *frameHeight, int *numFrames, int currentFrame, const model_t *pSprite )
{
mspriteframe_t *pFrame;
if( !pSprite || pSprite->type != mod_sprite ) return; // bad model ?
pFrame = R_GetSpriteFrame( pSprite, currentFrame, 0.0f );
if( frameWidth ) *frameWidth = pFrame->width;
if( frameHeight ) *frameHeight = pFrame->height;
if( numFrames ) *numFrames = pSprite->numframes;
}
int R_GetSpriteTexture( const model_t *m_pSpriteModel, int frame )
{
if( !m_pSpriteModel || m_pSpriteModel->type != mod_sprite || !m_pSpriteModel->cache.data )
return 0;
return R_GetSpriteFrame( m_pSpriteModel, frame, 0.0f )->gl_texturenum;
}
/*
=============
R_DrawStretchPic

View File

@@ -691,97 +691,6 @@ static void GL_SetTextureFormat( gl_texture_t *tex, pixformat_t format, int chan
}
}
/*
=================
GL_ResampleTexture
Assume input buffer is RGBA
=================
*/
byte *GL_ResampleTexture( const byte *source, int inWidth, int inHeight, int outWidth, int outHeight, qboolean isNormalMap )
{
uint frac, fracStep;
uint *in = (uint *)source;
uint p1[0x1000], p2[0x1000];
byte *pix1, *pix2, *pix3, *pix4;
uint *out, *inRow1, *inRow2;
static byte *scaledImage = NULL; // pointer to a scaled image
vec3_t normal;
int i, x, y;
if( !source ) return NULL;
scaledImage = Mem_Realloc( r_temppool, scaledImage, outWidth * outHeight * 4 );
fracStep = inWidth * 0x10000 / outWidth;
out = (uint *)scaledImage;
frac = fracStep >> 2;
for( i = 0; i < outWidth; i++ )
{
p1[i] = 4 * (frac >> 16);
frac += fracStep;
}
frac = (fracStep >> 2) * 3;
for( i = 0; i < outWidth; i++ )
{
p2[i] = 4 * (frac >> 16);
frac += fracStep;
}
if( isNormalMap )
{
for( y = 0; y < outHeight; y++, out += outWidth )
{
inRow1 = in + inWidth * (int)(((float)y + 0.25f) * inHeight / outHeight);
inRow2 = in + inWidth * (int)(((float)y + 0.75f) * inHeight / outHeight);
for( x = 0; x < outWidth; x++ )
{
pix1 = (byte *)inRow1 + p1[x];
pix2 = (byte *)inRow1 + p2[x];
pix3 = (byte *)inRow2 + p1[x];
pix4 = (byte *)inRow2 + p2[x];
normal[0] = MAKE_SIGNED( pix1[0] ) + MAKE_SIGNED( pix2[0] ) + MAKE_SIGNED( pix3[0] ) + MAKE_SIGNED( pix4[0] );
normal[1] = MAKE_SIGNED( pix1[1] ) + MAKE_SIGNED( pix2[1] ) + MAKE_SIGNED( pix3[1] ) + MAKE_SIGNED( pix4[1] );
normal[2] = MAKE_SIGNED( pix1[2] ) + MAKE_SIGNED( pix2[2] ) + MAKE_SIGNED( pix3[2] ) + MAKE_SIGNED( pix4[2] );
if( !VectorNormalizeLength( normal ))
VectorSet( normal, 0.5f, 0.5f, 1.0f );
((byte *)(out+x))[0] = 128 + (byte)(127.0f * normal[0]);
((byte *)(out+x))[1] = 128 + (byte)(127.0f * normal[1]);
((byte *)(out+x))[2] = 128 + (byte)(127.0f * normal[2]);
((byte *)(out+x))[3] = 255;
}
}
}
else
{
for( y = 0; y < outHeight; y++, out += outWidth )
{
inRow1 = in + inWidth * (int)(((float)y + 0.25f) * inHeight / outHeight);
inRow2 = in + inWidth * (int)(((float)y + 0.75f) * inHeight / outHeight);
for( x = 0; x < outWidth; x++ )
{
pix1 = (byte *)inRow1 + p1[x];
pix2 = (byte *)inRow1 + p2[x];
pix3 = (byte *)inRow2 + p1[x];
pix4 = (byte *)inRow2 + p2[x];
((byte *)(out+x))[0] = (pix1[0] + pix2[0] + pix3[0] + pix4[0]) >> 2;
((byte *)(out+x))[1] = (pix1[1] + pix2[1] + pix3[1] + pix4[1]) >> 2;
((byte *)(out+x))[2] = (pix1[2] + pix2[2] + pix3[2] + pix4[2]) >> 2;
((byte *)(out+x))[3] = (pix1[3] + pix2[3] + pix3[3] + pix4[3]) >> 2;
}
}
}
return scaledImage;
}
/*
=================
GL_BoxFilter3x3
@@ -1238,6 +1147,8 @@ static void GL_ProcessImage( gl_texture_t *tex, rgbdata_t *pic )
// force upload texture as RGB or RGBA (detail textures requires this)
if( tex->flags & TF_FORCE_COLOR ) pic->flags |= IMAGE_HAS_COLOR;
if( pic->flags & IMAGE_HAS_ALPHA ) tex->flags |= TF_HAS_ALPHA;
if( FBitSet( pic->flags, IMAGE_PREMULTIPLIED ))
SetBits( tex->flags, TF_PREMULTIPLIED );
tex->encode = pic->encode; // share encode method
@@ -1275,6 +1186,23 @@ static void GL_ProcessImage( gl_texture_t *tex, rgbdata_t *pic )
// processing image before uploading (force to rgba, make luma etc)
if( pic->buffer ) gEngfuncs.Image_Process( &pic, 0, 0, img_flags, 0 );
if( FBitSet( pic->flags, IMAGE_PLAYERDECAL ) && pic->buffer && pic->type == PF_RGBA_32 && FBitSet( pic->flags, IMAGE_HAS_ALPHA )
&& !FBitSet( pic->flags, IMAGE_PREMULTIPLIED ))
{
int i, cnt = (int)( pic->width * pic->height );
byte *p = pic->buffer;
for( i = 0; i < cnt; i++, p += 4 )
{
int a = p[3];
p[0] = ( p[0] * a + 127 ) / 255;
p[1] = ( p[1] * a + 127 ) / 255;
p[2] = ( p[2] * a + 127 ) / 255;
}
SetBits( pic->flags, IMAGE_PREMULTIPLIED );
SetBits( tex->flags, TF_PREMULTIPLIED );
}
if( FBitSet( tex->flags, TF_LUMINANCE ))
ClearBits( pic->flags, IMAGE_HAS_COLOR );
}

View File

@@ -15,17 +15,12 @@ GNU General Public License for more details.
#ifndef GL_LOCAL_H
#define GL_LOCAL_H
#include "ref_common.h"
#include "port.h"
#include "xash3d_types.h"
#include "cvardef.h"
#include "const.h"
#include "com_model.h"
#include "cl_entity.h"
#include "render_api.h"
#include "protocol.h"
#include "gl_frustum.h"
#include "ref_api.h"
#include "xash3d_mathlib.h"
#include "ref_params.h"
#include "enginefeatures.h"
#include "com_strings.h"
@@ -52,7 +47,6 @@ void VGL_ShimEndFrame( void );
#endif
#endif
#define Assert(x) if(!( x )) gEngfuncs.Host_Error( "assert failed at %s:%i\n", __FILE__, __LINE__ )
#include <stdio.h>
@@ -60,7 +54,6 @@ void VGL_ShimEndFrame( void );
#define LM_SAMPLE_SIZE 16
extern poolhandle_t r_temppool;
#define BLOCK_SIZE tr.block_size // lightmap blocksize
#define BLOCK_SIZE_DEFAULT 128 // for keep backward compatibility
@@ -239,7 +232,6 @@ typedef struct
qboolean fFlipViewModel;
byte visbytes[(MAX_MAP_LEAFS+7)/8]; // member custom PVS
int lightstylevalue[MAX_LIGHTSTYLES]; // value 0 - 65536
int block_size; // lightmap blocksize
double frametime; // special frametime for multipass rendering (will set to 0 on a nextview)
@@ -255,7 +247,6 @@ typedef struct
movevars_t *movevars;
color24 *palette;
cl_entity_t *viewent;
dlight_t *dlights;
dlight_t *elights;
byte *texgammatable;
uint *lightgammatable;
@@ -359,7 +350,6 @@ gl_texture_t *R_GetTexture( unsigned int texnum );
int GL_LoadTexture( const char *name, const byte *buf, size_t size, int flags );
int GL_LoadTextureArray( const char **names, int flags );
int GL_LoadTextureFromBuffer( const char *name, rgbdata_t *pic, texFlags_t flags, qboolean update );
byte *GL_ResampleTexture( const byte *source, int in_w, int in_h, int out_w, int out_h, qboolean isNormalMap );
int GL_CreateTexture( const char *name, int width, int height, const void *buffer, texFlags_t flags );
int GL_CreateTextureArray( const char *name, int width, int height, int depth, const void *buffer, texFlags_t flags );
void GL_ProcessTexture( int texnum, float gamma, int topColor, int bottomColor );
@@ -377,16 +367,6 @@ qboolean R_SearchForTextureReplacement( char *out, size_t size, const char *mode
void R_TextureReplacementReport( const char *modelname, int gl_texturenum, const char *foundpath );
void R_ShowTextures( void );
//
// gl_rlight.c
//
void CL_RunLightStyles( lightstyle_t *ls );
void R_PushDlights( void );
void R_GetLightSpot( vec3_t lightspot );
void R_MarkLights( const dlight_t *light, int bit, const mnode_t *node );
colorVec R_LightVec( const vec3_t start, const vec3_t end, vec3_t lightspot, vec3_t lightvec );
colorVec R_LightPoint( const vec3_t p0 );
//
// gl_rmain.c
//
@@ -407,17 +387,6 @@ void R_PopScene( void );
void R_DrawFog( void );
int CL_FxBlend( cl_entity_t *e );
//
// gl_rmath.c
//
void Matrix4x4_ToArrayFloatGL( const matrix4x4 in, float out[16] );
void Matrix4x4_Concat( matrix4x4 out, const matrix4x4 in1, const matrix4x4 in2 );
void Matrix4x4_ConcatTranslate( matrix4x4 out, float x, float y, float z );
void Matrix4x4_ConcatRotate( matrix4x4 out, float angle, float x, float y, float z );
void Matrix4x4_CreateProjection(matrix4x4 out, float xMax, float xMin, float yMax, float yMin, float zNear, float zFar);
void Matrix4x4_CreateOrtho(matrix4x4 m, float xLeft, float xRight, float yBottom, float yTop, float zNear, float zFar);
void Matrix4x4_CreateModelview( matrix4x4 out );
//
// gl_rmisc.c
//
@@ -434,7 +403,6 @@ void GL_SubdivideSurface( model_t *mod, msurface_t *fa );
void GL_SetupFogColorForSurfaces( void );
void R_DrawAlphaTextureChains( void );
void GL_RebuildLightmaps( void );
void GL_InitRandomTable( void );
void GL_BuildLightmaps( void );
void GL_ResetFogColor( void );
void R_GenerateVBO( void );
@@ -456,9 +424,6 @@ void CL_DrawTracers( double frametime, particle_t *cl_active_tracers );
//
// gl_sprite.c
//
void R_SpriteInit( void );
void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, uint texFlags );
mspriteframe_t *R_GetSpriteFrame( const model_t *pModel, int frame, float yaw );
void R_DrawSpriteModel( cl_entity_t *e );
//
@@ -493,7 +458,6 @@ void R_ClearSkyBox( void );
void R_DrawSkyBox( void );
void R_DrawClouds( void );
void R_UnloadSkybox( void );
void EmitWaterPolys( msurface_t *warp, qboolean reverse, qboolean ripples );
void R_ResetRipples( void );
void R_AnimateRipples( void );
qboolean R_UploadRipples( texture_t *image );
@@ -518,7 +482,6 @@ void R_RenderFrame( const struct ref_viewpass_s *vp );
void R_EndFrame( void );
void R_ClearScene( void );
void R_GetTextureParms( int *w, int *h, int texnum );
void R_GetSpriteParms( int *frameWidth, int *frameHeight, int *numFrames, int curFrame, const struct model_s *pSprite );
void R_DrawStretchRaw( float x, float y, float w, float h, int cols, int rows, const byte *data, qboolean dirty );
void R_DrawStretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, int texnum );
qboolean R_SpeedsMessage( char *out, size_t size );
@@ -526,20 +489,17 @@ qboolean R_CullBox( const vec3_t mins, const vec3_t maxs );
int R_WorldToScreen( const vec3_t point, vec3_t screen );
void R_ScreenToWorld( const vec3_t screen, vec3_t point );
qboolean R_AddEntity( struct cl_entity_s *pRefEntity, int entityType );
void Mod_SpriteUnloadTextures( void *data );
void Mod_UnloadAliasModel( struct model_s *mod );
void Mod_AliasUnloadTextures( void *data );
void GL_SetRenderMode( int mode );
void R_RunViewmodelEvents( void );
void R_DrawViewModel( void );
int R_GetSpriteTexture( const struct model_s *m_pSpriteModel, int frame );
void R_DecalShoot( int textureIndex, int entityIndex, int modelIndex, vec3_t pos, int flags, float scale );
void R_DecalRemoveAll( int texture );
int R_CreateDecalList( decallist_t *pList );
void R_ClearAllDecals( void );
byte *Mod_GetCurrentVis( void );
void Mod_SetOrthoBounds( const float *mins, const float *maxs );
void CL_AddCustomBeam( cl_entity_t *pEnvBeam );
//
// gl_opengl.c
@@ -699,13 +659,6 @@ extern glconfig_t glConfig;
extern glstate_t glState;
// move to engine
extern glwstate_t glw_state;
extern ref_api_t gEngfuncs;
extern ref_globals_t *gpGlobals;
extern ref_client_t *gp_cl;
extern ref_host_t *gp_host;
#define ENGINE_GET_PARM_ (*gEngfuncs.EngineGetParm)
#define ENGINE_GET_PARM( parm ) ENGINE_GET_PARM_( ( parm ), 0 )
//
// helper funcs
@@ -795,7 +748,6 @@ extern convar_t gl_stencilbits;
extern convar_t gl_overbright;
extern convar_t gl_fog;
extern convar_t r_lighting_extended;
extern convar_t r_lighting_ambient;
extern convar_t r_studio_lambert;
extern convar_t r_detailtextures;
@@ -815,28 +767,16 @@ extern convar_t r_ripple;
extern convar_t r_ripple_updatetime;
extern convar_t r_ripple_spawntime;
extern convar_t r_large_lightmaps;
extern convar_t r_dlight_virtual_radius;
//
// engine shared convars
//
DECLARE_ENGINE_SHARED_CVAR_LIST()
//
// engine callbacks
//
#include "crtlib.h"
void _Mem_Free( void *data, const char *filename, int fileline );
void *_Mem_Alloc( poolhandle_t poolptr, size_t size, qboolean clear, const char *filename, int fileline )
ALLOC_CHECK( 2 ) MALLOC_LIKE( _Mem_Free, 1 ) WARN_UNUSED_RESULT;
#define Mem_Malloc( pool, size ) _Mem_Alloc( pool, size, false, __FILE__, __LINE__ )
#define Mem_Calloc( pool, size ) _Mem_Alloc( pool, size, true, __FILE__, __LINE__ )
#define Mem_Realloc( pool, ptr, size ) gEngfuncs._Mem_Realloc( pool, ptr, size, true, __FILE__, __LINE__ )
#define Mem_Free( mem ) _Mem_Free( mem, __FILE__, __LINE__ )
#define Mem_AllocPool( name ) gEngfuncs._Mem_AllocPool( name, __FILE__, __LINE__ )
#define Mem_FreePool( pool ) gEngfuncs._Mem_FreePool( pool, __FILE__, __LINE__ )
#define Mem_EmptyPool( pool ) gEngfuncs._Mem_EmptyPool( pool, __FILE__, __LINE__ )
#endif // GL_LOCAL_H

View File

@@ -22,7 +22,6 @@ CVAR_DEFINE_AUTO( gl_msaa, "1", FCVAR_GLCONFIG, "enable or disable multisample a
CVAR_DEFINE_AUTO( gl_stencilbits, "8", FCVAR_GLCONFIG|FCVAR_READ_ONLY, "pixelformat stencil bits (0 - auto)" );
CVAR_DEFINE_AUTO( gl_overbright, "1", FCVAR_GLCONFIG, "overbrights" );
CVAR_DEFINE_AUTO( gl_fog, "1", FCVAR_GLCONFIG, "allow for rendering fog using built-in OpenGL fog implementation" );
CVAR_DEFINE_AUTO( r_lighting_extended, "1", FCVAR_GLCONFIG, "allow to get lighting from world and bmodels" );
CVAR_DEFINE_AUTO( r_lighting_ambient, "0.3", FCVAR_GLCONFIG, "map ambient lighting scale" );
CVAR_DEFINE_AUTO( r_detailtextures, "1", FCVAR_GLCONFIG, "enable detail textures support" );
CVAR_DEFINE_AUTO( r_novis, "0", 0, "ignore vis information (perfomance test)" );
@@ -39,11 +38,7 @@ CVAR_DEFINE_AUTO( r_ripple, "0", FCVAR_GLCONFIG, "enable software-like water tex
CVAR_DEFINE_AUTO( r_ripple_updatetime, "0.05", FCVAR_GLCONFIG, "how fast ripple simulation is" );
CVAR_DEFINE_AUTO( r_ripple_spawntime, "0.1", FCVAR_GLCONFIG, "how fast new ripples spawn" );
CVAR_DEFINE_AUTO( r_large_lightmaps, "0", FCVAR_GLCONFIG|FCVAR_LATCH, "enable larger lightmap atlas textures (might break custom renderer mods)" );
CVAR_DEFINE_AUTO( r_dlight_virtual_radius, "3", FCVAR_GLCONFIG, "increase dlight radius virtually by this amount, should help against ugly cut off dlights on highly scaled textures" );
DEFINE_ENGINE_SHARED_CVAR_LIST()
poolhandle_t r_temppool;
gl_globals_t tr;
glconfig_t glConfig;
@@ -1141,9 +1136,6 @@ GL_InitCommands
*/
static void GL_InitCommands( void )
{
RETRIEVE_ENGINE_SHARED_CVAR_LIST();
gEngfuncs.Cvar_RegisterVariable( &r_lighting_extended );
gEngfuncs.Cvar_RegisterVariable( &r_lighting_ambient );
gEngfuncs.Cvar_RegisterVariable( &r_novis );
gEngfuncs.Cvar_RegisterVariable( &r_nocull );
@@ -1162,7 +1154,6 @@ static void GL_InitCommands( void )
gEngfuncs.Cvar_RegisterVariable( &r_vbo_overbrightmode );
gEngfuncs.Cvar_RegisterVariable( &r_vbo_detail );
gEngfuncs.Cvar_RegisterVariable( &r_large_lightmaps );
gEngfuncs.Cvar_RegisterVariable( &r_dlight_virtual_radius );
gEngfuncs.Cvar_RegisterVariable( &gl_extensions );
gEngfuncs.Cvar_RegisterVariable( &gl_texture_nearest );
@@ -1276,13 +1267,11 @@ qboolean R_Init( void )
tr.lightgammatable = (uint *)ENGINE_GET_PARM( PARM_GET_LIGHTGAMMATABLE_PTR );
tr.screengammatable = (uint *)ENGINE_GET_PARM( PARM_GET_SCREENGAMMATABLE_PTR );
tr.lineargammatable = (uint *)ENGINE_GET_PARM( PARM_GET_LINEARGAMMATABLE_PTR );
tr.dlights = (dlight_t *)ENGINE_GET_PARM( PARM_GET_DLIGHTS_PTR );
tr.elights = (dlight_t *)ENGINE_GET_PARM( PARM_GET_ELIGHTS_PTR );
GL_SetDefaults();
R_CheckVBO();
R_InitImages();
R_SpriteInit();
R_StudioInit();
R_AliasInit();
R_ClearDecals();

View File

@@ -243,9 +243,6 @@ qboolean R_AddEntity( struct cl_entity_s *clent, int type )
if( !r_drawentities->value )
return false; // not allow to drawing
if( !clent || !clent->model )
return false; // if set to invisible, skip
if( FBitSet( clent->curstate.effects, EF_NODRAW ))
return false; // done
@@ -260,10 +257,22 @@ qboolean R_AddEntity( struct cl_entity_s *clent, int type )
case ET_TEMPENTITY:
r_stats.c_active_tents_count++;
break;
default: break;
}
if( R_OpaqueEntity( clent ))
if( type == ET_BEAM )
{
if( tr.draw_list->num_beam_entities >= MAX_VISIBLE_PACKET )
{
gEngfuncs.Con_Printf( S_ERROR "Too many beams %d!\n", tr.draw_list->num_beam_entities );
return false;
}
tr.draw_list->beam_entities[tr.draw_list->num_beam_entities] = clent;
tr.draw_list->num_beam_entities++;
return true;
}
else if( R_OpaqueEntity( clent ))
{
// opaque
if( tr.draw_list->num_solid_entities >= MAX_VISIBLE_PACKET )
@@ -989,7 +998,7 @@ void R_RenderScene( void )
// begin a new frame
tr.framecount++;
R_PushDlights();
tr.dlightframecount = R_PushDlights( WORLDMODEL, tr.framecount );
R_SetupFrustum();
R_SetupFrame();

View File

@@ -1,189 +0,0 @@
/*
gl_rmath.c - renderer mathlib
Copyright (C) 2010 Uncle Mike
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#include "gl_local.h"
#include "xash3d_mathlib.h"
/*
========================================================================
Matrix4x4 operations (private to renderer)
========================================================================
*/
void Matrix4x4_Concat( matrix4x4 out, const matrix4x4 in1, const matrix4x4 in2 )
{
out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] + in1[0][2] * in2[2][0] + in1[0][3] * in2[3][0];
out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] + in1[0][2] * in2[2][1] + in1[0][3] * in2[3][1];
out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] + in1[0][2] * in2[2][2] + in1[0][3] * in2[3][2];
out[0][3] = in1[0][0] * in2[0][3] + in1[0][1] * in2[1][3] + in1[0][2] * in2[2][3] + in1[0][3] * in2[3][3];
out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] + in1[1][2] * in2[2][0] + in1[1][3] * in2[3][0];
out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] + in1[1][2] * in2[2][1] + in1[1][3] * in2[3][1];
out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] + in1[1][2] * in2[2][2] + in1[1][3] * in2[3][2];
out[1][3] = in1[1][0] * in2[0][3] + in1[1][1] * in2[1][3] + in1[1][2] * in2[2][3] + in1[1][3] * in2[3][3];
out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] + in1[2][2] * in2[2][0] + in1[2][3] * in2[3][0];
out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] + in1[2][2] * in2[2][1] + in1[2][3] * in2[3][1];
out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] + in1[2][2] * in2[2][2] + in1[2][3] * in2[3][2];
out[2][3] = in1[2][0] * in2[0][3] + in1[2][1] * in2[1][3] + in1[2][2] * in2[2][3] + in1[2][3] * in2[3][3];
out[3][0] = in1[3][0] * in2[0][0] + in1[3][1] * in2[1][0] + in1[3][2] * in2[2][0] + in1[3][3] * in2[3][0];
out[3][1] = in1[3][0] * in2[0][1] + in1[3][1] * in2[1][1] + in1[3][2] * in2[2][1] + in1[3][3] * in2[3][1];
out[3][2] = in1[3][0] * in2[0][2] + in1[3][1] * in2[1][2] + in1[3][2] * in2[2][2] + in1[3][3] * in2[3][2];
out[3][3] = in1[3][0] * in2[0][3] + in1[3][1] * in2[1][3] + in1[3][2] * in2[2][3] + in1[3][3] * in2[3][3];
}
/*
================
Matrix4x4_CreateProjection
NOTE: produce quake style world orientation
================
*/
void Matrix4x4_CreateProjection( matrix4x4 out, float xMax, float xMin, float yMax, float yMin, float zNear, float zFar )
{
out[0][0] = ( 2.0f * zNear ) / ( xMax - xMin );
out[1][1] = ( 2.0f * zNear ) / ( yMax - yMin );
out[2][2] = -( zFar + zNear ) / ( zFar - zNear );
out[3][3] = out[0][1] = out[1][0] = out[3][0] = out[0][3] = out[3][1] = out[1][3] = 0.0f;
out[2][0] = 0.0f;
out[2][1] = 0.0f;
out[0][2] = ( xMax + xMin ) / ( xMax - xMin );
out[1][2] = ( yMax + yMin ) / ( yMax - yMin );
out[3][2] = -1.0f;
out[2][3] = -( 2.0f * zFar * zNear ) / ( zFar - zNear );
}
void Matrix4x4_CreateOrtho( matrix4x4 out, float xLeft, float xRight, float yBottom, float yTop, float zNear, float zFar )
{
out[0][0] = 2.0f / (xRight - xLeft);
out[1][1] = 2.0f / (yTop - yBottom);
out[2][2] = -2.0f / (zFar - zNear);
out[3][3] = 1.0f;
out[0][1] = out[0][2] = out[1][0] = out[1][2] = out[3][0] = out[3][1] = out[3][2] = 0.0f;
out[2][0] = 0.0f;
out[2][1] = 0.0f;
out[0][3] = -(xRight + xLeft) / (xRight - xLeft);
out[1][3] = -(yTop + yBottom) / (yTop - yBottom);
out[2][3] = -(zFar + zNear) / (zFar - zNear);
}
/*
================
Matrix4x4_CreateModelview
NOTE: produce quake style world orientation
================
*/
void Matrix4x4_CreateModelview( matrix4x4 out )
{
out[0][0] = out[1][1] = out[2][2] = 0.0f;
out[3][0] = out[0][3] = 0.0f;
out[3][1] = out[1][3] = 0.0f;
out[3][2] = out[2][3] = 0.0f;
out[3][3] = 1.0f;
out[1][0] = out[0][2] = out[2][1] = 0.0f;
out[2][0] = out[0][1] = -1.0f;
out[1][2] = 1.0f;
}
void Matrix4x4_ToArrayFloatGL( const matrix4x4 in, float out[16] )
{
out[ 0] = in[0][0];
out[ 1] = in[1][0];
out[ 2] = in[2][0];
out[ 3] = in[3][0];
out[ 4] = in[0][1];
out[ 5] = in[1][1];
out[ 6] = in[2][1];
out[ 7] = in[3][1];
out[ 8] = in[0][2];
out[ 9] = in[1][2];
out[10] = in[2][2];
out[11] = in[3][2];
out[12] = in[0][3];
out[13] = in[1][3];
out[14] = in[2][3];
out[15] = in[3][3];
}
static void Matrix4x4_CreateTranslate( matrix4x4 out, float x, float y, float z )
{
out[0][0] = 1.0f;
out[0][1] = 0.0f;
out[0][2] = 0.0f;
out[0][3] = x;
out[1][0] = 0.0f;
out[1][1] = 1.0f;
out[1][2] = 0.0f;
out[1][3] = y;
out[2][0] = 0.0f;
out[2][1] = 0.0f;
out[2][2] = 1.0f;
out[2][3] = z;
out[3][0] = 0.0f;
out[3][1] = 0.0f;
out[3][2] = 0.0f;
out[3][3] = 1.0f;
}
static void Matrix4x4_CreateRotate( matrix4x4 out, float angle, float x, float y, float z )
{
float len, c, s;
len = x * x + y * y + z * z;
if( len != 0.0f ) len = 1.0f / sqrt( len );
x *= len;
y *= len;
z *= len;
angle *= (-M_PI_F / 180.0f);
SinCos( angle, &s, &c );
out[0][0]=x * x + c * (1 - x * x);
out[0][1]=x * y * (1 - c) + z * s;
out[0][2]=z * x * (1 - c) - y * s;
out[0][3]=0.0f;
out[1][0]=x * y * (1 - c) - z * s;
out[1][1]=y * y + c * (1 - y * y);
out[1][2]=y * z * (1 - c) + x * s;
out[1][3]=0.0f;
out[2][0]=z * x * (1 - c) + y * s;
out[2][1]=y * z * (1 - c) - x * s;
out[2][2]=z * z + c * (1 - z * z);
out[2][3]=0.0f;
out[3][0]=0.0f;
out[3][1]=0.0f;
out[3][2]=0.0f;
out[3][3]=1.0f;
}
void Matrix4x4_ConcatTranslate( matrix4x4 out, float x, float y, float z )
{
matrix4x4 base, temp;
Matrix4x4_Copy( base, out );
Matrix4x4_CreateTranslate( temp, x, y, z );
Matrix4x4_Concat( out, base, temp );
}
void Matrix4x4_ConcatRotate( matrix4x4 out, float angle, float x, float y, float z )
{
matrix4x4 base, temp;
Matrix4x4_Copy( base, out );
Matrix4x4_CreateRotate( temp, angle, x, y, z );
Matrix4x4_Concat( out, base, temp );
}

View File

@@ -17,6 +17,14 @@ GNU General Public License for more details.
#include "xash3d_mathlib.h"
#include "mod_local.h"
#define TURBSCALE ( 256.0f / ( M_PI2 ))
// speed up sin calculations
static const float r_turbsin[] =
{
#include "warpsin.h"
};
typedef struct
{
int allocated[BLOCK_SIZE_MAX];
@@ -32,7 +40,6 @@ static vec2_t world_orthohalf;
static uint r_blocklights[BLOCK_SIZE_MAX*BLOCK_SIZE_MAX*3];
static mextrasurf_t *fullbright_surfaces[MAX_TEXTURES];
static mextrasurf_t *detail_surfaces[MAX_TEXTURES];
static int rtable[MOD_FRAMES][MOD_FRAMES];
typedef struct
{
@@ -324,7 +331,8 @@ void GL_SubdivideSurface( model_t *loadmodel, msurface_t *fa )
for( i = 0; i < fa->numedges; i++ )
R_GetEdgePosition( loadmodel, fa, i, verts[i] );
SetBits( fa->flags, SURF_DRAWTURB_QUADS ); // predict state
if( glConfig.context == CONTEXT_TYPE_GL )
SetBits( fa->flags, SURF_DRAWTURB_QUADS ); // predict state
// do subdivide
SubdividePolygon_r( loadmodel, fa, fa->numedges, verts[0] );
@@ -567,7 +575,7 @@ static void R_AddDynamicLights( const msurface_t *surf )
if( !FBitSet( surf->dlightbits, BIT( lnum )))
continue; // not lit by this light
dl = &tr.dlights[lnum];
dl = &gp_dlights[lnum];
// transform light origin to local bmodel space
if( !tr.modelviewIdentity )
@@ -629,21 +637,6 @@ static void R_AddDynamicLights( const msurface_t *surf )
}
}
/*
================
R_SetCacheState
================
*/
static void R_SetCacheState( msurface_t *surf )
{
int maps;
for( maps = 0; maps < MAXLIGHTMAPS && surf->styles[maps] != 255; maps++ )
{
surf->cached_light[maps] = tr.lightstylevalue[surf->styles[maps]];
}
}
/*
=============================================================================
@@ -774,7 +767,7 @@ static void R_BuildLightMap( const msurface_t *surf, byte *dest, int stride, qbo
if( surf->styles[map] >= 255 )
break;
scale = tr.lightstylevalue[surf->styles[map]];
scale = g_lightstylevalue[surf->styles[map]];
for( i = 0; i < size; i++ )
{
@@ -944,6 +937,89 @@ static void DrawGLPoly( glpoly2_t *p, float xScale, float yScale )
GL_SetupFogColorForSurfaces();
}
/*
=============
EmitWaterPolys
Does a water warp on the pre-fragmented glpoly_t chain
=============
*/
static void EmitWaterPolys( msurface_t *warp, qboolean reverse, qboolean ripples )
{
float *v, nv, waveHeight;
float s, t, os, ot;
glpoly2_t *p;
int i;
const qboolean useQuads = FBitSet( warp->flags, SURF_DRAWTURB_QUADS ) && glConfig.context == CONTEXT_TYPE_GL;
if( !warp->polys ) return;
// set the current waveheight
if( warp->polys->verts[0][2] >= RI.vieworg[2] )
waveHeight = -RI.currententity->curstate.scale;
else waveHeight = RI.currententity->curstate.scale;
// reset fog color for nonlightmapped water
GL_ResetFogColor();
if( useQuads )
pglBegin( GL_QUADS );
for( p = warp->polys; p; p = p->next )
{
if( reverse )
v = p->verts[0] + ( p->numverts - 1 ) * VERTEXSIZE;
else v = p->verts[0];
if( !useQuads )
pglBegin( GL_POLYGON );
for( i = 0; i < p->numverts; i++ )
{
if( waveHeight )
{
nv = r_turbsin[(int)(gp_cl->time * 160.0f + v[1] + v[0]) & 255] + 8.0f;
nv = (r_turbsin[(int)(v[0] * 5.0f + gp_cl->time * 171.0f - v[1]) & 255] + 8.0f ) * 0.8f + nv;
nv = nv * waveHeight + v[2];
}
else nv = v[2];
os = v[3];
ot = v[4];
if( !ripples )
{
s = os + r_turbsin[(int)((ot * 0.125f + gp_cl->time) * TURBSCALE) & 255];
t = ot + r_turbsin[(int)((os * 0.125f + gp_cl->time) * TURBSCALE) & 255];
}
else
{
s = os;
t = ot;
}
s *= ( 1.0f / SUBDIVIDE_SIZE );
t *= ( 1.0f / SUBDIVIDE_SIZE );
pglTexCoord2f( s, t );
pglVertex3f( v[0], v[1], nv );
if( reverse )
v -= VERTEXSIZE;
else v += VERTEXSIZE;
}
if( !useQuads )
pglEnd();
}
if( useQuads )
pglEnd();
GL_SetupFogColorForSurfaces();
}
/*
================
DrawGLPolyChain
@@ -1306,7 +1382,7 @@ static qboolean R_CheckLightMap( msurface_t *fa )
// check for light styles
for( maps = 0; maps < MAXLIGHTMAPS && fa->styles[maps] != 255; maps++ )
{
if( tr.lightstylevalue[fa->styles[maps]] == fa->cached_light[maps] )
if( g_lightstylevalue[fa->styles[maps]] == fa->cached_light[maps] )
continue;
const int style = fa->styles[maps];
@@ -1331,7 +1407,7 @@ static qboolean R_CheckLightMap( msurface_t *fa )
//Host_MapDesignError( "%s: bad surface extents: %d %d", __func__, fa->extents[0], fa->extents[1] );
}
R_SetCacheState( fa );
R_UpdateSurfaceCachedLight( fa );
#if XASH_WES
GL_Bind( XASH_TEXTURE1, tr.lightmapTextures[fa->lightmaptexturenum] );
@@ -1766,20 +1842,7 @@ void R_DrawBrushModel( cl_entity_t *e )
e->visframe = tr.realframecount; // visible
// calculate dynamic lighting for bmodel
for( int k = 0; k < MAX_DLIGHTS; k++ )
{
dlight_t *l = &tr.dlights[k];
vec3_t origin_l, oldorigin;
if( l->die < gp_cl->time || !l->radius )
continue;
VectorCopy( l->origin, oldorigin ); // save lightorigin
Matrix4x4_VectorITransform( RI.objectMatrix, l->origin, origin_l );
VectorCopy( origin_l, l->origin ); // move light in bmodel space
R_MarkLights( l, 1<<k, clmodel->nodes + clmodel->hulls[0].firstclipnode );
VectorCopy( oldorigin, l->origin ); // restore lightorigin
}
R_PushDlightsForBmodel( clmodel, tr.dlightframecount, RI.objectMatrix );
// setup the rendermode
R_SetRenderMode( e );
@@ -2461,14 +2524,13 @@ static texture_t *R_SetupVBOTexture( texture_t *tex, int number )
}
else R_DisableDetail();
GL_Bind( mtst.tmu_gl, r_lightmap->value ?tr.whiteTexture:tex->gl_texturenum );
if(number)
GL_Bind( mtst.tmu_gl, r_lightmap->value ? tr.whiteTexture : tex->gl_texturenum );
if( number )
vboarray.itexture = number;
return tex;
}
static void R_SetupVBOArrayStatic( vboarray_t *vbo, qboolean drawlightmap, qboolean drawtextures )
{
if( vboarray.astate != VBO_ARRAY_STATIC )
@@ -2483,7 +2545,6 @@ static void R_SetupVBOArrayStatic( vboarray_t *vbo, qboolean drawlightmap, qbool
pglVertexPointer( 3, GL_FLOAT, sizeof( vbovertex_t ), (void*)offsetof(vbovertex_t,pos) );
}
// setup multitexture
if( drawtextures && vboarray.tstate != VBO_TEXTURE_MAIN )
{
@@ -2512,11 +2573,8 @@ static void R_SetupVBOArrayStatic( vboarray_t *vbo, qboolean drawlightmap, qbool
}
}
static void R_SetupVBOArrayDlight( vboarray_t *vbo, texture_t *texture )
{
if( vboarray.astate != VBO_ARRAY_DLIGHT )
{
if( vboarray.astate == VBO_ARRAY_DECAL_DLIGHT )
@@ -2584,7 +2642,6 @@ static void R_SetupVBOArrayDecalDlight( int decalcount )
vboarray.lstate = VBO_LIGHTMAP_DYNAMIC;
}
/*
===================
R_AdditionalPasses
@@ -2652,11 +2709,9 @@ static void R_AdditionalPasses( vboarray_t *vbo, int indexlen, void *indexarray,
}
}
#define MINIMIZE_UPLOAD
#define DISCARD_DLIGHTS
static void R_DrawDlightedDecals( vboarray_t *vbo, msurface_t *newsurf, msurface_t *surf, int decalcount, texture_t *texture )
{
msurface_t *decalsurf;
@@ -2691,7 +2746,9 @@ static void R_DrawDlightedDecals( vboarray_t *vbo, msurface_t *newsurf, msurface
if( glt->fogParams[3] > 230 )
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
else pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
if( FBitSet( glt->flags, TF_PREMULTIPLIED ))
pglBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA );
else pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
}
else
{
@@ -3113,7 +3170,9 @@ static void R_DrawStaticDecals( vboarray_t *vbo, qboolean drawlightmap, int ilig
if( glt->fogParams[3] > 230 )
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
else pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
if( FBitSet( glt->flags, TF_PREMULTIPLIED ))
pglBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA );
else pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
}
else
{
@@ -3784,7 +3843,7 @@ static void GL_CreateSurfaceLightmap( msurface_t *surf, model_t *loadmodel )
base = gl_lms.lightmap_buffer;
base += ( surf->light_t * BLOCK_SIZE + surf->light_s ) * 4;
R_SetCacheState( surf );
R_UpdateSurfaceCachedLight( surf );
R_BuildLightMap( surf, base, BLOCK_SIZE * 4, false );
}
@@ -3920,17 +3979,3 @@ void GL_BuildLightmaps( void )
}
}
void GL_InitRandomTable( void )
{
int tu, tv;
for( tu = 0; tu < MOD_FRAMES; tu++ )
{
for( tv = 0; tv < MOD_FRAMES; tv++ )
{
rtable[tu][tv] = gEngfuncs.COM_RandomLong( 0, 0x7FFF );
}
}
gEngfuncs.COM_SetRandomSeed( 0 );
}

View File

@@ -21,329 +21,8 @@ GNU General Public License for more details.
#define GLARE_FALLOFF 19000.0f
static char sprite_name[MAX_QPATH];
static char group_suffix[8];
static uint r_texFlags = 0;
static int sprite_version;
static float sprite_radius;
/*
====================
R_SpriteInit
====================
*/
void R_SpriteInit( void )
{
}
/*
====================
R_SpriteLoadFrame
upload a single frame
====================
*/
static const byte *R_SpriteLoadFrame( model_t *mod, const void *pin, mspriteframe_t **ppframe, int num )
{
dspriteframe_t pinframe;
mspriteframe_t *pspriteframe;
int gl_texturenum = 0;
char texname[128];
int bytes = 1;
memcpy( &pinframe, pin, sizeof( dspriteframe_t ));
if( sprite_version == SPRITE_VERSION_32 )
bytes = 4;
// build uinque frame name
if( FBitSet( mod->flags, MODEL_CLIENT )) // it's a HUD sprite
{
Q_snprintf( texname, sizeof( texname ), "#HUD/%s(%s:%i%i).spr", sprite_name, group_suffix, num / 10, num % 10 );
gl_texturenum = GL_LoadTexture( texname, pin, pinframe.width * pinframe.height * bytes, r_texFlags );
}
else
{
// partial HD-textures support
if( Mod_AllowMaterials( ))
{
if( R_SearchForTextureReplacement( texname, sizeof( texname ), sprite_name, "materials/%s/%s%i%i.tga", sprite_name, group_suffix, num / 10, num % 10 ))
{
gl_texturenum = GL_LoadTexture( texname, NULL, 0, r_texFlags );
R_TextureReplacementReport( sprite_name, gl_texturenum, texname );
}
}
if( gl_texturenum == 0 )
{
Q_snprintf( texname, sizeof( texname ), "#%s(%s:%i%i).spr", sprite_name, group_suffix, num / 10, num % 10 );
gl_texturenum = GL_LoadTexture( texname, pin, pinframe.width * pinframe.height * bytes, r_texFlags );
}
}
// setup frame description
pspriteframe = Mem_Malloc( mod->mempool, sizeof( mspriteframe_t ));
pspriteframe->width = pinframe.width;
pspriteframe->height = pinframe.height;
pspriteframe->up = pinframe.origin[1];
pspriteframe->left = pinframe.origin[0];
pspriteframe->down = pinframe.origin[1] - pinframe.height;
pspriteframe->right = pinframe.width + pinframe.origin[0];
pspriteframe->gl_texturenum = gl_texturenum;
*ppframe = pspriteframe;
return (( const byte* )pin + sizeof( dspriteframe_t ) + pinframe.width * pinframe.height * bytes );
}
/*
====================
R_SpriteLoadGroup
upload a group frames
====================
*/
static const byte *R_SpriteLoadGroup( model_t *mod, const void *pin, mspriteframe_t **ppframe, int framenum )
{
const dspritegroup_t *pingroup;
mspritegroup_t *pspritegroup;
const dspriteinterval_t *pin_intervals;
float *poutintervals;
int i, groupsize, numframes;
const void *ptemp;
pingroup = (const dspritegroup_t *)pin;
numframes = pingroup->numframes;
groupsize = sizeof( mspritegroup_t ) + (numframes - 1) * sizeof( pspritegroup->frames[0] );
pspritegroup = Mem_Calloc( mod->mempool, groupsize );
pspritegroup->numframes = numframes;
*ppframe = (mspriteframe_t *)pspritegroup;
pin_intervals = (const dspriteinterval_t *)(pingroup + 1);
poutintervals = Mem_Calloc( mod->mempool, numframes * sizeof( float ));
pspritegroup->intervals = poutintervals;
for( i = 0; i < numframes; i++ )
{
*poutintervals = pin_intervals->interval;
if( *poutintervals <= 0.0f )
*poutintervals = 1.0f; // set error value
poutintervals++;
pin_intervals++;
}
ptemp = (const void *)pin_intervals;
for( i = 0; i < numframes; i++ )
{
ptemp = R_SpriteLoadFrame( mod, ptemp, &pspritegroup->frames[i], framenum * 10 + i );
}
return ptemp;
}
/*
====================
Mod_LoadSpriteModel
load sprite model
====================
*/
void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, uint texFlags )
{
const dsprite_t *pin;
const short *numi = NULL;
const byte *pframetype;
msprite_t *psprite;
int i;
pin = buffer;
psprite = mod->cache.data;
if( pin->version == SPRITE_VERSION_Q1 || pin->version == SPRITE_VERSION_32 )
numi = NULL;
else if( pin->version == SPRITE_VERSION_HL )
numi = (const short *)((const byte *)buffer + sizeof( dsprite_hl_t ));
r_texFlags = texFlags;
sprite_version = pin->version;
Q_strncpy( sprite_name, mod->name, sizeof( sprite_name ));
COM_StripExtension( sprite_name );
if( numi == NULL )
{
rgbdata_t *pal;
pal = gEngfuncs.FS_LoadImage( "#id.pal", (byte *)&i, 768 );
pframetype = ((const byte*)buffer + sizeof( dsprite_q1_t )); // pinq1 + 1
gEngfuncs.FS_FreeImage( pal ); // palette installed, no reason to keep this data
}
else if( *numi <= 256 )
{
const byte *src = (const byte *)(numi+1);
rgbdata_t *pal;
size_t pal_bytes = *numi * 3;
// install palette
switch( psprite->texFormat )
{
case SPR_INDEXALPHA:
pal = gEngfuncs.FS_LoadImage( "#gradient.pal", src, pal_bytes );
break;
case SPR_ALPHTEST:
pal = gEngfuncs.FS_LoadImage( "#masked.pal", src, pal_bytes );
break;
default:
pal = gEngfuncs.FS_LoadImage( "#texgamma.pal", src, pal_bytes );
break;
}
pframetype = (const byte *)(src + pal_bytes);
gEngfuncs.FS_FreeImage( pal ); // palette installed, no reason to keep this data
}
else
{
gEngfuncs.Con_DPrintf( S_ERROR "%s has wrong number of palette colors %i (should be less or equal than 256)\n", mod->name, *numi );
return;
}
if( mod->numframes < 1 )
return;
for( i = 0; i < mod->numframes; i++ )
{
frametype_t frametype;
dframetype_t dframetype;
memcpy( &dframetype, pframetype, sizeof( dframetype ));
frametype = dframetype.type;
psprite->frames[i].type = (spriteframetype_t)frametype;
switch( frametype )
{
case FRAME_SINGLE:
Q_strncpy( group_suffix, "frame", sizeof( group_suffix ));
pframetype = R_SpriteLoadFrame( mod, pframetype + sizeof( dframetype_t ), &psprite->frames[i].frameptr, i );
break;
case FRAME_GROUP:
Q_strncpy( group_suffix, "group", sizeof( group_suffix ));
pframetype = R_SpriteLoadGroup( mod, pframetype + sizeof( dframetype_t ), &psprite->frames[i].frameptr, i );
break;
case FRAME_ANGLED:
Q_strncpy( group_suffix, "angle", sizeof( group_suffix ));
pframetype = R_SpriteLoadGroup( mod, pframetype + sizeof( dframetype_t ), &psprite->frames[i].frameptr, i );
break;
}
if( pframetype == NULL ) break; // technically an error
}
if( loaded ) *loaded = true; // done
}
/*
====================
Mod_UnloadSpriteModel
release sprite model and frames
====================
*/
void Mod_SpriteUnloadTextures( void *data )
{
msprite_t *psprite = data;
int i;
if( !data )
return;
// release all textures
for( i = 0; i < psprite->numframes; i++ )
{
if( !psprite->frames[i].frameptr )
continue;
if( psprite->frames[i].type == SPR_SINGLE )
{
GL_FreeTexture( psprite->frames[i].frameptr->gl_texturenum );
}
else
{
mspritegroup_t *pspritegroup = (mspritegroup_t *)psprite->frames[i].frameptr;
int j;
for( j = 0; j < pspritegroup->numframes; j++ )
{
if( pspritegroup->frames[j] )
GL_FreeTexture( pspritegroup->frames[j]->gl_texturenum );
}
}
}
}
/*
================
R_GetSpriteFrame
assume pModel is valid
================
*/
mspriteframe_t *R_GetSpriteFrame( const model_t *pModel, int frame, float yaw )
{
msprite_t *psprite;
mspritegroup_t *pspritegroup;
mspriteframe_t *pspriteframe = NULL;
float *pintervals, fullinterval;
int i, numframes;
float targettime;
Assert( pModel != NULL );
psprite = pModel->cache.data;
if( frame < 0 )
{
frame = 0;
}
else if( frame >= psprite->numframes )
{
if( frame > psprite->numframes )
gEngfuncs.Con_Printf( S_WARN "%s: no such frame %d (%s)\n", __func__, frame, pModel->name );
frame = psprite->numframes - 1;
}
if( psprite->frames[frame].type == SPR_SINGLE )
{
pspriteframe = psprite->frames[frame].frameptr;
}
else if( psprite->frames[frame].type == SPR_GROUP )
{
pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr;
pintervals = pspritegroup->intervals;
numframes = pspritegroup->numframes;
fullinterval = pintervals[numframes-1];
// when loading in Mod_LoadSpriteGroup, we guaranteed all interval values
// are positive, so we don't have to worry about division by zero
targettime = gp_cl->time - ((int)( gp_cl->time / fullinterval )) * fullinterval;
for( i = 0; i < (numframes - 1); i++ )
{
if( pintervals[i] > targettime )
break;
}
pspriteframe = pspritegroup->frames[i];
}
else if( psprite->frames[frame].type == FRAME_ANGLED )
{
int angleframe = (int)(Q_rint(( RI.viewangles[1] - yaw + 45.0f ) / 360 * 8) - 4) & 7;
// e.g. doom-style sprite monsters
pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr;
pspriteframe = pspritegroup->frames[angleframe];
}
return pspriteframe;
}
/*
================
R_GetSpriteFrameInterpolant
@@ -800,7 +479,7 @@ void R_DrawSpriteModel( cl_entity_t *e )
if( R_SpriteAllowLerping( e, psprite ))
lerp = R_GetSpriteFrameInterpolant( e, &oldframe, &frame );
else frame = oldframe = R_GetSpriteFrame( model, e->curstate.frame, e->angles[YAW] );
else frame = oldframe = gEngfuncs.R_GetSpriteFrame( model, e->curstate.frame, e->angles[YAW] );
type = psprite->type;

View File

@@ -1441,7 +1441,7 @@ static void R_StudioDynamicLight( cl_entity_t *ent, alight_t *plight )
for( lnum = 0; lnum < MAX_DLIGHTS; lnum++ )
{
dl = &tr.dlights[lnum];
dl = &gp_dlights[lnum];
if( dl->die < g_studio.time || !r_dynamic->value )
continue;

View File

@@ -245,7 +245,10 @@ int TriSpriteTexture( model_t *pSpriteModel, int frame )
{
int gl_texturenum;
if(( gl_texturenum = R_GetSpriteTexture( pSpriteModel, frame )) == 0 )
if( !pSpriteModel || pSpriteModel->type != mod_sprite || !pSpriteModel->cache.data )
return 0;
if(( gl_texturenum = gEngfuncs.R_GetSpriteFrame( pSpriteModel, frame, 0.0f )->gl_texturenum ) == 0 )
return 0;
if( gl_texturenum <= 0 || gl_texturenum >= MAX_TEXTURES )

View File

@@ -19,7 +19,6 @@ GNU General Public License for more details.
#define SKYCLOUDS_QUALITY 12
#define MAX_CLIP_VERTS 128 // skybox clip vertices
#define TURBSCALE ( 256.0f / ( M_PI2 ))
static const int r_skyTexOrder[SKYBOX_MAX_SIDES] = { 0, 2, 1, 3, 4, 5 };
@@ -55,12 +54,6 @@ static const int vec_to_st[SKYBOX_MAX_SIDES][3] =
{ -2, 1, -3 }
};
// speed up sin calculations
static float r_turbsin[] =
{
#include "warpsin.h"
};
#define RIPPLES_CACHEWIDTH_BITS 7
#define RIPPLES_CACHEWIDTH ( 1 << RIPPLES_CACHEWIDTH_BITS )
#define RIPPLES_CACHEWIDTH_MASK (( RIPPLES_CACHEWIDTH ) - 1 )
@@ -563,89 +556,6 @@ void R_DrawClouds( void )
pglFogf( GL_FOG_DENSITY, RI.fogDensity );
}
/*
=============
EmitWaterPolys
Does a water warp on the pre-fragmented glpoly_t chain
=============
*/
void EmitWaterPolys( msurface_t *warp, qboolean reverse, qboolean ripples )
{
float *v, nv, waveHeight;
float s, t, os, ot;
glpoly2_t *p;
int i;
const qboolean useQuads = FBitSet( warp->flags, SURF_DRAWTURB_QUADS ) && glConfig.context == CONTEXT_TYPE_GL;
if( !warp->polys ) return;
// set the current waveheight
if( warp->polys->verts[0][2] >= RI.vieworg[2] )
waveHeight = -RI.currententity->curstate.scale;
else waveHeight = RI.currententity->curstate.scale;
// reset fog color for nonlightmapped water
GL_ResetFogColor();
if( useQuads )
pglBegin( GL_QUADS );
for( p = warp->polys; p; p = p->next )
{
if( reverse )
v = p->verts[0] + ( p->numverts - 1 ) * VERTEXSIZE;
else v = p->verts[0];
if( !useQuads )
pglBegin( GL_POLYGON );
for( i = 0; i < p->numverts; i++ )
{
if( waveHeight )
{
nv = r_turbsin[(int)(gp_cl->time * 160.0f + v[1] + v[0]) & 255] + 8.0f;
nv = (r_turbsin[(int)(v[0] * 5.0f + gp_cl->time * 171.0f - v[1]) & 255] + 8.0f ) * 0.8f + nv;
nv = nv * waveHeight + v[2];
}
else nv = v[2];
os = v[3];
ot = v[4];
if( !ripples )
{
s = os + r_turbsin[(int)((ot * 0.125f + gp_cl->time) * TURBSCALE) & 255];
t = ot + r_turbsin[(int)((os * 0.125f + gp_cl->time) * TURBSCALE) & 255];
}
else
{
s = os;
t = ot;
}
s *= ( 1.0f / SUBDIVIDE_SIZE );
t *= ( 1.0f / SUBDIVIDE_SIZE );
pglTexCoord2f( s, t );
pglVertex3f( v[0], v[1], nv );
if( reverse )
v -= VERTEXSIZE;
else v += VERTEXSIZE;
}
if( !useQuads )
pglEnd();
}
if( useQuads )
pglEnd();
GL_SetupFogColorForSurfaces();
}
/*
============================================================

View File

@@ -25,7 +25,7 @@ def configure(conf):
conf.check_cc(lib='log')
def build(bld):
libs = [ 'engine_includes', 'werror' ]
libs = [ 'ref_common', 'engine_includes', 'werror' ]
# on PSVita do not link any libraries that are already in the main executable, but add the includes target
if bld.env.DEST_OS == 'psvita':
libs += [ 'sdk_includes', 'vgl_shim' ]

View File

@@ -75,11 +75,6 @@ static qboolean R_AddEntity( struct cl_entity_s *clent, int type )
return true;
}
static void CL_AddCustomBeam( cl_entity_t *pEnvBeam )
{
;
}
static void R_ProcessEntData( qboolean allocate, cl_entity_t *entities, unsigned int max_entities )
{
;
@@ -177,22 +172,6 @@ static void CL_RunLightStyles( lightstyle_t *ls )
}
static void R_GetSpriteParms( int *frameWidth, int *frameHeight, int *numFrames, int currentFrame, const model_t *pSprite )
{
if( frameWidth )
*frameWidth = 0;
if( frameHeight )
*frameHeight = 0;
if( numFrames )
*numFrames = 0;
}
static int R_GetSpriteTexture( const model_t *m_pSpriteModel, int frame )
{
return 0;
}
static qboolean Mod_ProcessRenderData( model_t *mod, qboolean create, const byte *buffer, size_t buffersize )
{
@@ -460,7 +439,6 @@ static const ref_interface_t gReffuncs =
.GL_SetRenderMode = R_SimpleStubInt,
.R_AddEntity = R_AddEntity,
.CL_AddCustomBeam = CL_AddCustomBeam,
.R_ProcessEntData = R_ProcessEntData,
.R_Flush = R_SimpleStubUInt,
@@ -495,8 +473,6 @@ static const ref_interface_t gReffuncs =
.GL_SubdivideSurface = GL_SubdivideSurface,
.CL_RunLightStyles = CL_RunLightStyles,
.R_GetSpriteParms = R_GetSpriteParms,
.R_GetSpriteTexture = R_GetSpriteTexture,
.Mod_ProcessRenderData = Mod_ProcessRenderData,
.Mod_StudioLoadTextures = Mod_StudioLoadTextures,
@@ -539,8 +515,6 @@ static const ref_interface_t gReffuncs =
.GL_TextureTarget = R_SimpleStubUInt,
.GL_TexCoordArrayMode = R_SimpleStubUInt,
.GL_UpdateTexSize = GL_UpdateTexSize,
.GL_Reserved0 = NULL,
.GL_Reserved1 = NULL,
.GL_DrawParticles = GL_DrawParticles,
.LightVec = LightVec,

View File

@@ -122,29 +122,6 @@ qboolean GAME_EXPORT R_BeamCull( const vec3_t start, const vec3_t end, qboolean
return false;
}
/*
================
CL_AddCustomBeam
Add the beam that encoded as custom entity
================
*/
void GAME_EXPORT CL_AddCustomBeam( cl_entity_t *pEnvBeam )
{
if( tr.draw_list->num_beam_entities >= MAX_VISIBLE_PACKET )
{
gEngfuncs.Con_Printf( S_ERROR "Too many beams %d!\n", tr.draw_list->num_beam_entities );
return;
}
if( pEnvBeam )
{
tr.draw_list->beam_entities[tr.draw_list->num_beam_entities] = pEnvBeam;
tr.draw_list->num_beam_entities++;
}
}
/*
==============================================================

View File

@@ -15,24 +15,10 @@ GNU General Public License for more details.
#include "r_local.h"
ref_api_t gEngfuncs;
ref_globals_t *gpGlobals;
ref_client_t *gp_cl;
ref_host_t *gp_host;
gl_globals_t tr;
ref_speeds_t r_stats;
poolhandle_t r_temppool;
viddef_t vid;
void _Mem_Free( void *data, const char *filename, int fileline )
{
gEngfuncs._Mem_Free( data, filename, fileline );
}
void *_Mem_Alloc( poolhandle_t poolptr, size_t size, qboolean clear, const char *filename, int fileline )
{
return gEngfuncs._Mem_Alloc( poolptr, size, clear, filename, fileline );
}
static void GAME_EXPORT R_ClearScreen( void )
{
@@ -96,7 +82,6 @@ static void Mod_UnloadTextures( model_t *mod )
Mod_BrushUnloadTextures( mod );
break;
case mod_sprite:
Mod_SpriteUnloadTextures( mod->cache.data );
break;
default: gEngfuncs.Host_Error( "%s: unsupported type %d\n", __func__, mod->type );
}
@@ -122,7 +107,7 @@ static qboolean GAME_EXPORT Mod_ProcessRenderData( model_t *mod, qboolean create
loaded = true;
break;
case mod_sprite:
Mod_LoadSpriteModel( mod, buf, &loaded, mod->numtexinfo );
loaded = true;
break;
default:
gEngfuncs.Host_Error( "%s: unsupported type %d\n", __func__, mod->type );
@@ -188,7 +173,7 @@ static int GL_RefGetParm( int parm, int arg )
return 0; // glState.activeTMU;
case PARM_LIGHTSTYLEVALUE:
arg = bound( 0, arg, MAX_LIGHTSTYLES - 1 );
return tr.lightstylevalue[arg];
return g_lightstylevalue[arg];
case PARM_MAX_IMAGE_UNITS:
return 0; // GL_MaxTextureUnits();
case PARM_REBUILD_GAMMA:
@@ -413,7 +398,7 @@ static void * GAME_EXPORT R_GetProcAddress( const char *name )
return gEngfuncs.GL_GetProcAddress( name );
}
static const ref_interface_t gReffuncs =
const ref_interface_t gReffuncs =
{
R_Init,
R_Shutdown,
@@ -438,7 +423,6 @@ static const ref_interface_t gReffuncs =
GL_SetRenderMode,
R_AddEntity,
CL_AddCustomBeam,
R_ProcessEntData,
R_Flush,
@@ -473,8 +457,6 @@ static const ref_interface_t gReffuncs =
GL_SubdivideSurface,
CL_RunLightStyles,
R_GetSpriteParms,
R_GetSpriteTexture,
Mod_ProcessRenderData,
Mod_StudioLoadTextures,
@@ -517,8 +499,6 @@ static const ref_interface_t gReffuncs =
GL_TextureTarget,
GL_SetTexCoordArrayMode,
GL_UpdateTexSize,
NULL,
NULL,
CL_DrawParticlesExternal,
R_LightVec,
@@ -550,19 +530,3 @@ static const ref_interface_t gReffuncs =
VGUI_UploadTextureBlock,
};
int EXPORT GetRefAPI( int version, ref_interface_t *funcs, ref_api_t *engfuncs, ref_globals_t *globals );
int EXPORT GetRefAPI( int version, ref_interface_t *funcs, ref_api_t *engfuncs, ref_globals_t *globals )
{
if( version != REF_API_VERSION )
return 0;
// fill in our callbacks
*funcs = gReffuncs;
gEngfuncs = *engfuncs;
gpGlobals = globals;
gp_cl = (ref_client_t *)ENGINE_GET_PARM( PARM_GET_CLIENT_PTR );
gp_host = (ref_host_t *)ENGINE_GET_PARM( PARM_GET_HOST_PTR );
return REF_API_VERSION;
}

View File

@@ -31,39 +31,6 @@ void R_GetTextureParms( int *w, int *h, int texnum )
*h = glt->srcHeight;
}
/*
=============
R_GetSpriteParms
same as GetImageParms but used
for sprite models
=============
*/
void GAME_EXPORT R_GetSpriteParms( int *frameWidth, int *frameHeight, int *numFrames, int currentFrame, const model_t *pSprite )
{
mspriteframe_t *pFrame;
if( !pSprite || pSprite->type != mod_sprite )
return; // bad model ?
pFrame = R_GetSpriteFrame( pSprite, currentFrame, 0.0f );
if( frameWidth )
*frameWidth = pFrame->width;
if( frameHeight )
*frameHeight = pFrame->height;
if( numFrames )
*numFrames = pSprite->numframes;
}
int GAME_EXPORT R_GetSpriteTexture( const model_t *m_pSpriteModel, int frame )
{
if( !m_pSpriteModel || m_pSpriteModel->type != mod_sprite || !m_pSpriteModel->cache.data )
return 0;
return R_GetSpriteFrame( m_pSpriteModel, frame, 0.0f )->gl_texturenum;
}
/*
=============
Draw_StretchPicImplementation

View File

@@ -115,98 +115,6 @@ static void GL_SetTextureDimensions( image_t *tex, int width, int height, int de
tex->depth = Q_max( 1, depth );
}
/*
=================
GL_ResampleTexture
Assume input buffer is RGBA
=================
*/
byte *GL_ResampleTexture( const byte *source, int inWidth, int inHeight, int outWidth, int outHeight, qboolean isNormalMap )
{
uint frac, fracStep;
uint *in = (uint *)source;
uint p1[0x1000], p2[0x1000];
byte *pix1, *pix2, *pix3, *pix4;
uint *out, *inRow1, *inRow2;
static byte *scaledImage = NULL; // pointer to a scaled image
vec3_t normal;
int i, x, y;
if( !source )
return NULL;
scaledImage = Mem_Realloc( r_temppool, scaledImage, outWidth * outHeight * 4 );
fracStep = inWidth * 0x10000 / outWidth;
out = (uint *)scaledImage;
frac = fracStep >> 2;
for( i = 0; i < outWidth; i++ )
{
p1[i] = 4 * ( frac >> 16 );
frac += fracStep;
}
frac = ( fracStep >> 2 ) * 3;
for( i = 0; i < outWidth; i++ )
{
p2[i] = 4 * ( frac >> 16 );
frac += fracStep;
}
if( isNormalMap )
{
for( y = 0; y < outHeight; y++, out += outWidth )
{
inRow1 = in + inWidth * (int)(((float)y + 0.25f ) * inHeight / outHeight );
inRow2 = in + inWidth * (int)(((float)y + 0.75f ) * inHeight / outHeight );
for( x = 0; x < outWidth; x++ )
{
pix1 = (byte *)inRow1 + p1[x];
pix2 = (byte *)inRow1 + p2[x];
pix3 = (byte *)inRow2 + p1[x];
pix4 = (byte *)inRow2 + p2[x];
normal[0] = MAKE_SIGNED( pix1[0] ) + MAKE_SIGNED( pix2[0] ) + MAKE_SIGNED( pix3[0] ) + MAKE_SIGNED( pix4[0] );
normal[1] = MAKE_SIGNED( pix1[1] ) + MAKE_SIGNED( pix2[1] ) + MAKE_SIGNED( pix3[1] ) + MAKE_SIGNED( pix4[1] );
normal[2] = MAKE_SIGNED( pix1[2] ) + MAKE_SIGNED( pix2[2] ) + MAKE_SIGNED( pix3[2] ) + MAKE_SIGNED( pix4[2] );
if( !VectorNormalizeLength( normal ))
VectorSet( normal, 0.5f, 0.5f, 1.0f );
((byte *)( out + x ))[0] = 128 + (byte)( 127.0f * normal[0] );
((byte *)( out + x ))[1] = 128 + (byte)( 127.0f * normal[1] );
((byte *)( out + x ))[2] = 128 + (byte)( 127.0f * normal[2] );
((byte *)( out + x ))[3] = 255;
}
}
}
else
{
for( y = 0; y < outHeight; y++, out += outWidth )
{
inRow1 = in + inWidth * (int)(((float)y + 0.25f ) * inHeight / outHeight );
inRow2 = in + inWidth * (int)(((float)y + 0.75f ) * inHeight / outHeight );
for( x = 0; x < outWidth; x++ )
{
pix1 = (byte *)inRow1 + p1[x];
pix2 = (byte *)inRow1 + p2[x];
pix3 = (byte *)inRow2 + p1[x];
pix4 = (byte *)inRow2 + p2[x];
((byte *)( out + x ))[0] = ( pix1[0] + pix2[0] + pix3[0] + pix4[0] ) >> 2;
((byte *)( out + x ))[1] = ( pix1[1] + pix2[1] + pix3[1] + pix4[1] ) >> 2;
((byte *)( out + x ))[2] = ( pix1[2] + pix2[2] + pix3[2] + pix4[2] ) >> 2;
((byte *)( out + x ))[3] = ( pix1[3] + pix2[3] + pix3[3] + pix4[3] ) >> 2;
}
}
}
return scaledImage;
}
/*
=================
GL_BuildMipMap

View File

@@ -1,463 +0,0 @@
/*
gl_rlight.c - dynamic and static lights
Copyright (C) 2010 Uncle Mike
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#include "r_local.h"
#include "pm_local.h"
#include "studio.h"
#include "xash3d_mathlib.h"
#include "ref_params.h"
// unused, need refactor
unsigned blocklights[10240];
/*
=============================================================================
DYNAMIC LIGHTS
=============================================================================
*/
/*
==================
CL_RunLightStyles
==================
*/
void CL_RunLightStyles( lightstyle_t *ls )
{
int i;
float frametime = ( gp_cl->time - gp_cl->oldtime );
if( !WORLDMODEL )
return;
if( r_fullbright->value || !WORLDMODEL->lightdata )
{
for( i = 0; i < MAX_LIGHTSTYLES; i++ )
tr.lightstylevalue[i] = 256 * 256;
return;
}
// light animations
// 'm' is normal light, 'a' is no light, 'z' is double bright
for( i = 0; i < MAX_LIGHTSTYLES; i++ )
{
int k, flight, clight;
float l, lerpfrac, backlerp;
if( !gp_cl->paused && frametime <= 0.1f )
ls[i].time += frametime; // evaluate local time
if( !ls[i].length )
{
tr.lightstylevalue[i] = 256;
continue;
}
else if( ls[i].length == 1 )
{
// single length style so don't bother interpolating
tr.lightstylevalue[i] = ( ls[i].map[0] ) * 22;
continue;
}
flight = (int)Q_floor( ls[i].time * 10 );
if( !ls[i].interp || !cl_lightstyle_lerping->value )
{
tr.lightstylevalue[i] = ls[i].map[flight % ls[i].length] * 22;
continue;
}
clight = (int)Q_ceil( ls[i].time * 10 );
lerpfrac = ( ls[i].time * 10 ) - flight;
backlerp = 1.0f - lerpfrac;
// interpolate animating light
// frame just gone
k = ls[i].map[flight % ls[i].length];
l = (float)( k * 22.0f ) * backlerp;
// upcoming frame
k = ls[i].map[clight % ls[i].length];
l += (float)( k * 22.0f ) * lerpfrac;
tr.lightstylevalue[i] = (int)l;
}
}
/*
=============
R_MarkLights
=============
*/
void R_MarkLights( dlight_t *light, int bit, mnode_t *node )
{
float dist;
msurface_t *surf;
int i;
int firstsurface, numsurfaces;
if( !node || node->contents < 0 )
return;
dist = PlaneDiff( light->origin, node->plane );
firstsurface = node_firstsurface( node, RI.currentmodel );
numsurfaces = node_numsurfaces( node, RI.currentmodel );
if( dist > light->radius )
{
R_MarkLights( light, bit, node_child( node, 0, RI.currentmodel ));
return;
}
if( dist < -light->radius )
{
R_MarkLights( light, bit, node_child( node, 1, RI.currentmodel ));
return;
}
// mark the polygons
surf = RI.currentmodel->surfaces + firstsurface;
for( i = 0; i < numsurfaces; i++, surf++ )
{
if( !BoundsAndSphereIntersect( surf->info->mins, surf->info->maxs, light->origin, light->radius ))
continue; // no intersection
if( surf->dlightframe != tr.dlightframecount )
{
surf->dlightbits = 0;
surf->dlightframe = tr.dlightframecount;
}
surf->dlightbits |= bit;
}
R_MarkLights( light, bit, node_child( node, 0, RI.currentmodel ));
R_MarkLights( light, bit, node_child( node, 1, RI.currentmodel ));
}
/*
=============
R_PushDlights
=============
*/
void R_PushDlights( void )
{
int i;
tr.dlightframecount = tr.framecount;
RI.currententity = CL_GetEntityByIndex( 0 );
// no world -- no dlights
if( !RI.currententity )
return;
RI.currentmodel = RI.currententity->model;
for( i = 0; i < MAX_DLIGHTS; i++ )
{
dlight_t *l = &tr.dlights[i];
if( l->die < gp_cl->time || !l->radius )
continue;
R_MarkLights( l, 1 << i, RI.currentmodel->nodes );
}
}
/*
=======================================================================
AMBIENT LIGHTING
=======================================================================
*/
static vec3_t g_trace_lightspot;
static vec3_t g_trace_lightvec;
static float g_trace_fraction;
/*
=================
R_RecursiveLightPoint
=================
*/
static qboolean R_RecursiveLightPoint( model_t *model, mnode_t *node, float p1f, float p2f, colorVec *cv, const vec3_t start, const vec3_t end )
{
float front, back, frac, midf;
int i, map, side, size;
float ds, dt, s, t;
int sample_size;
color24 *lm, *dm;
mextrasurf_t *info;
msurface_t *surf;
matrix3x4 tbn;
vec3_t mid;
int firstsurface, numsurfaces;
// didn't hit anything
if( !node || node->contents < 0 )
{
cv->r = cv->g = cv->b = cv->a = 0;
return false;
}
firstsurface = node_firstsurface( node, model );
numsurfaces = node_numsurfaces( node, model );
// calculate mid point
front = PlaneDiff( start, node->plane );
back = PlaneDiff( end, node->plane );
side = front < 0;
if(( back < 0 ) == side )
return R_RecursiveLightPoint( model, node_child( node, side, model ), p1f, p2f, cv, start, end );
frac = front / ( front - back );
VectorLerp( start, frac, end, mid );
midf = p1f + ( p2f - p1f ) * frac;
// co down front side
if( R_RecursiveLightPoint( model, node_child( node, side, model ), p1f, midf, cv, start, mid ))
return true; // hit something
if(( back < 0 ) == side )
{
cv->r = cv->g = cv->b = cv->a = 0;
return false; // didn't hit anything
}
// check for impact on this node
surf = model->surfaces + firstsurface;
VectorCopy( mid, g_trace_lightspot );
for( i = 0; i < numsurfaces; i++, surf++ )
{
int smax, tmax;
info = surf->info;
if( FBitSet( surf->flags, SURF_DRAWTILED ))
continue; // no lightmaps
s = DotProduct( mid, info->lmvecs[0] ) + info->lmvecs[0][3];
t = DotProduct( mid, info->lmvecs[1] ) + info->lmvecs[1][3];
if( s < info->lightmapmins[0] || t < info->lightmapmins[1] )
continue;
ds = s - info->lightmapmins[0];
dt = t - info->lightmapmins[1];
if( ds > info->lightextents[0] || dt > info->lightextents[1] )
continue;
cv->r = cv->g = cv->b = cv->a = 0;
if( !surf->samples )
return true;
sample_size = gEngfuncs.Mod_SampleSizeForFace( surf );
smax = ( info->lightextents[0] / sample_size ) + 1;
tmax = ( info->lightextents[1] / sample_size ) + 1;
ds /= sample_size;
dt /= sample_size;
lm = surf->samples + Q_rint( dt ) * smax + Q_rint( ds );
g_trace_fraction = midf;
size = smax * tmax;
dm = NULL;
if( surf->info->deluxemap )
{
vec3_t faceNormal;
if( FBitSet( surf->flags, SURF_PLANEBACK ))
VectorNegate( surf->plane->normal, faceNormal );
else
VectorCopy( surf->plane->normal, faceNormal );
// compute face TBN
#if 1
Vector4Set( tbn[0], surf->info->lmvecs[0][0], surf->info->lmvecs[0][1], surf->info->lmvecs[0][2], 0.0f );
Vector4Set( tbn[1], -surf->info->lmvecs[1][0], -surf->info->lmvecs[1][1], -surf->info->lmvecs[1][2], 0.0f );
Vector4Set( tbn[2], faceNormal[0], faceNormal[1], faceNormal[2], 0.0f );
#else
Vector4Set( tbn[0], surf->info->lmvecs[0][0], -surf->info->lmvecs[1][0], faceNormal[0], 0.0f );
Vector4Set( tbn[1], surf->info->lmvecs[0][1], -surf->info->lmvecs[1][1], faceNormal[1], 0.0f );
Vector4Set( tbn[2], surf->info->lmvecs[0][2], -surf->info->lmvecs[1][2], faceNormal[2], 0.0f );
#endif
VectorNormalize( tbn[0] );
VectorNormalize( tbn[1] );
VectorNormalize( tbn[2] );
dm = surf->info->deluxemap + Q_rint( dt ) * smax + Q_rint( ds );
}
for( map = 0; map < MAXLIGHTMAPS && surf->styles[map] != 255; map++ )
{
uint scale = tr.lightstylevalue[surf->styles[map]];
cv->r += lm->r * scale;
cv->g += lm->g * scale;
cv->b += lm->b * scale;
lm += size; // skip to next lightmap
if( dm != NULL )
{
vec3_t srcNormal, lightNormal;
float f = ( 1.0f / 128.0f );
VectorSet( srcNormal, ((float)dm->r - 128.0f ) * f, ((float)dm->g - 128.0f ) * f, ((float)dm->b - 128.0f ) * f );
Matrix3x4_VectorIRotate( tbn, srcNormal, lightNormal ); // turn to world space
VectorScale( lightNormal, (float)scale * -1.0f, lightNormal ); // turn direction from light
VectorAdd( g_trace_lightvec, lightNormal, g_trace_lightvec );
dm += size; // skip to next deluxmap
}
}
return true;
}
// go down back side
return R_RecursiveLightPoint( model, node_child( node, !side, model ), midf, p2f, cv, mid, end );
}
/*
=================
R_LightVec
check bspmodels to get light from
=================
*/
static colorVec R_LightVecInternal( const vec3_t start, const vec3_t end, vec3_t lspot, vec3_t lvec )
{
float last_fraction;
int i, maxEnts = 1;
colorVec light, cv;
if( lspot )
VectorClear( lspot );
if( lvec )
VectorClear( lvec );
if( WORLDMODEL && WORLDMODEL->lightdata )
{
light.r = light.g = light.b = light.a = 0;
last_fraction = 1.0f;
// get light from bmodels too
// if( CVAR_TO_BOOL( r_lighting_extended ))
maxEnts = MAX_PHYSENTS;
// check all the bsp-models
for( i = 0; i < maxEnts; i++ )
{
physent_t *pe = gEngfuncs.EV_GetPhysent( i );
vec3_t offset, start_l, end_l;
mnode_t *pnodes;
matrix4x4 matrix;
if( !pe )
break;
if( !pe->model || pe->model->type != mod_brush )
continue; // skip non-bsp models
pnodes = &pe->model->nodes[pe->model->hulls[0].firstclipnode];
VectorSubtract( pe->model->hulls[0].clip_mins, vec3_origin, offset );
VectorAdd( offset, pe->origin, offset );
VectorSubtract( start, offset, start_l );
VectorSubtract( end, offset, end_l );
// rotate start and end into the models frame of reference
if( !VectorIsNull( pe->angles ))
{
Matrix4x4_CreateFromEntity( matrix, pe->angles, offset, 1.0f );
Matrix4x4_VectorITransform( matrix, start, start_l );
Matrix4x4_VectorITransform( matrix, end, end_l );
}
VectorClear( g_trace_lightspot );
VectorClear( g_trace_lightvec );
g_trace_fraction = 1.0f;
if( !R_RecursiveLightPoint( pe->model, pnodes, 0.0f, 1.0f, &cv, start_l, end_l ))
continue; // didn't hit anything
if( g_trace_fraction < last_fraction )
{
if( lspot )
VectorCopy( g_trace_lightspot, lspot );
if( lvec )
VectorNormalize2( g_trace_lightvec, lvec );
light.r = Q_min(( cv.r >> 8 ), 255 );
light.g = Q_min(( cv.g >> 8 ), 255 );
light.b = Q_min(( cv.b >> 8 ), 255 );
last_fraction = g_trace_fraction;
if(( light.r + light.g + light.b ) != 0 )
break; // we get light now
}
}
}
else
{
light.r = light.g = light.b = 255;
light.a = 0;
}
return light;
}
/*
=================
R_LightVec
check bspmodels to get light from
=================
*/
colorVec GAME_EXPORT R_LightVec( const vec3_t start, const vec3_t end, vec3_t lspot, vec3_t lvec )
{
colorVec light = R_LightVecInternal( start, end, lspot, lvec );
// light.r = light.g = light.b = 255;
if( lspot != NULL && lvec != NULL ) // CVAR_TO_BOOL( r_lighting_extended ) &&
{
// trying to get light from ceiling (but ignore gradient analyze)
if(( light.r + light.g + light.b ) == 0 )
return R_LightVecInternal( end, start, lspot, lvec );
}
return light;
}
/*
=================
R_LightPoint
light from floor
=================
*/
colorVec GAME_EXPORT R_LightPoint( const vec3_t p0 )
{
vec3_t p1;
VectorSet( p1, p0[0], p0[1], p0[2] - 2048.0f );
return R_LightVec( p0, p1, NULL, NULL );
}

View File

@@ -15,16 +15,11 @@ GNU General Public License for more details.
#ifndef GL_LOCAL_H
#define GL_LOCAL_H
#include "ref_common.h"
#include "port.h"
#include "xash3d_types.h"
#include "cvardef.h"
#include "const.h"
#include "com_model.h"
#include "cl_entity.h"
#include "render_api.h"
#include "protocol.h"
#include "ref_api.h"
#include "xash3d_mathlib.h"
#include "ref_params.h"
#include "enginefeatures.h"
#include "com_strings.h"
@@ -36,16 +31,13 @@ typedef struct mip_s mip_t;
typedef int fixed8_t;
typedef int fixed16_t;
#define ASSERT( x ) if( !( x )) gEngfuncs.Host_Error( "assert failed at %s:%i\n", __FILE__, __LINE__ )
#define Assert( x ) if( !( x )) gEngfuncs.Host_Error( "assert failed at %s:%i\n", __FILE__, __LINE__ )
#define ASSERT( x ) Assert( x )
#include <stdio.h>
// make mod_ref.h?
#define LM_SAMPLE_SIZE 16
extern poolhandle_t r_temppool;
#define BLOCK_SIZE tr.block_size // lightmap blocksize
#define BLOCK_SIZE_DEFAULT 128 // for keep backward compatibility
#define BLOCK_SIZE_MAX 1024
@@ -259,7 +251,6 @@ typedef struct
int max_recursion;
byte visbytes[( MAX_MAP_LEAFS + 7 ) / 8]; // member custom PVS
int lightstylevalue[MAX_LIGHTSTYLES]; // value 0 - 65536
int block_size; // lightmap blocksize
double frametime; // special frametime for multipass rendering (will set to 0 on a nextview)
@@ -278,7 +269,6 @@ typedef struct
color24 *palette;
cl_entity_t *viewent;
lightstyle_t *lightstyles;
dlight_t *dlights;
dlight_t *elights;
byte *texgammatable;
uint *lightgammatable;
@@ -375,7 +365,6 @@ image_t *R_GetTexture( unsigned int texnum );
int GL_LoadTexture( const char *name, const byte *buf, size_t size, int flags );
int GL_LoadTextureArray( const char **names, int flags );
int GL_LoadTextureFromBuffer( const char *name, rgbdata_t *pic, texFlags_t flags, qboolean update );
byte *GL_ResampleTexture( const byte *source, int in_w, int in_h, int out_w, int out_h, qboolean isNormalMap );
int GL_CreateTexture( const char *name, int width, int height, const void *buffer, texFlags_t flags );
int GL_CreateTextureArray( const char *name, int width, int height, int depth, const void *buffer, texFlags_t flags );
void GL_ProcessTexture( int texnum, float gamma, int topColor, int bottomColor );
@@ -389,17 +378,6 @@ void R_InitImages( void );
void R_ShutdownImages( void );
int R_TexMemory( void );
#if 1
//
// gl_rlight.c
//
void CL_RunLightStyles( lightstyle_t *ls );
void R_PushDlights( void );
void R_GetLightSpot( vec3_t lightspot );
void R_MarkLights( dlight_t *light, int bit, mnode_t *node );
colorVec R_LightVec( const vec3_t start, const vec3_t end, vec3_t lightspot, vec3_t lightvec );
colorVec R_LightPoint( const vec3_t p0 );
#endif
//
// gl_rmain.c
//
@@ -419,18 +397,6 @@ void R_PushScene( void );
void R_PopScene( void );
void R_DrawFog( void );
//
// gl_rmath.c
//
void Matrix4x4_Concat( matrix4x4 out, const matrix4x4 in1, const matrix4x4 in2 );
void Matrix4x4_ConcatTranslate( matrix4x4 out, float x, float y, float z );
void Matrix4x4_ConcatRotate( matrix4x4 out, float angle, float x, float y, float z );
void Matrix4x4_CreateTranslate( matrix4x4 out, float x, float y, float z );
void Matrix4x4_CreateRotate( matrix4x4 out, float angle, float x, float y, float z );
void Matrix4x4_CreateProjection( matrix4x4 out, float xMax, float xMin, float yMax, float yMin, float zNear, float zFar );
void Matrix4x4_CreateOrtho( matrix4x4 m, float xLeft, float xRight, float yBottom, float yTop, float zNear, float zFar );
void Matrix4x4_CreateModelview( matrix4x4 out );
//
// gl_rpart.c
//
@@ -442,9 +408,6 @@ void CL_DrawTracers( double frametime, particle_t *cl_active_tracers );
//
// gl_sprite.c
//
void R_SpriteInit( void );
void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, uint texFlags );
mspriteframe_t *R_GetSpriteFrame( const model_t *pModel, int frame, float yaw );
void R_DrawSpriteModel( cl_entity_t *e );
//
@@ -507,7 +470,6 @@ void R_RenderFrame( const struct ref_viewpass_s *vp );
void R_EndFrame( void );
void R_ClearScene( void );
void R_GetTextureParms( int *w, int *h, int texnum );
void R_GetSpriteParms( int *frameWidth, int *frameHeight, int *numFrames, int curFrame, const struct model_s *pSprite );
void R_DrawStretchRaw( float x, float y, float w, float h, int cols, int rows, const byte *data, qboolean dirty );
void R_DrawStretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, int texnum );
qboolean R_SpeedsMessage( char *out, size_t size );
@@ -515,13 +477,11 @@ qboolean R_CullBox( const vec3_t mins, const vec3_t maxs );
int R_WorldToScreen( const vec3_t point, vec3_t screen );
void R_ScreenToWorld( const vec3_t screen, vec3_t point );
qboolean R_AddEntity( struct cl_entity_s *pRefEntity, int entityType );
void Mod_SpriteUnloadTextures( void *data );
void Mod_UnloadAliasModel( struct model_s *mod );
void Mod_AliasUnloadTextures( void *data );
void GL_SetRenderMode( int mode );
void R_RunViewmodelEvents( void );
void R_DrawViewModel( void );
int R_GetSpriteTexture( const struct model_s *m_pSpriteModel, int frame );
void R_DecalShoot( int textureIndex, int entityIndex, int modelIndex, vec3_t pos, int flags, float scale );
void R_DecalRemoveAll( int texture );
int R_CreateDecalList( decallist_t *pList );
@@ -529,7 +489,6 @@ void R_ClearAllDecals( void );
byte *Mod_GetCurrentVis( void );
void Mod_SetOrthoBounds( const float *mins, const float *maxs );
void R_NewMap( void );
void CL_AddCustomBeam( cl_entity_t *pEnvBeam );
//
// gl_triapi.c
@@ -552,15 +511,7 @@ void TriFogParams( float flDensity, int iFogSkybox );
void TriCullFace( TRICULLSTYLE mode );
void TriBrightness( float brightness );
#define ENGINE_GET_PARM_ ( *gEngfuncs.EngineGetParm )
#define ENGINE_GET_PARM( parm ) ENGINE_GET_PARM_(( parm ), 0 )
extern ref_api_t gEngfuncs;
extern ref_globals_t *gpGlobals;
extern ref_client_t *gp_cl;
extern ref_host_t *gp_host;
DECLARE_ENGINE_SHARED_CVAR_LIST()
//
// helper funcs
@@ -1099,7 +1050,6 @@ void R_ScanEdges( void );
//
// r_surf.c
//
void GL_InitRandomTable( void );
void D_FlushCaches( void );
//
@@ -1147,16 +1097,6 @@ void R_SetUpWorldTransform( void );
//
#include "crtlib.h"
#include "crclib.h"
void _Mem_Free( void *data, const char *filename, int fileline );
void *_Mem_Alloc( poolhandle_t poolptr, size_t size, qboolean clear, const char *filename, int fileline )
ALLOC_CHECK( 2 ) MALLOC_LIKE( _Mem_Free, 1 ) WARN_UNUSED_RESULT;
#define Mem_Malloc( pool, size ) _Mem_Alloc( pool, size, false, __FILE__, __LINE__ )
#define Mem_Calloc( pool, size ) _Mem_Alloc( pool, size, true, __FILE__, __LINE__ )
#define Mem_Realloc( pool, ptr, size ) gEngfuncs._Mem_Realloc( pool, ptr, size, true, __FILE__, __LINE__ )
#define Mem_Free( mem ) _Mem_Free( mem, __FILE__, __LINE__ )
#define Mem_AllocPool( name ) gEngfuncs._Mem_AllocPool( name, __FILE__, __LINE__ )
#define Mem_FreePool( pool ) gEngfuncs._Mem_FreePool( pool, __FILE__, __LINE__ )
#define Mem_EmptyPool( pool ) gEngfuncs._Mem_EmptyPool( pool, __FILE__, __LINE__ )
#endif // GL_LOCAL_H

View File

@@ -71,7 +71,6 @@ CVAR_DEFINE_AUTO( sw_texfilt, "0", FCVAR_GLCONFIG, "texture dither" );
static CVAR_DEFINE_AUTO( r_novis, "0", 0, "" );
DEFINE_ENGINE_SHARED_CVAR_LIST()
int r_viewcluster, r_oldviewcluster;
@@ -319,9 +318,6 @@ qboolean GAME_EXPORT R_AddEntity( struct cl_entity_s *clent, int type )
if( !r_drawentities->value )
return false; // not allow to drawing
if( !clent || !clent->model )
return false; // if set to invisible, skip
if( FBitSet( clent->curstate.effects, EF_NODRAW ))
return false; // done
@@ -331,7 +327,20 @@ qboolean GAME_EXPORT R_AddEntity( struct cl_entity_s *clent, int type )
if( type == ET_FRAGMENTED )
r_stats.c_client_ents++;
if( R_OpaqueEntity( clent ))
if( type == ET_BEAM )
{
if( tr.draw_list->num_beam_entities >= MAX_VISIBLE_PACKET )
{
gEngfuncs.Con_Printf( S_ERROR "Too many beams %d!\n", tr.draw_list->num_beam_entities );
return false;
}
tr.draw_list->beam_entities[tr.draw_list->num_beam_entities] = clent;
tr.draw_list->num_beam_entities++;
return true;
}
else if( R_OpaqueEntity( clent ))
{
if( clent->model->type == mod_brush )
{
@@ -831,21 +840,8 @@ static void R_DrawBEntitiesOnList( void )
R_RotateBmodel();
// calculate dynamic lighting for bmodel
for( k = 0; k < MAX_DLIGHTS; k++ )
{
dlight_t *l = &tr.dlights[k];
vec3_t origin_l, oldorigin;
if( l->die < gp_cl->time || !l->radius )
continue;
VectorCopy( l->origin, oldorigin ); // save lightorigin
Matrix4x4_CreateFromEntity( RI.objectMatrix, RI.currententity->angles, RI.currententity->origin, 1 );
Matrix4x4_VectorITransform( RI.objectMatrix, l->origin, origin_l );
VectorCopy( origin_l, l->origin ); // move light in bmodel space
R_MarkLights( l, 1 << k, RI.currentmodel->nodes + RI.currentmodel->hulls[0].firstclipnode );
VectorCopy( oldorigin, l->origin ); // restore lightorigin
}
Matrix4x4_CreateFromEntity( RI.objectMatrix, RI.currententity->angles, RI.currententity->origin, 1 );
R_PushDlightsForBmodel( RI.currentmodel, tr.dlightframecount, RI.objectMatrix );
RI.currententity->topnode = topnode;
if( topnode->contents >= 0 )
@@ -956,22 +952,9 @@ void R_DrawBrushModel( cl_entity_t *pent )
R_RotateBmodel();
// calculate dynamic lighting for bmodel
for( k = 0; k < MAX_DLIGHTS; k++ )
{
dlight_t *l = &tr.dlights[k];
vec3_t origin_l, oldorigin;
if( l->die < gp_cl->time || !l->radius )
continue;
VectorCopy( l->origin, oldorigin ); // save lightorigin
Matrix4x4_CreateFromEntity( RI.objectMatrix, RI.currententity->angles, RI.currententity->origin, 1 );
Matrix4x4_VectorITransform( RI.objectMatrix, l->origin, origin_l );
tr.modelviewIdentity = false;
VectorCopy( origin_l, l->origin ); // move light in bmodel space
R_MarkLights( l, 1 << k, RI.currentmodel->nodes + RI.currentmodel->hulls[0].firstclipnode );
VectorCopy( oldorigin, l->origin ); // restore lightorigin*/
}
Matrix4x4_CreateFromEntity( RI.objectMatrix, RI.currententity->angles, RI.currententity->origin, 1 );
R_PushDlightsForBmodel( RI.currentmodel, tr.dlightframecount, RI.objectMatrix );
tr.modelviewIdentity = false;
RI.currententity->topnode = topnode;
if( topnode->contents >= 0 )
@@ -1121,7 +1104,7 @@ void GAME_EXPORT R_RenderScene( void )
R_SetupFrustum();
R_SetupFrame();
R_PushDlights();
tr.dlightframecount = R_PushDlights( WORLDMODEL, tr.framecount );
R_SetupModelviewMatrix( RI.worldviewMatrix );
R_SetupProjectionMatrix( RI.projectionMatrix );
@@ -1397,9 +1380,6 @@ qboolean GAME_EXPORT R_Init( void )
{
qboolean glblit = false;
RETRIEVE_ENGINE_SHARED_CVAR_LIST();
gEngfuncs.Cvar_RegisterVariable( &sw_clearcolor );
gEngfuncs.Cvar_RegisterVariable( &sw_drawflat );
gEngfuncs.Cvar_RegisterVariable( &sw_draworder );
@@ -1444,8 +1424,7 @@ qboolean GAME_EXPORT R_Init( void )
tr.lightgammatable = (uint *)ENGINE_GET_PARM( PARM_GET_LIGHTGAMMATABLE_PTR );
tr.screengammatable = (uint *)ENGINE_GET_PARM( PARM_GET_SCREENGAMMATABLE_PTR );
tr.lineargammatable = (uint *)ENGINE_GET_PARM( PARM_GET_LINEARGAMMATABLE_PTR );
tr.dlights = (dlight_t *)ENGINE_GET_PARM( PARM_GET_DLIGHTS_PTR );
tr.elights = (dlight_t *)ENGINE_GET_PARM( PARM_GET_ELIGHTS_PTR );
tr.elights = (dlight_t *)ENGINE_GET_PARM( PARM_GET_ELIGHTS_PTR );
if( !R_InitBlit( glblit ))
{
@@ -1462,7 +1441,6 @@ qboolean GAME_EXPORT R_Init( void )
qfrustum.view_clipplanes[1].leftedge = qfrustum.view_clipplanes[2].leftedge = qfrustum.view_clipplanes[3].leftedge = false;
qfrustum.view_clipplanes[0].rightedge = qfrustum.view_clipplanes[2].rightedge = qfrustum.view_clipplanes[3].rightedge = false;
R_StudioInit();
R_SpriteInit();
R_InitTurb();
GL_InitRandomTable();

View File

@@ -21,317 +21,8 @@ GNU General Public License for more details.
#define GLARE_FALLOFF 19000.0f
static char sprite_name[MAX_QPATH];
static char group_suffix[8];
static uint r_texFlags = 0;
static int sprite_version;
static float sprite_radius;
/*
====================
R_SpriteInit
====================
*/
void R_SpriteInit( void )
{
}
/*
====================
R_SpriteLoadFrame
upload a single frame
====================
*/
static const byte *R_SpriteLoadFrame( model_t *mod, const void *pin, mspriteframe_t **ppframe, int num )
{
dspriteframe_t pinframe;
mspriteframe_t *pspriteframe;
int gl_texturenum = 0;
char texname[128];
int bytes = 1;
memcpy( &pinframe, pin, sizeof( dspriteframe_t ));
if( sprite_version == SPRITE_VERSION_32 )
bytes = 4;
// build uinque frame name
if( FBitSet( mod->flags, MODEL_CLIENT )) // it's a HUD sprite
{
Q_snprintf( texname, sizeof( texname ), "#HUD/%s(%s:%i%i).spr", sprite_name, group_suffix, num / 10, num % 10 );
gl_texturenum = GL_LoadTexture( texname, pin, pinframe.width * pinframe.height * bytes, r_texFlags );
}
else
{
Q_snprintf( texname, sizeof( texname ), "#%s(%s:%i%i).spr", sprite_name, group_suffix, num / 10, num % 10 );
gl_texturenum = GL_LoadTexture( texname, pin, pinframe.width * pinframe.height * bytes, r_texFlags );
}
// setup frame description
pspriteframe = Mem_Malloc( mod->mempool, sizeof( mspriteframe_t ));
pspriteframe->width = pinframe.width;
pspriteframe->height = pinframe.height;
pspriteframe->up = pinframe.origin[1];
pspriteframe->left = pinframe.origin[0];
pspriteframe->down = pinframe.origin[1] - pinframe.height;
pspriteframe->right = pinframe.width + pinframe.origin[0];
pspriteframe->gl_texturenum = gl_texturenum;
*ppframe = pspriteframe;
return (const byte *)((const byte *)pin + sizeof( dspriteframe_t ) + pinframe.width * pinframe.height * bytes );
}
/*
====================
R_SpriteLoadGroup
upload a group frames
====================
*/
static const void *R_SpriteLoadGroup( model_t *mod, const void *pin, mspriteframe_t **ppframe, int framenum )
{
const dspritegroup_t *pingroup;
mspritegroup_t *pspritegroup;
const dspriteinterval_t *pin_intervals;
float *poutintervals;
int i, groupsize, numframes;
const void *ptemp;
pingroup = (const dspritegroup_t *)pin;
numframes = pingroup->numframes;
groupsize = sizeof( mspritegroup_t ) + ( numframes - 1 ) * sizeof( pspritegroup->frames[0] );
pspritegroup = Mem_Calloc( mod->mempool, groupsize );
pspritegroup->numframes = numframes;
*ppframe = (mspriteframe_t *)pspritegroup;
pin_intervals = (const dspriteinterval_t *)( pingroup + 1 );
poutintervals = Mem_Calloc( mod->mempool, numframes * sizeof( float ));
pspritegroup->intervals = poutintervals;
for( i = 0; i < numframes; i++ )
{
*poutintervals = pin_intervals->interval;
if( *poutintervals <= 0.0f )
*poutintervals = 1.0f; // set error value
poutintervals++;
pin_intervals++;
}
ptemp = (const void *)pin_intervals;
for( i = 0; i < numframes; i++ )
{
ptemp = R_SpriteLoadFrame( mod, ptemp, &pspritegroup->frames[i], framenum * 10 + i );
}
return ptemp;
}
/*
====================
Mod_LoadSpriteModel
load sprite model
====================
*/
void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, uint texFlags )
{
const dsprite_t *pin;
const short *numi = NULL;
const byte *pframetype;
msprite_t *psprite;
int i;
pin = buffer;
psprite = mod->cache.data;
if( pin->version == SPRITE_VERSION_Q1 || pin->version == SPRITE_VERSION_32 )
numi = NULL;
else if( pin->version == SPRITE_VERSION_HL )
numi = (const short *)((const byte *)buffer + sizeof( dsprite_hl_t ));
r_texFlags = texFlags;
sprite_version = pin->version;
Q_strncpy( sprite_name, mod->name, sizeof( sprite_name ));
COM_StripExtension( sprite_name );
if( numi == NULL )
{
rgbdata_t *pal;
pal = gEngfuncs.FS_LoadImage( "#id.pal", (byte *)&i, 768 );
pframetype = ((const byte *)buffer + sizeof( dsprite_q1_t )); // pinq1 + 1
gEngfuncs.FS_FreeImage( pal ); // palette installed, no reason to keep this data
}
else if( *numi <= 256 )
{
const byte *src = (const byte *)(numi+1);
rgbdata_t *pal;
size_t pal_bytes = *numi * 3;
// install palette
switch( psprite->texFormat )
{
case SPR_INDEXALPHA:
pal = gEngfuncs.FS_LoadImage( "#gradient.pal", src, pal_bytes );
break;
case SPR_ALPHTEST:
pal = gEngfuncs.FS_LoadImage( "#masked.pal", src, pal_bytes );
break;
default:
pal = gEngfuncs.FS_LoadImage( "#texgamma.pal", src, pal_bytes );
break;
}
pframetype = (const byte *)(src + pal_bytes);
gEngfuncs.FS_FreeImage( pal ); // palette installed, no reason to keep this data
}
else
{
gEngfuncs.Con_DPrintf( S_ERROR "%s has wrong number of palette colors %i (should be less or equal than 256)\n", mod->name, *numi );
return;
}
if( mod->numframes < 1 )
return;
for( i = 0; i < mod->numframes; i++ )
{
frametype_t frametype;
dframetype_t dframetype;
memcpy( &dframetype, pframetype, sizeof( dframetype ));
frametype = dframetype.type;
psprite->frames[i].type = (spriteframetype_t)frametype;
switch( frametype )
{
case FRAME_SINGLE:
Q_strncpy( group_suffix, "frame", sizeof( group_suffix ));
pframetype = R_SpriteLoadFrame( mod, pframetype + sizeof( dframetype_t ), &psprite->frames[i].frameptr, i );
break;
case FRAME_GROUP:
Q_strncpy( group_suffix, "group", sizeof( group_suffix ));
pframetype = R_SpriteLoadGroup( mod, pframetype + sizeof( dframetype_t ), &psprite->frames[i].frameptr, i );
break;
case FRAME_ANGLED:
Q_strncpy( group_suffix, "angle", sizeof( group_suffix ));
pframetype = R_SpriteLoadGroup( mod, pframetype + sizeof( dframetype_t ), &psprite->frames[i].frameptr, i );
break;
}
if( pframetype == NULL )
break; // technically an error
}
if( loaded )
*loaded = true; // done
}
/*
====================
Mod_UnloadSpriteModel
release sprite model and frames
====================
*/
void Mod_SpriteUnloadTextures( void *data )
{
msprite_t *psprite = data;
int i;
if( !data )
return;
// release all textures
for( i = 0; i < psprite->numframes; i++ )
{
if( !psprite->frames[i].frameptr )
continue;
if( psprite->frames[i].type == SPR_SINGLE )
{
GL_FreeTexture( psprite->frames[i].frameptr->gl_texturenum );
}
else
{
mspritegroup_t *pspritegroup = (mspritegroup_t *)psprite->frames[i].frameptr;
int j;
for( j = 0; j < pspritegroup->numframes; j++ )
{
if( pspritegroup->frames[j] )
GL_FreeTexture( pspritegroup->frames[j]->gl_texturenum );
}
}
}
}
/*
================
R_GetSpriteFrame
assume pModel is valid
================
*/
mspriteframe_t *R_GetSpriteFrame( const model_t *pModel, int frame, float yaw )
{
msprite_t *psprite;
mspritegroup_t *pspritegroup;
mspriteframe_t *pspriteframe = NULL;
float *pintervals, fullinterval;
int i, numframes;
float targettime;
Assert( pModel != NULL );
psprite = pModel->cache.data;
if( frame < 0 )
{
frame = 0;
}
else if( frame >= psprite->numframes )
{
if( frame > psprite->numframes )
gEngfuncs.Con_Printf( S_WARN "%s: no such frame %d (%s)\n", __func__, frame, pModel->name );
frame = psprite->numframes - 1;
}
if( psprite->frames[frame].type == SPR_SINGLE )
{
pspriteframe = psprite->frames[frame].frameptr;
}
else if( psprite->frames[frame].type == SPR_GROUP )
{
pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr;
pintervals = pspritegroup->intervals;
numframes = pspritegroup->numframes;
fullinterval = pintervals[numframes - 1];
// when loading in Mod_LoadSpriteGroup, we guaranteed all interval values
// are positive, so we don't have to worry about division by zero
targettime = gp_cl->time - ((int)( gp_cl->time / fullinterval )) * fullinterval;
for( i = 0; i < ( numframes - 1 ); i++ )
{
if( pintervals[i] > targettime )
break;
}
pspriteframe = pspritegroup->frames[i];
}
else if( psprite->frames[frame].type == FRAME_ANGLED )
{
int angleframe = (int)( Q_rint(( RI.viewangles[1] - yaw + 45.0f ) / 360 * 8 ) - 4 ) & 7;
// e.g. doom-style sprite monsters
pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr;
pspriteframe = pspritegroup->frames[angleframe];
}
return pspriteframe;
}
/*
================
R_CullSpriteModel
@@ -371,16 +62,15 @@ Set sprite brightness factor
*/
static float R_SpriteGlowBlend( vec3_t origin, int rendermode, int renderfx, float *pscale )
{
float dist, brightness;
vec3_t glowDist;
pmtrace_t *tr;
float dist, brightness;
vec3_t glowDist;
VectorSubtract( origin, RI.vieworg, glowDist );
dist = VectorLength( glowDist );
if( RP_NORMALPASS( ))
{
tr = gEngfuncs.EV_VisTraceLine( RI.vieworg, origin, r_traceglow.value ? PM_GLASS_IGNORE : ( PM_GLASS_IGNORE | PM_STUDIO_IGNORE ));
pmtrace_t *tr = gEngfuncs.EV_VisTraceLine( RI.vieworg, origin, r_traceglow.value ? PM_GLASS_IGNORE : ( PM_GLASS_IGNORE | PM_STUDIO_IGNORE ));
if(( 1.0f - tr->fraction ) * dist > 8.0f )
return 0.0f;
@@ -536,7 +226,7 @@ void R_DrawSpriteModel( cl_entity_t *e )
color[2] = 1.0f;
}
frame = R_GetSpriteFrame( model, e->curstate.frame, e->angles[YAW] );
frame = gEngfuncs.R_GetSpriteFrame( model, e->curstate.frame, e->angles[YAW] );
type = psprite->type;

View File

@@ -1467,7 +1467,7 @@ static void R_StudioDynamicLight( cl_entity_t *ent, alight_t *plight )
for( lnum = 0; lnum < MAX_DLIGHTS; lnum++ )
{
dl = &tr.dlights[lnum];
dl = &gp_dlights[lnum];
if( dl->die < g_studio.time || !r_dynamic->value )
continue;

View File

@@ -53,7 +53,7 @@ static void (*surfmiptable[4])( void ) = {
};
// void R_BuildLightMap (void);
extern unsigned blocklights[10240]; // allow some very large lightmaps
static unsigned blocklights[10240]; // allow some very large lightmaps
static float surfscale;
static qboolean r_cache_thrash; // set if surface cache is thrashing
@@ -62,7 +62,6 @@ static int sc_size;
surfcache_t *sc_rover;
static surfcache_t *sc_base;
static int rtable[MOD_FRAMES][MOD_FRAMES];
static void R_BuildLightMap( void );
/*
@@ -108,7 +107,7 @@ static void R_AddDynamicLights( const msurface_t *surf )
if( !FBitSet( surf->dlightbits, BIT( lnum )))
continue; // not lit by this light
dl = &tr.dlights[lnum];
dl = &gp_dlights[lnum];
// transform light origin to local bmodel space
if( !tr.modelviewIdentity )
@@ -209,7 +208,7 @@ static void R_BuildLightMap( void )
if( surf->styles[map] >= 255 )
break;
scale = tr.lightstylevalue[surf->styles[map]];
scale = g_lightstylevalue[surf->styles[map]];
for( i = 0; i < size; i++ )
blocklights[i] += ( lm[i].r + lm[i].g + lm[i].b ) * scale;
@@ -238,20 +237,6 @@ static void R_BuildLightMap( void )
}
}
void GL_InitRandomTable( void )
{
int tu, tv;
for( tu = 0; tu < MOD_FRAMES; tu++ )
{
for( tv = 0; tv < MOD_FRAMES; tv++ )
{
rtable[tu][tv] = gEngfuncs.COM_RandomLong( 0, 0x7FFF );
}
}
gEngfuncs.COM_SetRandomSeed( 0 );
}
/*
===============
@@ -1118,7 +1103,7 @@ surfcache_t *D_CacheSurface( msurface_t *surface, int miplevel )
// check for lightmap modification
for( maps = 0; maps < MAXLIGHTMAPS && surface->styles[maps] != 255; maps++ )
{
if( tr.lightstylevalue[surface->styles[maps]] != surface->cached_light[maps] )
if( g_lightstylevalue[surface->styles[maps]] != surface->cached_light[maps] )
{
surface->dlightframe = tr.framecount;
}
@@ -1188,10 +1173,7 @@ surfcache_t *D_CacheSurface( msurface_t *surface, int miplevel )
cache->lightadj[1] = r_drawsurf.lightadj[1];
cache->lightadj[2] = r_drawsurf.lightadj[2];
cache->lightadj[3] = r_drawsurf.lightadj[3];
for( maps = 0; maps < MAXLIGHTMAPS && surface->styles[maps] != 255; maps++ )
{
surface->cached_light[maps] = tr.lightstylevalue[surface->styles[maps]];
}
R_UpdateSurfaceCachedLight( surface );
//
// draw and light the surface texture
//

View File

@@ -286,7 +286,10 @@ int TriSpriteTexture( model_t *pSpriteModel, int frame )
{
int gl_texturenum;
if(( gl_texturenum = R_GetSpriteTexture( pSpriteModel, frame )) == 0 )
if( !pSpriteModel || pSpriteModel->type != mod_sprite || !pSpriteModel->cache.data )
return 0;
if(( gl_texturenum = gEngfuncs.R_GetSpriteFrame( pSpriteModel, frame, 0.0f )->gl_texturenum ) == 0 )
return 0;
if( gl_texturenum <= 0 || gl_texturenum >= MAX_TEXTURES )

View File

@@ -14,7 +14,7 @@ def configure(conf):
return
def build(bld):
libs = [ 'engine_includes', 'werror' ]
libs = [ 'ref_common', 'engine_includes', 'werror' ]
# on PSVita do not link any libraries that are already in the main executable, but add the includes target
if bld.env.DEST_OS == 'psvita':
libs += [ 'sdk_includes' ]

View File

@@ -5,41 +5,37 @@ SCRIPTDIR=${0%/*}
cd "$SCRIPTDIR" || exit 1
#shouldn't build any mods that are supported by mobile_hacks
./buildhlsdk.sh aghl _ag
./buildhlsdk.sh aomdc _AoMDC
./buildhlsdk.sh asheep _asheep
./buildhlsdk.sh blackops _blackops
./buildhlsdk.sh bubblemod _bubblemod
./buildhlsdk.sh CAd _CAd
./buildhlsdk.sh cracklife _cracklife
./buildhlsdk.sh clcampaign _clcampaign
./buildhlsdk.sh dmc _dmc
./buildhlsdk.sh eftd _eftd
#linux only??
./buildhlsdk.sh decay-pc _decay
./buildhlsdk.sh echoes _echoes
./buildhlsdk.sh gravgun _gravgun
./buildhlsdk.sh opfor _opfor
./buildhlsdk.sh sci _sci
./buildhlsdk.sh topdown _topdown
./buildhlsdk.sh half-screwed _half-screwed
./buildhlsdk.sh noffice _noffice
./buildhlsdk.sh poke646 _poke646
./buildhlsdk.sh poke646_vendetta _poke646_vendetta
./buildhlsdk.sh rebellion _rebellion
./buildhlsdk.sh residual_point _rl
./buildhlsdk.sh residual_point _rp_v1_pub_final1
./buildhlsdk.sh sohl1.2 _Spirit
./buildhlsdk.sh halloween _shall1
./buildhlsdk.sh thegate _thegate
./buildhlsdk.sh theyhunger _hunger
./buildhlsdk.sh zombie-x _Zombie-X-DLE
./buildhlsdk.sh aghl
./buildhlsdk.sh aomdc
./buildhlsdk.sh asheep
./buildhlsdk.sh blackops
./buildhlsdk.sh bubblemod
./buildhlsdk.sh CAd
./buildhlsdk.sh cracklife
./buildhlsdk.sh clcampaign
./buildhlsdk.sh dmc
./buildhlsdk.sh eftd
./buildhlsdk.sh decay-pc
./buildhlsdk.sh echoes
./buildhlsdk.sh gravgun
./buildhlsdk.sh opfor
./buildhlsdk.sh sci
./buildhlsdk.sh topdown
./buildhlsdk.sh half-screwed
./buildhlsdk.sh noffice
./buildhlsdk.sh poke646
./buildhlsdk.sh poke646_vendetta
./buildhlsdk.sh rebellion
./buildhlsdk.sh residual_point
./buildhlsdk.sh sohl1.2
./buildhlsdk.sh halloween
./buildhlsdk.sh thegate
./buildhlsdk.sh theyhunger
./buildhlsdk.sh zombie-x
./buildhlsdk.sh delta_particles
#untested if this works
export XENWARRIOR=ON
./buildhlsdk.sh sohl1.2 _xenwar
./buildhlsdk.sh sohl1.2 xenwar
./buildhlsdk.sh
cd ../../
./createipa.sh

25
scripts/ios/buildcs16.sh Executable file
View File

@@ -0,0 +1,25 @@
#!/bin/bash
#cd into script directory
SCRIPTDIR=${0%/*}
cd $SCRIPTDIR
MODPATH=mod-build/cs16-client
git clone --recursive https://github.com/Velaron/cs16-client mod-build/cs16-client
mkdir -p ../../build/ios/libs
LIBSDIR=$(realpath ../../build/ios/libs)
cd $MODPATH
cmake -DCMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk -DCMAKE_DEVELOPER_ROOT=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DMAC=0 -DDEBUG=1 -DXASH_COMPAT=1 -DMAINUI_USE_STB=1 -DCMAKE_BUILD_TYPE=Debug -B build -S .
cmake --build build --config Debug
cmake --install build --prefix $LIBSDIR
cd ../../
./createipa.sh
if [ -d mod-build ]; then
rm -rf mod-build/
fi
exit 0

View File

@@ -12,20 +12,19 @@ else
git clone --recursive https://github.com/FWGS/hlsdk-portable -b "$1" "$MODPATH"
fi
mkdir -p ../../build/ios || exit 1
IOSDIR=$(realpath ../../build/ios)
mkdir -p ../../build/ios/libs || exit 1
LIBSDIR=$(realpath ../../build/ios/libs)
cd "$MODPATH" || exit 1
#compiling hlsdk for ios release is broken, so just build for debug
cmake -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DGAMEDIR="$IOSDIR" -DCMAKE_BUILD_TYPE=Debug -B build -S .
cmake --build build --target install
if [ ! -z "$2" ]; then
mv "$IOSDIR/cl_dlls/client_arm64.dylib" "$IOSDIR/cl_dlls/client_arm64$2.dylib"
if [ ! -z $2 ]; then
cmake -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DCMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT=0 -DCMAKE_INSTALL_PREFIX="$LIBSDIR" -DGAMEDIR="$2" -DCMAKE_BUILD_TYPE=Debug -B build -S .
else
cd ../../
./createipa.sh
cmake -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DCMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT=0 -DCMAKE_INSTALL_PREFIX="$LIBSDIR" -DCMAKE_BUILD_TYPE=Debug -B build -S .
fi
cmake --build build --target install
if [ -d mod-build ]; then
rm -rf mod-build/

View File

@@ -10,10 +10,8 @@ cd "../../engine/platform/ios/bundle" || exit 1
if [ -d "$BUILDDIR" ]; then
mkdir -p "$BUILDDIR/ios/xash3d.app"
cp -r "$BUILDDIR/ios/dlls" "$BUILDDIR/ios/xash3d.app"
cp -r "$BUILDDIR/ios/cl_dlls" "$BUILDDIR/ios/xash3d.app"
cp -r "$BUILDDIR/ios/libs/"* "$BUILDDIR/ios/xash3d.app"
cp Info.plist "$BUILDDIR/ios/xash3d.app"
cp ftp_commands.plist "$BUILDDIR/ios/xash3d.app"
if [ ! -d "$BUILDDIR/SDL2.framework" ]; then
echo "Couldn't find SDL2.framework, place it in the build directory"
exit 1

View File

@@ -91,6 +91,7 @@ SUBDIRS = [
Subproject('3rdparty/nanogl', lambda x: x.env.CLIENT and x.env.NANOGL),
Subproject('3rdparty/gl-wes-v2', lambda x: x.env.CLIENT and x.env.GLWES),
Subproject('3rdparty/gl4es', lambda x: x.env.CLIENT and x.env.GL4ES),
Subproject('ref/common', lambda x: x.env.CLIENT),
Subproject('ref/gl', lambda x: x.env.CLIENT and (x.env.GL or x.env.NANOGL or x.env.GLWES or x.env.GL4ES or x.env.GLES3COMPAT)),
Subproject('ref/soft', lambda x: x.env.CLIENT and x.env.SOFT),
Subproject('ref/null', lambda x: x.env.CLIENT and x.env.NULL),