rendered paste body/*
qwh - Enemy Territory: Quake Wars hack for linux
http://www.nixcoders.org/
Copyright (C) 2007 - *nixCoders team
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "qwh.h"
DEFVFUNC(orig_idGameLocal_Draw2D, bool, (idGameLocal *this_idGameLocal));
DEFVFUNC(orig_idGameLocal_InitFromNewMap, void, (idGameLocal *this_idGameLocal, const char* mapName, idRenderWorld *renderWorld, idSoundWorld *soundWorld, bool isServer, bool isClient, int randSeed, int startTime, bool isUserChange));
//DEFVFUNC(orig_idRenderSystem_AllocRenderWorld, idRenderWorld *, (idRenderSystem *this_idRenderSystem));
DEFVFUNC(orig_idRenderWorld_AddEntityDef, qhandle_t, (idRenderWorld *this_renderWorld, renderEntity_t *re));
Qw::Qw() {
this->orig_GetGameAPI = NULL;
this->gameLibHandle = NULL;
// Hook system functions
pltHook("dlopen", (void *)qwh_dlopen);
pltHook("dlsym", (void *)qwh_dlsym);
pltHook("dlclose", (void *)qwh_dlclose);
// Workaround for french keyboard open console key
char *envLang = getenv("LANG");
if (envLang && strstr(envLang, "fr_FR"))
pltHook("SDL_PollEvent", (void *)qwh_SDL_PollEvent);
}
Qw::~Qw() {
}
void *Qw::dlopen(const char *filename, int flag) {
void *handle = ::dlopen(filename, flag);
LOG_DEBUG("Qw::dlopen(): " << filename << " handle:" << handle);
if (!strcmp(basename(strdupa(filename)), QW_GAMELIB_NAME))
this->gameLibHandle = handle;
return handle;
}
void *Qw::dlsym(void *handle, const char *symbol) {
void *addr = ::dlsym(handle, symbol);
LOG_DEBUG("Qw::dlsym(): handle:" << handle << " " << symbol << " addr:" << addr);
if ((handle == this->gameLibHandle) && (!strcmp(symbol, QW_GETGAMEAPI_SYMBOL))) {
this->orig_GetGameAPI = (_GetGameAPI_t *)addr;
return (void *)qwh_GetGameAPI;
}
return addr;
}
int Qw::dlclose(void *handle) {
int result = ::dlclose(handle);
LOG_DEBUG("Qw::dlclose(): handle:" << handle << " " << result);
return result;
}
void Qw::drawPlayersEsp() {
idVec2 position;
for ( int i = 0; i < MAX_CLIENTS; i++ ) {
idPlayer* player = gLocal->GetClient( i );
if(i == gLocal->localClientNum) {
if(player->CheckDetected(750.0f)) {
deviceContext->DrawText(va( L"Detected!"), sdBounds2D(0, 45, 640, 0), DTF_CENTER | DTF_NOCLIPPING);
}
continue;
}
if ( player == NULL || player->IsInLimbo())
continue;
//LOG_DEBUG(gLocal->entities[i]->GetSkin()->DefaultDefinition());
idVec3 enemy = player->GetPlayerPhysics().GetOrigin();
idVec3 enemy2 = enemy - (enemy * gLocal->GetLocalPlayer()->GetPlayerPhysics().GetGravityNormal ( )) * gLocal->GetLocalPlayer()->GetPlayerPhysics().GetGravityNormal ( );
idVec3 pos2 = gLocal->GetLocalPlayer()->GetPlayerPhysics().GetOrigin();
pos2 = pos2 - (pos2 * gLocal->GetLocalPlayer()->GetPlayerPhysics().GetGravityNormal ( )) * gLocal->GetLocalPlayer()->GetPlayerPhysics().GetGravityNormal ( );
float fdist = (enemy2 - pos2).LengthFast ( );
int fdist2 = static_cast<int>(fdist);
int size = (fdist2/1500)*6;
if(size <= 8)
size = 8;
if(size < 20) {
idVec3 coord = player->GetEyeOffset(player->eyePosition) + idVec3(0,0,10);
this->w2s(gLocal->playerView.GetCurrentView(), coord, position);
deviceContext->SetFontSize(size);
deviceContext->SetColor(1, 1, 1, 1);
//virtual void DrawText( const char *text, const idVec3 &origin, float scale, const idVec4 &color, const idMat3 &viewAxis, const int align = 1, const int lifetime = 0) = 0;
//rWorld->DrawText(va( "%s", player->userInfo.name.c_str()), player->firstPersonViewOrigin, 1.0f, idVec4(1.0f, 1.0f, 5.0f, 1.0f), gLocal->playerView.GetCurrentView().viewaxis);
deviceContext->DrawText(va( L"%s", player->userInfo.name.c_str()), sdBounds2D(position.x, position.y, 0, 0), DTF_CENTER | DTF_NOCLIPPING);
//deviceContext->DrawText(L"someone", sdBounds2D(position.x, position.y, 0, 0), DTF_CENTER);
//LOG_DEBUG("fini");
}
//idBox b = idBox( player->GetPhysics()->GetBounds(), player->GetPhysics()->GetOrigin(), gLocal->playerView.GetCurrentView().viewaxis); //player->GetPhysics()->GetAxis() );
//rWorld->DebugBox(idVec4(0.0f, 1.0f, 1.0f, 1.0f), b);
// virtual void DebugBounds( const idVec4 &color, const idBounds &bounds, const idVec3 &org = vec3_origin, const idMat3& axes = mat3_identity, const int lifetime = 0 ) = 0;
rWorld->DebugBounds(idVec4(0.0f, 1.0f, 1.0f, 1.0f), player->GetPhysics()->GetBounds(), player->GetPhysics()->GetOrigin(), gLocal->playerView.GetCurrentView().viewaxis);
//
// idVec3 org = player->GetPhysics()->GetOrigin();
// idMat3 axes = player->GetAxis();
// idBounds bounds = player->GetPhysics()->GetBounds();
// sdWorldToScreenConverter converter(gLocal->playerView.GetCurrentView());
//
// sdBounds2D bracketBounds;
// converter.Transform(bounds, axes, org, bracketBounds);
//
// idVec4 v = bracketBounds.ToVec4();
//deviceContext->DrawRect( 0, 0, SCREEN_WIDTH * 1.0f / aspectRatio, SCREEN_HEIGHT, 0.0f, 0.0f, 1.0f, 1.0f, declHolder.declMaterialType.LocalFind( "_white" ) );
//virtual void DrawRect( float x, float y, float w, float h, float s1, float t1, float s2, float t2, const idMaterial* material, float angle = 0.0f ) = 0;
//deviceContext->DrawRect(v.x, v.y, v.z, v.w, 0.0f, 0.0f, 1.0f, 1.0f, whiteMat);
}
}
bool Qw::idGameLocal_Draw2D(idGameLocal *this_idGameLocal) {
bool result = orig_idGameLocal_Draw2D(this_idGameLocal);
this->drawPlayersEsp();
// Advert
deviceContext->SetColor(1, 0, 0, 1);
//deviceContext->DrawRect( 0, 0, SCREEN_WIDTH * 1.0f / aspectRatio, SCREEN_HEIGHT, 0.0f, 0.0f, 1.0f, 1.0f, declHolder.declMaterialType.LocalFind( "_white" ) );
deviceContext->DrawText(va( L"QWHACK! v0.1"), sdBounds2D(0, 30, 640, 0), DTF_CENTER | DTF_NOCLIPPING);
return result;
}
void Qw::idGameLocal_InitFromNewMap(idGameLocal *this_idGameLocal, const char *mapName, idRenderWorld *renderWorld, idSoundWorld *soundWorld, bool isServer, bool isClient, int randSeed, int startTime, bool isUserChange) {
LOG_DEBUG("Qw::idGameLocal_InitFromNewMap() " << rWorld);
rWorld = renderWorld;
HOOKVFUNC(rWorld, &idRenderWorld::AddEntityDef, orig_idRenderWorld_AddEntityDef, qwh_idRenderWorld_AddEntityDef);
this->whiteMat = declHolder.declMaterialType.LocalFind( "_white" );
orig_idGameLocal_InitFromNewMap(this_idGameLocal, mapName, renderWorld, soundWorld, isServer, isClient, randSeed, startTime, isUserChange);
}
//virtual qhandle_t AddEntityDef( const renderEntity_t *re ) = 0;
qhandle_t Qw::idRenderWorld_AddEntityDef(idRenderWorld *this_renderWorld, renderEntity_t *re) {
if(!(gLocal->GetClient(re->spawnID)->GetHealth() <= 0)) {
LOG_DEBUG("Not dead.");
if(strstr(re->hModel->Name(), "models/characters/animations/strogg/") || strstr(re->hModel->Name(), "models/characters/animations/initial_edf/")) {
if(gLocal->entities[gLocal->localClientNum]->GetEntityAllegiance(gLocal->entities[re->spawnID]) == TA_ENEMY) {
LOG_DEBUG("Enemy");
re->modelDepthHack = 1.0f;
re->shaderParms[ SHADERPARM_RED ] = 1.0f;
re->shaderParms[ SHADERPARM_GREEN ] = 0.0f;
re->shaderParms[ SHADERPARM_BLUE ] = 1.0f;
re->shaderParms[ SHADERPARM_ALPHA ] = 0.5f;
re->customShader = whiteMat;
} else if(gLocal->entities[gLocal->localClientNum]->GetEntityAllegiance(gLocal->entities[re->spawnID]) == TA_FRIEND) {
LOG_DEBUG("Friend");
re->modelDepthHack = 1.0f;
re->shaderParms[ SHADERPARM_RED ] = 1.0f;
re->shaderParms[ SHADERPARM_GREEN ] = 1.0f;
re->shaderParms[ SHADERPARM_BLUE ] = 0.0f;
re->shaderParms[ SHADERPARM_ALPHA ] = 0.5f;
re->customShader = whiteMat;
}
}
}
qhandle_t qh = orig_idRenderWorld_AddEntityDef(this_renderWorld, re);
return qh;
}
//virtual idRenderWorld * AllocRenderWorld( void ) = 0;
/*
idRenderWorld *Qw::idRenderSystem_AllocRenderWorld(idRenderSystem *this_idRenderSystem) {
//idRenderWorld *renderWorld = orig_idRenderSystem_AllocRenderWorld(this_idRenderSystem);
LOG_DEBUG("Qw::idRenderSystem_AllocRenderWorld() " << renderWorld);
//if(!rWorld || rWorld == NULL) {
rWorld = renderWorld;
LOG_DEBUG("Qw::idRenderSystem_AllocRenderWorld() rWorld = " << renderWorld);
//}
return renderWorld;
}
*/
//void sdUIRenderModel::SetRenderWorld( idRenderWorld* world )
//void
gameExport_t *Qw::qw_GetGameAPI(gameImport_t *import) {
gameExport_t *gameExport = this->orig_GetGameAPI(import);
LOG_DEBUG("Qw::GetGameAPI(): export:" << gameExport << " import:" << import);
gLocal = (idGameLocal *)gameExport->game;
sys = import->sys;
common = import->common;
cmdSystem = import->cmdSystem;
cvarSystem = import->cvarSystem;
fileSystem = import->fileSystem;
networkSystem = import->networkSystem;
renderSystem = import->renderSystem;
deviceContext = import->deviceContext;
soundSystem = import->soundSystem;
renderModelManager = import->renderModelManager;
declManager = import->declManager;
collisionModelManager = import->collisionModelManager;
// bse = import->bse;
networkService = import->networkService;
// adManager = import->adManager;
// keyInputManager = import->keyInputManager;
AASFileManager = import->AASFileManager;
notificationSystem = import->notificationSystem;
graphManager = import->graphManager;
idDict::SetGlobalPools(import->globalKeys, import->globalValues);
idStr::SetStringAllocator(import->stringAllocator);
idWStr::SetStringAllocator(import->wideStringAllocator);
// set interface pointers used by idLib
idLib::sys = sys;
idLib::common = common;
idLib::cvarSystem = cvarSystem;
idLib::fileSystem = fileSystem;
//rWorld = renderSystem->AllocRenderWorld();
HOOKVFUNC(gLocal, &idGameLocal::InitFromNewMap, orig_idGameLocal_InitFromNewMap, qwh_idGameLocal_InitFromNewMap);
HOOKVFUNC(gLocal, &idGameLocal::Draw2D, orig_idGameLocal_Draw2D, qwh_idGameLocal_Draw2D);
//HOOKVFUNC(renderSystem, &idRenderSystem::AllocRenderWorld, orig_idRenderSystem_AllocRenderWorld, qwh_idRenderSystem_AllocRenderWorld);
LOG_DEBUG("Qw::GetGameAPI(): done");
return gameExport;
}
//void Qw::w2sTransform(const idBounds& src, const idMat3& axes, const idVec3& origin, sdBounds2D& dst) const {
// //Constructor
// const float width = SCREEN_WIDTH * 1.0f / deviceContext->GetAspectRatioCorrection();
// w2s_extents.Set( width, SCREEN_HEIGHT );
// //Setup( view );
//
// //Setup
// w2s_projectionMatrix = w2s_projectionMatrixArray;
// w2s_modelViewMatrix = w2s_modelViewMatrixArray;
// rWorld->SetupMatrices( &view, w2s_projectionMatrix, w2s_modelViewMatrix );
//
// idVec3 point;
// idVec2 screenPoint;
//
// dst.Clear();
//
// int i;
// for ( i = 0; i < 8; i++ ) {
// point[ 0 ] = src[ ( i & 1 ) >> 0 ][ 0 ];
// point[ 1 ] = src[ ( i & 2 ) >> 1 ][ 1 ];
// point[ 2 ] = src[ ( i & 4 ) >> 2 ][ 2 ];
//
// point *= axes;
// point += origin;
//
// Transform( point, screenPoint );
//
// dst.AddPoint( screenPoint );
// }
//}
void Qw::w2s( const renderView_t& view, const idVec3& src, idVec2& dst ) {
//Constructor
const float width = SCREEN_WIDTH * 1.0f / deviceContext->GetAspectRatioCorrection();
w2s_extents.Set( width, SCREEN_HEIGHT );
//Setup( view );
//Setup
w2s_projectionMatrix = w2s_projectionMatrixArray;
w2s_modelViewMatrix = w2s_modelViewMatrixArray;
rWorld->SetupMatrices( &view, w2s_projectionMatrix, w2s_modelViewMatrix );
//Transform
int i;
idPlane eye, clip;
for ( i = 0 ; i < 4 ; i++ ) {
eye[i] =
src[0] * w2s_modelViewMatrix[ i + 0 * 4 ] +
src[1] * w2s_modelViewMatrix[ i + 1 * 4 ] +
src[2] * w2s_modelViewMatrix[ i + 2 * 4 ] +
w2s_modelViewMatrix[ i + 3 * 4 ];
}
for ( i = 0 ; i < 4 ; i++ ) {
clip[i] =
eye[0] * w2s_projectionMatrix[ i + 0 * 4 ] +
eye[1] * w2s_projectionMatrix[ i + 1 * 4 ] +
eye[2] * w2s_projectionMatrix[ i + 2 * 4 ] +
eye[3] * w2s_projectionMatrix[ i + 3 * 4 ];
}
if( clip[ 3 ] <= 0.01f ) {
clip[ 3 ] = 0.01f;
}
dst[ 0 ] = clip[ 0 ] / clip[ 3 ];
dst[ 1 ] = clip[ 1 ] / clip[ 3 ];
dst[ 0 ] = ( 0.5f * ( 1.0f + dst[ 0 ] ) * w2s_extents[ 0 ] );
dst[ 1 ] = ( 0.5f * ( 1.0f - dst[ 1 ] ) * w2s_extents[ 1 ] );
}