123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568 |
- /*************************************************************************************************\
- gameTacMap.cpp : Implementation of the gameTacMap component.
- //---------------------------------------------------------------------------//
- // Copyright (C) Microsoft Corporation. All rights reserved. //
- //===========================================================================//
- \*************************************************************************************************/
- #include "gameTacMap.h"
- #include "team.h"
- #include "comndr.h"
- #include "objMgr.h"
- #include "cellip.h"
- #include "gameCam.h"
- #include "Objective.h"
- #include "mission.h"
- #include <windows.h>
- #include "..\resource.h"
- extern unsigned char godMode;
- extern bool useLeftRightMouseProfile;
- #define SQUARE_BLIP 0
- #define DOT_BLIP 1
- #define TRIANGLE_BLIP 2
- const float GameTacMap::s_blinkLength = .5f;
- float GameTacMap::s_lastBlinkTime = 0.f;
- extern bool ShowMovers;
- GameTacMap::GameTacMap()
- {
- top = 0;
- left = 0;
- right = 0;
- bottom = 0;
- buildingPoints = NULL;
- buildingCount = 0;
- navMarkerCount = 0;
- curNavMarker = -1;
- objectiveAnimationId = -1;
- objectiveFlashTime = 0.0f;
- objectiveNumFlashes = 0;
- }
- void GameTacMap::init( unsigned char* bitmapData, int dataSize )
- {
- EllipseElement::init();
- TGAFileHeader* pHeader = (TGAFileHeader*)bitmapData;
- bmpWidth = pHeader->width;
- bmpHeight = pHeader->height;
- textureHandle = gos_NewTextureFromMemory(gos_Texture_Solid,".tga",bitmapData,dataSize,0);
- char path[256];
- strcpy( path, artPath );
- strcat( path, "viewingrect.tga" );
- viewRectHandle = mcTextureManager->loadTexture(path, gos_Texture_Alpha, 0 );
- strcpy( path, artPath );
- strcat( path, "blip.tga" );
- blipHandle = mcTextureManager->loadTexture( path, gos_Texture_Alpha, 0 );
- }
- void GameTacMap::update()
- {
- Stuff::Vector2DOf<long> screen;
- screen.x = userInput->getMouseX();
- screen.y = userInput->getMouseY();
- float width = right - left;
- float height = bottom - top;
- if ( !inRegion(screen.x, screen.y) )
- return;
- ControlGui::instance->setRolloverHelpText( IDS_TACMAP_HELP );
-
- if ( userInput->isLeftClick() )
- {
- screen.x -= left;
- screen.y -= top;
-
- Stuff::Vector3D world;
- tacMapToWorld( screen, width, height, world );
- if (MissionInterfaceManager::instance()->getControlGui()->isAddingAirstrike() &&
- MissionInterfaceManager::instance()->getControlGui()->isButtonPressed( ControlGui::SENSOR_PROBE ))
- MissionInterfaceManager::instance()->doMove(world);
- else
- {
- eye->setPosition( world, false );
- ((GameCamera*)(eye))->setTarget( 0 );
- }
- }
- else if ( userInput->isRightClick() && useLeftRightMouseProfile )
- {
- screen.x -= left;
- screen.y -= top;
-
- Stuff::Vector3D world;
- tacMapToWorld( screen, width, height, world );
- MissionInterfaceManager::instance()->doMove(world);
- }
- }
- bool GameTacMap::animate (long objectiveId, long nFlashes)
- {
- if (objectiveAnimationId == -1)
- {
- objectiveAnimationId = objectiveId - 1;
- objectiveFlashTime = 0.0f;
- objectiveNumFlashes = nFlashes;
- return true;
- }
- return false;
- }
- void GameTacMap::render()
- {
- if (turn < 2) //Terrain not setup yet. Left,Right,Top,Bottom are poopy!
- return;
- gos_VERTEX corners[5];
- gos_SetRenderState( gos_State_AlphaMode, gos_Alpha_OneZero );
- gos_SetRenderState( gos_State_Specular,FALSE );
- gos_SetRenderState( gos_State_AlphaTest, FALSE );
-
- gos_SetRenderState( gos_State_Filter, gos_FilterNone );
- gos_SetRenderState( gos_State_ZWrite, 0 );
- gos_SetRenderState( gos_State_ZCompare, 0 );
- gos_SetRenderState( gos_State_Texture, textureHandle );
- for ( int i = 0; i < 4; ++i )
- {
- corners[i].rhw = 1.0f;
- corners[i].argb = 0xffffffff;
- corners[i].frgb = 0;
- corners[i].z = 0.0f;
- }
- corners[0].x = corners[2].x = left;
- corners[1].x = corners[3].x = right;
- corners[3].y = corners[2].y = bottom;
- corners[0].y = corners[1].y = top;
- corners[0].u = 2.f/(float)bmpWidth;
- corners[3].u = 128.f/(float)bmpWidth;
- corners[2].u = 2.f/(float)bmpWidth;
- corners[1].u = 128.f/(float)bmpWidth;
- corners[0].v = 2.f/(float)bmpWidth;
- corners[3].v = 128.f/(float)bmpHeight;
- corners[2].v = 128.f/(float)bmpHeight;
- corners[1].v = 2.f/(float)bmpWidth;
-
- gos_DrawTriangles( corners, 3 );
- gos_DrawTriangles( &corners[1], 3 );
- Stuff::Vector2DOf<long> screen;
- Stuff::Vector4D nScreen;
- Stuff::Vector3D world;
- //-----------------------------------------------------------
- // Render the objective markers
- long count = 0;
- for ( EList< CObjective*, CObjective* >::EIterator iter = Team::home->objectives.Begin();
- !iter.IsDone(); iter++ )
- {
- //We are there. Start flashing.
- if ((objectiveAnimationId == count) && objectiveNumFlashes)
- {
- objectiveFlashTime += frameLength;
- if ( objectiveFlashTime > .5f )
- {
- objectiveFlashTime = 0.0f;
- objectiveNumFlashes--;
- }
- else if ( objectiveFlashTime > 0.25f)
- {
- (*iter)->RenderMarkers(this, 0);
- }
- if (objectiveNumFlashes == 0)
- {
- //Flashing is done. We now return you to your regularly scheduled program.
- objectiveAnimationId = 0;
- }
- }
- else
- {
- (*iter)->RenderMarkers(this, 0);
- }
- count++;
- }
-
- // this is the little viewing rect
- // Routine that InverseProjects is slightly less accurate but an order of magnitude faster.
- // Can make more accurate later at very little expense to performance.
- // Easy to fix with camera later. -fs
- screen.x = 1;
- screen.y = 1;
-
- nScreen.x = nScreen.y = 1.0f;
- nScreen.z = nScreen.w = 0.0f;
-
- eye->inverseProjectZ( nScreen, world );
- worldToTacMap( world, corners[0] );
- screen.y = Environment.screenHeight - 1;
- nScreen.y = (Environment.screenHeight * 0.6667f) - 1;
- nScreen.z = nScreen.w = 0.0f;
- eye->inverseProjectZ( nScreen, world );
- worldToTacMap( world, corners[1] );
- screen.x = Environment.screenWidth - 1;
- nScreen.x = Environment.screenWidth - 1;
- nScreen.z = nScreen.w = 0.0f;
- eye->inverseProjectZ( nScreen, world );
- worldToTacMap( world, corners[2] );
- screen.y = 1;
- nScreen.y = 1;
- nScreen.z = nScreen.w = 0.0f;
- eye->inverseProjectZ( nScreen, world );
- worldToTacMap( world, corners[3] );
- corners[0].argb = 0xffffffff;
- corners[1].argb = 0xffffffff;
- corners[2].argb = 0xffffffff;
- corners[3].argb = 0xffffffff;
- corners[0].u = corners[1].u = 0.078125f;
- corners[3].u = corners[2].u = .99875f;
- corners[0].v = corners[3].v = 0.078125f;
- corners[1].v = corners[2].v = .99875f;
- corners[4] = corners[0];
- gos_SetRenderState( gos_State_AlphaMode, gos_Alpha_AlphaInvAlpha);
- gos_SetRenderState( gos_State_ShadeMode, gos_ShadeGouraud);
- gos_SetRenderState( gos_State_MonoEnable, 0);
- gos_SetRenderState( gos_State_Perspective, 0);
- gos_SetRenderState( gos_State_Clipping, 2);
- gos_SetRenderState( gos_State_AlphaTest, 0);
- gos_SetRenderState( gos_State_Specular, 0);
- gos_SetRenderState( gos_State_Dither, 1);
- gos_SetRenderState( gos_State_TextureMapBlend, gos_BlendModulate);
- gos_SetRenderState( gos_State_Filter, gos_FilterBiLinear);
- gos_SetRenderState( gos_State_TextureAddress, gos_TextureWrap );
- gos_SetRenderState( gos_State_ZCompare, 0);
- gos_SetRenderState( gos_State_ZWrite, 0);
- DWORD gosTextureHandle = mcTextureManager->get_gosTextureHandle(viewRectHandle);
- gos_SetRenderState( gos_State_Texture, gosTextureHandle );
- gos_DrawQuads( &corners[0], 4 );
- unsigned long colors[MAX_MOVERS];
- unsigned long ringColors[MAX_MOVERS];
- Stuff::Vector3D positions[MAX_MOVERS];
- unsigned long ranges[MAX_MOVERS];
- bool selected[MAX_MOVERS];
- count = 0;
- //------------------------------------------------------------
- // draw non-movers, must do separate check for vehicles, I'm not sure they
- // have sensors
- for ( i = 0; i < MAX_TEAMS; ++i )
- {
- TeamSensorSystem* pSys = SensorManager->getTeamSensor( i );
-
- if ( pSys )
- {
- for ( int j = 0; j < pSys->numSensors; ++j )
- {
- SensorSystem* pSensor = pSys->sensors[j];
- if ( !pSensor )
- continue;
- if ( pSensor->owner->isDestroyed() || pSensor->owner->isDisabled() || pSensor->owner->getStatus() == OBJECT_STATUS_SHUTDOWN )
- continue;
- if ( pSensor->getRange() < 1.1 || pSensor->broken)
- continue;
- if (!pSensor->owner->getTeam())
- continue;
- ObjectClass objClass = pSensor->owner->getObjectClass();
- unsigned long colorBlip = pSensor->owner->getSelected() ? 0xff4bff4b : 0xff00cc00;
- unsigned long colorRing = 0xff00cc00;
-
- if ( pSensor->owner->getTeam()->isNeutral( Team::home ) )
- {
- colorBlip = pSensor->owner->getSelected() ? 0xff4c4cff : 0xff0000ff;
- colorRing = 0xff0000ff;
- }
- else if ( pSensor->owner->getTeam()->isEnemy( Team::home ) ) // enemy
- {
-
- {
- colorBlip = pSensor->owner->getSelected() ? 0xffff3f3f : 0xffff0000;
- colorRing = 0xffff0000;
- }
- }
- if ( objClass != BATTLEMECH && objClass != GROUNDVEHICLE)
- {
- if ( objClass == ARTILLERY )
- {
- // blink
- s_lastBlinkTime += frameLength;
- if ( s_lastBlinkTime > s_blinkLength )
- {
- colorBlip = 0;
- colorRing = 0;
- s_lastBlinkTime = 0.f;
- }
- }
- colors[count] = colorBlip;
- ringColors[count] = colorRing;
- ranges[count] = pSensor->getRange();
- selected[count] = 0;
- positions[count] = pSensor->owner->getPosition();
- count++;
- }
- }
- }
- }
- unsigned long colorBlip, colorRing;
- //-----------------------------------------------------
- // draw the movers
- for (i=0;i<(ObjectManager->numMovers);i++)
- {
- MoverPtr mover = ObjectManager->getMover(i);
- if (mover && mover->getExists() && !(mover->isDestroyed() || mover->isDisabled()))
- {
- SensorSystem* pSensor = mover->getSensorSystem();
- float range = pSensor ? pSensor->getRange() : 0;
- long contactStatus = mover->getContactStatus(Team::home->getId(), true);
- if (mover->getTeamId() == Team::home->id)
- {
- if (mover->getCommanderId() == Commander::home->getId())
- {
- if (mover->isOnGUI())
- {
- colorBlip = mover->getSelected() ? 0xff4bff4b : 0xff00cc00;
- mover->getStatus() == OBJECT_STATUS_SHUTDOWN ? colorRing = 0 : colorRing = 0xff00cc00;
- }
- else
- continue;
- }
- else
- {
- if (mover->isOnGUI() && land->IsGameSelectTerrainPosition(mover->getPosition()) && mover->pathLocks)
- {
- colorBlip = mover->getSelected() ? 0xff4b4bff : 0xff0000cc;
- mover->getStatus() == OBJECT_STATUS_SHUTDOWN ? colorRing = 0 : colorRing = 0xff0000cc;
- }
- else
- continue;
- }
- }
- else if (ShowMovers || (MPlayer && MPlayer->allUnitsDestroyed[MPlayer->commanderID]) || ((mover->getTeamId() != Team::home->id)
- && ( contactStatus != CONTACT_NONE )
- && (mover->getStatus() != OBJECT_STATUS_SHUTDOWN)
- && (!mover->hasNullSignature())
- && (mover->getEcmRange() <= 0.0f) ) ) //Do not draw ECM mechs!!)
- {
- //Not on our side. Draw by contact status
- colorBlip = mover->getSelected() ? 0xffff3f3f : 0xffff0000;
- colorRing = 0xffff0000;
-
- }
- else
- continue;
- colors[count] = colorBlip;
- ringColors[count] = colorRing;
- ranges[count] = range;
- selected[count] = mover->getSelected();
- positions[count] = mover->getPosition();
- count++;
- }
- }
- for ( i = 0; i < count; i++ )
- {
- drawSensor( positions[i], ranges[i], ringColors[i] );
- }
- bool bSel = 0; // draw unselected first
- for ( int j = 0; j < 2; j++ )
- {
- for ( int i = 0; i < count; i++ )
- {
- if ( selected[i] == bSel )
- {
- drawBlip( positions[i], colors[i], DOT_BLIP );
- }
- }
- bSel = 1;
- }
- }
- void GameTacMap::worldToTacMap( Stuff::Vector3D& world, gos_VERTEX& tac )
- {
- TacMap::worldToTacMap( world, left, top, right - left, bottom - top, tac );
- }
- void GameTacMap::initBuildings( unsigned char* data, int size )
- {
- if ( data )
- {
- long* pData = (long*)data;
- buildingCount = *pData++;
- if (buildingCount)
- {
- buildingPoints = new gos_VERTEX[buildingCount];
- gos_VERTEX* pTmp = buildingPoints;
- for ( int i = 0; i < buildingCount; ++i, pTmp++)
- {
- pTmp->x = *pData++ + left;
- pTmp->y = *pData++ + top;
- pTmp->z = 0;
- pTmp->argb = BUILDING_COLOR;
- pTmp->frgb = 0;
- pTmp->rhw = .5;
- pTmp->u = 0.f;
- pTmp->v = 0.f;
- }
- }
- }
- }
- void GameTacMap::drawSensor( const Stuff::Vector3D& pos, float radius, long color )
- {
- if ( color == 0 )
- return;
- gos_VERTEX sqare[4];
- if ( radius > 1 )
- radius += land->metersPerCell * 6.f; // a little fudge
- radius *= ((float)(right - left))/(land->metersPerCell * land->realVerticesMapSide * 3.f);
- for ( int i = 0; i < 4; ++i )
- {
- sqare[i].z = 0;
- sqare[i].rhw = .5;
- sqare[i].argb = color;
- sqare[i].frgb = 0;
- }
- worldToTacMap( (Stuff::Vector3D&)pos, sqare[0] );
- sqare[1].x = sqare[0].x;
- sqare[1].y = sqare[0].y + 1;
- sqare[2].x = sqare[0].x + 1;
- sqare[2].y = sqare[0].y;
- sqare[3].x = sqare[0].x + 1;
- sqare[3].y = sqare[0].y + 1;
- // need to draw that round thing
- Stuff::Vector2DOf< long > center;
- Stuff::Vector2DOf< long > radii;
- center.x = float2long(sqare[1].x);
- center.y = float2long(sqare[1].y);
- radii.x = 2.0f * float2long(radius+.5);
- radii.y = 2.0f * float2long(radius+.5);
- EllipseElement circle( center, radii, color, 0 );
- GUI_RECT rect = { left, top, right, bottom };
- circle.setClip( rect );
- circle.draw();
- }
- void GameTacMap::drawBlip( const Stuff::Vector3D& pos, long color, int type )
- {
- if ( color == 0 )
- return;
- gos_VERTEX triangle[4];
- gos_SetRenderState( gos_State_AlphaTest, 1);
- gos_SetRenderState( gos_State_Specular, 0);
- gos_SetRenderState( gos_State_Dither, 1);
- gos_SetRenderState( gos_State_Filter, gos_FilterBiLinear);
- gos_SetRenderState( gos_State_ZCompare, 0);
- gos_SetRenderState( gos_State_ZWrite, 0);
- unsigned long gosID = mcTextureManager->get_gosTextureHandle( blipHandle );
- gos_SetRenderState( gos_State_Texture, gosID );
- for ( int i = 0; i < 4; ++i )
- {
- triangle[i].z = 0;
- triangle[i].rhw = .5;
- triangle[i].argb = color;
- triangle[i].frgb = 0;
- triangle[i].u = 0.f;
- triangle[i].v = 0.f;
- }
-
- worldToTacMap( (Stuff::Vector3D&)pos, triangle[0] );
- triangle[0].x -= 2.f;
- triangle[1].x = triangle[0].x;
- triangle[2].x = triangle[3].x = triangle[0].x + 4.1f;
- triangle[0].y -= 2.f;
- triangle[3].y = triangle[0].y;
- triangle[1].y = triangle[2].y = triangle[0].y + 4.1f;
- triangle[2].u = triangle[3].u = .250001f;
- triangle[1].v = triangle[2].v = .250001f;
- gos_DrawQuads( triangle, 4 );
- }
- void GameTacMap::setPos( const GUI_RECT& newPos )
- {
- left = newPos.left;
- right = newPos.right;
- top = newPos.top;
- bottom = newPos.bottom;
- }
- //*************************************************************************************************
- // end of file ( TacMap.cpp )
- //*************************************************************************************************
- // end of file ( gameTacMap.cpp )
|