wwdebug.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521
  1. /*
  2. ** Command & Conquer Generals Zero Hour(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. #if 0 //(gth) this is giving me link errors for some reason...
  293. #ifndef W3D_MAX4
  294. #ifdef WWDEBUG
  295. void __cdecl _assert(void *expr, void *filename, unsigned lineno)
  296. {
  297. WWDebug_Assert_Fail((const char*)expr, (const char*)filename, lineno);
  298. }
  299. #endif //WWDEBUG
  300. #endif
  301. #endif
  302. /***********************************************************************************************
  303. * WWDebug_Assert_Fail_Print -- Internal function, passes assert message to handler *
  304. * *
  305. * INPUT: *
  306. * *
  307. * OUTPUT: *
  308. * *
  309. * WARNINGS: *
  310. * *
  311. * HISTORY: *
  312. * 2/19/98 GTH : Created. *
  313. *=============================================================================================*/
  314. #ifdef WWDEBUG
  315. void WWDebug_Assert_Fail_Print(const char * expr,const char * file, int line,const char * string)
  316. {
  317. if (_CurAssertHandler != NULL) {
  318. char buffer[4096];
  319. sprintf(buffer,"%s (%d) Assert: %s %s\n",file,line,expr, string);
  320. _CurAssertHandler(buffer);
  321. } else {
  322. assert(0);
  323. }
  324. }
  325. #endif
  326. /***********************************************************************************************
  327. * WWDebug_Check_Trigger -- calls the user-installed debug trigger handler *
  328. * *
  329. * INPUT: *
  330. * *
  331. * OUTPUT: *
  332. * *
  333. * WARNINGS: *
  334. * *
  335. * HISTORY: *
  336. * 2/24/98 GTH : Created. *
  337. *=============================================================================================*/
  338. bool WWDebug_Check_Trigger(int trigger_num)
  339. {
  340. if (_CurTriggerHandler != NULL) {
  341. return _CurTriggerHandler(trigger_num);
  342. } else {
  343. return false;
  344. }
  345. }
  346. /***********************************************************************************************
  347. * WWDebug_Profile_Start -- calls the user-installed profile start handler *
  348. * *
  349. * INPUT: *
  350. * *
  351. * OUTPUT: *
  352. * *
  353. * WARNINGS: *
  354. * *
  355. * HISTORY: *
  356. * 2/24/98 GTH : Created. *
  357. *=============================================================================================*/
  358. void WWDebug_Profile_Start( const char * title)
  359. {
  360. if (_CurProfileStartHandler != NULL) {
  361. _CurProfileStartHandler( title );
  362. }
  363. }
  364. /***********************************************************************************************
  365. * WWDebug_Profile_Stop -- calls the user-installed profile start handler *
  366. * *
  367. * INPUT: *
  368. * *
  369. * OUTPUT: *
  370. * *
  371. * WARNINGS: *
  372. * *
  373. * HISTORY: *
  374. * 2/24/98 GTH : Created. *
  375. *=============================================================================================*/
  376. void WWDebug_Profile_Stop( const char * title)
  377. {
  378. if (_CurProfileStopHandler != NULL) {
  379. _CurProfileStopHandler( title );
  380. }
  381. }
  382. #ifdef WWDEBUG
  383. /***********************************************************************************************
  384. * WWDebug_DBWin32_Message_Handler -- *
  385. * *
  386. * INPUT: *
  387. * *
  388. * OUTPUT: *
  389. * *
  390. * WARNINGS: *
  391. * *
  392. * HISTORY: *
  393. * 10/30/98 BMG : Created. *
  394. *=============================================================================================*/
  395. void WWDebug_DBWin32_Message_Handler( const char * str )
  396. {
  397. HANDLE heventDBWIN; /* DBWIN32 synchronization object */
  398. HANDLE heventData; /* data passing synch object */
  399. HANDLE hSharedFile; /* memory mapped file shared data */
  400. LPSTR lpszSharedMem;
  401. /* make sure DBWIN is open and waiting */
  402. heventDBWIN = OpenEvent(EVENT_MODIFY_STATE, FALSE, "DBWIN_BUFFER_READY");
  403. if ( !heventDBWIN )
  404. {
  405. //MessageBox(NULL, "DBWIN_BUFFER_READY nonexistent", NULL, MB_OK);
  406. return;
  407. }
  408. /* get a handle to the data synch object */
  409. heventData = OpenEvent(EVENT_MODIFY_STATE, FALSE, "DBWIN_DATA_READY");
  410. if ( !heventData )
  411. {
  412. // MessageBox(NULL, "DBWIN_DATA_READY nonexistent", NULL, MB_OK);
  413. CloseHandle(heventDBWIN);
  414. return;
  415. }
  416. hSharedFile = CreateFileMapping((HANDLE)-1, NULL, PAGE_READWRITE, 0, 4096, "DBWIN_BUFFER");
  417. if (!hSharedFile)
  418. {
  419. //MessageBox(NULL, "DebugTrace: Unable to create file mapping object DBWIN_BUFFER", "Error", MB_OK);
  420. CloseHandle(heventDBWIN);
  421. CloseHandle(heventData);
  422. return;
  423. }
  424. lpszSharedMem = (LPSTR)MapViewOfFile(hSharedFile, FILE_MAP_WRITE, 0, 0, 512);
  425. if (!lpszSharedMem)
  426. {
  427. //MessageBox(NULL, "DebugTrace: Unable to map shared memory", "Error", MB_OK);
  428. CloseHandle(heventDBWIN);
  429. CloseHandle(heventData);
  430. return;
  431. }
  432. /* wait for buffer event */
  433. WaitForSingleObject(heventDBWIN, INFINITE);
  434. /* write it to the shared memory */
  435. *((LPDWORD)lpszSharedMem) = 0;
  436. wsprintf(lpszSharedMem + sizeof(DWORD), "%s", str);
  437. /* signal data ready event */
  438. SetEvent(heventData);
  439. /* clean up handles */
  440. CloseHandle(hSharedFile);
  441. CloseHandle(heventData);
  442. CloseHandle(heventDBWIN);
  443. return;
  444. }
  445. #endif // WWDEBUG