wwdebug.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  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. /***********************************************************************************************
  19. *** 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 ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : WWDebug *
  23. * *
  24. * $Archive:: /Commando/Code/wwdebug/wwdebug.cpp $*
  25. * *
  26. * $Author:: Greg_h $*
  27. * *
  28. * $Modtime:: 1/13/02 1:46p $*
  29. * *
  30. * $Revision:: 16 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * WWDebug_Install_Message_Handler -- install function for handling the debug messages *
  35. * WWDebug_Install_Assert_Handler -- Install a function for handling the assert messages *
  36. * WWDebug_Install_Trigger_Handler -- install a trigger handler function *
  37. * WWDebug_Printf -- Internal function for passing messages to installed handler *
  38. * WWDebug_Assert_Fail -- Internal function for passing assert messages to installed handler *
  39. * WWDebug_Assert_Fail_Print -- Internal function, passes assert message to handler *
  40. * WWDebug_Check_Trigger -- calls the user-installed debug trigger handler *
  41. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  42. #include "wwdebug.h"
  43. #include <windows.h>
  44. //#include "win.h" can use this if allowed to see wwlib
  45. #include <stdlib.h>
  46. #include <stdarg.h>
  47. #include <stdio.h>
  48. #include <assert.h>
  49. #include <string.h>
  50. #include <signal.h>
  51. #include "except.h"
  52. static PrintFunc _CurMessageHandler = NULL;
  53. static AssertPrintFunc _CurAssertHandler = NULL;
  54. static TriggerFunc _CurTriggerHandler = NULL;
  55. static ProfileFunc _CurProfileStartHandler = NULL;
  56. static ProfileFunc _CurProfileStopHandler = NULL;
  57. // Convert the latest system error into a string and return a pointer to
  58. // a static buffer containing the error string.
  59. void Convert_System_Error_To_String(int id, char* buffer, int buf_len)
  60. {
  61. #ifndef _UNIX
  62. FormatMessage(
  63. FORMAT_MESSAGE_FROM_SYSTEM,
  64. NULL,
  65. id,
  66. 0,
  67. buffer,
  68. buf_len,
  69. NULL);
  70. #endif
  71. }
  72. int Get_Last_System_Error()
  73. {
  74. return GetLastError();
  75. }
  76. /***********************************************************************************************
  77. * WWDebug_Install_Message_Handler -- install function for handling the debug messages *
  78. * *
  79. * INPUT: *
  80. * *
  81. * OUTPUT: *
  82. * *
  83. * WARNINGS: *
  84. * *
  85. * HISTORY: *
  86. * 2/19/98 GTH : Created. *
  87. *=============================================================================================*/
  88. PrintFunc WWDebug_Install_Message_Handler(PrintFunc func)
  89. {
  90. PrintFunc tmp = _CurMessageHandler;
  91. _CurMessageHandler = func;
  92. return tmp;
  93. }
  94. /***********************************************************************************************
  95. * WWDebug_Install_Assert_Handler -- Install a function for handling the assert messages *
  96. * *
  97. * INPUT: *
  98. * *
  99. * OUTPUT: *
  100. * *
  101. * WARNINGS: *
  102. * *
  103. * HISTORY: *
  104. * 2/19/98 GTH : Created. *
  105. *=============================================================================================*/
  106. AssertPrintFunc WWDebug_Install_Assert_Handler(AssertPrintFunc func)
  107. {
  108. AssertPrintFunc tmp = _CurAssertHandler;
  109. _CurAssertHandler = func;
  110. return tmp;
  111. }
  112. /***********************************************************************************************
  113. * WWDebug_Install_Trigger_Handler -- install a trigger handler function *
  114. * *
  115. * INPUT: *
  116. * *
  117. * OUTPUT: *
  118. * *
  119. * WARNINGS: *
  120. * *
  121. * HISTORY: *
  122. * 2/24/98 GTH : Created. *
  123. *=============================================================================================*/
  124. TriggerFunc WWDebug_Install_Trigger_Handler(TriggerFunc func)
  125. {
  126. TriggerFunc tmp = _CurTriggerHandler;
  127. _CurTriggerHandler = func;
  128. return tmp;
  129. }
  130. /***********************************************************************************************
  131. * WWDebug_Install_Profile_Start_Handler -- install a profile handler function *
  132. * *
  133. * INPUT: *
  134. * *
  135. * OUTPUT: *
  136. * *
  137. * WARNINGS: *
  138. * *
  139. * HISTORY: *
  140. * 2/24/98 GTH : Created. *
  141. *=============================================================================================*/
  142. ProfileFunc WWDebug_Install_Profile_Start_Handler(ProfileFunc func)
  143. {
  144. ProfileFunc tmp = _CurProfileStartHandler;
  145. _CurProfileStartHandler = func;
  146. return tmp;
  147. }
  148. /***********************************************************************************************
  149. * WWDebug_Install_Profile_Stop_Handler -- install a profile handler function *
  150. * *
  151. * INPUT: *
  152. * *
  153. * OUTPUT: *
  154. * *
  155. * WARNINGS: *
  156. * *
  157. * HISTORY: *
  158. * 2/24/98 GTH : Created. *
  159. *=============================================================================================*/
  160. ProfileFunc WWDebug_Install_Profile_Stop_Handler(ProfileFunc func)
  161. {
  162. ProfileFunc tmp = _CurProfileStopHandler;
  163. _CurProfileStopHandler = func;
  164. return tmp;
  165. }
  166. /***********************************************************************************************
  167. * WWDebug_Printf -- Internal function for passing messages to installed handler *
  168. * *
  169. * INPUT: *
  170. * *
  171. * OUTPUT: *
  172. * *
  173. * WARNINGS: *
  174. * *
  175. * HISTORY: *
  176. * 2/19/98 GTH : Created. *
  177. *=============================================================================================*/
  178. void WWDebug_Printf(const char * format,...)
  179. {
  180. if (_CurMessageHandler != NULL) {
  181. va_list va;
  182. char buffer[4096];
  183. va_start(va, format);
  184. vsprintf(buffer, format, va);
  185. WWASSERT((strlen(buffer) < sizeof(buffer)));
  186. _CurMessageHandler(WWDEBUG_TYPE_INFORMATION, buffer);
  187. va_end(va);
  188. }
  189. }
  190. /***********************************************************************************************
  191. * WWDebug_Printf_Warning -- Internal function for passing messages to installed handler *
  192. * *
  193. * INPUT: *
  194. * *
  195. * OUTPUT: *
  196. * *
  197. * WARNINGS: *
  198. * *
  199. * HISTORY: *
  200. * 2/19/98 GTH : Created. *
  201. *=============================================================================================*/
  202. void WWDebug_Printf_Warning(const char * format,...)
  203. {
  204. if (_CurMessageHandler != NULL) {
  205. va_list va;
  206. char buffer[4096];
  207. va_start(va, format);
  208. vsprintf(buffer, format, va);
  209. WWASSERT((strlen(buffer) < sizeof(buffer)));
  210. _CurMessageHandler(WWDEBUG_TYPE_WARNING, buffer);
  211. va_end(va);
  212. }
  213. }
  214. /***********************************************************************************************
  215. * WWDebug_Printf_Error -- Internal function for passing messages to installed handler *
  216. * *
  217. * INPUT: *
  218. * *
  219. * OUTPUT: *
  220. * *
  221. * WARNINGS: *
  222. * *
  223. * HISTORY: *
  224. * 2/19/98 GTH : Created. *
  225. *=============================================================================================*/
  226. void WWDebug_Printf_Error(const char * format,...)
  227. {
  228. if (_CurMessageHandler != NULL) {
  229. va_list va;
  230. char buffer[4096];
  231. va_start(va, format);
  232. vsprintf(buffer, format, va);
  233. WWASSERT((strlen(buffer) < sizeof(buffer)));
  234. _CurMessageHandler(WWDEBUG_TYPE_ERROR, buffer);
  235. va_end(va);
  236. }
  237. }
  238. /***********************************************************************************************
  239. * WWDebug_Assert_Fail -- Internal function for passing assert messages to installed handler *
  240. * *
  241. * INPUT: *
  242. * *
  243. * OUTPUT: *
  244. * *
  245. * WARNINGS: *
  246. * *
  247. * HISTORY: *
  248. * 2/19/98 GTH : Created. *
  249. *=============================================================================================*/
  250. #ifdef WWDEBUG
  251. void WWDebug_Assert_Fail(const char * expr,const char * file, int line)
  252. {
  253. if (_CurAssertHandler != NULL) {
  254. char buffer[4096];
  255. sprintf(buffer,"%s (%d) Assert: %s\n",file,line,expr);
  256. _CurAssertHandler(buffer);
  257. } else {
  258. /*
  259. // If the exception handler is try to quit the game then don't show an assert.
  260. */
  261. if (Is_Trying_To_Exit()) {
  262. ExitProcess(0);
  263. }
  264. char assertbuf[4096];
  265. sprintf(assertbuf, "Assert failed\n\n. File %s Line %d", file, line);
  266. int code = MessageBoxA(NULL, assertbuf, "WWDebug_Assert_Fail", MB_ABORTRETRYIGNORE|MB_ICONHAND|MB_SETFOREGROUND|MB_TASKMODAL);
  267. if (code == IDABORT) {
  268. raise(SIGABRT);
  269. _exit(3);
  270. }
  271. if (code == IDRETRY) {
  272. _asm int 3;
  273. return;
  274. }
  275. }
  276. }
  277. #endif
  278. /***********************************************************************************************
  279. * _assert -- Catch all asserts by overriding lib function *
  280. * *
  281. * *
  282. * *
  283. * INPUT: Assert stuff *
  284. * *
  285. * OUTPUT: Nothing *
  286. * *
  287. * WARNINGS: None *
  288. * *
  289. * HISTORY: *
  290. * 12/11/2001 3:56PM ST : Created *
  291. *=============================================================================================*/
  292. #ifdef WWDEBUG
  293. void __cdecl _assert(void *expr, void *filename, unsigned lineno)
  294. {
  295. WWDebug_Assert_Fail((const char*)expr, (const char*)filename, lineno);
  296. }
  297. #endif //WWDEBUG
  298. /***********************************************************************************************
  299. * WWDebug_Assert_Fail_Print -- Internal function, passes assert message to handler *
  300. * *
  301. * INPUT: *
  302. * *
  303. * OUTPUT: *
  304. * *
  305. * WARNINGS: *
  306. * *
  307. * HISTORY: *
  308. * 2/19/98 GTH : Created. *
  309. *=============================================================================================*/
  310. #ifdef WWDEBUG
  311. void WWDebug_Assert_Fail_Print(const char * expr,const char * file, int line,const char * string)
  312. {
  313. if (_CurAssertHandler != NULL) {
  314. char buffer[4096];
  315. sprintf(buffer,"%s (%d) Assert: %s %s\n",file,line,expr, string);
  316. _CurAssertHandler(buffer);
  317. } else {
  318. assert(0);
  319. }
  320. }
  321. #endif
  322. /***********************************************************************************************
  323. * WWDebug_Check_Trigger -- calls the user-installed debug trigger handler *
  324. * *
  325. * INPUT: *
  326. * *
  327. * OUTPUT: *
  328. * *
  329. * WARNINGS: *
  330. * *
  331. * HISTORY: *
  332. * 2/24/98 GTH : Created. *
  333. *=============================================================================================*/
  334. bool WWDebug_Check_Trigger(int trigger_num)
  335. {
  336. if (_CurTriggerHandler != NULL) {
  337. return _CurTriggerHandler(trigger_num);
  338. } else {
  339. return false;
  340. }
  341. }
  342. /***********************************************************************************************
  343. * WWDebug_Profile_Start -- calls the user-installed profile start handler *
  344. * *
  345. * INPUT: *
  346. * *
  347. * OUTPUT: *
  348. * *
  349. * WARNINGS: *
  350. * *
  351. * HISTORY: *
  352. * 2/24/98 GTH : Created. *
  353. *=============================================================================================*/
  354. void WWDebug_Profile_Start( const char * title)
  355. {
  356. if (_CurProfileStartHandler != NULL) {
  357. _CurProfileStartHandler( title );
  358. }
  359. }
  360. /***********************************************************************************************
  361. * WWDebug_Profile_Stop -- calls the user-installed profile start handler *
  362. * *
  363. * INPUT: *
  364. * *
  365. * OUTPUT: *
  366. * *
  367. * WARNINGS: *
  368. * *
  369. * HISTORY: *
  370. * 2/24/98 GTH : Created. *
  371. *=============================================================================================*/
  372. void WWDebug_Profile_Stop( const char * title)
  373. {
  374. if (_CurProfileStopHandler != NULL) {
  375. _CurProfileStopHandler( title );
  376. }
  377. }
  378. #ifdef WWDEBUG
  379. /***********************************************************************************************
  380. * WWDebug_DBWin32_Message_Handler -- *
  381. * *
  382. * INPUT: *
  383. * *
  384. * OUTPUT: *
  385. * *
  386. * WARNINGS: *
  387. * *
  388. * HISTORY: *
  389. * 10/30/98 BMG : Created. *
  390. *=============================================================================================*/
  391. void WWDebug_DBWin32_Message_Handler( const char * str )
  392. {
  393. HANDLE heventDBWIN; /* DBWIN32 synchronization object */
  394. HANDLE heventData; /* data passing synch object */
  395. HANDLE hSharedFile; /* memory mapped file shared data */
  396. LPSTR lpszSharedMem;
  397. /* make sure DBWIN is open and waiting */
  398. heventDBWIN = OpenEvent(EVENT_MODIFY_STATE, FALSE, "DBWIN_BUFFER_READY");
  399. if ( !heventDBWIN )
  400. {
  401. //MessageBox(NULL, "DBWIN_BUFFER_READY nonexistent", NULL, MB_OK);
  402. return;
  403. }
  404. /* get a handle to the data synch object */
  405. heventData = OpenEvent(EVENT_MODIFY_STATE, FALSE, "DBWIN_DATA_READY");
  406. if ( !heventData )
  407. {
  408. // MessageBox(NULL, "DBWIN_DATA_READY nonexistent", NULL, MB_OK);
  409. CloseHandle(heventDBWIN);
  410. return;
  411. }
  412. hSharedFile = CreateFileMapping((HANDLE)-1, NULL, PAGE_READWRITE, 0, 4096, "DBWIN_BUFFER");
  413. if (!hSharedFile)
  414. {
  415. //MessageBox(NULL, "DebugTrace: Unable to create file mapping object DBWIN_BUFFER", "Error", MB_OK);
  416. CloseHandle(heventDBWIN);
  417. CloseHandle(heventData);
  418. return;
  419. }
  420. lpszSharedMem = (LPSTR)MapViewOfFile(hSharedFile, FILE_MAP_WRITE, 0, 0, 512);
  421. if (!lpszSharedMem)
  422. {
  423. //MessageBox(NULL, "DebugTrace: Unable to map shared memory", "Error", MB_OK);
  424. CloseHandle(heventDBWIN);
  425. CloseHandle(heventData);
  426. return;
  427. }
  428. /* wait for buffer event */
  429. WaitForSingleObject(heventDBWIN, INFINITE);
  430. /* write it to the shared memory */
  431. *((LPDWORD)lpszSharedMem) = 0;
  432. wsprintf(lpszSharedMem + sizeof(DWORD), "%s", str);
  433. /* signal data ready event */
  434. SetEvent(heventData);
  435. /* clean up handles */
  436. CloseHandle(hSharedFile);
  437. CloseHandle(heventData);
  438. CloseHandle(heventDBWIN);
  439. return;
  440. }
  441. #endif // WWDEBUG