RADAR.CPP 82 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961
  1. //
  2. // Copyright 2020 Electronic Arts Inc.
  3. //
  4. // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free
  5. // software: you can redistribute it and/or modify it under the terms of
  6. // the GNU General Public License as published by the Free Software Foundation,
  7. // either version 3 of the License, or (at your option) any later version.
  8. // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
  9. // in the hope that it will be useful, but with permitted additional restrictions
  10. // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
  11. // distributed with this program. You should have received a copy of the
  12. // GNU General Public License along with permitted additional restrictions
  13. // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
  14. /* $Header: F:\projects\c&c\vcs\code\radar.cpv 2.17 16 Oct 1995 16:49:28 JOE_BOSTIC $ */
  15. /***********************************************************************************************
  16. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  17. ***********************************************************************************************
  18. * *
  19. * Project Name : Command & Conquer *
  20. * *
  21. * File Name : RADAR.CPP *
  22. * *
  23. * Programmer : Joe L. Bostic *
  24. * *
  25. * Start Date : 12/15/94 *
  26. * *
  27. * Last Update : November 17, 1995 [PWG] *
  28. * *
  29. *---------------------------------------------------------------------------------------------*
  30. * Functions: *
  31. * Get_Multi_Color -- Get the multi color offset number *
  32. * RadarClass::AI -- Processes radar input (non-tactical). *
  33. * RadarClass::Cell_On_Radar -- Determines if a cell is currently visible on radar. *
  34. * RadarClass::Click_Cell_Calc -- Determines what cell the pixel coordinate is over. *
  35. * RadarClass::Click_In_Radar -- Check to see if a click is in radar map *
  36. * RadarClass::Click_In_Radar -- Converts a radar click into cell X and Y coordinate. *
  37. * RadarClass::Draw_It -- Displays the radar map of the terrain. *
  38. * RadarClass::Draw_Names -- draws players' names on the radar map *
  39. * RadarClass::Init_Clear -- Sets the radar map to a known state *
  40. * RadarClass::Map_Cell -- Updates radar map when a cell becomes mapped. *
  41. * RadarClass::One_Time -- Handles one time processing for the radar map. *
  42. * RadarClass::Player_Names -- toggles the Player-Names mode of the radar map *
  43. * RadarClass::Plot_Radar_Pixel -- Updates the radar map with a terrain pixel. *
  44. * RadarClass::RadarClass -- Default constructor for RadarClass object. *
  45. * RadarClass::Radar_Activate -- Controls radar activation. *
  46. * RadarClass::Radar_Anim -- Renders current frame of radar animation *
  47. * RadarClass::Radar_Cursor -- Adjust the position of the radar map cursor. *
  48. * RadarClass::Radar_Pixel -- Mark a cell to be rerendered on the radar map. *
  49. * RadarClass::Radar_Position -- Returns with the current position of the radar map. *
  50. * RadarClass::Refresh_Cells -- Intercepts refresh request and updates radar if needed *
  51. * RadarClass::Render_Infantry -- Displays objects on the radar map. *
  52. * RadarClass::Render_Overlay -- Renders an icon for given overlay *
  53. * RadarClass::Render_Terrain -- Render the terrain over the given cell *
  54. * RadarClass::Set_Map_Dimensions -- Sets the tactical map dimensions. *
  55. * RadarClass::Set_Radar_Position -- Sets the radar map coordinates. *
  56. * RadarClass::Set_Radar_Position -- Sets the radar position to center around specified cell.*
  57. * RadarClass::Set_Tactical_Position -- Called when setting the tactical display position. *
  58. * RadarClass::Set_Tactical_Position -- Called when setting the tactical display position. *
  59. * RadarClass::TacticalClass::Action -- I/O function for the radar map. *
  60. * RadarClass::Zoom_Mode(void) -- Handles toggling zoom on the map *
  61. * RadarClass::Set_Tactical_Position -- Sets the map's tactical position and adjusts radar to*
  62. * RadarClass::Coord_To_Radar_Pixel -- Converts a coordinate to a radar pixel position *
  63. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  64. #include "function.h"
  65. #include <stdlib.h>
  66. //void const * RadarClass::CoverShape;
  67. RadarClass::TacticalClass RadarClass::RadarButton;
  68. void const * RadarClass::RadarAnim = NULL;
  69. static bool FullRedraw = false;
  70. #define _MAX_NAME 13
  71. static GraphicBufferClass _IconStage(3,3);
  72. static GraphicBufferClass _TileStage(24,24);
  73. /***********************************************************************************************
  74. * RadarClass::RadarClass -- Default constructor for RadarClass object. *
  75. * *
  76. * This default constructor merely sets the radar specific values to default settings. The *
  77. * radar must be deliberately activated in order for it to be displayed. *
  78. * *
  79. * INPUT: none *
  80. * *
  81. * OUTPUT: none *
  82. * *
  83. * WARNINGS: none *
  84. * *
  85. * HISTORY: *
  86. * 12/16/1994 JLB : Created. *
  87. *=============================================================================================*/
  88. RadarClass::RadarClass(void)
  89. {
  90. IsZoomed = true;
  91. IsRadarActive = false;
  92. IsToRedraw = false;
  93. RadarCursorRedraw = false;
  94. PixelPtr = 0;
  95. SpecialRadarFrame = 0;
  96. IsPlayerNames = false;
  97. }
  98. /***********************************************************************************************
  99. * RadarClass::One_Time -- Handles one time processing for the radar map. *
  100. * *
  101. * This routine handles any one time processing required in order for the radar map to *
  102. * function. This actually only requires an allocation of the radar staging buffer. This *
  103. * buffer is needed for those cases where the radar area of the page is being destroyed *
  104. * and it needs to be destroyed. *
  105. * *
  106. * INPUT: none *
  107. * *
  108. * OUTPUT: none *
  109. * *
  110. * WARNINGS: Be sure to call this routine only ONCE. *
  111. * *
  112. * HISTORY: *
  113. * 12/22/1994 JLB : Created. *
  114. *=============================================================================================*/
  115. void RadarClass::One_Time(void)
  116. {
  117. int factor = Get_Resolution_Factor();
  118. RadWidth = 80 << factor;
  119. RadHeight = 70 << factor;
  120. RadX = SeenBuff.Get_Width() - RadWidth;
  121. RadY = Map.Get_Tab_Height() - (1 << factor);
  122. RadPWidth = 64 << factor;
  123. RadPHeight = 64 << factor;
  124. if ( factor ) {
  125. RadOffX = 16;
  126. RadOffY = 7;
  127. RadIWidth = 128;
  128. RadIHeight = 128;
  129. } else {
  130. RadOffX = 4 << factor;
  131. RadOffY = 1 << factor;
  132. RadIWidth = 72 << factor;
  133. RadIHeight = 69 << factor;
  134. }
  135. DisplayClass::One_Time();
  136. RadarButton.X = RadX+RadOffX;
  137. RadarButton.Y = RadY+RadOffY;
  138. RadarButton.Width = RadIWidth;
  139. RadarButton.Height = RadIHeight;
  140. }
  141. /***********************************************************************************************
  142. * RadarClass::Init_Clear -- Sets the radar map to a known state. *
  143. * *
  144. * This routine is used to initialize the radar map at the start of the scenario. It *
  145. * sets the radar map position and starts it in the disabled state. *
  146. * *
  147. * INPUT: theater -- The theater that the scenario is starting (unused by this routine). *
  148. * *
  149. * OUTPUT: none *
  150. * *
  151. * WARNINGS: none *
  152. * *
  153. * HISTORY: *
  154. * 12/22/1994 JLB : Created. *
  155. *=============================================================================================*/
  156. void RadarClass::Init_Clear(void)
  157. {
  158. DisplayClass::Init_Clear();
  159. IsRadarActive = false;
  160. IsToRedraw = true;
  161. RadarCursorRedraw = true;
  162. IsRadarActivating = false;
  163. IsRadarDeactivating = false;
  164. DoesRadarExist = false;
  165. PixelPtr = 0;
  166. IsPlayerNames = false;
  167. /*
  168. ** If we have a valid map lets make sure that we set it correctly
  169. */
  170. if (MapCellWidth || MapCellHeight) {
  171. IsZoomed = false;
  172. Zoom_Mode(Coord_Cell(Map.TacticalCoord));
  173. }
  174. }
  175. /***********************************************************************************************
  176. * RadarClass::Radar_Activate -- Controls radar activation. *
  177. * *
  178. * Use this routine to turn the radar map on or off. *
  179. * *
  180. * INPUT: control -- What to do with the radar map: *
  181. * 0 = Turn radar off. *
  182. * 1 = Turn radar on. *
  183. * 2 = Remove Radar Gadgets *
  184. * 3 = Add Radar Gadgets *
  185. * 4 = Remove radar. *
  186. * -1= Toggle radar on or off. *
  187. * *
  188. * OUTPUT: bool; Was the radar map already on? *
  189. * *
  190. * WARNINGS: none *
  191. * *
  192. * HISTORY: *
  193. * 12/11/1994 JLB : Created. *
  194. *=============================================================================================*/
  195. bool RadarClass::Radar_Activate(int control)
  196. {
  197. bool old = IsRadarActive;
  198. switch (control) {
  199. /*
  200. ** Toggle the state of the radar map on or off.
  201. */
  202. case -1:
  203. {
  204. int temp = (IsRadarActive == false);
  205. if (temp) {
  206. Radar_Activate(1);
  207. } else {
  208. Radar_Activate(0);
  209. }
  210. }
  211. break;
  212. /*
  213. ** Turn the radar map off properly.
  214. */
  215. case 0:
  216. if (Map.IsSidebarActive) {
  217. if (IsRadarActive && !IsRadarDeactivating) {
  218. // Sound_Effect(VOC_RADAR_OFF); // MBL 07.20.2020: These are never being sent to the client, so handled there; Disabling here for good measure.
  219. IsRadarDeactivating = true;
  220. IsRadarActive = false;
  221. if (IsRadarActivating == true) {
  222. IsRadarActivating = false;
  223. } else {
  224. RadarAnimFrame = RADAR_ACTIVATED_FRAME;
  225. }
  226. }
  227. } else {
  228. Radar_Activate(2);
  229. }
  230. return(old);
  231. case 1:
  232. if (Map.IsSidebarActive) {
  233. if (!IsRadarActivating && !IsRadarActive) {
  234. // Sound_Effect(VOC_RADAR_ON); // MBL 07.20.2020: These are never being sent to the client, so handled there; Disabling here for good measure.
  235. IsRadarActivating = true;
  236. if (IsRadarDeactivating == true) {
  237. IsRadarDeactivating = false;
  238. } else {
  239. if (DoesRadarExist) {
  240. RadarAnimFrame = MAX_RADAR_FRAMES;
  241. } else {
  242. RadarAnimFrame = 0;
  243. }
  244. }
  245. }
  246. } else {
  247. Radar_Activate(3);
  248. }
  249. return(old);
  250. case 2:
  251. if (GameToPlay==GAME_NORMAL) {
  252. Map.Zoom.Disable();
  253. }
  254. IsRadarActive = false;
  255. IsRadarActivating = false;
  256. IsRadarDeactivating = false;
  257. break;
  258. case 3:
  259. if (GameToPlay==GAME_NORMAL) {
  260. Map.Zoom.Enable();
  261. }
  262. IsRadarActive = true;
  263. IsRadarActivating = false;
  264. IsRadarDeactivating = false;
  265. break;
  266. case 4:
  267. IsRadarActive = false;
  268. IsRadarActivating = false;
  269. IsRadarDeactivating = false;
  270. DoesRadarExist = false;
  271. Flag_To_Redraw(false);
  272. IsToRedraw = true;
  273. break;
  274. }
  275. if (IsRadarActive != old) {
  276. IsToRedraw = true;
  277. Flag_To_Redraw(false);
  278. }
  279. FullRedraw = IsRadarActive;
  280. return(old);
  281. }
  282. /***********************************************************************************************
  283. * RadarClass::Draw_It -- Displays the radar map of the terrain. *
  284. * *
  285. * This is used to display the radar map that appears in the lower *
  286. * right corner. The main changes to this map are the vehicles and *
  287. * structure pixels. *
  288. * *
  289. * INPUT: none *
  290. * *
  291. * OUTPUT: none *
  292. * *
  293. * WARNINGS: none *
  294. * *
  295. * HISTORY: *
  296. * 04/24/1991 JLB : Created. *
  297. * 05/08/1994 JLB : Converted to member function. *
  298. *=============================================================================================*/
  299. void RadarClass::Draw_It(bool forced)
  300. {
  301. DisplayClass::Draw_It(forced);
  302. // if (!In_Debugger) while (!HidPage.Lock()) {}
  303. #if (0) // Legacy radar rendering not used. ST - 2/26/2020 3:53PM
  304. /*
  305. ** Don't perform any rendering if none is requested.
  306. */
  307. if (!forced && !IsToRedraw && !FullRedraw) return;
  308. static HousesType _house = HOUSE_NONE;
  309. if (PlayerPtr->ActLike != _house) {
  310. char name[_MAX_NAME + _MAX_EXT];
  311. if (Special.IsJurassic && AreThingiesEnabled) {
  312. strcpy(name, "RADAR.JP");
  313. } else {
  314. _makepath(name, NULL, NULL, "RADAR", HouseTypeClass::As_Reference(PlayerPtr->ActLike).Suffix);
  315. }
  316. RadarAnim = Hires_Retrieve(name);
  317. _house = PlayerPtr->ActLike;
  318. }
  319. /*
  320. ** If in player name mode, just draw player names
  321. */
  322. if (IsPlayerNames) {
  323. Draw_Names();
  324. IsToRedraw = false;
  325. return;
  326. }
  327. if (IsRadarActivating || IsRadarDeactivating) {
  328. Radar_Anim();
  329. IsToRedraw = false;
  330. return;
  331. }
  332. if (Map.IsSidebarActive) {
  333. if (IsRadarActive) {
  334. //HidPage.Lock();
  335. // ST 8/13/96 2:24PM
  336. //forced = true;
  337. /*
  338. ** If only a few of the radar pixels need to be redrawn, then find and redraw
  339. ** only these.
  340. */
  341. if (!forced && IsToRedraw && !FullRedraw) {
  342. IsToRedraw = false;
  343. if (PixelPtr) {
  344. /*
  345. ** Render all pixels in the "to redraw" stack.
  346. */
  347. for (unsigned int index = 0; index < PixelPtr; index++) {
  348. CELL cell = PixelStack[index];
  349. if (Cell_On_Radar(cell)) {
  350. (*this)[cell].IsPlot = false;
  351. Plot_Radar_Pixel(cell);
  352. RadarCursorRedraw |= (*this)[cell].IsRadarCursor;
  353. }
  354. }
  355. /*
  356. ** Refill the stack if there is pending pixels yet to be plotted.
  357. ** This should only process in sections for speed reasons
  358. */
  359. if (PixelPtr == PIXELSTACK) {
  360. PixelPtr = 0;
  361. for (int y = 0; y < MapCellHeight; y++) {
  362. for (int x = 0; x < MapCellWidth; x++) {
  363. CELL cell = XY_Cell(MapCellX + x, MapCellY + y);
  364. if (Cell_On_Radar(cell)) {
  365. if ((*this)[cell].IsPlot) {
  366. PixelStack[PixelPtr++] = cell;
  367. IsToRedraw = true;
  368. if (PixelPtr == PIXELSTACK) break;
  369. }
  370. }
  371. }
  372. if (PixelPtr == PIXELSTACK) break;
  373. }
  374. } else {
  375. PixelPtr = 0;
  376. }
  377. }
  378. Radar_Cursor(RadarCursorRedraw);
  379. } else {
  380. GraphicViewPortClass *oldpage = Set_Logic_Page(HidPage);
  381. // if (LogicPage->Lock()) {
  382. CC_Draw_Shape(RadarAnim, RADAR_ACTIVATED_FRAME, RadX, RadY+1, WINDOW_MAIN, SHAPE_NORMAL);
  383. if (BaseX || BaseY) {
  384. LogicPage->Fill_Rect( RadX + RadOffX,
  385. RadY + RadOffY,
  386. RadX + RadOffX + RadIWidth - 1,
  387. RadY + RadOffY + RadIHeight - 1,
  388. DKGREY);
  389. } else {
  390. LogicPage->Fill_Rect( RadX + RadOffX,
  391. RadY + RadOffY,
  392. RadX + RadOffX + RadIWidth - 1,
  393. RadY + RadOffY + RadIHeight - 1,
  394. BLACK);
  395. }
  396. /*
  397. ** Draw the entire radar map.
  398. */
  399. for (int index = 0; index < MAP_CELL_TOTAL; index++) {
  400. Plot_Radar_Pixel(index);
  401. }
  402. Radar_Cursor(true);
  403. FullRedraw = false;
  404. IsToRedraw = false;
  405. LogicPage->Unlock();
  406. if (oldpage == &SeenBuff) {
  407. Hide_Mouse();
  408. LogicPage->Blit(SeenBuff, RadX, RadY, RadX, RadY, RadWidth, RadHeight);
  409. Show_Mouse();
  410. }
  411. // Set_Logic_Page(oldpage);
  412. // }
  413. }
  414. } else {
  415. /*
  416. ** If the radar is not active, then only draw the cover plate if forced to do so.
  417. */
  418. // if (forced) {
  419. int val = (DoesRadarExist) ? MAX_RADAR_FRAMES : 0;
  420. CC_Draw_Shape(RadarAnim, val, RadX, RadY + 1, WINDOW_MAIN, SHAPE_NORMAL);
  421. FullRedraw = false;
  422. IsToRedraw = false;
  423. // }
  424. }
  425. //HidPage.Unlock();
  426. // Map.Activator.Draw_Me(true);
  427. }
  428. #endif
  429. }
  430. /***************************************************************************
  431. * RadarClass::Render_Terrain -- Render the terrain over the given cell *
  432. * *
  433. * INPUT: *
  434. * *
  435. * OUTPUT: *
  436. * *
  437. * WARNINGS: *
  438. * *
  439. * HISTORY: *
  440. * 04/12/1995 PWG : Created. *
  441. *=========================================================================*/
  442. void RadarClass::Render_Terrain(CELL cell, int x, int y, int size)
  443. {
  444. TerrainClass *list[4];
  445. int listidx = 0;
  446. int lp,lp2;
  447. ObjectClass *obj = Map[cell].Cell_Occupier();
  448. /*
  449. ** If the cell is occupied by a terrain type, add it to the sortable
  450. ** list.
  451. */
  452. if (obj && obj->What_Am_I() == RTTI_TERRAIN)
  453. list[listidx++] = (TerrainClass *)obj;
  454. /*
  455. ** Now loop through all the occupiers and add them to the list if they
  456. ** are terrain type.
  457. */
  458. for (lp = 0; lp < 3; lp ++) {
  459. obj = Map[cell].Overlapper[lp];
  460. if (obj && obj->What_Am_I() == RTTI_TERRAIN)
  461. list[listidx++] = (TerrainClass *)obj;
  462. }
  463. /*
  464. ** If there are no entrys in our list then just get out.
  465. */
  466. if (!listidx) return;
  467. /*
  468. ** If there is terrain in this cell then draw a dark pixel to
  469. ** represent it.
  470. */
  471. if (size == 1) {
  472. LogicPage->Put_Pixel(x, y, 60);
  473. return;
  474. }
  475. /*
  476. ** Sort the list by its sort Y value so that we can render in the proper
  477. ** order.
  478. */
  479. for (lp = 0; lp < listidx - 1; lp ++) {
  480. for (lp2 = lp + 1; lp2 < listidx; lp2++) {
  481. if (list[lp]->Sort_Y() > list[lp2]->Sort_Y()) {
  482. TerrainClass *terrain = list[lp];
  483. list[lp] = list[lp2];
  484. list[lp2] = terrain;
  485. }
  486. }
  487. }
  488. /*
  489. ** loop through the list and take care of rendering the correct icon.
  490. */
  491. for (lp = 0; lp < listidx; lp ++) {
  492. unsigned char *icon = list[lp]->Radar_Icon(cell);
  493. if (!icon) continue;
  494. Buffer_To_Page(0, 0, 3, 3, icon, _IconStage);
  495. _IconStage.Scale(*LogicPage, 0, 0, x, y, 3, 3, ZoomFactor, ZoomFactor, TRUE, (char *)&FadingBrighten[0]);
  496. }
  497. }
  498. /***********************************************************************************************
  499. * RadarClass::Render_Infantry -- Displays objects on the radar map. *
  500. * *
  501. * This routine will display an object imagery at the location specified according to the *
  502. * condition of the specified cell. *
  503. * *
  504. * INPUT: cell -- The cell to use as reference when drawing the radar pixel. *
  505. * *
  506. * x,y -- The pixel coordinate to render the radar "pixel" at. *
  507. * *
  508. * size -- The size of the "pixel". When zoomed in, this value will be "3". *
  509. * *
  510. * OUTPUT: none *
  511. * *
  512. * WARNINGS: none *
  513. * *
  514. * HISTORY: *
  515. * 08/17/1995 JLB : Created. *
  516. *=============================================================================================*/
  517. void RadarClass::Render_Infantry(CELL cell, int x, int y, int size)
  518. {
  519. ObjectClass *obj;
  520. int xoff,yoff;
  521. obj = (ObjectClass *)Map[cell].Cell_Occupier();
  522. while (obj) {
  523. if (obj->Is_Techno() && (((TechnoClass *)obj)->Cloak != CLOAKED || ((TechnoClass *)obj)->House->Is_Ally(PlayerPtr))) {
  524. switch (obj->What_Am_I()) {
  525. case RTTI_INFANTRY:
  526. {
  527. //int divisor = 255 / ZoomFactor;
  528. int divisor = 86;
  529. if ( ZoomFactor >= 3 ) {
  530. xoff = Coord_XLepton(obj->Coord) / divisor;
  531. yoff = Coord_YLepton(obj->Coord) / divisor;
  532. if ( ZoomFactor >= 6 ) {
  533. xoff<<=1;
  534. yoff<<=1;
  535. }
  536. } else {
  537. xoff = 0;
  538. yoff = 0;
  539. }
  540. LogicPage->Put_Pixel(x+xoff, y+yoff, ((InfantryClass *)obj)->House->Class->BrightColor);
  541. }
  542. break;
  543. case RTTI_UNIT:
  544. case RTTI_AIRCRAFT:
  545. // PWG: Slowdown?
  546. //if (LogicPage->Lock()){
  547. Fat_Put_Pixel(x, y, ((UnitClass *)obj)->House->Class->BrightColor, size, *LogicPage);
  548. //LogicPage->Unlock();
  549. //}
  550. break;
  551. }
  552. }
  553. obj = obj->Next;
  554. }
  555. }
  556. /***************************************************************************
  557. * RadarClass::Render_Overlay -- Renders an icon for given overlay *
  558. * *
  559. * INPUT: *
  560. * *
  561. * OUTPUT: *
  562. * *
  563. * WARNINGS: *
  564. * *
  565. * HISTORY: *
  566. * 04/18/1995 PWG : Created. *
  567. *=========================================================================*/
  568. void RadarClass::Render_Overlay(CELL cell, int x, int y, int size)
  569. {
  570. OverlayType overlay = (*this)[cell].Overlay;
  571. if (overlay != OVERLAY_NONE) {
  572. OverlayTypeClass const * otype = &OverlayTypeClass::As_Reference(overlay);
  573. if (otype->IsRadarVisible) {
  574. unsigned char *icon = otype->Radar_Icon((*this)[cell].OverlayData);
  575. if (!icon) return;
  576. Buffer_To_Page(0, 0, 3, 3, icon, _IconStage);
  577. if (otype->IsTiberium) {
  578. _IconStage.Scale(*LogicPage, 0, 0, x, y, 3, 3, size, size, TRUE, (char *)&FadingGreen[0]);
  579. } else {
  580. _IconStage.Scale(*LogicPage, 0, 0, x, y, 3, 3, size, size, TRUE, (char *)&FadingBrighten[0]);
  581. }
  582. }
  583. }
  584. }
  585. /***************************************************************************
  586. * RadarClass::Zoom_Mode -- Handles toggling zoom on the map *
  587. * *
  588. * INPUT: none *
  589. * *
  590. * OUTPUT: none *
  591. * *
  592. * HISTORY: *
  593. * 05/29/1995 PWG : Created. *
  594. *=========================================================================*/
  595. void RadarClass::Zoom_Mode(CELL cell)
  596. {
  597. int map_c_width;
  598. int map_c_height;
  599. /*
  600. ** Set all of the initial zoom mode variables to the correct
  601. ** setting.
  602. */
  603. IsZoomed = !IsZoomed;
  604. BaseX = 0;
  605. BaseY = 0;
  606. /*
  607. ** Figure out exactly what size we need to zoom the map to.
  608. */
  609. if ( !IsZoomed ) {
  610. int xfactor = RadIWidth / MapCellWidth;
  611. int yfactor = RadIHeight / MapCellHeight;
  612. ZoomFactor = MIN(xfactor,yfactor);
  613. map_c_width = MapCellWidth;
  614. map_c_height = MapCellHeight;
  615. } else {
  616. ZoomFactor = 6;
  617. map_c_width = RadIWidth / ZoomFactor;
  618. map_c_height = RadIHeight / ZoomFactor;
  619. }
  620. /*
  621. ** Make sure we do not show more cell then are on the map.
  622. */
  623. map_c_width = MIN(map_c_width, 62);
  624. map_c_height = MIN(map_c_height, 62);
  625. /*
  626. ** Find the amount of remainder because this will let us calculate
  627. ** how to center the thing.
  628. */
  629. int rem_x = RadIWidth - (map_c_width * ZoomFactor);
  630. int rem_y = RadIHeight - (map_c_height * ZoomFactor);
  631. /*
  632. ** Finally mark the map so it shows just as much as it is supposed
  633. ** to.
  634. */
  635. BaseX = rem_x / 2;
  636. BaseY = rem_y / 2;
  637. RadarCellWidth = map_c_width;
  638. RadarCellHeight = map_c_height;
  639. RadarWidth = RadIWidth - rem_x;
  640. RadarHeight = RadIWidth - rem_y;
  641. /*
  642. ** Set the radar position to the current cell.
  643. */
  644. Set_Radar_Position(cell);
  645. /*
  646. ** When zoom mode changes then we need to redraw the radar
  647. ** area.
  648. */
  649. IsToRedraw = true;
  650. /*
  651. ** Notify the map that we need to redraw a portion
  652. */
  653. Flag_To_Redraw(false);
  654. /*
  655. ** Since we have made a vast change we must redraw everything
  656. */
  657. FullRedraw = true;
  658. }
  659. /***********************************************************************************************
  660. * RadarClass::Plot_Radar_Pixel -- Updates the radar map with a terrain pixel. *
  661. * *
  662. * This will update the radar map with a pixel. It is used to display *
  663. * vehicle positions on the radar map. *
  664. * *
  665. * INPUT: unit -- Pointer to unit to render at the given position. If *
  666. * NULL is passed in, then the underlying terrain is *
  667. * displayed instead. *
  668. * *
  669. * pos -- Position on the map to update. *
  670. * *
  671. * OUTPUT: none *
  672. * *
  673. * WARNINGS: This routine does NOT hide the mouse. It is up to you to *
  674. * do so. *
  675. * *
  676. * HISTORY: *
  677. * 06/04/1991 JLB : Created. *
  678. * 06/21/1991 JLB : Large blips for units & buildings. *
  679. * 02/14/1994 JLB : Revamped. *
  680. * 04/17/1995 PWG : Created. *
  681. * 04/18/1995 PWG : Created. *
  682. *=============================================================================================*/
  683. void RadarClass::Plot_Radar_Pixel(CELL cell)
  684. {
  685. if (cell == -1) cell = 1;
  686. int x,y; // Coordinate of cell location.
  687. /*
  688. ** Perform any clipping on the cell coordinate.
  689. */
  690. if (!IsRadarActive || (unsigned)cell > MAP_CELL_TOTAL) return;
  691. if (!In_Radar(cell) || !Cell_On_Radar(cell)) {
  692. return;
  693. }
  694. /*
  695. ** If we are zoomed in then calculate the pixel based off of the portion
  696. ** of the map the radar is viewing.
  697. */
  698. x = Cell_X(cell) - RadarX;
  699. y = Cell_Y(cell) - RadarY;
  700. if (LogicPage->Lock()) {
  701. CellClass * cellptr = &(*this)[cell];
  702. x = RadX + RadOffX + BaseX + (x * ZoomFactor);
  703. y = RadY + RadOffY + BaseY + (y * ZoomFactor);
  704. /*
  705. ** Determine what (if any) vehicle or unit should be rendered in this blip.
  706. */
  707. int color=TBLACK; // Color of the pixel to plot.
  708. if ((*this)[cell].IsVisible || Debug_Unshroud) {
  709. color = cellptr->Cell_Color(true);
  710. } else {
  711. color = BLACK;
  712. }
  713. // ST 8/13/96 2:24PM
  714. //if (cellptr->IsRadarCursor){
  715. // color = WHITE;
  716. //}
  717. /*
  718. ** If no color override occurs for this cell, then render the underlying
  719. ** terrain.
  720. */
  721. if (color == TBLACK) {
  722. if (ZoomFactor > 1) {
  723. void const *ptr;
  724. long offset;
  725. int icon;
  726. if (cellptr->TType != TEMPLATE_NONE) {
  727. ptr = TemplateTypeClass::As_Reference(cellptr->TType).Get_Image_Data();
  728. icon = cellptr->TIcon;
  729. } else {
  730. ptr = TemplateTypeClass::As_Reference(TEMPLATE_CLEAR1).Get_Image_Data();
  731. icon = cellptr->Clear_Icon();
  732. }
  733. /*
  734. ** Convert the logical icon number into the actual icon number.
  735. */
  736. Mem_Copy(Add_Long_To_Pointer((void *)ptr, 28), &offset, sizeof(offset));
  737. Mem_Copy(Add_Long_To_Pointer((void *)ptr, offset+icon), &icon, sizeof(char));
  738. icon &= 0x00FF;
  739. Mem_Copy(Add_Long_To_Pointer((void *)ptr, 12), &offset, sizeof(offset));
  740. ptr = Add_Long_To_Pointer((void *)ptr, offset + icon*(24*24));
  741. unsigned char * data = (unsigned char *)ptr;
  742. Buffer_To_Page(0, 0, 24, 24, data, _TileStage);
  743. _TileStage.Scale(*LogicPage, 0, 0, x, y, 24, 24, ZoomFactor, ZoomFactor, TRUE);
  744. } else {
  745. if (LogicPage->Lock()){
  746. Fat_Put_Pixel(x, y, cellptr->Cell_Color(false), ZoomFactor, *LogicPage);
  747. LogicPage->Unlock();
  748. }
  749. }
  750. } else {
  751. if (LogicPage->Lock()){
  752. Fat_Put_Pixel(x, y, color, ZoomFactor, *LogicPage);
  753. LogicPage->Unlock();
  754. }
  755. }
  756. if (color != BLACK) {
  757. Render_Overlay(cell, x, y, ZoomFactor);
  758. Render_Terrain(cell, x, y, ZoomFactor);
  759. Render_Infantry(cell, x, y, ZoomFactor);
  760. }
  761. LogicPage->Unlock();
  762. }
  763. }
  764. /***********************************************************************************************
  765. * RadarClass::Radar_Pixel -- Mark a cell to be rerendered on the radar map. *
  766. * *
  767. * This routine is used to inform the system that a pixel needs to be *
  768. * rerendered on the radar map. The pixel(s) will be rendered the *
  769. * next time the map is refreshed. *
  770. * *
  771. * INPUT: cell -- The map cell to be rerendered. *
  772. * *
  773. * OUTPUT: none *
  774. * *
  775. * WARNINGS: none *
  776. * *
  777. * HISTORY: *
  778. * 07/12/1992 JLB : Created. *
  779. * 05/08/1994 JLB : Converted to member function. *
  780. *=============================================================================================*/
  781. void RadarClass::Radar_Pixel(CELL cell)
  782. {
  783. if (IsRadarActive && Map.IsSidebarActive && Cell_On_Radar(cell)) {
  784. IsToRedraw = true;
  785. (*this)[cell].IsPlot = true;
  786. if (PixelPtr < PIXELSTACK) {
  787. PixelStack[PixelPtr++] = cell;
  788. }
  789. }
  790. }
  791. /***********************************************************************************************
  792. * RadarClass::Click_In_Radar -- Converts a radar click into cell X and Y coordinate. *
  793. * *
  794. * This routine will examine the X and Y coordinate and convert them into the X and Y *
  795. * cell coordinate value that cooresponds to the location. *
  796. * *
  797. * INPUT: x,y -- The X and Y moouse coordinate already normalized to the radar upper left *
  798. * corner. *
  799. * *
  800. * OUTPUT: Returns with success rating in addition, the X and Y values will now hold the *
  801. * cell coordinates of the cell the pixel offsets indicated. *
  802. * Result 1 = click was in radar region *
  803. * Result 0 = click was outside radar region completly *
  804. * Result-1 = click in radar area but not on clickable reagion of radar. *
  805. * *
  806. * WARNINGS: none *
  807. * *
  808. * HISTORY: *
  809. * 05/30/1995 PWG : Created. *
  810. * 07/16/1995 JLB : Recognizes when sidebar is closed now. *
  811. *=============================================================================================*/
  812. int RadarClass::Click_In_Radar(int &ptr_x, int &ptr_y, bool change)
  813. {
  814. int x = ptr_x;
  815. int y = ptr_y;
  816. /*
  817. ** If radar is not active the click could have been on a radar point
  818. */
  819. if (!IsRadarActive || !Map.IsSidebarActive) return(0);
  820. x -= (RadX + RadOffX);
  821. y -= (RadY + RadOffY);
  822. if (x < RadIWidth && y < RadIHeight) {
  823. x -= BaseX;
  824. y -= BaseY;
  825. if ((unsigned)x < RadarWidth && (unsigned)y < RadarHeight) {
  826. x = RadarX + (x / ZoomFactor);
  827. y = RadarY + (y / ZoomFactor);
  828. if (change) {
  829. ptr_x = x;
  830. ptr_y = y;
  831. }
  832. return(1);
  833. }
  834. return(-1);
  835. }
  836. return(0);
  837. }
  838. /***********************************************************************************************
  839. * RadarClass::Click_Cell_Calc -- Determines what cell the pixel coordinate is over. *
  840. * *
  841. * This routine will examine the pixel coordinate provided and determine what cell it *
  842. * represents. If the radar map is not active or the coordinates are not positioned over *
  843. * the radar map, then it will fall into the base class corresponding routine. *
  844. * *
  845. * INPUT: x,y -- The pixel coordinate to convert into a cell number. *
  846. * *
  847. * OUTPUT: Returns with the cell number that the coordinate is over or -1 if not over any *
  848. * cell. *
  849. * *
  850. * WARNINGS: none *
  851. * *
  852. * HISTORY: *
  853. * 12/22/1994 JLB : Created. *
  854. *=============================================================================================*/
  855. CELL RadarClass::Click_Cell_Calc(int x, int y)
  856. {
  857. int result = Click_In_Radar(x, y, true);
  858. switch (result) {
  859. case 1:
  860. return(XY_Cell(x, y));
  861. case -1:
  862. return(-1);
  863. }
  864. return(DisplayClass::Click_Cell_Calc(x, y));
  865. }
  866. /***********************************************************************************************
  867. * RadarClass::Map_Cell -- Updates radar map when a cell becomes mapped. *
  868. * *
  869. * This routine will update the radar map if a cell becomes mapped. *
  870. * *
  871. * INPUT: cell -- The cell that is being mapped. *
  872. * *
  873. * house -- The house that is doing the mapping. *
  874. * *
  875. * OUTPUT: bool; Was the cell mapped (for the first time) by this routine? *
  876. * *
  877. * WARNINGS: none *
  878. * *
  879. * HISTORY: *
  880. * 12/22/1994 JLB : Created. *
  881. *=============================================================================================*/
  882. bool RadarClass::Map_Cell(CELL cell, HouseClass * house, bool and_for_allies)
  883. {
  884. if (DisplayClass::Map_Cell(cell, house, and_for_allies)) {
  885. Radar_Pixel(cell);
  886. return(true);
  887. }
  888. return(false);
  889. }
  890. void RadarClass::Cursor_Cell(CELL cell, int value)
  891. {
  892. int temp = (*this)[cell].IsRadarCursor;
  893. /*
  894. ** If this cell is not on the radar don't botther doing anything.
  895. */
  896. if (In_Radar(cell) && temp != value) {
  897. /*
  898. ** Record the new state of this cell.
  899. */
  900. (*this)[cell].IsRadarCursor = value;
  901. /*
  902. ** If we are erasing then erase the cell.
  903. */
  904. ////// ST 8/13/96 2:23PM
  905. if (value == FALSE) {
  906. Plot_Radar_Pixel(cell);
  907. //////
  908. }
  909. }
  910. }
  911. void RadarClass::Mark_Radar(int x1, int y1, int x2, int y2, int value, int barlen)
  912. {
  913. int x, y;
  914. /*
  915. ** First step is to convert pixel coordinates back to a CellX and CellY.
  916. */
  917. x1 = RadarX + (x1 / ZoomFactor);
  918. y1 = RadarY + (y1 / ZoomFactor);
  919. x2 = RadarX + (x2 / ZoomFactor);
  920. y2 = RadarY + (y2 / ZoomFactor);
  921. /*
  922. ** Now we need to convert the Pixel length to a cell length.
  923. */
  924. barlen = (barlen / ZoomFactor)+1;
  925. /*
  926. ** Now lets loop through and mark the map with the proper value.
  927. */
  928. for (int lp = 0; lp <= barlen; lp++) {
  929. /*
  930. ** Do Horizontal action to upper and lower left corners.
  931. */
  932. x = x1 + lp;
  933. Cursor_Cell(XY_Cell(x,y1), value);
  934. Cursor_Cell(XY_Cell(x,y2), value);
  935. /*
  936. ** Do Horizontal Action to upper and lower right corners
  937. */
  938. x = x2 - lp;
  939. Cursor_Cell(XY_Cell(x,y1), value);
  940. Cursor_Cell(XY_Cell(x,y2), value);
  941. /*
  942. ** Do Vertical Action to left and right upper corners
  943. */
  944. y = y1 + lp;
  945. Cursor_Cell(XY_Cell(x1,y), value);
  946. Cursor_Cell(XY_Cell(x2,y), value);
  947. /*
  948. ** Do Vertical action to left and right lower corners.
  949. */
  950. y = y2 - lp;
  951. Cursor_Cell(XY_Cell(x1,y), value);
  952. Cursor_Cell(XY_Cell(x2,y), value);
  953. }
  954. }
  955. /***********************************************************************************************
  956. * RadarClass::Cell_XY_To_Radar_Pixel-- Adjust the position of the radar map cursor. *
  957. * *
  958. * This routine will adjust the location (and visibility) of the radar *
  959. * map cursor. It handles all restoration, drawing, and flashing. *
  960. * *
  961. * INPUT: pos - Cell position for the cursor. If the value is -1 then *
  962. * the cursor will be hidden. If the value is equal to *
  963. * the last value passed in then cursor flashing will *
  964. * be maintained. *
  965. * *
  966. * OUTPUT: none *
  967. * *
  968. * WARNINGS: none *
  969. * *
  970. * HISTORY: *
  971. * 05/22/1991 JLB : Created. *
  972. * 11/17/1995 PWG : Created. *
  973. *=============================================================================================*/
  974. void RadarClass::Cell_XY_To_Radar_Pixel(int cellx, int celly, int &x, int &y)
  975. {
  976. x = (cellx - RadarX) * ZoomFactor;
  977. y = (celly - RadarY) * ZoomFactor;
  978. }
  979. /***********************************************************************************************
  980. * RadarClass::Radar_Cursor -- Adjust the position of the radar map cursor. *
  981. * *
  982. * This routine will adjust the location (and visibility) of the radar *
  983. * map cursor. It handles all restoration, drawing, and flashing. *
  984. * *
  985. * INPUT: pos - Cell position for the cursor. If the value is -1 then *
  986. * the cursor will be hidden. If the value is equal to *
  987. * the last value passed in then cursor flashing will *
  988. * be maintained. *
  989. * *
  990. * OUTPUT: none *
  991. * *
  992. * WARNINGS: none *
  993. * *
  994. * HISTORY: *
  995. * 05/22/1991 JLB : Created. *
  996. * 11/17/1995 PWG : Created. *
  997. *=============================================================================================*/
  998. //#pragma argsused
  999. void RadarClass::Radar_Cursor(int forced)
  1000. {
  1001. static int _last_pos = -1;
  1002. static int _last_frame = -1;
  1003. GraphicViewPortClass *oldpage;
  1004. int x1, y1, x2, y2;
  1005. /*
  1006. ** figure out these function calls as we will need to call them multiple times.
  1007. */
  1008. int tac_cell = Coord_Cell(TacticalCoord);
  1009. int tac_cell_x = Cell_X(tac_cell);
  1010. int tac_cell_y = Cell_Y(tac_cell);
  1011. int barlen = 6;
  1012. /*
  1013. ** If the current tactical cell is invalid or we haven't moved and we are not forced to redraw then
  1014. ** just skip the redraw process.
  1015. */
  1016. if (tac_cell != -1 && _last_pos == tac_cell && _last_frame == SpecialRadarFrame && !forced) return;
  1017. if ( _last_pos != -1 ) {
  1018. /*
  1019. ** The first thing we need to do is take care of erasing the last radar cell position. We do this
  1020. ** by converting to pixel coordinates, then adjusting for the pixel coords for the current frame and
  1021. ** finally taking care of calling the erase procedure which will convert the pixel coordinates back
  1022. ** to the cells that need to be redraw.
  1023. **/
  1024. int last_cell_x = Cell_X(_last_pos);
  1025. int last_cell_y = Cell_Y(_last_pos);
  1026. Cell_XY_To_Radar_Pixel(last_cell_x, last_cell_y, x1, y1);
  1027. Cell_XY_To_Radar_Pixel(last_cell_x + Lepton_To_Cell(TacLeptonWidth), last_cell_y + Lepton_To_Cell(TacLeptonHeight), x2, y2);
  1028. x2--;
  1029. y2--;
  1030. /*
  1031. ** Adjust the current coordinates based on the last animation frame.
  1032. */
  1033. x1-= _last_frame;
  1034. y1-= _last_frame;
  1035. x2+= _last_frame;
  1036. y2+= _last_frame;
  1037. /*
  1038. ** Finally mark the map (actually remove the marks that indicate the radar cursor was there
  1039. */
  1040. Mark_Radar(x1, y1, x2, y2, FALSE, barlen);
  1041. }
  1042. /*
  1043. ** find the upper left and lower right corners of the radar cursor. Remember to adjust x2 and y2 back
  1044. ** by one pixel as they will not be pointing to the right value otherwise. They point one cell ahead
  1045. ** of where they should.
  1046. */
  1047. Cell_XY_To_Radar_Pixel(tac_cell_x, tac_cell_y, x1, y1);
  1048. Cell_XY_To_Radar_Pixel(tac_cell_x + Lepton_To_Cell(TacLeptonWidth), tac_cell_y + Lepton_To_Cell(TacLeptonHeight), x2, y2);
  1049. x2--;
  1050. y2--;
  1051. /*
  1052. ** Adjust the coordinates based on the current frame of radar animation.
  1053. */
  1054. x1-= SpecialRadarFrame;
  1055. y1-= SpecialRadarFrame;
  1056. x2+= SpecialRadarFrame;
  1057. y2+= SpecialRadarFrame;
  1058. Mark_Radar(x1, y1, x2, y2, TRUE, barlen);
  1059. /*
  1060. ** setup a graphic view port class so we can write all the pixels relative
  1061. ** to 0,0 rather than relative to full screen coordinates.
  1062. */
  1063. oldpage = Set_Logic_Page(HidPage);
  1064. GraphicViewPortClass draw_window(LogicPage->Get_Graphic_Buffer(),
  1065. RadX + RadOffX + BaseX + LogicPage->Get_XPos(),
  1066. RadY + RadOffY + BaseY + LogicPage->Get_YPos(),
  1067. RadarWidth,
  1068. RadarHeight);
  1069. draw_window.Draw_Line(x1, y1, x1 + barlen, y1, LTGREEN);
  1070. draw_window.Draw_Line(x1, y1, x1, y1 + barlen, LTGREEN);
  1071. // Draw upper right hand corner
  1072. draw_window.Draw_Line(x2 - barlen, y1, x2, y1, LTGREEN);
  1073. draw_window.Draw_Line(x2, y1, x2, y1 + barlen, LTGREEN);
  1074. // Draw lower left hand corner
  1075. draw_window.Draw_Line(x1, y2 - barlen, x1, y2, LTGREEN);
  1076. draw_window.Draw_Line(x1, y2, x1 + barlen, y2, LTGREEN);
  1077. // Draw lower right hand corner
  1078. draw_window.Draw_Line(x2, y2 - barlen, x2, y2, LTGREEN);
  1079. draw_window.Draw_Line(x2 - barlen, y2, x2, y2, LTGREEN);
  1080. #if(0)
  1081. draw_window.Draw_Rect(x1, y1, x2, y2, WHITE);
  1082. #endif
  1083. #if(FALSE)
  1084. if (oldpage == &SeenBuff) {
  1085. Hide_Mouse();
  1086. HidPage.Blit( SeenBuff,
  1087. (int)(RadX + RadOffX + BaseX),
  1088. (int)(RadY + RadOffY + BaseY),
  1089. (int)(RadX + RadOffX + BaseX),
  1090. (int)(RadY + RadOffY + BaseY),
  1091. (int)draw_window.Get_Width(),
  1092. (int)draw_window.Get_Height(),
  1093. (BOOL)FALSE);
  1094. Show_Mouse();
  1095. }
  1096. #endif
  1097. Set_Logic_Page(oldpage);
  1098. _last_pos = tac_cell;
  1099. _last_frame = SpecialRadarFrame;
  1100. RadarCursorRedraw = FALSE;
  1101. }
  1102. /***************************************************************************
  1103. * RadarClass::Radar_Anim -- Renders current frame of radar animation *
  1104. * *
  1105. * *
  1106. * *
  1107. * INPUT: *
  1108. * *
  1109. * OUTPUT: *
  1110. * *
  1111. * WARNINGS: *
  1112. * *
  1113. * HISTORY: *
  1114. * 04/19/1995 PWG : Created. *
  1115. *=========================================================================*/
  1116. void RadarClass::Radar_Anim(void)
  1117. {
  1118. /*
  1119. ** Do nothing if we're in player-name mode
  1120. */
  1121. if (IsPlayerNames)
  1122. return;
  1123. if (!Map.IsSidebarActive) return;
  1124. GraphicViewPortClass *oldpage= Set_Logic_Page(HidPage);
  1125. GraphicViewPortClass draw_window(LogicPage->Get_Graphic_Buffer(),
  1126. RadX + RadOffX + LogicPage->Get_XPos(),
  1127. RadY + RadOffY + LogicPage->Get_YPos(),
  1128. RadIWidth,
  1129. RadIHeight);
  1130. Draw_Box(RadX+RadOffX-1, RadY+RadOffY-1, RadIWidth+2, RadIHeight+2, BOXSTYLE_RAISED, true);
  1131. draw_window.Clear();
  1132. CC_Draw_Shape(RadarAnim, RadarAnimFrame, RadX, RadY+1, WINDOW_MAIN, SHAPE_NORMAL);
  1133. Flag_To_Redraw(false);
  1134. Set_Logic_Page(oldpage);
  1135. }
  1136. /***********************************************************************************************
  1137. * RadarClass::AI -- Processes radar input (non-tactical). *
  1138. * *
  1139. * This routine intercepts any player input that concerns the radar map, but not those *
  1140. * areas that represent the tactical map. These are handled by the tactical map AI *
  1141. * processor. Primarily, this routine handles the little buttons that border the radar *
  1142. * map. *
  1143. * *
  1144. * INPUT: input -- The player input code. *
  1145. * *
  1146. * x,y -- Mouse coordinate parameters to use. *
  1147. * *
  1148. * OUTPUT: none *
  1149. * *
  1150. * WARNINGS: none *
  1151. * *
  1152. * HISTORY: *
  1153. * 12/23/1994 JLB : Created. *
  1154. * 12/26/1994 JLB : Moves tactical map with click or drag. *
  1155. * 12/31/1994 JLB : Uses mouse coordinate parameters. *
  1156. *=============================================================================================*/
  1157. void RadarClass::AI(KeyNumType & input, int x, int y)
  1158. {
  1159. /*
  1160. ** Check to see if we need to animate the radar cursor
  1161. */
  1162. if (IsRadarActive && Map.IsSidebarActive && SpecialRadarFrame) {
  1163. SpecialRadarFrame--;
  1164. RadarCursorRedraw = TRUE;
  1165. IsToRedraw = TRUE;
  1166. Flag_To_Redraw(FALSE);
  1167. }
  1168. /*
  1169. ** Check goes here to see if there is enough power to run the radar
  1170. */
  1171. if (IsRadarActivating) {
  1172. if (!DoesRadarExist) {
  1173. RadarAnimFrame++;
  1174. if (RadarAnimFrame < RADAR_ACTIVATED_FRAME) {
  1175. IsToRedraw = true;
  1176. Flag_To_Redraw(false);
  1177. } else {
  1178. DoesRadarExist = true;
  1179. Radar_Activate(3);
  1180. }
  1181. } else {
  1182. RadarAnimFrame--;
  1183. if (RadarAnimFrame > RADAR_ACTIVATED_FRAME) {
  1184. IsToRedraw = true;
  1185. Flag_To_Redraw(false);
  1186. } else {
  1187. Radar_Activate(3);
  1188. }
  1189. }
  1190. }
  1191. if (IsRadarDeactivating) {
  1192. RadarAnimFrame++;
  1193. if (RadarAnimFrame == MAX_RADAR_FRAMES) {
  1194. IsRadarDeactivating = false;
  1195. } else {
  1196. IsToRedraw = true;
  1197. Flag_To_Redraw(false);
  1198. }
  1199. }
  1200. DisplayClass::AI(input, x, y);
  1201. }
  1202. /***********************************************************************************************
  1203. * RadarClass::TacticalClass::Action -- I/O function for the radar map. *
  1204. * *
  1205. * This is the main action function for handling player I/O on the radar map. It processes *
  1206. * mouse clicks as well as mouse moves. *
  1207. * *
  1208. * INPUT: flags -- The event flags that trigger this function call. *
  1209. * *
  1210. * key -- Reference the keyboard event that applies to the trigger event. *
  1211. * *
  1212. * OUTPUT: Should further processing of the input list be aborted? *
  1213. * *
  1214. * WARNINGS: none *
  1215. * *
  1216. * HISTORY: *
  1217. * 05/08/1995 JLB : Created. *
  1218. *=============================================================================================*/
  1219. int RadarClass::TacticalClass::Action(unsigned flags, KeyNumType & key)
  1220. {
  1221. CELL cell; // cell num click happened over
  1222. int x,y; // Sub cell pixel coordinates.
  1223. int cellx,celly; // Sub cell pixel coordinates.
  1224. bool shadow; // is the cell in shadow or not
  1225. ObjectClass *object = 0; // what object is in the cell
  1226. ActionType action = ACTION_NONE; // Action possible with currently selected object.
  1227. /*
  1228. ** Force any help label to disappear when the mouse is held over the
  1229. ** radar map.
  1230. */
  1231. if (Map.IsSidebarActive) {
  1232. Map.Help_Text(TXT_NONE);
  1233. }
  1234. if (!Map.IsRadarActive) {
  1235. if (Map.IsSidebarActive) {
  1236. Map.Override_Mouse_Shape(MOUSE_NORMAL, true);
  1237. }
  1238. return(false);
  1239. }
  1240. /*
  1241. ** Disable processing if the player names are up
  1242. */
  1243. if (Map.Is_Player_Names()) {
  1244. GadgetClass::Action(0, key);
  1245. return(true);
  1246. }
  1247. /*
  1248. ** Set some working variables that depend on the mouse position. For the press
  1249. ** or release event, special mouse queuing storage variables are used. Other
  1250. ** events must use the current mouse position globals.
  1251. */
  1252. if (flags & (LEFTPRESS|LEFTRELEASE|RIGHTPRESS|RIGHTRELEASE)) {
  1253. x = _Kbd->MouseQX;
  1254. y = _Kbd->MouseQY;
  1255. } else {
  1256. x = Get_Mouse_X();
  1257. y = Get_Mouse_Y();
  1258. }
  1259. int result = Map.RadarClass::Click_In_Radar(x, y, false);
  1260. if (result == 1) {
  1261. cell = Map.RadarClass::Click_Cell_Calc(x, y);
  1262. if (cell != -1) {
  1263. //using function for IsVisible so we have different results for different players - JAS 2019/09/30
  1264. shadow = (!Map[cell].Is_Visible(PlayerPtr) && !Debug_Unshroud);
  1265. cellx = 12;
  1266. celly = 12;
  1267. /*
  1268. ** Determine the object that the mouse is currently over.
  1269. */
  1270. if (!shadow) {
  1271. object = Map.Cell_Object(cell, cellx, celly);
  1272. }
  1273. /*
  1274. ** If there is a currently selected object, then the action to perform if
  1275. ** the left mouse button were clicked must be determined.
  1276. */
  1277. if (CurrentObject.Count()) {
  1278. if (object) {
  1279. action = CurrentObject[0]->What_Action(object);
  1280. } else {
  1281. action = CurrentObject[0]->What_Action(cell);
  1282. }
  1283. /*
  1284. ** If this is not a valid radar map action then we are not going to do
  1285. ** anything.
  1286. */
  1287. switch (action) {
  1288. case ACTION_MOVE:
  1289. case ACTION_NOMOVE:
  1290. case ACTION_ATTACK:
  1291. case ACTION_ENTER:
  1292. case ACTION_CAPTURE:
  1293. case ACTION_SABOTAGE:
  1294. break;
  1295. default:
  1296. action = ACTION_NONE;
  1297. object = NULL;
  1298. break;
  1299. }
  1300. /*
  1301. ** On the radar map the only reason we would want the normal cursor to
  1302. ** appear is if we were over one of our own selected units. Otherwise
  1303. ** we can't move there.
  1304. **/
  1305. if (action == ACTION_NONE) {
  1306. if (object && object->Is_Selected_By_Player()) {
  1307. object = NULL;
  1308. } else {
  1309. action = ACTION_NOMOVE;
  1310. }
  1311. }
  1312. /*
  1313. ** A right mouse button press toggles the zoom mode.
  1314. */
  1315. if (flags & RIGHTPRESS) {
  1316. Map.Mouse_Right_Press();
  1317. }
  1318. /*
  1319. ** When the mouse buttons aren't pressed, only the mouse cursor shape is processed.
  1320. ** The shape changes depending on what object the mouse is currently over and what
  1321. ** object is currently selected.
  1322. */
  1323. if (flags & LEFTUP) {
  1324. Map.Mouse_Left_Up(shadow, object, action, true);
  1325. }
  1326. /*
  1327. ** Normal actions occur when the mouse button is released. The press event is
  1328. ** intercepted and possible rubber-band mode is flagged.
  1329. */
  1330. if (flags & LEFTPRESS) {
  1331. Map.Mouse_Left_Release(cell, cellx, celly, object, action, true);
  1332. }
  1333. } else {
  1334. Map.Set_Default_Mouse(MOUSE_RADAR_CURSOR, !Map.IsZoomed);
  1335. if (flags & LEFTPRESS) {
  1336. cell = Map.RadarClass::Click_Cell_Calc(x, y);
  1337. if (cell != -1) {
  1338. int cellx = Cell_X(cell);
  1339. int celly = Cell_Y(cell);
  1340. cellx -= Lepton_To_Cell(Map.TacLeptonWidth) / 2;
  1341. cellx = MAX(cellx, Map.MapCellX);
  1342. celly -= Lepton_To_Cell(Map.TacLeptonHeight) / 2;
  1343. celly = MAX(celly, Map.MapCellY);
  1344. cell = XY_Cell(cellx, celly);
  1345. shadow = (!Map[cell].Is_Visible(PlayerPtr) && !Debug_Unshroud);
  1346. Map.Set_Tactical_Position(Cell_Coord(cell));
  1347. cell = Coord_Cell(Map.DesiredTacticalCoord);
  1348. Map.DisplayClass::IsToRedraw = true;
  1349. //Map.Flag_To_Redraw(false);
  1350. Map.Flag_To_Redraw(true);
  1351. Map.SpecialRadarFrame = 4;
  1352. }
  1353. }
  1354. /*
  1355. ** A right mouse button press toggles the zoom mode.
  1356. */
  1357. if (flags & RIGHTPRESS) {
  1358. Map.Zoom_Mode(cell);
  1359. }
  1360. }
  1361. }
  1362. }
  1363. if (result == -1) {
  1364. Map.Override_Mouse_Shape(MOUSE_NORMAL, true);
  1365. }
  1366. GadgetClass::Action(0, key);
  1367. return(true);
  1368. }
  1369. /***********************************************************************************************
  1370. * RadarClass::Refresh_Cells -- Intercepts refresh request and updates radar if needed *
  1371. * *
  1372. * This routine intercepts the refresh cells request and if it detects that the sidebar *
  1373. * should be rerendered, it flags the radar map to redraw during the next draw operation. *
  1374. * *
  1375. * INPUT: cell -- The origin cell that the refresh cell offset list is based upon. *
  1376. * *
  1377. * list -- Pointer to the list of offsets from the origin cell that specifies the *
  1378. * cells to be flagged for redraw. If the list starts with the special *
  1379. * code to refresh the sidebar, then this routine recognizes it and flags *
  1380. * the radar map to be redrawn accordingly. *
  1381. * *
  1382. * OUTPUT: none *
  1383. * *
  1384. * WARNINGS: none *
  1385. * *
  1386. * HISTORY: *
  1387. * 01/01/1995 JLB : Created. *
  1388. *=============================================================================================*/
  1389. void RadarClass::Refresh_Cells(CELL cell, short const *list)
  1390. {
  1391. if (*list == REFRESH_SIDEBAR) {
  1392. IsToRedraw = true;
  1393. Flag_To_Redraw(false);
  1394. }
  1395. DisplayClass::Refresh_Cells(cell, list);
  1396. }
  1397. /***********************************************************************************************
  1398. * RadarClass::Set_Radar_Position -- Sets the radar position to center around specified cell. *
  1399. * *
  1400. * This routine will try to center the radar map around the cell position specified. *
  1401. * *
  1402. * INPUT: cell -- The cell to try and position the radar map around. *
  1403. * *
  1404. * OUTPUT: none *
  1405. * *
  1406. * WARNINGS: none *
  1407. * *
  1408. * HISTORY: *
  1409. * 05/08/1995 JLB : Created. *
  1410. *=============================================================================================*/
  1411. void RadarClass::Set_Radar_Position(CELL cell)
  1412. {
  1413. int oldx, oldy;
  1414. int newx, newy;
  1415. int newcell;
  1416. if (ZoomFactor != 1) {
  1417. #if(FALSE)
  1418. oldx = (Cell_X(cell) - MapCellX) - (RadarCellWidth / 2);
  1419. oldy = (Cell_Y(cell) - MapCellY) - (RadarCellHeight / 2);
  1420. #else
  1421. oldx = (Cell_X(cell) - MapCellX);
  1422. oldy = (Cell_Y(cell) - MapCellY);
  1423. #endif
  1424. } else {
  1425. oldx = 0;
  1426. oldy = 0;
  1427. }
  1428. Confine_Rect(&oldx, &oldy, RadarCellWidth, RadarCellHeight, MapCellWidth, MapCellHeight);
  1429. newx = oldx + MapCellX;
  1430. newy = oldy + MapCellY;
  1431. newcell = XY_Cell(newx, newy);
  1432. if (RadarCell != newcell) {
  1433. int forced = FALSE;
  1434. int xmod = newx;
  1435. int ymod = newy;
  1436. int radx = (Cell_X(RadarCell)) - xmod;
  1437. int rady = (Cell_Y(RadarCell)) - ymod;
  1438. RadarX = newx;
  1439. RadarY = newy;
  1440. RadarCell = newcell;
  1441. if (Map.IsSidebarActive&& Map.IsRadarActive) {
  1442. int radw = RadarCellWidth-ABS(radx); // Replicable width.
  1443. int radh = RadarCellHeight-ABS(rady); // Replicable height.
  1444. if (radw < 1) forced = true;
  1445. if (radh < 1) forced = true;
  1446. if (!forced && (radw != RadarWidth || radh != RadarHeight)) {
  1447. /*
  1448. ** Blit the section that is actually overlapping.
  1449. */
  1450. if (OverlappedVideoBlits || !HidPage.Get_IsDirectDraw()){
  1451. HidPage.Blit(HidPage,
  1452. (((radx < 0) ? -radx : 0) * ZoomFactor) + RadX + RadOffX + BaseX,
  1453. (((rady < 0) ? -rady : 0) * ZoomFactor) + RadY + RadOffY + BaseY,
  1454. (((radx < 0) ? 0 : radx) * ZoomFactor) + RadX+ RadOffX + BaseX,
  1455. (((rady < 0) ? 0 : rady) * ZoomFactor) + RadY + RadOffY + BaseY,
  1456. radw * ZoomFactor,
  1457. radh * ZoomFactor);
  1458. }else{
  1459. /*
  1460. ** System does not support overlapped blitting of video surfaces.
  1461. ** Blit it in 2 stages using an intermediate buffer.
  1462. */
  1463. GraphicBufferClass temp_surface;
  1464. temp_surface.Init((RadarWidth + 16) & 0xfffffff0,
  1465. (RadarHeight + 16) & 0xfffffff0,
  1466. NULL, 0, (GBC_Enum) GBC_VIDEOMEM);
  1467. HidPage.Blit(temp_surface, (((radx < 0) ? -radx : 0) * ZoomFactor) + RadX + RadOffX + BaseX,
  1468. (((rady < 0) ? -rady : 0) * ZoomFactor) + RadY + RadOffY + BaseY,
  1469. 0,
  1470. 0,
  1471. RadarWidth,
  1472. RadarHeight);
  1473. temp_surface.Blit (HidPage,0,
  1474. 0,
  1475. (((radx < 0) ? 0 : radx) * ZoomFactor) + RadX + RadOffX + BaseX,
  1476. (((rady < 0) ? 0 : rady) * ZoomFactor) + RadY + RadOffY + BaseY,
  1477. radw * ZoomFactor,
  1478. radh * ZoomFactor);
  1479. }
  1480. /*
  1481. ** Now we need to flag the section of the map that is going to redraw.
  1482. */
  1483. if ( radx != 0 ) {
  1484. int min;
  1485. int max;
  1486. if ( radx < 0 ) { // this mean regen the right edge
  1487. min = radw;
  1488. max = radw+ABS(radx);
  1489. } else { // this mean regen the left edge
  1490. min = 0;
  1491. max = radx;
  1492. }
  1493. for (int x = min; x < max; x++ ) {
  1494. for (unsigned int y = 0; y < RadarCellHeight; y++ ) {
  1495. Radar_Pixel(XY_Cell(newx + x, newy + y));
  1496. }
  1497. }
  1498. }
  1499. if ( newy != 0 ) {
  1500. int min;
  1501. int max;
  1502. if ( rady < 0 ) { // this mean regen the bottom edge
  1503. min = radh;
  1504. max = radh+ABS(rady);
  1505. } else { // this mean regen the top edge
  1506. min = 0;
  1507. max = rady;
  1508. }
  1509. for (int y = min; y < max; y++ ) {
  1510. for ( unsigned int x = 0; x < RadarCellWidth; x++ ) {
  1511. Radar_Pixel(XY_Cell(newx + x, newy + y));
  1512. }
  1513. }
  1514. }
  1515. }
  1516. }
  1517. RadarCursorRedraw = IsRadarActive;
  1518. IsToRedraw = IsRadarActive;
  1519. Flag_To_Redraw(false);
  1520. if (ZoomFactor > 4) {
  1521. FullRedraw = forced;
  1522. }
  1523. } else {
  1524. RadarCursorRedraw = IsRadarActive;
  1525. IsToRedraw = IsRadarActive;
  1526. Flag_To_Redraw(false);
  1527. }
  1528. }
  1529. /***********************************************************************************************
  1530. * RadarClass::Radar_Position -- Returns with the current position of the radar map. *
  1531. * *
  1532. * This returns the cell number of the upper left corner of the radar map. *
  1533. * *
  1534. * INPUT: none *
  1535. * *
  1536. * OUTPUT: Returns with the radar map upper left corner cell position. *
  1537. * *
  1538. * WARNINGS: none *
  1539. * *
  1540. * HISTORY: *
  1541. * 05/08/1995 JLB : Created. *
  1542. *=============================================================================================*/
  1543. CELL RadarClass::Radar_Position(void)
  1544. {
  1545. return(RadarCell);
  1546. }
  1547. /***********************************************************************************************
  1548. * RadarClass::Set_Map_Dimensions -- Sets the tactical map dimensions. *
  1549. * *
  1550. * This routine is called when the tactical map changes its dimensions. This occurs when *
  1551. * the tactical map moves and when the sidebar pops on or off. *
  1552. * *
  1553. * INPUT: x,y -- The cell coordinate of the upper left corner of the tactical map. *
  1554. * *
  1555. * w,y -- The cell width and height of the tactical map. *
  1556. * *
  1557. * OUTPUT: none *
  1558. * *
  1559. * WARNINGS: none *
  1560. * *
  1561. * HISTORY: *
  1562. * 05/08/1995 JLB : Created. *
  1563. *=============================================================================================*/
  1564. void RadarClass::Set_Map_Dimensions(int x, int y, int w, int h)
  1565. {
  1566. Set_Radar_Position(XY_Cell(x, y));
  1567. DisplayClass::Set_Map_Dimensions(x, y, w, h);
  1568. }
  1569. /***********************************************************************************************
  1570. * RadarClass::Set_Tactical_Position -- Sets the map's tactical position and adjusts radar to *
  1571. * *
  1572. * This routine is called when the tactical map is to change position. The radar map might *
  1573. * be adjusted as well by this routine. *
  1574. * *
  1575. * INPUT: coord -- The new coordinate to use for the upper left corner of the tactical *
  1576. * map. *
  1577. * *
  1578. * OUTPUT: none *
  1579. * *
  1580. * WARNINGS: none *
  1581. * *
  1582. * HISTORY: *
  1583. * 08/17/1995 JLB : Created. *
  1584. *=============================================================================================*/
  1585. void RadarClass::Set_Tactical_Position(COORDINATE coord)
  1586. {
  1587. DisplayClass::Set_Tactical_Position(coord);
  1588. Set_Radar_Position(Coord_Cell(DesiredTacticalCoord));
  1589. }
  1590. /***********************************************************************************************
  1591. * RadarClass::Cell_On_Radar -- Determines if a cell is currently visible on radar. *
  1592. * *
  1593. * This routine will examine the specified cell number and return whether it is visible *
  1594. * on the radar map. This depends on the radar map position. *
  1595. * *
  1596. * INPUT: cell -- The cell number to check. *
  1597. * *
  1598. * OUTPUT: Is the specified cell visible on the radar map currently? *
  1599. * *
  1600. * WARNINGS: none *
  1601. * *
  1602. * HISTORY: *
  1603. * 05/03/1995 JLB : Created. *
  1604. *=============================================================================================*/
  1605. bool RadarClass::Cell_On_Radar(CELL cell)
  1606. {
  1607. if ((unsigned)cell > MAP_CELL_TOTAL)
  1608. return(false);
  1609. int x = Cell_X(cell) - RadarX;
  1610. int y = Cell_Y(cell) - RadarY;
  1611. return (!((unsigned)x >= RadarCellWidth || (unsigned)y >= RadarCellHeight));
  1612. // if (!IsZoomed) {
  1613. // return(true);
  1614. // }
  1615. // return(!(((Cell_X(cell) - RadarX) > RadarCellWidth) || ((Cell_Y(cell) - RadarY) > RadarCellHeight)));
  1616. }
  1617. /***********************************************************************************************
  1618. * RadarClass::Player_Names -- toggles the Player-Names mode of the radar map *
  1619. * *
  1620. * INPUT: *
  1621. * on true = turn on; false = turn off *
  1622. * *
  1623. * OUTPUT: *
  1624. * none. *
  1625. * *
  1626. * WARNINGS: *
  1627. * none. *
  1628. * *
  1629. * HISTORY: *
  1630. * 06/07/1995 BRR : Created. *
  1631. *=============================================================================================*/
  1632. void RadarClass::Player_Names(bool on)
  1633. {
  1634. IsPlayerNames = on;
  1635. IsToRedraw = true;
  1636. if (on) {
  1637. Flag_To_Redraw(true);
  1638. // Flag_To_Redraw(false);
  1639. } else {
  1640. Flag_To_Redraw(true); // force drawing of the plate
  1641. }
  1642. }
  1643. /***********************************************************************************************
  1644. * Draw_Names -- draws players' names on the radar map *
  1645. * *
  1646. * INPUT: *
  1647. * none. *
  1648. * *
  1649. * OUTPUT: *
  1650. * none. *
  1651. * *
  1652. * WARNINGS: *
  1653. * none. *
  1654. * *
  1655. * HISTORY: *
  1656. * 06/07/1995 BRR : Created. *
  1657. *=============================================================================================*/
  1658. void RadarClass::Draw_Names(void)
  1659. {
  1660. int c_idx;
  1661. HousesType house;
  1662. HouseClass *ptr;
  1663. int y;
  1664. char txt[40];
  1665. unsigned char id;
  1666. int i;
  1667. HousesType h;
  1668. int kills;
  1669. int color;
  1670. TextPrintType style;
  1671. int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2;
  1672. /*
  1673. ** Do nothing if the sidebar isn't there
  1674. */
  1675. if (!Map.IsSidebarActive) {
  1676. return;
  1677. }
  1678. CC_Draw_Shape(RadarAnim, RADAR_ACTIVATED_FRAME, RadX, RadY+1, WINDOW_MAIN, SHAPE_NORMAL);
  1679. LogicPage->Fill_Rect( RadX + RadOffX,
  1680. RadY + RadOffY,
  1681. RadX + RadOffX + RadIWidth - 1,
  1682. RadY + RadOffY + RadIHeight - 1,
  1683. BLACK);
  1684. y = RadY + RadOffY;
  1685. Fancy_Text_Print (TXT_NAME_COLON, RadX + RadOffX, y, LTGREY, TBLACK,
  1686. TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
  1687. Fancy_Text_Print (TXT_KILLS_COLON, RadX + RadOffX + RadIWidth - 2, y,
  1688. LTGREY, TBLACK, TPF_RIGHT | TPF_6PT_GRAD | TPF_NOSHADOW | TPF_USE_GRAD_PAL);
  1689. y += 6*factor+1;
  1690. LogicPage->Draw_Line(RadX + RadOffX, y,
  1691. RadX + RadOffX + RadIWidth - 1, y, LTGREY);
  1692. y += 2*factor;
  1693. for (house = HOUSE_MULTI1; house < (HOUSE_MULTI1 + MPlayerMax); house++) {
  1694. ptr = HouseClass::As_Pointer(house);
  1695. if (!ptr)
  1696. continue;
  1697. /*
  1698. ** Decode this house's color
  1699. */
  1700. c_idx = ptr->RemapColor;
  1701. if (ptr->IsDefeated) {
  1702. color = GREY;
  1703. style = TPF_6PT_GRAD | TPF_NOSHADOW | TPF_USE_GRAD_PAL;
  1704. } else {
  1705. color = MPlayerTColors[c_idx];
  1706. style = TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW;
  1707. }
  1708. /*
  1709. ** Initialize our message
  1710. */
  1711. txt[0] = 0;
  1712. /*
  1713. ** If the house is non-human, generate the message
  1714. */
  1715. if (!ptr->IsHuman) {
  1716. sprintf(txt,"%s", Text_String(TXT_COMPUTER));
  1717. } else {
  1718. /*
  1719. ** For a human house:
  1720. ** - Compute the multiplayer ID for this house
  1721. ** - find the name for this player
  1722. */
  1723. id = Build_MPlayerID (c_idx,ptr->ActLike);
  1724. for (i = 0; i < MPlayerCount; i++) {
  1725. if (id == MPlayerID[i]) {
  1726. sprintf(txt,"%s",MPlayerNames[i]);
  1727. break;
  1728. }
  1729. }
  1730. }
  1731. /*
  1732. ** Print the player name, and the # of kills
  1733. */
  1734. if (strlen(txt)) {
  1735. if (strlen(txt) > 9) {
  1736. txt[9] = '.';
  1737. txt[10] = '\0';
  1738. }
  1739. Fancy_Text_Print (txt, RadX + RadOffX, y, color, BLACK, style);
  1740. kills = 0;
  1741. for (h = HOUSE_FIRST; h < HOUSE_COUNT; h++) {
  1742. kills += ptr->UnitsKilled[h];
  1743. kills += ptr->BuildingsKilled[h];
  1744. }
  1745. sprintf(txt, "%2d", kills);
  1746. Fancy_Text_Print (txt, RadX + RadOffX + RadIWidth - 2, y,
  1747. color, BLACK, style | TPF_RIGHT);
  1748. y += 6*factor+1;
  1749. }
  1750. }
  1751. }