Rise
The Vieneo Province
AttitudeIndicator.cpp
Go to the documentation of this file.
1 #include "../Instrument.h"
2 
3 AttitudeIndicator::AttitudeIndicator(int prmX, int prmY, float prmXScale, float prmYScale, Bus* prmBus, Logger* prmLogger, DeviceObject* prmDevice, std::vector<Font*> prmFonts) :
4  Instrument(prmX, prmY, prmXScale, prmYScale, prmBus, prmLogger, prmDevice, prmFonts)
5 {
6  logger->AddToCallStack("AttitudeIndicator::ctor");
7 
8  // so 1:1 scale is 83x89
9  // to make sure we don't show blackness we need to expand based on hypotenuse
10 
11  // old design which showed 45 degrees so that is 1/4 of the height
12  float tvrange = 89.0f * prmYScale; // displayed height
13  tvpitchscale = tvrange / D3DXToRadian(45.0f); // 2 px per degree converted to radian
14  tvvertoffset = 480.0f * 0.5f + 1.0f; // halfway down on the sprite
15  const float hypotenuse = sqrtf(powf(83.0f*prmXScale, 2.0f) + powf(tvrange, 2.0f));
16  xMargins = static_cast<int>((hypotenuse - 83.0f * prmXScale) * 0.5f);
17  yMargins = static_cast<int>((hypotenuse - tvrange) * 0.5f);
18  tvrange += yMargins * 2.0f;
19  halftvrange = tvrange * 0.5f;
20 
21  scissor_rect.left = x;
22  scissor_rect.top = y;
23  scissor_rect.right = x + static_cast<long>(83.0f * xScale);
24  scissor_rect.bottom = y + static_cast<long>(89.0f * yScale);
25 
26  artificialHorizon = new Sprite(logger, pDevice, "Textures/Instruments/FlatHorizon.png", prmX - xMargins, prmY - yMargins, 0.1f, 0, 0, 150, 480, 0xFFFFFFFF, prmXScale, prmYScale);
27  artificialHorizon->SetRotationCenter(D3DXVECTOR2(83.0f*0.5f*xScale + xMargins, 89.0f*0.5f*yScale + yMargins));
28  // 83x89 vs ="348" height="344
29  commandBars = new Sprite(logger, pDevice, "Textures/Instruments/command bars.png", prmX, prmY, 0.9f, 0, 0, 219, 70, 0xFFFFFFFF, prmXScale*0.24f, prmYScale* 0.26f);
30  failFlagLocalizer = new Sprite(logger, pDevice, "Textures/Instruments/yellow_x.png", prmX + 27, prmY + 81, 0.5f, 0, 0, 38, 55, 0xFFFFFFFF, prmXScale * 0.78f, prmYScale*0.09f);
31  failFlagGlideslope = new Sprite(logger, pDevice, "Textures/Instruments/yellow_x.png", prmX + 75, prmY + 30, 0.5f, 0, 0, 38, 55, 0xFFFFFFFF, prmXScale*0.13f, prmYScale*0.56f);
32  glideslopeBox = new Sprite(logger, pDevice, "Textures/Instruments/glideslope.png", prmX + 75, prmY + 31, 0.4f, 0, 0, 25, 160, 0xFFFFFFFF, prmXScale*0.24f, prmYScale* 0.26f);
33  glideslopeBug = new Sprite(logger, pDevice, "Textures/Instruments/glideslope-bug.png", prmX + 76, prmY + 38, 0.5f, 0, 0, 18, 18, 0xFFFFFFFF, prmXScale*0.24f, prmYScale* 0.26f);
34  localizerBox = new Sprite(logger, pDevice, "Textures/Instruments/localizer.png", prmX + 27, prmY + 81, 0.4f, 0, 0, 160, 25, 0xFFFFFFFF, prmXScale*0.24f, prmYScale* 0.26f);
35  localizerBug = new Sprite(logger, pDevice, "Textures/Instruments/glideslope-bug.png", prmX + 76, prmY + 38, 0.5f, 0, 0, 18, 18, 0xFFFFFFFF, prmXScale*0.24f, prmYScale* 0.26f);
36  aoaHigh = new Sprite(logger, pDevice, "Textures/Instruments/aoahigh.dds", prmX + 25, prmY - 7, 0.5f, 0, 0, 32, 32, 0xFFFFFFFF);
37  aoa = new Sprite(logger, pDevice, "Textures/Instruments/aoa.dds", prmX, prmY, 0.5f, 0, 0, 32, 32, 0xFFFFFFFF);
38  aoaLow = new Sprite(logger, pDevice, "Textures/Instruments/aoalow.dds", prmX + 25, prmY + 64, 0.5f, 0, 0, 32, 32, 0xFFFFFFFF);
39  recticle = new Sprite(logger, pDevice, "Textures/Instruments/recticle.png", prmX, prmY, 0.5f, 0, 0, 32, 32, 0xFFFFFFFF);
40  vector = new Sprite(logger, pDevice, "Textures/Instruments/vector.png", prmX, prmY, 0.5f, 0, 0, 32, 32, 0xFFFFFFFF);
41 
42  cbpitchscale = 2.1f / D3DXToRadian(1); // 67 pixels for 10 degrees converted to radian
43  cbvertoffset = y + 36.0f;
44 }
45 
47 {
48  HRESULT hr;
49 
50  RECT oldScissorRect;
51  V(pDevice->GetScissorRect(&oldScissorRect));
52 
53  try
54  {
55  V(pDevice->pSprite->Flush());
56  }
57  catch (...) // this is because if there is nothing in the buffer drawn this will throw an unhandled exception!
58  {
59  }
60 
62 
63  // artificial horizon is at 1.0
65 
66  // then command bars at 0.9
68  commandBars->Draw();
69 
70  // tests
71  //bus->AFCS.CurrentLateralMode = Bus::Afcs::LateralModes::Localizer;
72  //static float boo = 0.0f;
73  //boo += 0.01f;
74  //bus->LocalizerDeviationRadians = D3DXToRadian(sinf(boo)*2.6f); // want it from 2.5 degrees to -2.5 degrees
75 
76  if (bus->AFCS.CurrentLateralMode == Bus::Afcs::LateralModes::Localizer || bus->AFCS.StandbyLateralMode == Bus::Afcs::LateralModes::Localizer)
77  {
78  localizerBox->Draw();
79 
80  if (fabsf(D3DXToDegree(bus->LocalizerDeviationRadians)) <= 2.5f)
81  localizerBug->Draw();
82  else
84  }
85 
86  // tests
87  //bus->AFCS.CurrentVerticalMode = Bus::Afcs::VerticalModes::GlideSlope;
88  //static float boo = 0.0f;
89  //boo += 0.01f;
90  //bus->GlideslopeDeviationRadians = D3DXToRadian(sinf(boo)*0.8f); // want it from 0.8 degrees to -0.8 degrees
91 
92  if (bus->AFCS.CurrentVerticalMode == Bus::Afcs::VerticalModes::GlideSlope || bus->AFCS.StandbyVerticalMode == Bus::Afcs::VerticalModes::GlideSlope)
93  {
95 
96  if (fabsf(D3DXToDegree(bus->GlideslopeDeviationRadians)) <= 0.7f)
98  else
100  }
101 
102 
103  // aoa bugs
104  // ReSharper disable once CppDefaultCaseNotHandledInSwitchStatement
105  switch (lastAOA)
106  {
107  case 0: aoaHigh->Draw(); break;
108  case 1: aoa->Draw(); break;
109  case 2: aoaLow->Draw(); break;
110  }
111 
112 
114  DrawText(L"AF", 1, 0, 0.9f, DT_NOCLIP, 0xFF00FF00, 1, "AF");
115 
116 
117  if (velocityVec.z == 1.0f)
118  vector->Draw(0xFF00FF00); // green
119  else if (velocityVec.z == -1.0f)
120  vector->Draw(0xFFFF0000); // red
121 
122 
123  if (recticleVec.z == 1.0f)
124  recticle->Draw(0xFF00FF00); // green
125  else if(recticleVec.z == -1.0f)
126  recticle->Draw(0xFFFF0000); // red
127 
128 
129  V(pDevice->pSprite->Flush());
130 
131  V(pDevice->SetScissorRect(&oldScissorRect));
132 }
133 
134 void AttitudeIndicator::FrameMove(float fElapsed)
135 {
136  if (roll > D3DX_HALFPI && bus->RollAttitudeRadians < -D3DX_HALFPI)
137  roll -= D3DX_TAU;
138  if (roll < -D3DX_HALFPI && bus->RollAttitudeRadians > D3DX_HALFPI)
139  roll += D3DX_TAU;
140  roll += (bus->RollAttitudeRadians - roll)*0.25f;
141  pitch += (bus->PitchAttitudeRadians - pitch)*0.25f;
143 
144  artificialHorizon->SetRectangle(static_cast<int>(tvvertoffset - halftvrange - tvpitch), 34 - xMargins, 117 + xMargins, static_cast<int>(tvvertoffset + halftvrange - tvpitch));
147 
149  {
151  if (bus->AFCS.CurrentLateralMode == Bus::Afcs::LateralModes::Localizer)
152  commandBars->rotate *= 2.0f;
153 
154  float pitchDev = bus->AFCS.DesiredPitchRadians - pitch;
155  if (bus->AFCS.CurrentVerticalMode == Bus::Afcs::VerticalModes::GlideSlope)
156  pitchDev *= 2.0f;
157  if (pitchDev > D3DXToRadian(20.0f)) pitchDev = D3DXToRadian(20.0f);
158  if (pitchDev < D3DXToRadian(-20.0f)) pitchDev = D3DXToRadian(-20.0f);
159 
160  commandBars->SetLocation(x + 15, static_cast<int>(cbvertoffset - pitchDev * cbpitchscale));
161  commandBars->Update();
162  }
163 
164  if (bus->AFCS.CurrentLateralMode == Bus::Afcs::LateralModes::Localizer || bus->AFCS.StandbyLateralMode == Bus::Afcs::LateralModes::Localizer)
165  {
166  if (fabsf(D3DXToDegree(bus->LocalizerDeviationRadians)) <= 2.5f)
167  {
168  localizerBug->SetLocation(x + 27 + 26 * static_cast<int>((D3DXToDegree(bus->LocalizerDeviationRadians) + 2.5f) / 5.0f), y + 81);
169  localizerBug->Update();
170  }
171  }
172 
173  if (bus->AFCS.CurrentVerticalMode == Bus::Afcs::VerticalModes::GlideSlope || bus->AFCS.StandbyVerticalMode == Bus::Afcs::VerticalModes::GlideSlope)
174  {
175  if (fabsf(D3DXToDegree(bus->GlideslopeDeviationRadians)) <= 0.7f)
176  {
177  glideslopeBug->SetLocation(x + 75, y + 30 + static_cast<int>(28.0f * (D3DXToDegree(bus->GlideslopeDeviationRadians) + 0.7f) / 1.4f));
179  }
180  }
181 
182 
183  // aoa bugs
184  const short offsety = static_cast<short>(D3DXToDegree(-bus->AngleOfAttackRadians) * 2.0f) + 38; // 2 pixels per degree
185  char thisAOA;
186  if (offsety < 0)
187  thisAOA = 0;
188  else if (offsety > 71)
189  thisAOA = 2;
190  else
191  {
192  thisAOA = 1;
193  aoa->SetLocation(x + 25, y - 7 + offsety);
194  aoa->Update();
195  }
196  if (((lastAOA == 2 && thisAOA == 0) || (lastAOA == 0 && thisAOA == 2)) &&
197  playerships[0].reference != REF_ONGROUND && bus->IndicatedAirspeedKms > 0.02f &&
198  ourcockpit.power > 0.5f)
199  {
200  Command command;
201  command.name = "AuralAOA";
202  bus->AddCommand(command, true);
203  }
204  lastAOA = thisAOA;
205 
206 
207  // Velocity vector in 10 seconds
208  if (bearVel != 999.0f && markVel != 999.0f)
209  {
210  // Adjust for center of ADI
211  if (fabs(bearVel) > 90.0f)
212  {
213  velocityVec.z = -1.0f;
214  if (bearVel > 90.0f)
215  velocityVec.x = 66.0f - ((bearVel - 180.0f) / 31.289076f)*41.5f;
216  else
217  velocityVec.x = 66.0f - ((bearVel + 180.0f) / 31.289076f)*41.5f;
218  velocityVec.y = 69.0f - (markVel / 31.289076f)*44.0f;
219  }
220  else
221  {
222  velocityVec.z = 1.0f;
223  velocityVec.x = 66.0f + (bearVel / 31.289076f)*41.5f;
224  velocityVec.y = 69.0f + (-markVel / 31.289076f)*44.0f;
225  }
226  if (velocityVec.x < 24.0f)
227  velocityVec.x = 24.0f;
228  else if (velocityVec.x > 107.0f)
229  velocityVec.x = 107.0f;
230  if (velocityVec.y < 24.0f)
231  velocityVec.y = 24.0f;
232  else if (velocityVec.y > 113.0f)
233  velocityVec.y = 113.0f;
234  // Adjust for upper left of sprite
235  velocityVec.x -= 16.0f;
236  velocityVec.y -= 16.0f;
237  vector->SetLocation(static_cast<int>(velocityVec.x), static_cast<int>(velocityVec.y));
238  vector->Update();
239  }
240  else
241  velocityVec.z = 0.0f;
242 
243 
244  // Bearing/mark reticle
245  if (bear != 999.0f && mark != 999.0f)
246  {
247  // Adjust for center of ADI
248  if (fabs(bear) > 90.0f)
249  {
250  recticleVec.z = -1.0f;
251  if (bear > 90.0f)
252  recticleVec.x = 65.0f - ((bear - 180.0f) / 31.289076f)*41.5f;
253  else
254  recticleVec.x = 65.0f - ((bear + 180.0f) / 31.289076f)*41.5f;
255  recticleVec.y = 69.0f - (mark / 31.289076f)*44.0f;
256  }
257  else
258  {
259  recticleVec.z = 1.0f;
260  recticleVec.x = 65.0f + (bear / 31.289076f)*41.5f;
261  recticleVec.y = 69.0f + (-mark / 31.289076f)*44.0f;
262  }
263  if (recticleVec.x < 24.0f)
264  recticleVec.x = 24.0f;
265  else if (recticleVec.x > 107.0f)
266  recticleVec.x = 107.0f;
267  if (recticleVec.y < 24.0f)
268  recticleVec.y = 24.0f;
269  else if (recticleVec.y > 113.0f)
270  recticleVec.y = 113.0f;
271  // Adjust for upper left of sprite
272  recticleVec.x -= 16.0f;
273  recticleVec.y -= 16.0f;
274  recticle->SetLocation(static_cast<int>(recticleVec.x), static_cast<int>(recticleVec.y));
275  recticle->Update();
276  }
277  else
278  recticleVec.z = 0.0f;
279 }
void SetLocation(int absoluteX, int absoluteY)
Definition: Sprite.cpp:90
Scockpit ourcockpit
Definition: globals.cpp:176
Sprite * recticle
Definition: Instrument.h:374
float power
Definition: globals.h:608
struct Bus::Afcs AFCS
void FrameMove(float fElapsed) override
void SetRectangle(int top, int left, int right, int bottom)
Definition: Sprite.cpp:96
Definition: Logger.h:9
enum Bus::Afcs::LateralModes CurrentLateralMode
Sprite * failFlagLocalizer
Definition: Instrument.h:365
D3DXVECTOR3 recticleVec
Definition: Instrument.h:389
s_network_objects playerships[MAX_SCAN]
Definition: globals.cpp:174
Sprite * commandBars
Definition: Instrument.h:364
float RollAttitudeRadians
Definition: Bus.h:37
DeviceObject * pDevice
Definition: Instrument.h:17
void Update()
Definition: Sprite.cpp:41
AttitudeIndicator(int prmX, int prmY, float prmXScale, float prmYScale, Bus *prmBus, Logger *prmLogger, DeviceObject *prmDevice, std::vector< Font *> prmFonts)
void AddCommand(Command command, bool onlyOne)
Definition: Bus.cpp:3
float markVel
Definition: globals.cpp:61
float rotate
Definition: Sprite.h:30
void Draw(D3DXCOLOR prmColor)
Definition: Sprite.cpp:66
float AngleOfAttackRadians
Definition: Bus.h:152
float GlideslopeDeviationRadians
Definition: Bus.h:136
float DesiredRollRadians
Definition: Bus.h:116
float mark
Definition: globals.cpp:59
D3DXVECTOR3 velocityVec
Definition: Instrument.h:390
Definition: Bus.h:16
std::string name
Definition: Command.h:11
Definition: Sprite.h:7
Sprite * glideslopeBug
Definition: Instrument.h:368
float bearVel
Definition: globals.cpp:60
void SetRotationCenter(D3DXVECTOR2 rotationCenter)
Definition: Sprite.h:47
Bus * bus
Definition: Instrument.h:18
float LocalizerDeviationRadians
Definition: Bus.h:135
float DesiredPitchRadians
Definition: Bus.h:117
float xScale
Definition: Instrument.h:15
float IndicatedAirspeedKms
Definition: Bus.h:27
float bear
Definition: globals.cpp:58
void Render() override
Definition: Command.h:5
enum Bus::Afcs::VerticalModes CurrentVerticalMode
Sprite * glideslopeBox
Definition: Instrument.h:367
HRESULT SetScissorRect(RECT *rect) const
Sprite * artificialHorizon
Definition: Instrument.h:363
enum Bus::Afcs::VerticalModes StandbyVerticalMode
Logger * logger
Definition: Instrument.h:19
Sprite * localizerBox
Definition: Instrument.h:369
bool AutopilotEngaged
Definition: Bus.h:74
enum Bus::Afcs::LateralModes StandbyLateralMode
Sprite * aoaHigh
Definition: Instrument.h:371
void AddToCallStack(const char *msg)
Definition: Logger.cpp:86
Sprite * failFlagGlideslope
Definition: Instrument.h:366
Sprite * localizerBug
Definition: Instrument.h:370
LPD3DXSPRITE pSprite
Definition: DeviceObject.h:21
HRESULT GetScissorRect(RECT *rect) const
void DrawText(const WCHAR *str, int relativeX, int relativeY, float prmZ, int flags, D3DXCOLOR color, int font=-1, std::string elementName="", int width=0, int height=0)
Definition: Instrument.h:41
float yScale
Definition: Instrument.h:16
float PitchAttitudeRadians
Definition: Bus.h:36