mainloop.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /* $Header: /Commando/Code/Tests/MeshTest/mainloop.cpp 47 12/10/98 5:53p Greg_h $ */
  19. /***********************************************************************************************
  20. *** Confidential - Westwood Studios ***
  21. ***********************************************************************************************
  22. * *
  23. * Project Name : Commando *
  24. * *
  25. * $Archive:: /Commando/Code/Tests/MeshTest/mainloop.cpp $*
  26. * *
  27. * $Author:: Greg_h $*
  28. * *
  29. * $Modtime:: 12/07/98 1:30p $*
  30. * *
  31. * $Revision:: 47 $*
  32. * *
  33. *---------------------------------------------------------------------------------------------*
  34. * Functions: *
  35. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  36. #define NOMINMAX
  37. #include "mainloop.h"
  38. #include "mono.h"
  39. #include "msgloop.h"
  40. #include "wwfile.h"
  41. #include "rawfile.h"
  42. #include "_globals.h"
  43. #include "_viewpt.h"
  44. #include <sr.hpp>
  45. #include <assert.h>
  46. #include "assetmgr.h"
  47. #include "sr_util.h"
  48. #include "_scenes.h"
  49. #include "rendobj.h"
  50. #include "r3dobj.h"
  51. #include "mesh.h"
  52. #include "hmodel.h"
  53. #include "light.h"
  54. #include "wwdebug.h"
  55. #include "ww3d.h"
  56. #define SPIN_MODEL
  57. #define SPIN_LIGHT
  58. //#define CAPTURE_BONE
  59. //#define TEST_DAMAGE
  60. //#define TEST_TEXTURE_ANIMATION
  61. /*
  62. ** Globals
  63. */
  64. WW3DAssetManager The3DAssetManager;
  65. CameraClass * Camera;
  66. LightClass * Light;
  67. LightClass * Light2;
  68. RenderObjClass * TestModel = NULL;
  69. HAnimClass * TestAnim = NULL;
  70. float CameraDist = 10.0f;
  71. float CameraDir = 0.0f;
  72. Quaternion ModelOrientation(1);
  73. #ifdef SPIN_MODEL
  74. Quaternion ModelRotation(Vector3(0,0,1),DEG_TO_RAD(1.5f));
  75. #else
  76. Quaternion ModelRotation(1);
  77. #endif
  78. Quaternion LightOrientation(1);
  79. Quaternion LightRotation(Vector3(.2,1,.1),DEG_TO_RAD(3.0f));
  80. /*
  81. ** Local functions
  82. */
  83. void Render(void);
  84. void Create_Scene(void);
  85. void Create_Objects(void);
  86. void Destroy_Scene(void);
  87. void Destroy_Objects(void);
  88. void Load_Data(void);
  89. void Render_Scene(void);
  90. void Time_Step(void);
  91. void Init_Debug(void);
  92. void Shutdown_Debug(void);
  93. void wwdebug_message_handler(const char * message);
  94. void wwdebug_assert_handler(const char * message);
  95. bool wwdebug_trigger_handler(int trigger_num);
  96. void Debug_Refs(void);
  97. /*
  98. ** delay for time milliseconds
  99. */
  100. void Wait( int time )
  101. {
  102. int start = SystemTimer();
  103. while ( 1000 * ( SystemTimer() - start ) < ( time * SYSTEM_TIMER_RATE ) ) ;
  104. }
  105. /*
  106. ** MAIN GAME LOOP
  107. */
  108. void Main_Loop(void)
  109. {
  110. Init_Debug();
  111. Create_Scene();
  112. Load_Data();
  113. Create_Objects();
  114. while (!Keyboard->Down(VK_ESCAPE)) {
  115. Time_Step();
  116. Render();
  117. Windows_Message_Handler();
  118. if (Keyboard->Down(VK_F1)) {
  119. while(Keyboard->Down(VK_F1));
  120. WW3D::Set_Next_Render_Device();
  121. }
  122. if (Keyboard->Down(VK_F2)) {
  123. while(Keyboard->Down(VK_F2));
  124. }
  125. }
  126. Destroy_Objects();
  127. WW3DAssetManager::Get_Instance()->Free_Assets();
  128. Destroy_Scene();
  129. Shutdown_Debug();
  130. Debug_Refs();
  131. }
  132. void Render(void)
  133. {
  134. ViewportClass view(Vector2(-1,-1),Vector2(1,1));
  135. Light->Set_Diffuse(Vector3(1.0f,1.0f,1.0f));
  136. TheScene->Set_Ambient_Light(Vector3(0.8f,0.8f,0.8f));
  137. WW3D::Begin_Render(true,true,Vector3(0.2f,0.2f,0.5f));
  138. WW3D::Gerd_Render(TheScene,Camera);
  139. WW3D::End_Render();
  140. }
  141. void Create_Scene(void)
  142. {
  143. int rd_index = 0;
  144. int width = 640;
  145. int height = 480;
  146. int color_depth = 16;
  147. bool windowed = true;
  148. WW3D::Set_Render_Device(rd_index,width,height,color_depth,windowed);
  149. TheScene = new SimpleSceneClass();
  150. }
  151. /*
  152. ** Load initial game data
  153. */
  154. void Load_Data(void)
  155. {
  156. // WW3DAssetManager::Get_Instance()->Load_3D_Assets(RawFileClass("crap.W3D"));
  157. // WW3DAssetManager::Get_Instance()->Load_3D_Assets(RawFileClass("HUMAN.W3D"));
  158. // WW3DAssetManager::Get_Instance()->Load_3D_Assets(RawFileClass("COMMANDO.W3D"));
  159. // WW3DAssetManager::Get_Instance()->Load_3D_Assets(RawFileClass("Mtankl1.W3D"));
  160. WW3DAssetManager::Get_Instance()->Load_3D_Assets(RawFileClass("Triangle.W3D"));
  161. // WW3DAssetManager::Get_Instance()->Load_3D_Assets(RawFileClass("Sphere.W3D"));
  162. // WW3DAssetManager::Get_Instance()->Load_3D_Assets(RawFileClass("new_mtl_test.W3D"));
  163. }
  164. /*
  165. **
  166. */
  167. void Create_Objects(void)
  168. {
  169. Camera = NEW_REF(CameraClass,());
  170. Camera->Set_Viewport(Vector2(0,0),Vector2(640,480));
  171. Camera->Set_Clip_Planes(1.0f, 200.0f);
  172. Camera->Set_Environment_Range(1.0f, 200.0f);
  173. // TestModel = WW3DAssetManager::Get_Instance()->Create_Render_Obj("Mtankl1");
  174. // TestModel = WW3DAssetManager::Get_Instance()->Create_Render_Obj("Crap");
  175. TestModel = WW3DAssetManager::Get_Instance()->Create_Render_Obj("triangle");
  176. // TestModel = WW3DAssetManager::Get_Instance()->Create_Render_Obj("new_mtl_test");
  177. assert(TestModel);
  178. TestModel->Add(TheScene);
  179. Light = NEW_REF(LightClass,());
  180. Matrix3D lighttm(1);
  181. lighttm.Set_Translation(Vector3(5,0,0));
  182. Light->Set_Transform(lighttm);
  183. Light->Add(TheScene);
  184. }
  185. /*
  186. **
  187. */
  188. void Destroy_Scene(void)
  189. {
  190. TheScene->Release_Ref();
  191. TheScene = NULL;
  192. }
  193. /*
  194. **
  195. */
  196. void Destroy_Objects(void)
  197. {
  198. if (TestModel) {
  199. TestModel->Remove();
  200. TestModel->Release_Ref();
  201. TestModel = NULL;
  202. }
  203. if (Camera) {
  204. Camera->Release_Ref();
  205. Camera = NULL;
  206. }
  207. if (Light) {
  208. Light->Remove();
  209. Light->Release_Ref();
  210. Light = NULL;
  211. }
  212. if (Light2) {
  213. Light2->Remove();
  214. Light2->Release_Ref();
  215. Light2 = NULL;
  216. }
  217. WW3DAssetManager::Get_Instance()->Free_Assets();
  218. }
  219. void Time_Step(void)
  220. {
  221. if (Keyboard->Down(VK_UP)) {
  222. CameraDist = CameraDist * 0.9f;
  223. }
  224. if (Keyboard->Down(VK_DOWN)) {
  225. CameraDist = CameraDist * 1.1f;
  226. }
  227. if (Keyboard->Down(VK_LEFT)) {
  228. CameraDir -= (float)DEG_TO_RAD(10.0f);
  229. }
  230. if (Keyboard->Down(VK_RIGHT)) {
  231. CameraDir += (float)DEG_TO_RAD(10.0f);
  232. }
  233. Matrix3D camtm(1);
  234. camtm.Rotate_Z(CameraDir);
  235. camtm.Rotate_X(DEG_TO_RAD(35.0f));
  236. camtm.Translate(Vector3(0,0,CameraDist));
  237. Camera->Set_Transform(camtm);
  238. #ifdef SPIN_MODEL
  239. ModelOrientation = ModelOrientation * ModelRotation;
  240. ModelOrientation.Normalize();
  241. if (TestModel) TestModel->Set_Transform(Build_Matrix3D(ModelOrientation));
  242. #else
  243. if (TestModel) TestModel->Set_Transform(Matrix3D(1));
  244. #endif
  245. #ifdef SPIN_LIGHT
  246. LightOrientation = LightOrientation * LightRotation;
  247. LightOrientation.Normalize();
  248. Matrix3D ltm = Build_Matrix3D(LightOrientation);
  249. ltm.Translate(Vector3(5.0f,0.0f,0.0f));
  250. Light->Set_Transform(ltm);
  251. #endif
  252. #if 0
  253. MeshClass * mesh = NULL;
  254. static int _frame = 0;
  255. if (TestAnim) {
  256. _frame++;
  257. if (_frame >= TestAnim->Get_Num_Frames()) {
  258. _frame = 0;
  259. }
  260. TestModel->Set_Animation(TestAnim,_frame);
  261. } else {
  262. TestModel->Set_Animation();
  263. }
  264. #ifdef CAPTURE_BONE
  265. int boneid = TestModel->Get_Bone_Index("Head");
  266. if (boneid != -1) {
  267. static float r = 10.0f;
  268. static float theta = 0.0f;
  269. theta += 0.05f;
  270. Matrix3D tm(1);
  271. tm.Rotate_Z(theta);
  272. TestModel->Capture_Bone(boneid);
  273. TestModel->Control_Bone(boneid,tm);
  274. }
  275. #endif
  276. #ifdef SPIN_MODEL
  277. ModelOrientation = ModelOrientation * ModelRotation;
  278. ModelOrientation.Normalize();
  279. TestModel->Set_Transform(Build_Matrix3D(ModelOrientation));
  280. #else
  281. TestModel->Set_Transform(Matrix3D(1));
  282. #endif
  283. Matrix3D camtm(1);
  284. camtm.Rotate_X(DEG_TO_RAD(35.0f));
  285. camtm.Translate(0,0,20.0f);
  286. Camera->Set_Transform(camtm);
  287. camtm.Make_Identity();
  288. camtm.Translate(Vector3(0,0,20.0f));
  289. Camera->Set_Transform(camtm);
  290. Camera->Set_Viewport(Vector2(0,0),Vector2(320,200));
  291. Camera->Set_View_Plane(60.0f,4.0f/3.0f * 60.0f);
  292. Camera->Set_Clip_Planes(1.0f, 200.0f);
  293. Camera->Set_Environment_Range(1.0f, 200.0f);
  294. #ifdef SPIN_LIGHT
  295. LightOrientation = LightOrientation * LightRotation;
  296. LightOrientation.Normalize();
  297. Matrix3D ltm = Build_Matrix3D(LightOrientation);
  298. ltm.Translate(Vector3(5.0f,0.0f,0.0f));
  299. Light->Set_Transform(ltm);
  300. #endif
  301. #ifdef TEST_DAMAGE
  302. #define DAMAGE_RATE 0.03f;
  303. static float _dam_amt = 0.0f;
  304. static float _dam_chg = DAMAGE_RATE;
  305. _dam_amt += _dam_chg;
  306. if (_dam_amt >= 1.0f) {
  307. _dam_amt = 1.0f;
  308. _dam_chg = -DAMAGE_RATE;
  309. }
  310. if (_dam_amt <= 0.0f) {
  311. _dam_amt = 0.0f;
  312. _dam_chg = DAMAGE_RATE;
  313. }
  314. mesh = (MeshClass*)TestModel->Get_Sub_Object("Orca01");
  315. if (mesh) {
  316. mesh->Apply_Damage(0,_dam_amt);
  317. mesh->Release_Ref();
  318. }
  319. #endif
  320. #ifdef TEST_TEXTURE_ANIMATION
  321. mesh = (MeshClass*)TestModel->Get_Sub_Object("Box01");
  322. if (mesh) {
  323. MaterialInfoClass * matinfo = mesh->Get_Material_Info();
  324. if (matinfo) {
  325. MaterialClass * mtl = matinfo->Get_Material(0);
  326. if (mtl && (stricmp(mtl->Get_Name(),"Explosion Material") == 0)) {
  327. #if 1
  328. int curframe = mtl->Get_Channel_Anim_Frame(MaterialClass::DIFFUSE_COLOR);
  329. curframe = (curframe+1) % mtl->Get_Channel_Anim_Frame_Count(MaterialClass::DIFFUSE_COLOR);
  330. mtl->Set_Channel_Anim_Frame(MaterialClass::DIFFUSE_COLOR,curframe);
  331. #else
  332. TextureClass * tex = mtl->Get_Channel_Texture(MaterialClass::DIFFUSE_COLOR);
  333. assert(tex);
  334. int curframe = tex->Get_Anim_Frame();
  335. curframe = (curframe+1) % tex->Get_Num_Frames();
  336. tex->Set_Anim_Frame(curframe);
  337. //tex->invalidate();
  338. tex->Release_Ref();
  339. #endif
  340. }
  341. matinfo->Release_Ref();
  342. matinfo = NULL;
  343. if (mtl) mtl->Release_Ref();
  344. }
  345. mesh->Release_Ref();
  346. }
  347. #endif
  348. #endif
  349. }
  350. void Init_Debug(void)
  351. {
  352. /*
  353. ** Install message handler functions for the WWDebug messages
  354. ** and assertion failures.
  355. */
  356. WWDebug_Install_Message_Handler(wwdebug_message_handler);
  357. WWDebug_Install_Assert_Handler(wwdebug_assert_handler);
  358. WWDebug_Install_Trigger_Handler(wwdebug_trigger_handler);
  359. }
  360. void Shutdown_Debug(void)
  361. {
  362. /*
  363. ** Remove message handler functions for the WWDebug messages
  364. ** and assertion failures.
  365. */
  366. WWDebug_Install_Message_Handler(NULL);
  367. WWDebug_Install_Assert_Handler(NULL);
  368. WWDebug_Install_Trigger_Handler(NULL);
  369. }
  370. void wwdebug_message_handler(const char * message)
  371. {
  372. /*
  373. ** Hand the message off to the scrolling debug screen
  374. */
  375. // Debug_Say((message));
  376. }
  377. void wwdebug_assert_handler(const char * message)
  378. {
  379. /*
  380. ** Hand the message off to the scrolling debug screen
  381. */
  382. // Debug_Say((message));
  383. /*
  384. ** break into the debugger
  385. */
  386. _asm int 0x03;
  387. }
  388. bool wwdebug_trigger_handler(int trigger_num)
  389. {
  390. return Keyboard->Down(trigger_num);
  391. }
  392. void Debug_Refs(void)
  393. {
  394. #ifndef NDEBUG
  395. char buf[1024];
  396. if (RefCountClass::Total_Refs() != 0) {
  397. sprintf(buf,"Main Loop End %d refs\n", RefCountClass::Total_Refs() );
  398. MessageBox(NULL,buf,"Ref Debugging",MB_OK);
  399. }
  400. RefBaseNodeClass * node = RefBaseClass::ActiveRefList.First();
  401. while (node->Is_Valid())
  402. {
  403. RefBaseClass * obj = node->Get();
  404. ActiveRefStruct * ref = &(obj->ActiveRefInfo);
  405. sprintf(buf,"Active Ref: %s\nLine: %d\nPointer %p\n", ref->File,ref->Line,obj);
  406. if (MessageBox(NULL,buf,"Ref Debugging",MB_OKCANCEL) == IDCANCEL) {
  407. break;
  408. }
  409. node = node->Next();
  410. }
  411. #endif
  412. }