2022-02-27 07:53:44 -05:00
# include <STDInclude.hpp>
2017-01-19 16:23:59 -05:00
namespace Components
{
Utils : : Signal < Renderer : : BackendCallback > Renderer : : BackendFrameSignal ;
2017-06-22 16:05:22 -04:00
Utils : : Signal < Renderer : : BackendCallback > Renderer : : SingleBackendFrameSignal ;
2017-01-19 16:23:59 -05:00
2022-05-05 10:03:14 -04:00
Utils : : Signal < Renderer : : Callback > Renderer : : EndRecoverDeviceSignal ;
Utils : : Signal < Renderer : : Callback > Renderer : : BeginRecoverDeviceSignal ;
2017-04-23 07:31:48 -04:00
2021-11-11 08:00:46 -05:00
Dvar : : Var Renderer : : r_drawTriggers ;
Dvar : : Var Renderer : : r_drawSceneModelCollisions ;
Dvar : : Var Renderer : : r_drawModelBoundingBoxes ;
Dvar : : Var Renderer : : r_drawModelNames ;
Dvar : : Var Renderer : : r_drawAABBTrees ;
Dvar : : Var Renderer : : r_playerDrawDebugDistance ;
2022-12-14 03:40:15 -05:00
Dvar : : Var Renderer : : r_forceTechnique ;
2023-02-04 12:29:32 -05:00
Dvar : : Var Renderer : : r_drawRunners ;
2021-11-11 08:00:46 -05:00
float cyan [ 4 ] = { 0.0f , 0.5f , 0.5f , 1.0f } ;
float red [ 4 ] = { 1.0f , 0.0f , 0.0f , 1.0f } ;
float green [ 4 ] = { 0.0f , 1.0f , 0.0f , 1.0f } ;
// R_draw model names & collisions colors
2021-11-08 11:56:19 -05:00
float sceneModelsColor [ 4 ] = { 1.0f , 1.0f , 0.0f , 1.0f } ;
float dobjsColor [ 4 ] = { 0.0f , 1.0f , 1.0f , 1.0f } ;
float staticModelsColor [ 4 ] = { 1.0f , 0.0f , 1.0f , 1.0f } ;
float gentitiesColor [ 4 ] = { 1.0f , 0.5f , 0.5f , 1.0f } ;
2021-11-11 08:00:46 -05:00
// Trigger colors
float hurt [ 4 ] = { 1.0f , 0.0f , 0.0f , 1.0f } ;
float hurtTouch [ 4 ] = { 0.75f , 0.0f , 0.0f , 1.0f } ;
float damage [ 4 ] = { 0.0f , 0.0f , 1.0f , 1.0f } ;
float once [ 4 ] = { 0.0f , 1.0f , 1.0f , 1.0f } ;
float multiple [ 4 ] = { 0.0f , 1.0f , 0.0f , 1.0f } ;
2021-11-08 11:56:19 -05:00
2017-01-19 16:23:59 -05:00
__declspec ( naked ) void Renderer : : BackendFrameStub ( )
{
__asm
{
pushad
call Renderer : : BackendFrameHandler
popad
mov eax , ds : 66E1 BF0h
2017-01-28 06:39:03 -05:00
push 536 A85h
retn
2017-01-19 16:23:59 -05:00
}
}
void Renderer : : BackendFrameHandler ( )
{
IDirect3DDevice9 * device = * Game : : dx_ptr ;
if ( device )
{
device - > AddRef ( ) ;
2017-06-22 16:05:22 -04:00
2017-01-19 16:23:59 -05:00
Renderer : : BackendFrameSignal ( device ) ;
2017-06-22 16:05:22 -04:00
Utils : : Signal < Renderer : : BackendCallback > copy ( Renderer : : SingleBackendFrameSignal ) ;
Renderer : : SingleBackendFrameSignal . clear ( ) ;
copy ( device ) ;
2017-01-19 16:23:59 -05:00
device - > Release ( ) ;
}
}
2017-06-22 16:05:22 -04:00
void Renderer : : OnNextBackendFrame ( Utils : : Slot < Renderer : : BackendCallback > callback )
{
Renderer : : SingleBackendFrameSignal . connect ( callback ) ;
}
2017-01-19 16:23:59 -05:00
void Renderer : : OnBackendFrame ( Utils : : Slot < Renderer : : BackendCallback > callback )
{
Renderer : : BackendFrameSignal . connect ( callback ) ;
}
2022-05-05 10:03:14 -04:00
void Renderer : : OnDeviceRecoveryEnd ( Utils : : Slot < Renderer : : Callback > callback )
2017-01-19 16:23:59 -05:00
{
Renderer : : EndRecoverDeviceSignal . connect ( callback ) ;
}
2022-05-05 10:03:14 -04:00
void Renderer : : OnDeviceRecoveryBegin ( Utils : : Slot < Renderer : : Callback > callback )
2017-01-19 16:23:59 -05:00
{
Renderer : : BeginRecoverDeviceSignal . connect ( callback ) ;
}
int Renderer : : Width ( )
{
2017-06-22 16:05:22 -04:00
return reinterpret_cast < LPPOINT > ( 0x66E1C68 ) - > x ;
2017-01-19 16:23:59 -05:00
}
int Renderer : : Height ( )
{
2017-06-22 16:05:22 -04:00
return reinterpret_cast < LPPOINT > ( 0x66E1C68 ) - > y ;
2017-01-19 16:23:59 -05:00
}
2017-06-06 08:02:56 -04:00
void Renderer : : PreVidRestart ( )
{
Renderer : : BeginRecoverDeviceSignal ( ) ;
}
void Renderer : : PostVidRestart ( )
{
Renderer : : EndRecoverDeviceSignal ( ) ;
}
__declspec ( naked ) void Renderer : : PostVidRestartStub ( )
{
__asm
{
pushad
call Renderer : : PostVidRestart
popad
push 4F 84 C0h
retn
}
}
2023-02-04 12:29:32 -05:00
void Renderer : : R_TextureFromCodeError ( const char * sampler , Game : : GfxCmdBufState * state , int samplerCode )
2018-12-24 15:42:39 -05:00
{
2023-02-04 12:29:32 -05:00
Logger : : Error (
Game : : ERR_FATAL ,
" Tried to use sampler #{} ('{}') at the wrong timing! Additional info: \n Material: '{}' \n Technique {} \n Technique slot: {} \n Technique flags:{} \n Pass: {} \n Pixel shader: {} \n " ,
samplerCode , sampler , state - > material - > info . name , state - > technique - > name , ( int ) state - > techType , state - > technique - > flags , state - > passIndex , state - > pixelShader - > name
) ;
2018-12-24 15:42:39 -05:00
}
__declspec ( naked ) void Renderer : : StoreGfxBufContextPtrStub1 ( )
{
__asm
{
// original code
2022-06-12 17:07:53 -04:00
mov eax , dword ptr [ eax * 4 + 0x66E600C ]
2018-12-24 15:42:39 -05:00
// show error
2022-06-12 17:07:53 -04:00
pushad
push [ esp + 0x24 + 0x20 ]
push eax
call R_TextureFromCodeError
add esp , 8
popad
2018-12-24 15:42:39 -05:00
// go back
2022-06-12 17:07:53 -04:00
push 0x54CAC1
retn
2018-12-24 15:42:39 -05:00
}
}
__declspec ( naked ) void Renderer : : StoreGfxBufContextPtrStub2 ( )
{
__asm
{
// original code
2022-06-12 17:07:53 -04:00
mov edx , dword ptr [ eax * 4 + 0x66E600C ]
2018-12-24 15:42:39 -05:00
// show error
2022-06-12 17:07:53 -04:00
pushad
2023-02-04 12:29:32 -05:00
push eax
2022-06-12 17:07:53 -04:00
push ebx
push edx
call R_TextureFromCodeError
2023-02-04 12:29:32 -05:00
add esp , 0xC
2022-06-12 17:07:53 -04:00
popad
2018-12-24 15:42:39 -05:00
// go back
2022-06-12 17:07:53 -04:00
push 0x54CFA4
retn
2018-12-24 15:42:39 -05:00
}
}
2018-12-25 16:47:10 -05:00
int Renderer : : DrawTechsetForMaterial ( int a1 , float a2 , float a3 , const char * material , Game : : vec4_t * color , int a6 )
{
auto mat = Game : : DB_FindXAssetHeader ( Game : : XAssetType : : ASSET_TYPE_MATERIAL , Utils : : String : : VA ( " wc/%s " , material ) ) . material ;
return Utils : : Hook : : Call < int ( int , float , float , const char * , Game : : vec4_t * , int ) > ( 0x005033E0 ) ( a1 , a2 , a3 , Utils : : String : : VA ( " %s (^3%s^7) " , mat - > info . name , mat - > techniqueSet - > name ) , color , a6 ) ;
}
2022-12-14 03:40:15 -05:00
void ListSamplers ( )
{
static auto * source = reinterpret_cast < Game : : GfxCmdBufSourceState * > ( 0x6CAF080 ) ;
Game : : Font_s * font = Game : : R_RegisterFont ( " fonts/smallFont " , 0 ) ;
auto height = Game : : R_TextHeight ( font ) ;
auto scale = 1.0f ;
float color [ 4 ] = { 0.0f , 1.0f , 0.0f , 1.0f } ;
for ( std : : size_t i = 0 ; i < 27 ; + + i )
{
if ( source - > input . codeImages [ i ] = = nullptr )
{
color [ 0 ] = 1.f ;
}
else
{
color [ 0 ] = 0.f ;
}
std : : stringstream str ;
str < < std : : format ( " {}/{:#X} => " , i , i ) < < ( source - > input . codeImages [ i ] = = nullptr ? " --- " : source - > input . codeImages [ i ] - > name ) < < " " < < std : : to_string ( source - > input . codeImageSamplerStates [ i ] ) ;
Game : : R_AddCmdDrawText ( str . str ( ) . data ( ) , std : : numeric_limits < int > : : max ( ) , font , 15.0f , ( height * scale + 1 ) * ( i + 1 ) + 14.0f , scale , scale , 0.0f , color , Game : : ITEM_TEXTSTYLE_NORMAL ) ;
}
}
2021-11-07 16:48:52 -05:00
void Renderer : : DebugDrawTriggers ( )
{
2021-11-11 08:00:46 -05:00
if ( ! r_drawTriggers . get < bool > ( ) ) return ;
2021-11-07 16:48:52 -05:00
2021-12-13 12:46:55 -05:00
auto entities = Game : : g_entities ;
2021-11-07 16:48:52 -05:00
2022-06-30 07:32:19 -04:00
for ( std : : size_t i = 0 ; i < Game : : MAX_GENTITIES ; + + i )
2021-11-07 16:48:52 -05:00
{
auto * ent = & entities [ i ] ;
if ( ent - > r . isInUse )
{
Game : : Bounds b = ent - > r . box ;
b . midPoint [ 0 ] + = ent - > r . currentOrigin [ 0 ] ;
b . midPoint [ 1 ] + = ent - > r . currentOrigin [ 1 ] ;
b . midPoint [ 2 ] + = ent - > r . currentOrigin [ 2 ] ;
switch ( ent - > handler )
{
case Game : : ENT_HANDLER_TRIGGER_HURT :
Game : : R_AddDebugBounds ( hurt , & b ) ;
break ;
case Game : : ENT_HANDLER_TRIGGER_HURT_TOUCH :
Game : : R_AddDebugBounds ( hurtTouch , & b ) ;
break ;
case Game : : ENT_HANDLER_TRIGGER_DAMAGE :
Game : : R_AddDebugBounds ( damage , & b ) ;
break ;
case Game : : ENT_HANDLER_TRIGGER_MULTIPLE :
if ( ent - > spawnflags & 0x40 )
Game : : R_AddDebugBounds ( once , & b ) ;
else
Game : : R_AddDebugBounds ( multiple , & b ) ;
break ;
default :
2021-11-11 08:00:46 -05:00
auto rv = std : : min ( static_cast < float > ( ent - > handler ) , 5.0f ) / 5.0f ;
2021-12-13 12:46:55 -05:00
auto gv = std : : clamp ( static_cast < float > ( ent - > handler - 5 ) , 0.f , 5.0f ) / 5.0f ;
auto bv = std : : clamp ( static_cast < float > ( ent - > handler - 10 ) , 0.f , 5.0f ) / 5.0f ;
2021-11-07 16:48:52 -05:00
float color [ 4 ] = { rv , gv , bv , 1.0f } ;
Game : : R_AddDebugBounds ( color , & b ) ;
break ;
}
}
}
}
void Renderer : : DebugDrawSceneModelCollisions ( )
{
2021-11-11 08:00:46 -05:00
if ( ! r_drawSceneModelCollisions . get < bool > ( ) ) return ;
2021-11-07 16:48:52 -05:00
2021-12-13 12:46:55 -05:00
auto scene = Game : : scene ;
2021-11-07 16:48:52 -05:00
2022-06-30 07:32:19 -04:00
for ( auto i = 0 ; i < scene - > sceneModelCount ; + + i )
2021-11-07 16:48:52 -05:00
{
if ( ! scene - > sceneModel [ i ] . model )
continue ;
for ( auto j = 0 ; j < scene - > sceneModel [ i ] . model - > numCollSurfs ; j + + )
{
auto b = scene - > sceneModel [ i ] . model - > collSurfs [ j ] . bounds ;
b . midPoint [ 0 ] + = scene - > sceneModel [ i ] . placement . base . origin [ 0 ] ;
b . midPoint [ 1 ] + = scene - > sceneModel [ i ] . placement . base . origin [ 1 ] ;
b . midPoint [ 2 ] + = scene - > sceneModel [ i ] . placement . base . origin [ 2 ] ;
b . halfSize [ 0 ] * = scene - > sceneModel [ i ] . placement . scale ;
b . halfSize [ 1 ] * = scene - > sceneModel [ i ] . placement . scale ;
b . halfSize [ 2 ] * = scene - > sceneModel [ i ] . placement . scale ;
Game : : R_AddDebugBounds ( green , & b , & scene - > sceneModel [ i ] . placement . base . quat ) ;
}
}
}
2021-11-08 11:56:19 -05:00
void Renderer : : DebugDrawModelBoundingBoxes ( )
2021-11-07 16:48:52 -05:00
{
2021-11-11 08:00:46 -05:00
auto val = r_drawModelBoundingBoxes . get < int > ( ) ;
2021-11-07 16:48:52 -05:00
2021-11-08 11:56:19 -05:00
if ( ! val ) return ;
2021-11-07 16:48:52 -05:00
2022-06-30 07:32:19 -04:00
auto clientNum = Game : : CG_GetClientNum ( ) ;
Game : : gentity_t * clientEntity = & Game : : g_entities [ clientNum ] ;
// Ingame only & player only
if ( ! Game : : CL_IsCgameInitialized ( ) | | clientEntity - > client = = nullptr )
{
2021-11-11 08:00:46 -05:00
return ;
}
2021-11-07 16:48:52 -05:00
2021-12-13 12:46:55 -05:00
float playerPosition [ 3 ] { clientEntity - > r . currentOrigin [ 0 ] , clientEntity - > r . currentOrigin [ 1 ] , clientEntity - > r . currentOrigin [ 2 ] } ;
2021-11-07 16:48:52 -05:00
2021-12-13 12:46:55 -05:00
auto scene = Game : : scene ;
2022-08-10 17:03:26 -04:00
auto gfxAsset = Game : : DB_FindXAssetEntry ( Game : : XAssetType : : ASSET_TYPE_GFXWORLD , Utils : : String : : VA ( " maps/mp/%s.d3dbsp " , ( * Game : : sv_mapname ) - > current . string ) ) ;
2022-06-30 07:32:19 -04:00
if ( gfxAsset = = nullptr )
{
return ;
}
auto world = gfxAsset - > asset . header . gfxWorld ;
2021-11-08 11:56:19 -05:00
2021-11-11 10:44:54 -05:00
auto drawDistance = r_playerDrawDebugDistance . get < int > ( ) ;
auto sqrDist = drawDistance * drawDistance ;
2021-12-13 12:46:55 -05:00
switch ( val )
{
2021-11-08 11:56:19 -05:00
case 1 :
for ( auto i = 0 ; i < scene - > sceneModelCount ; i + + )
{
if ( ! scene - > sceneModel [ i ] . model )
continue ;
2022-06-26 09:40:57 -04:00
if ( Utils : : Maths : : Vec3SqrDistance ( playerPosition , scene - > sceneModel [ i ] . placement . base . origin ) < sqrDist )
2021-11-08 11:56:19 -05:00
{
auto b = scene - > sceneModel [ i ] . model - > bounds ;
b . midPoint [ 0 ] + = scene - > sceneModel [ i ] . placement . base . origin [ 0 ] ;
b . midPoint [ 1 ] + = scene - > sceneModel [ i ] . placement . base . origin [ 1 ] ;
b . midPoint [ 2 ] + = scene - > sceneModel [ i ] . placement . base . origin [ 2 ] ;
b . halfSize [ 0 ] * = scene - > sceneModel [ i ] . placement . scale ;
b . halfSize [ 1 ] * = scene - > sceneModel [ i ] . placement . scale ;
b . halfSize [ 2 ] * = scene - > sceneModel [ i ] . placement . scale ;
Game : : R_AddDebugBounds ( sceneModelsColor , & b , & scene - > sceneModel [ i ] . placement . base . quat ) ;
}
}
break ;
case 2 :
for ( auto i = 0 ; i < scene - > sceneDObjCount ; i + + )
2021-11-07 16:48:52 -05:00
{
2022-06-26 09:40:57 -04:00
if ( Utils : : Maths : : Vec3SqrDistance ( playerPosition , scene - > sceneDObj [ i ] . cull . bounds . midPoint ) < sqrDist )
2021-11-08 11:56:19 -05:00
{
scene - > sceneDObj [ i ] . cull . bounds . halfSize [ 0 ] = std : : abs ( scene - > sceneDObj [ i ] . cull . bounds . halfSize [ 0 ] ) ;
scene - > sceneDObj [ i ] . cull . bounds . halfSize [ 1 ] = std : : abs ( scene - > sceneDObj [ i ] . cull . bounds . halfSize [ 1 ] ) ;
scene - > sceneDObj [ i ] . cull . bounds . halfSize [ 2 ] = std : : abs ( scene - > sceneDObj [ i ] . cull . bounds . halfSize [ 2 ] ) ;
if ( scene - > sceneDObj [ i ] . cull . bounds . halfSize [ 0 ] < 0 | |
scene - > sceneDObj [ i ] . cull . bounds . halfSize [ 1 ] < 0 | |
scene - > sceneDObj [ i ] . cull . bounds . halfSize [ 2 ] < 0 )
{
2022-06-12 17:07:53 -04:00
Logger : : Warning ( Game : : CON_CHANNEL_DONT_FILTER , " Negative half size for DOBJ {}, this will cause culling issues! " ,
scene - > sceneDObj [ i ] . obj - > models [ 0 ] - > name ) ;
2021-11-08 11:56:19 -05:00
}
Game : : R_AddDebugBounds ( dobjsColor , & scene - > sceneDObj [ i ] . cull . bounds ) ;
}
2021-11-07 16:48:52 -05:00
}
2021-11-08 11:56:19 -05:00
break ;
case 3 :
// Static models
for ( size_t i = 0 ; i < world - > dpvs . smodelCount ; i + + )
{
2022-12-14 03:40:15 -05:00
auto staticModel = & world - > dpvs . smodelDrawInsts [ i ] ;
Game : : Bounds * b = & world - > dpvs . smodelInsts [ i ] . bounds ;
2021-11-08 11:56:19 -05:00
2022-12-14 03:40:15 -05:00
if ( Utils : : Maths : : Vec3SqrDistance ( playerPosition , staticModel - > placement . origin ) < sqrDist )
2021-11-08 11:56:19 -05:00
{
2022-12-14 03:40:15 -05:00
if ( staticModel - > model )
2021-11-08 11:56:19 -05:00
{
2022-12-14 03:40:15 -05:00
2023-02-04 12:29:32 -05:00
Game : : R_AddDebugBounds ( staticModelsColor , b ) ;
2021-11-08 11:56:19 -05:00
}
}
}
break ;
2022-06-30 07:32:19 -04:00
default :
break ;
2021-11-07 16:48:52 -05:00
}
}
void Renderer : : DebugDrawModelNames ( )
{
2021-11-11 08:00:46 -05:00
auto val = r_drawModelNames . get < int > ( ) ;
2021-11-07 16:48:52 -05:00
if ( ! val ) return ;
2022-06-30 07:32:19 -04:00
auto clientNum = Game : : CG_GetClientNum ( ) ;
Game : : gentity_t * clientEntity = & Game : : g_entities [ clientNum ] ;
2021-11-11 08:00:46 -05:00
2022-06-30 07:32:19 -04:00
// Ingame only & player only
if ( ! Game : : CL_IsCgameInitialized ( ) | | clientEntity - > client = = nullptr )
{
2021-11-11 08:00:46 -05:00
return ;
}
2021-11-08 11:56:19 -05:00
2021-12-13 12:46:55 -05:00
float playerPosition [ 3 ] { clientEntity - > r . currentOrigin [ 0 ] , clientEntity - > r . currentOrigin [ 1 ] , clientEntity - > r . currentOrigin [ 2 ] } ;
2021-11-07 16:48:52 -05:00
2021-12-13 12:46:55 -05:00
auto scene = Game : : scene ;
2022-08-10 17:03:26 -04:00
auto gfxAsset = Game : : DB_FindXAssetEntry ( Game : : XAssetType : : ASSET_TYPE_GFXWORLD , Utils : : String : : VA ( " maps/mp/%s.d3dbsp " , ( * Game : : sv_mapname ) - > current . string ) ) ;
2022-06-30 07:32:19 -04:00
if ( gfxAsset = = nullptr )
{
return ;
}
auto world = gfxAsset - > asset . header . gfxWorld ;
2021-11-07 16:48:52 -05:00
2021-11-11 10:44:54 -05:00
auto drawDistance = r_playerDrawDebugDistance . get < int > ( ) ;
auto sqrDist = drawDistance * drawDistance ;
2022-06-30 07:32:19 -04:00
switch ( val )
{
2021-11-08 11:56:19 -05:00
case 1 :
2021-11-07 16:48:52 -05:00
for ( auto i = 0 ; i < scene - > sceneModelCount ; i + + )
{
if ( ! scene - > sceneModel [ i ] . model )
continue ;
2022-06-30 07:32:19 -04:00
if ( Utils : : Maths : : Vec3SqrDistance ( playerPosition , scene - > sceneModel [ i ] . placement . base . origin ) < static_cast < float > ( sqrDist ) )
2021-11-08 11:56:19 -05:00
{
Game : : R_AddDebugString ( sceneModelsColor , scene - > sceneModel [ i ] . placement . base . origin , 1.0 , scene - > sceneModel [ i ] . model - > name ) ;
}
2021-11-07 16:48:52 -05:00
}
2021-11-08 11:56:19 -05:00
break ;
case 2 :
2021-11-07 16:48:52 -05:00
for ( auto i = 0 ; i < scene - > sceneDObjCount ; i + + )
{
if ( scene - > sceneDObj [ i ] . obj )
{
for ( int j = 0 ; j < scene - > sceneDObj [ i ] . obj - > numModels ; j + + )
{
2022-06-30 07:32:19 -04:00
if ( Utils : : Maths : : Vec3SqrDistance ( playerPosition , scene - > sceneDObj [ i ] . placement . origin ) < static_cast < float > ( sqrDist ) )
2021-11-08 11:56:19 -05:00
{
Game : : R_AddDebugString ( dobjsColor , scene - > sceneDObj [ i ] . placement . origin , 1.0 , scene - > sceneDObj [ i ] . obj - > models [ j ] - > name ) ;
}
2021-11-07 16:48:52 -05:00
}
}
}
2021-11-08 11:56:19 -05:00
break ;
case 3 :
2021-11-07 16:48:52 -05:00
// Static models
for ( size_t i = 0 ; i < world - > dpvs . smodelCount ; i + + )
{
auto staticModel = world - > dpvs . smodelDrawInsts [ i ] ;
if ( staticModel . model )
{
2022-06-26 09:40:57 -04:00
const auto dist = Utils : : Maths : : Vec3SqrDistance ( playerPosition , staticModel . placement . origin ) ;
2022-06-30 07:32:19 -04:00
if ( dist < static_cast < float > ( sqrDist ) )
2021-11-08 11:56:19 -05:00
{
2022-12-16 09:55:50 -05:00
float rgb01Color [ ] =
{
staticModel . groundLighting . array [ 0 ] / 255.f ,
staticModel . groundLighting . array [ 1 ] / 255.f ,
staticModel . groundLighting . array [ 2 ] / 255.f ,
1.f ,
} ;
Game : : R_AddDebugString ( staticModel . flags & 0x20 ? rgb01Color : staticModelsColor , staticModel . placement . origin , 1.0f , staticModel . model - > name ) ;
2021-11-08 11:56:19 -05:00
}
2021-11-07 16:48:52 -05:00
}
}
2021-11-08 11:56:19 -05:00
break ;
2022-06-30 07:32:19 -04:00
default :
break ;
2021-11-07 16:48:52 -05:00
}
}
2023-02-04 12:29:32 -05:00
void Renderer : : DebugDrawRunners ( )
{
if ( ! Game : : CL_IsCgameInitialized ( ) )
{
return ;
}
if ( r_drawRunners . get < bool > ( ) )
{
auto * fxSystem = reinterpret_cast < Game : : FxSystem * > ( 0x173F200 ) ;
if ( fxSystem )
{
for ( auto i = 0 ; i < fxSystem - > activeElemCount ; i + + )
{
auto * elem = & fxSystem - > effects [ i ] ;
if ( elem - > def )
{
Game : : R_AddDebugString ( sceneModelsColor , elem - > frameNow . origin , 1.0f , elem - > def - > name ) ;
}
}
}
auto soundCount = * reinterpret_cast < int * > ( 0x7C5C90 ) ;
auto * sounds = reinterpret_cast < Game : : ClientEntSound * > ( 0x7C5CA0 ) ;
for ( auto i = 0 ; i < soundCount ; i + + )
{
if ( sounds [ i ] . aliasList )
{
Game : : R_AddDebugString ( staticModelsColor , sounds [ i ] . origin , 1.0f , sounds [ i ] . aliasList - > aliasName ) ;
}
}
}
}
2021-11-07 16:48:52 -05:00
void Renderer : : DebugDrawAABBTrees ( )
{
2021-11-11 08:00:46 -05:00
if ( ! r_drawAABBTrees . get < bool > ( ) ) return ;
2021-11-07 16:48:52 -05:00
Game : : clipMap_t * clipMap = * reinterpret_cast < Game : : clipMap_t * * > ( 0x7998E0 ) ;
if ( ! clipMap ) return ;
for ( unsigned short i = 0 ; i < clipMap - > smodelNodeCount ; + + i )
{
Game : : R_AddDebugBounds ( cyan , & clipMap - > smodelNodes [ i ] . bounds ) ;
}
for ( unsigned int i = 0 ; i < clipMap - > numStaticModels ; i + = 2 )
{
Game : : R_AddDebugBounds ( red , & clipMap - > staticModelList [ i ] . absBounds ) ;
}
}
2022-12-14 03:40:15 -05:00
void Renderer : : ForceTechnique ( )
{
auto forceTechnique = r_forceTechnique . get < int > ( ) ;
if ( forceTechnique > 0 )
{
Utils : : Hook : : Set ( 0x6FABDF4 , forceTechnique ) ;
}
}
int Renderer : : FixSunShadowPartitionSize ( Game : : GfxCamera * camera , Game : : GfxSunShadowMapMetrics * mapMetrics , Game : : GfxSunShadow * sunShadow , Game : : GfxSunShadowClip * clip , float * partitionFraction )
{
auto result = Utils : : Hook : : Call < int ( Game : : GfxCamera * , Game : : GfxSunShadowMapMetrics * , Game : : GfxSunShadow * , Game : : GfxSunShadowClip * , float * ) > ( 0x5463B0 ) ( camera , mapMetrics , sunShadow , clip , partitionFraction ) ;
if ( Maps : : IsCustomMap ( ) )
{
// Fixes shadowmap viewport which fixes pixel adjustment shadowmap bug - partly, because the real problem lies within the way CoD4 shaders are programmed
sunShadow - > partition [ Game : : SunShadowPartition : : R_SUNSHADOW_FAR ] . viewportParms . viewport = sunShadow - > partition [ Game : : SunShadowPartition : : R_SUNSHADOW_NEAR ] . viewportParms . viewport ;
}
return result ;
}
2017-01-19 16:23:59 -05:00
Renderer : : Renderer ( )
{
2017-02-25 06:54:26 -05:00
if ( Dedicated : : IsEnabled ( ) ) return ;
2022-05-05 10:03:14 -04:00
Scheduler : : Loop ( [ ]
{
2021-11-07 16:57:35 -05:00
if ( Game : : CL_IsCgameInitialized ( ) )
{
2023-02-04 12:29:32 -05:00
DebugDrawRunners ( ) ;
2021-11-07 16:57:35 -05:00
DebugDrawAABBTrees ( ) ;
DebugDrawModelNames ( ) ;
2021-11-08 11:56:19 -05:00
DebugDrawModelBoundingBoxes ( ) ;
2021-11-07 16:57:35 -05:00
DebugDrawSceneModelCollisions ( ) ;
DebugDrawTriggers ( ) ;
2022-12-14 03:40:15 -05:00
ForceTechnique ( ) ;
2021-11-07 16:57:35 -05:00
}
2022-05-05 10:03:14 -04:00
} , Scheduler : : Pipeline : : RENDERER ) ;
2021-11-08 11:56:19 -05:00
2022-12-14 03:40:15 -05:00
// COD4 Map Fixes
// The day map porting is perfect we should be able to remove these
Utils : : Hook ( 0x546A09 , FixSunShadowPartitionSize , HOOK_CALL ) . install ( ) - > quick ( ) ;
2022-04-12 17:15:50 -04:00
// Log broken materials
2018-12-24 15:42:39 -05:00
Utils : : Hook ( 0x0054CAAA , Renderer : : StoreGfxBufContextPtrStub1 , HOOK_JUMP ) . install ( ) - > quick ( ) ;
Utils : : Hook ( 0x0054CF8D , Renderer : : StoreGfxBufContextPtrStub2 , HOOK_JUMP ) . install ( ) - > quick ( ) ;
2018-12-25 16:47:10 -05:00
// Enhance cg_drawMaterial
Utils : : Hook : : Set ( 0x005086DA , " ^3solid^7 " ) ;
Utils : : Hook ( 0x00580F53 , Renderer : : DrawTechsetForMaterial , HOOK_CALL ) . install ( ) - > quick ( ) ;
2017-01-19 16:23:59 -05:00
Utils : : Hook ( 0x536A80 , Renderer : : BackendFrameStub , HOOK_JUMP ) . install ( ) - > quick ( ) ;
2017-06-06 08:02:56 -04:00
// Begin device recovery (not D3D9Ex)
2022-06-30 07:32:19 -04:00
Utils : : Hook ( 0x508298 , [ ]
2021-12-13 13:06:04 -05:00
{
Game : : DB_BeginRecoverLostDevice ( ) ;
Renderer : : BeginRecoverDeviceSignal ( ) ;
} , HOOK_CALL ) . install ( ) - > quick ( ) ;
2017-01-19 16:23:59 -05:00
2021-11-08 13:00:51 -05:00
// End device recovery (not D3D9Ex)
2022-06-30 07:32:19 -04:00
Utils : : Hook ( 0x508355 , [ ]
2021-11-08 13:00:51 -05:00
{
Renderer : : EndRecoverDeviceSignal ( ) ;
Game : : DB_EndRecoverLostDevice ( ) ;
} , HOOK_CALL ) . install ( ) - > quick ( ) ;
2017-06-06 08:02:56 -04:00
2021-11-08 13:00:51 -05:00
// Begin vid_restart
Utils : : Hook ( 0x4CA2FD , Renderer : : PreVidRestart , HOOK_CALL ) . install ( ) - > quick ( ) ;
2017-06-06 08:02:56 -04:00
2021-11-08 13:00:51 -05:00
// End vid_restart
Utils : : Hook ( 0x4CA3A7 , Renderer : : PostVidRestartStub , HOOK_CALL ) . install ( ) - > quick ( ) ;
2021-11-07 16:48:52 -05:00
2023-01-27 18:05:26 -05:00
Events : : OnDvarInit ( [ ]
2021-11-08 13:00:51 -05:00
{
2021-12-13 13:06:04 -05:00
static const char * values [ ] =
2021-11-08 13:00:51 -05:00
{
2021-11-11 08:00:46 -05:00
" Disabled " ,
" Scene Models " ,
" Scene Dynamic Objects " ,
" GfxWorld Static Models " ,
2021-11-08 13:00:51 -05:00
nullptr
} ;
2023-02-04 12:29:32 -05:00
Renderer : : r_drawRunners = Game : : Dvar_RegisterBool ( " r_drawRunners " , false , Game : : DVAR_NONE , " Draw active sound & fx runners " ) ;
2022-03-08 07:20:28 -05:00
Renderer : : r_drawModelBoundingBoxes = Game : : Dvar_RegisterEnum ( " r_drawModelBoundingBoxes " , values , 0 , Game : : DVAR_CHEAT , " Draw scene model bounding boxes " ) ;
Renderer : : r_drawSceneModelCollisions = Game : : Dvar_RegisterBool ( " r_drawSceneModelCollisions " , false , Game : : DVAR_CHEAT , " Draw scene model collisions " ) ;
Renderer : : r_drawTriggers = Game : : Dvar_RegisterBool ( " r_drawTriggers " , false , Game : : DVAR_CHEAT , " Draw triggers " ) ;
Renderer : : r_drawModelNames = Game : : Dvar_RegisterEnum ( " r_drawModelNames " , values , 0 , Game : : DVAR_CHEAT , " Draw all model names " ) ;
Renderer : : r_drawAABBTrees = Game : : Dvar_RegisterBool ( " r_drawAabbTrees " , false , Game : : DVAR_CHEAT , " Draw aabb trees " ) ;
2023-01-27 18:05:26 -05:00
Renderer : : r_playerDrawDebugDistance = Game : : Dvar_RegisterInt ( " r_drawDebugDistance " , 1000 , 0 , 50000 , Game : : DVAR_ARCHIVE , " r_draw debug functions draw distance relative to the player " ) ;
2022-12-14 03:40:15 -05:00
Renderer : : r_forceTechnique = Game : : Dvar_RegisterInt ( " r_forceTechnique " , 0 , 0 , 14 , Game : : DVAR_NONE , " Force a base technique on the renderer " ) ;
2023-01-27 18:05:26 -05:00
} ) ;
2017-01-19 16:23:59 -05:00
}
Renderer : : ~ Renderer ( )
{
Renderer : : BackendFrameSignal . clear ( ) ;
2017-06-22 16:05:22 -04:00
Renderer : : SingleBackendFrameSignal . clear ( ) ;
2017-01-19 16:23:59 -05:00
Renderer : : EndRecoverDeviceSignal . clear ( ) ;
Renderer : : BeginRecoverDeviceSignal . clear ( ) ;
}
}