| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273 |
- /*
- ** Command & Conquer Generals Zero Hour(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- ////////////////////////////////////////////////////////////////////////////////
- // //
- // (c) 2001-2003 Electronic Arts Inc. //
- // //
- ////////////////////////////////////////////////////////////////////////////////
- #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
- #include "Common/CRCDebug.h"
- #include "Common/Debug.h"
- #include "Common/PerfTimer.h"
- #include "GameClient/InGameUI.h"
- #include "GameNetwork/IPEnumeration.h"
- #include <cstdarg>
- #ifdef _INTERNAL
- // for occasional debugging...
- //#pragma optimize("", off)
- //#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
- #endif
- #ifdef DEBUG_CRC
- static const Int MaxStrings = 64000;
- static char DebugStrings[MaxStrings][1024];
- static Int nextDebugString = 0;
- static Int numDebugStrings = 0;
- //static char DumpStrings[MaxStrings][1024];
- //static Int nextDumpString = 0;
- //static Int numDumpStrings = 0;
- #define IS_FRAME_OK_TO_LOG TheGameLogic->isInGame() && !TheGameLogic->isInShellGame() && !TheDebugIgnoreSyncErrors && \
- TheCRCFirstFrameToLog >= 0 && TheCRCFirstFrameToLog <= TheGameLogic->getFrame() \
- && TheGameLogic->getFrame() <= TheCRCLastFrameToLog
- CRCVerification::CRCVerification()
- {
- #ifdef DEBUG_LOGGING
- /**/
- if (g_verifyClientCRC && (IS_FRAME_OK_TO_LOG))
- {
- m_startCRC = TheGameLogic->getCRC(CRC_RECALC, (g_clientDeepCRC)?"clientPre.crc":"");
- }
- else
- {
- m_startCRC = 0;
- }
- /**/
- #endif
- }
- CRCVerification::~CRCVerification()
- {
- #ifdef DEBUG_LOGGING
- /**/
- UnsignedInt endCRC = 0;
- if (g_verifyClientCRC && (IS_FRAME_OK_TO_LOG))
- {
- endCRC = TheGameLogic->getCRC(CRC_RECALC, (g_clientDeepCRC)?"clientPost.crc":"");
- }
- DEBUG_ASSERTCRASH(!TheGameLogic->isInGame() || m_startCRC == endCRC, ("GameLogic changed outside of GameLogic::update() on frame %d!", TheGameLogic->getFrame()));
- if (TheGameLogic->isInMultiplayerGame() && m_startCRC != endCRC)
- {
- if (TheInGameUI)
- {
- TheInGameUI->message(UnicodeString(L"GameLogic changed outside of GameLogic::update() - call Matt (x36804)!"));
- }
- CRCDEBUG_LOG(("GameLogic changed outside of GameLogic::update()!!!\n"));
- }
- /**/
- #endif
- }
- static Bool dumped = FALSE;
- void outputCRCDebugLines( void )
- {
- if (dumped)
- return;
- dumped = TRUE;
- IPEnumeration ips;
- AsciiString fname;
- fname.format("crcDebug%s.txt", ips.getMachineName().str());
- FILE *fp = fopen(fname.str(), "wt");
- int start = 0;
- int end = nextDebugString;
- if (numDebugStrings >= MaxStrings)
- start = nextDebugString - MaxStrings;
- for (Int i=start; i<end; ++i)
- {
- const char *line = DebugStrings[ (i + MaxStrings) % MaxStrings ];
- DEBUG_LOG(("%s\n", line));
- if (fp) fprintf(fp, "%s\n", line);
- }
- if (fp) fclose(fp);
- }
- void outputCRCDumpLines( void )
- {
- /*
- int start = 0;
- int end = nextDumpString;
- if (numDumpStrings >= MaxStrings)
- start = nextDumpString - MaxStrings;
- for (Int i=start; i<end; ++i)
- {
- const char *line = DumpStrings[ (i + MaxStrings) % MaxStrings ];
- DEBUG_LOG(("%s", line));
- }
- */
- }
- static AsciiString getFname(AsciiString path)
- {
- return path.reverseFind('\\') + 1;
- }
- Int lastCRCDebugFrame = 0;
- Int lastCRCDebugIndex = 0;
- extern Bool inCRCGen;
- void addCRCDebugLine(const char *fmt, ...)
- {
- if (dumped)// || inCRCGen /*|| !TheGameLogic->isInGameLogicUpdate()*/)
- return;
- if (IS_FRAME_OK_TO_LOG)
- {
- if (lastCRCDebugFrame != TheGameLogic->getFrame())
- {
- lastCRCDebugFrame = TheGameLogic->getFrame();
- lastCRCDebugIndex = 0;
- }
- sprintf(DebugStrings[nextDebugString], "%d:%d ", TheGameLogic->getFrame(), lastCRCDebugIndex++);
- //DebugStrings[nextDebugString][0] = 0;
- Int len = strlen(DebugStrings[nextDebugString]);
- va_list va;
- va_start( va, fmt );
- _vsnprintf(DebugStrings[nextDebugString]+len, 1024-len, fmt, va );
- DebugStrings[nextDebugString][1023] = 0;
- va_end( va );
- char *tmp = DebugStrings[nextDebugString];
- while (tmp && *tmp)
- {
- if (*tmp == '\r' || *tmp == '\n')
- {
- *tmp = ' ';
- }
- ++tmp;
- }
- //DEBUG_LOG(("%s\n", DebugStrings[nextDebugString]));
- ++nextDebugString;
- ++numDebugStrings;
- if (nextDebugString == MaxStrings)
- nextDebugString = 0;
- }
- }
- void addCRCGenLine(const char *fmt, ...)
- {
- if (dumped || !(IS_FRAME_OK_TO_LOG))
- return;
- static char buf[1024];
- va_list va;
- va_start( va, fmt );
- _vsnprintf(buf, 1024, fmt, va );
- va_end( va );
- buf[1023] = 0;
- addCRCDebugLine("%s", buf);
- //DEBUG_LOG(("%s", buf));
- }
- void addCRCDumpLine(const char *fmt, ...)
- {
- /*
- va_list va;
- va_start( va, fmt );
- _vsnprintf(DumpStrings[nextDumpString], 1024, fmt, va );
- DumpStrings[nextDumpString][1023] = 0;
- va_end( va );
- ++nextDumpString;
- ++numDumpStrings;
- if (nextDumpString == MaxStrings)
- nextDumpString = 0;
- */
- }
- void dumpVector3(const Vector3 *v, AsciiString name, AsciiString fname, Int line)
- {
- if (dumped)
- return;
- if (!(IS_FRAME_OK_TO_LOG)) return;
- fname.toLower();
- fname = getFname(fname);
- addCRCDebugLine("dumpVector3() %s:%d %s %8.8X %8.8X %8.8X\n",
- fname.str(), line, name.str(),
- AS_INT(v->X), AS_INT(v->Y), AS_INT(v->Z));
- }
- void dumpCoord3D(const Coord3D *c, AsciiString name, AsciiString fname, Int line)
- {
- if (dumped)
- return;
- if (!(IS_FRAME_OK_TO_LOG)) return;
- fname.toLower();
- fname = getFname(fname);
- addCRCDebugLine("dumpCoord3D() %s:%d %s %8.8X %8.8X %8.8X\n",
- fname.str(), line, name.str(),
- AS_INT(c->x), AS_INT(c->y), AS_INT(c->z));
- }
- void dumpMatrix3D(const Matrix3D *m, AsciiString name, AsciiString fname, Int line)
- {
- if (dumped)
- return;
- if (!(IS_FRAME_OK_TO_LOG)) return;
- fname.toLower();
- fname = getFname(fname);
- const Real *matrix = (const Real *)m;
- addCRCDebugLine("dumpMatrix3D() %s:%d %s\n",
- fname.str(), line, name.str());
- for (Int i=0; i<3; ++i)
- addCRCDebugLine(" 0x%08X 0x%08X 0x%08X 0x%08X\n",
- AS_INT(matrix[(i<<2)+0]), AS_INT(matrix[(i<<2)+1]), AS_INT(matrix[(i<<2)+2]), AS_INT(matrix[(i<<2)+3]));
- }
- void dumpReal(Real r, AsciiString name, AsciiString fname, Int line)
- {
- if (dumped)
- return;
- if (!(IS_FRAME_OK_TO_LOG)) return;
- fname.toLower();
- fname = getFname(fname);
- addCRCDebugLine("dumpReal() %s:%d %s %8.8X (%f)\n",
- fname.str(), line, name.str(), AS_INT(r), r);
- }
- #endif // DEBUG_CRC
|