Apprtype.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487
  1. //---------------------------------------------------------------------------
  2. //
  3. // ApprType.cpp -- File contains the Basic Game Appearance Type code
  4. //
  5. //---------------------------------------------------------------------------//
  6. // Copyright (C) Microsoft Corporation. All rights reserved. //
  7. //===========================================================================//
  8. //---------------------------------------------------------------------------
  9. // Include Files
  10. #ifndef APPRTYPE_H
  11. #include "apprtype.h"
  12. #endif
  13. #ifndef GVACTOR_H
  14. #include "gvactor.h"
  15. #endif
  16. #ifndef MECH3D_H
  17. #include "mech3d.h"
  18. #endif
  19. #ifndef BDACTOR_H
  20. #include "bdactor.h"
  21. #endif
  22. #ifndef GENACTOR_H
  23. #include "genactor.h"
  24. #endif
  25. #include "cident.h"
  26. #include "inifile.h"
  27. #include "paths.h"
  28. #include <gameos.hpp>
  29. //---------------------------------------------------------------------------
  30. // static Globals
  31. UserHeapPtr AppearanceTypeList::appearanceHeap = NULL;
  32. AppearanceTypeListPtr appearanceTypeList = NULL;
  33. //---------------------------------------------------------------------------
  34. // Class AppearanceType
  35. void* AppearanceType::operator new (size_t memSize)
  36. {
  37. void* result = NULL;
  38. if (AppearanceTypeList::appearanceHeap && AppearanceTypeList::appearanceHeap->heapReady())
  39. {
  40. result = AppearanceTypeList::appearanceHeap->Malloc(memSize);
  41. }
  42. return(result);
  43. }
  44. //---------------------------------------------------------------------------
  45. void AppearanceType::operator delete (void* treePtr)
  46. {
  47. long result;
  48. if (AppearanceTypeList::appearanceHeap && AppearanceTypeList::appearanceHeap->heapReady())
  49. {
  50. result = AppearanceTypeList::appearanceHeap->Free(treePtr);
  51. }
  52. }
  53. //---------------------------------------------------------------------------
  54. void AppearanceType::init (char *fileName)
  55. {
  56. name = (char *)AppearanceTypeList::appearanceHeap->Malloc(strlen(fileName)+1);
  57. strcpy(name,fileName);
  58. //Dig out the Type Bounds here for selections
  59. FullPathFileName iniName;
  60. iniName.init(tglPath,fileName,".ini");
  61. FitIniFile iniFile;
  62. long result = iniFile.open(iniName);
  63. if (result != NO_ERR)
  64. STOP(("Could not find appearance INI file %s",iniName));
  65. result = iniFile.seekBlock("3DBounds");
  66. if (result == NO_ERR)
  67. {
  68. designerTypeBounds = true;
  69. long tmpy;
  70. result = iniFile.readIdLong("UpperLeftX",tmpy);
  71. if (result != NO_ERR)
  72. STOP(("Cant find upperleftX type bounds in %s",iniName));
  73. else
  74. typeUpperLeft.x = tmpy;
  75. result = iniFile.readIdLong("UpperLeftY",tmpy);
  76. if (result != NO_ERR)
  77. STOP(("Cant find upperleftX type bounds in %s",iniName));
  78. else
  79. typeUpperLeft.y = tmpy;
  80. result = iniFile.readIdLong("UpperLeftZ",tmpy);
  81. if (result != NO_ERR)
  82. STOP(("Cant find upperleftX type bounds in %s",iniName));
  83. else
  84. typeUpperLeft.z = tmpy;
  85. result = iniFile.readIdLong("LowerRightX",tmpy);
  86. if (result != NO_ERR)
  87. STOP(("Cant find upperleftX type bounds in %s",iniName));
  88. else
  89. typeLowerRight.x = tmpy;
  90. result = iniFile.readIdLong("LowerRightY",tmpy);
  91. if (result != NO_ERR)
  92. STOP(("Cant find upperleftX type bounds in %s",iniName));
  93. else
  94. typeLowerRight.y = tmpy;
  95. result = iniFile.readIdLong("LowerRightZ",tmpy);
  96. if (result != NO_ERR)
  97. STOP(("Cant find upperleftX type bounds in %s",iniName));
  98. else
  99. typeLowerRight.z = tmpy;
  100. }
  101. iniFile.close();
  102. }
  103. //---------------------------------------------------------------------------
  104. void AppearanceType::reinit (void)
  105. {
  106. //Dig out the Type Bounds here for selections
  107. FullPathFileName iniName;
  108. iniName.init(tglPath,name,".ini");
  109. FitIniFile iniFile;
  110. long result = iniFile.open(iniName);
  111. if (result != NO_ERR)
  112. STOP(("Could not find appearance INI file %s",iniName));
  113. result = iniFile.seekBlock("3DBounds");
  114. if (result == NO_ERR)
  115. {
  116. designerTypeBounds = true;
  117. long tmpy;
  118. result = iniFile.readIdLong("UpperLeftX",tmpy);
  119. if (result != NO_ERR)
  120. STOP(("Cant find upperleftX type bounds in %s",iniName));
  121. else
  122. typeUpperLeft.x = tmpy;
  123. result = iniFile.readIdLong("UpperLeftY",tmpy);
  124. if (result != NO_ERR)
  125. STOP(("Cant find upperleftX type bounds in %s",iniName));
  126. else
  127. typeUpperLeft.y = tmpy;
  128. result = iniFile.readIdLong("UpperLeftZ",tmpy);
  129. if (result != NO_ERR)
  130. STOP(("Cant find upperleftX type bounds in %s",iniName));
  131. else
  132. typeUpperLeft.z = tmpy;
  133. result = iniFile.readIdLong("LowerRightX",tmpy);
  134. if (result != NO_ERR)
  135. STOP(("Cant find upperleftX type bounds in %s",iniName));
  136. else
  137. typeLowerRight.x = tmpy;
  138. result = iniFile.readIdLong("LowerRightY",tmpy);
  139. if (result != NO_ERR)
  140. STOP(("Cant find upperleftX type bounds in %s",iniName));
  141. else
  142. typeLowerRight.y = tmpy;
  143. result = iniFile.readIdLong("LowerRightZ",tmpy);
  144. if (result != NO_ERR)
  145. STOP(("Cant find upperleftX type bounds in %s",iniName));
  146. else
  147. typeLowerRight.z = tmpy;
  148. }
  149. iniFile.close();
  150. }
  151. //---------------------------------------------------------------------------
  152. void AppearanceType::destroy (void)
  153. {
  154. AppearanceTypeList::appearanceHeap->Free(name);
  155. name = NULL;
  156. }
  157. //---------------------------------------------------------------------------
  158. // class AppearanceTypeList
  159. void AppearanceTypeList::init (unsigned long heapSize)
  160. {
  161. appearanceHeap = new UserHeap;
  162. gosASSERT(appearanceHeap != NULL);
  163. appearanceHeap->init(heapSize,"APPEAR");
  164. //No More sprite files. Objects now have direct control over their appearances.
  165. }
  166. //---------------------------------------------------------------------------
  167. AppearanceTypePtr AppearanceTypeList::getAppearance (unsigned long apprNum, char *appearFile)
  168. {
  169. //----------------------------------------------------------------
  170. // The type of appearance is stored in the upper 8 bits of the
  171. // apprNum. To get the correct packet we mask off the top 8 bits
  172. // and store the number. To get the appearance type, we right shift
  173. // by 24.
  174. long appearanceClass = apprNum >> 24;
  175. AppearanceTypePtr appearanceType = NULL;
  176. //----------------------------------------------------
  177. // If these top bits are wrong, return NULL
  178. if (appearanceClass == 0)
  179. return(NULL);
  180. //----------------------------------------------------
  181. // If string passed in is NULL, return NULL
  182. if (!appearFile)
  183. {
  184. return NULL;
  185. }
  186. //-----------------------------------------------------------
  187. // Scan the list of appearances and see if we have this one.
  188. appearanceType = head;
  189. while (appearanceType && stricmp(appearanceType->name,appearFile) != 0)
  190. {
  191. appearanceType = appearanceType->next;
  192. }
  193. if (appearanceType)
  194. {
  195. appearanceType->numUsers++;
  196. }
  197. else
  198. {
  199. //---------------------------------------------------------
  200. // This appearance is not on the list yet, so load/new it.
  201. switch (appearanceClass)
  202. {
  203. //----------------------------------------
  204. case MECH_TYPE:
  205. {
  206. appearanceType = new Mech3DAppearanceType;
  207. gosASSERT(appearanceType != NULL);
  208. appearanceType->appearanceNum = apprNum;
  209. appearanceType->init(appearFile);
  210. //----------------------------------------
  211. // We have a new one, add it to the list.
  212. appearanceType->numUsers = 1;
  213. appearanceType->next = NULL;
  214. if (head == NULL)
  215. {
  216. head = appearanceType;
  217. last = head;
  218. }
  219. else
  220. {
  221. last->next = appearanceType;
  222. last = appearanceType;
  223. }
  224. }
  225. break;
  226. //----------------------------------------
  227. case GV_TYPE:
  228. {
  229. appearanceType = new GVAppearanceType;
  230. gosASSERT(appearanceType != NULL);
  231. appearanceType->appearanceNum = apprNum;
  232. appearanceType->init(appearFile);
  233. //----------------------------------------
  234. // We have a new one, add it to the list.
  235. appearanceType->numUsers = 1;
  236. appearanceType->next = NULL;
  237. if (head == NULL)
  238. {
  239. head = appearanceType;
  240. last = head;
  241. }
  242. else
  243. {
  244. last->next = appearanceType;
  245. last = appearanceType;
  246. }
  247. }
  248. break;
  249. //----------------------------------------
  250. case TREED_TYPE:
  251. {
  252. appearanceType = new TreeAppearanceType;
  253. gosASSERT(appearanceType != NULL);
  254. appearanceType->appearanceNum = apprNum;
  255. appearanceType->init(appearFile);
  256. //----------------------------------------
  257. // We have a new one, add it to the list.
  258. appearanceType->numUsers = 1;
  259. appearanceType->next = NULL;
  260. if (head == NULL)
  261. {
  262. head = appearanceType;
  263. last = head;
  264. }
  265. else
  266. {
  267. last->next = appearanceType;
  268. last = appearanceType;
  269. }
  270. }
  271. break;
  272. //----------------------------------------
  273. case GENERIC_APPR_TYPE:
  274. {
  275. appearanceType = new GenericAppearanceType;
  276. gosASSERT(appearanceType != NULL);
  277. appearanceType->appearanceNum = apprNum;
  278. appearanceType->init(appearFile);
  279. //----------------------------------------
  280. // We have a new one, add it to the list.
  281. appearanceType->numUsers = 1;
  282. appearanceType->next = NULL;
  283. if (head == NULL)
  284. {
  285. head = appearanceType;
  286. last = head;
  287. }
  288. else
  289. {
  290. last->next = appearanceType;
  291. last = appearanceType;
  292. }
  293. }
  294. break;
  295. //----------------------------------------
  296. case BLDG_TYPE:
  297. {
  298. appearanceType = new BldgAppearanceType;
  299. gosASSERT(appearanceType != NULL);
  300. appearanceType->appearanceNum = apprNum;
  301. appearanceType->init(appearFile);
  302. //----------------------------------------
  303. // We have a new one, add it to the list.
  304. appearanceType->numUsers = 1;
  305. appearanceType->next = NULL;
  306. if (head == NULL)
  307. {
  308. head = appearanceType;
  309. last = head;
  310. }
  311. else
  312. {
  313. last->next = appearanceType;
  314. last = appearanceType;
  315. }
  316. }
  317. break;
  318. default:
  319. return(NULL);
  320. }
  321. }
  322. return appearanceType;
  323. }
  324. //---------------------------------------------------------------------------
  325. long AppearanceTypeList::removeAppearance (AppearanceTypePtr which)
  326. {
  327. AppearanceTypePtr appearanceType = head;
  328. AppearanceTypePtr previous = NULL;
  329. while (appearanceType && (appearanceType != which))
  330. {
  331. previous = appearanceType;
  332. appearanceType = appearanceType->next;
  333. }
  334. if (appearanceType)
  335. appearanceType->numUsers--;
  336. else
  337. return(-1);
  338. //----------------------------------------------------------
  339. // NEVER remove the types anymore. Save cache time!
  340. //#if 0
  341. if (appearanceType && (appearanceType->numUsers == 0))
  342. {
  343. //------------------------------------------------------
  344. // Check if there is no previous appearanceType in list
  345. if (previous == NULL)
  346. {
  347. //----------------------------------------------------
  348. // if there was no previous, head is the next in list
  349. head = appearanceType->next;
  350. }
  351. else
  352. {
  353. previous->next = appearanceType->next;
  354. }
  355. //-------------------------------------------------------------
  356. // Make sure that we don't gratuitously free the last pointer
  357. if (appearanceType == last)
  358. last = previous;
  359. delete appearanceType;
  360. appearanceType = NULL;
  361. }
  362. //#endif
  363. return NO_ERR;
  364. }
  365. //---------------------------------------------------------------------------
  366. void AppearanceTypeList::destroy (void)
  367. {
  368. //---------------------------------------------------------------------
  369. // Run through the list and force a destroy call for each list element.
  370. // This will free any RAM used by each individual appearance.
  371. // DO NOT really need to do this. Just toss the heap!
  372. AppearanceTypePtr currentAppr = head;
  373. while (currentAppr)
  374. {
  375. AppearanceTypePtr nextPtr = currentAppr->next;
  376. currentAppr->destroy();
  377. currentAppr = nextPtr;
  378. }
  379. head = last = NULL;
  380. delete appearanceHeap;
  381. appearanceHeap = NULL;
  382. if (GVAppearanceType::SensorCircleShape)
  383. {
  384. delete GVAppearanceType::SensorCircleShape;
  385. GVAppearanceType::SensorCircleShape = NULL;
  386. }
  387. if (GVAppearanceType::SensorTriangleShape)
  388. {
  389. delete GVAppearanceType::SensorTriangleShape;
  390. GVAppearanceType::SensorTriangleShape = NULL;
  391. }
  392. if (Mech3DAppearanceType::SensorSquareShape)
  393. {
  394. delete Mech3DAppearanceType::SensorSquareShape;
  395. Mech3DAppearanceType::SensorSquareShape = NULL;
  396. }
  397. }
  398. //---------------------------------------------------------------------------
  399. bool AppearanceTypeList::pointerCanBeDeleted (void *ptr)
  400. {
  401. if (appearanceHeap && appearanceHeap->pointerOnHeap(ptr))
  402. return true;
  403. return false;
  404. }
  405. //---------------------------------------------------------------------------