Initial commit of Command & Conquer Generals and Command & Conquer Generals Zero Hour source code.
This commit is contained in:
parent
2e338c00cb
commit
3d0ee53a05
6072 changed files with 2283311 additions and 0 deletions
367
Generals/Code/Tools/CRCDiff/CRCDiff.cpp
Normal file
367
Generals/Code/Tools/CRCDiff/CRCDiff.cpp
Normal file
|
@ -0,0 +1,367 @@
|
|||
/*
|
||||
** Command & Conquer Generals(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/>.
|
||||
*/
|
||||
|
||||
#include "debug.h"
|
||||
#include "expander.h"
|
||||
#include "KVPair.h"
|
||||
#include "misc.h"
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
//=============================================================================
|
||||
|
||||
std::string tableRow;
|
||||
|
||||
//=============================================================================
|
||||
|
||||
static void exitWait(void)
|
||||
{
|
||||
system("PAUSE");
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
#define LINESIZE 1024
|
||||
static bool getNextLine(FILE *fp, char *line, int& frame, int& index) {
|
||||
if (!fp)
|
||||
return false;
|
||||
|
||||
char buf[LINESIZE];
|
||||
while (fgets(buf, LINESIZE-1, fp) != NULL)
|
||||
{
|
||||
int len = strlen(buf);
|
||||
if (buf[len-1] == '\n')
|
||||
buf[len-1] = '\0';
|
||||
if (sscanf(buf, "%d:%d ", &frame, &index) == 2)
|
||||
{
|
||||
strcpy(line, buf);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
static std::string readInFile(const char *fname) {
|
||||
FILE *fp = fopen(fname, "rt");
|
||||
if (!fp)
|
||||
return "";
|
||||
|
||||
std::string ret;
|
||||
char buf[LINESIZE];
|
||||
while (fgets(buf, LINESIZE-1, fp) != NULL)
|
||||
{
|
||||
ret.append(buf);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
static FILE *ofp = NULL;
|
||||
|
||||
void dumpQueued(void);
|
||||
|
||||
static void outputLine(const char *line)
|
||||
{
|
||||
dumpQueued();
|
||||
//cout << line << endl;
|
||||
if (ofp)
|
||||
{
|
||||
fputs(line, ofp);
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
static void outputLine(int frame, int index, int linkNum,
|
||||
const char *class1, const char *line1,
|
||||
const char *class2, const char *line2, bool same = false)
|
||||
{
|
||||
dumpQueued();
|
||||
if (!line1)
|
||||
line1 = " ";
|
||||
if (!line2)
|
||||
line2 = " ";
|
||||
if (!class1)
|
||||
class1 = "";
|
||||
if (!class2)
|
||||
class2 = "";
|
||||
|
||||
Expander e("((", "))");
|
||||
e.addExpansion("LEFTCLASS", class1);
|
||||
e.addExpansion("LEFTLINE", line1);
|
||||
e.addExpansion("RIGHTCLASS", class2);
|
||||
e.addExpansion("RIGHTLINE", line2);
|
||||
if (same)
|
||||
{
|
||||
e.addExpansion("NAME", "");
|
||||
e.addExpansion("PREV", intToString(linkNum-1));
|
||||
e.addExpansion("NEXT", intToString(linkNum));
|
||||
}
|
||||
else
|
||||
{
|
||||
e.addExpansion("NAME", intToString(linkNum));
|
||||
e.addExpansion("PREV", intToString(linkNum-1));
|
||||
e.addExpansion("NEXT", intToString(linkNum+1));
|
||||
}
|
||||
|
||||
std::string out;
|
||||
e.expand(tableRow, out);
|
||||
const char *buf = out.c_str();
|
||||
|
||||
//cout << buf << endl;
|
||||
if (ofp)
|
||||
{
|
||||
fputs(buf, ofp);
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
std::list<std::string> queuedLines;
|
||||
static void queueLine(int frame, int index, const char *line1)
|
||||
{
|
||||
if (!line1)
|
||||
line1 = " ";
|
||||
|
||||
Expander e("((", "))");
|
||||
e.addExpansion("LEFTCLASS", "leftHistory");
|
||||
e.addExpansion("LEFTLINE", line1);
|
||||
e.addExpansion("RIGHTCLASS", "rightHistory");
|
||||
e.addExpansion("RIGHTLINE", line1);
|
||||
e.addExpansion("NAME", "");
|
||||
e.addExpansion("PREV", intToString(0));
|
||||
e.addExpansion("NEXT", intToString(1));
|
||||
|
||||
std::string out;
|
||||
e.expand(tableRow, out);
|
||||
|
||||
queuedLines.push_back(out);
|
||||
if (queuedLines.size() > 150)
|
||||
queuedLines.pop_front();
|
||||
|
||||
//cout << buf << endl;
|
||||
}
|
||||
|
||||
void dumpQueued(void)
|
||||
{
|
||||
while (!queuedLines.empty())
|
||||
{
|
||||
std::list<std::string>::iterator it = queuedLines.begin();
|
||||
const char *buf = (*it).c_str();
|
||||
//cout << buf << endl;
|
||||
if (ofp)
|
||||
{
|
||||
fputs(buf, ofp);
|
||||
}
|
||||
|
||||
queuedLines.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
atexit(exitWait);
|
||||
const char *inFname[2];
|
||||
const char *outFname = "out.html";
|
||||
FILE *ifp[2] = {NULL, NULL};
|
||||
std::string header, footer;
|
||||
|
||||
if (argc != 7)
|
||||
{
|
||||
cout << "Usage: munkeeDiff top.html row.html bottom.html in1.txt in2.txt out.txt" << endl;
|
||||
header = readInFile("top.html");
|
||||
tableRow = readInFile("row.html");
|
||||
footer = readInFile("bottom.html");
|
||||
inFname[0] = "test1.txt";
|
||||
inFname[1] = "test2.txt";
|
||||
//return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
header = readInFile(argv[1]);
|
||||
tableRow = readInFile(argv[2]);
|
||||
footer = readInFile(argv[3]);
|
||||
inFname[0] = argv[4];
|
||||
inFname[1] = argv[5];
|
||||
outFname = argv[6];
|
||||
}
|
||||
|
||||
ifp[0] = fopen(inFname[0], "rt");
|
||||
if (!ifp[0])
|
||||
{
|
||||
cout << "could not open " << inFname[0] << endl;
|
||||
return 1;
|
||||
}
|
||||
ifp[1] = fopen(inFname[1], "rt");
|
||||
if (!ifp[1])
|
||||
{
|
||||
fclose(ifp[0]);
|
||||
cout << "could not open " << inFname[1] << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
ofp = fopen(outFname, "wt");
|
||||
|
||||
char lastLine[2][LINESIZE];
|
||||
int lastFrame[2] = {-1, -1};
|
||||
int lastIndex[2] = {-1, -1};
|
||||
bool fileOk[2] = {true, true};
|
||||
|
||||
outputLine(header.c_str());
|
||||
|
||||
int linkNum = 1;
|
||||
int numDiffs = 0;
|
||||
|
||||
bool seenRight = false;
|
||||
bool seenLeft = false;
|
||||
|
||||
while (fileOk[0] || fileOk[1])
|
||||
{
|
||||
for (int i=0; i<2; ++i)
|
||||
{
|
||||
if (fileOk[i] == true && lastFrame[i] < 0)
|
||||
{
|
||||
fileOk[i] = getNextLine(ifp[i], lastLine[i],
|
||||
lastFrame[i], lastIndex[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (fileOk[0] && fileOk[1])
|
||||
{
|
||||
if (lastFrame[0] < lastFrame[1] ||
|
||||
(lastFrame[0]==lastFrame[1] && lastIndex[0] < lastIndex[1]))
|
||||
{
|
||||
//if (!seenLeft)
|
||||
//cout << "Seen left on " << lastFrame[0] << ":" << lastIndex[0] << endl;
|
||||
//seenLeft = true;
|
||||
if (seenRight && seenLeft)
|
||||
{
|
||||
outputLine(lastFrame[0], lastIndex[0], linkNum++,
|
||||
"leftOnly", lastLine[0], NULL, NULL);
|
||||
++numDiffs;
|
||||
}
|
||||
lastFrame[0] = -1;
|
||||
}
|
||||
else if (lastFrame[1] < lastFrame[0] ||
|
||||
(lastFrame[1]==lastFrame[0] && lastIndex[1] < lastIndex[0]))
|
||||
{
|
||||
//if (!seenRight)
|
||||
//cout << "Seen right on " << lastFrame[1] << ":" << lastIndex[1] << endl;
|
||||
//seenRight = true;
|
||||
if (seenRight && seenLeft)
|
||||
{
|
||||
outputLine(lastFrame[1], lastIndex[1], linkNum++,
|
||||
NULL, NULL, "rightOnly", lastLine[1]);
|
||||
++numDiffs;
|
||||
}
|
||||
lastFrame[1] = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
int res = strcmp(lastLine[0], lastLine[1]);
|
||||
if (res!=0)
|
||||
{
|
||||
if (!seenLeft || !seenRight)
|
||||
cout << "Seen both on " << lastFrame[0] << ":" << lastIndex[0] << endl;
|
||||
seenLeft = seenRight = true;
|
||||
outputLine(lastFrame[0], lastIndex[0], linkNum++,
|
||||
"leftDiff", lastLine[0], "rightDiff", lastLine[1]);
|
||||
++numDiffs;
|
||||
}
|
||||
else
|
||||
{
|
||||
//if (!seenLeft || !seenRight)
|
||||
// cout << "Seen both on " << lastFrame[0] << ":" << lastIndex[0] << endl;
|
||||
//seenLeft = seenRight = true;
|
||||
static bool printedFirst = false;
|
||||
if (!printedFirst)
|
||||
{
|
||||
outputLine(lastFrame[0], lastIndex[0], linkNum,
|
||||
"leftSame", lastLine[0], "rightSame", lastLine[1], true);
|
||||
printedFirst = true;
|
||||
}
|
||||
else if (seenLeft && seenRight)
|
||||
{
|
||||
outputLine(lastFrame[0], lastIndex[0], linkNum,
|
||||
"leftSame", lastLine[0], "rightSame", lastLine[1], true);
|
||||
++numDiffs;
|
||||
}
|
||||
else
|
||||
queueLine(lastFrame[0], lastIndex[0], lastLine[0]);
|
||||
//++numDiffs;
|
||||
}
|
||||
lastFrame[0] = -1;
|
||||
lastFrame[1] = -1;
|
||||
}
|
||||
}
|
||||
else if (fileOk[0])
|
||||
{
|
||||
//if (!seenLeft)
|
||||
//cout << "Seen left on " << lastFrame[0] << ":" << lastIndex[0] << endl;
|
||||
//seenLeft = true;
|
||||
if (seenRight && seenLeft)
|
||||
{
|
||||
outputLine(lastFrame[0], lastIndex[0], linkNum++,
|
||||
"leftOnly", lastLine[0], NULL, NULL);
|
||||
++numDiffs;
|
||||
}
|
||||
lastFrame[0] = -1;
|
||||
}
|
||||
else if (fileOk[1])
|
||||
{
|
||||
//if (!seenRight)
|
||||
//cout << "Seen right on " << lastFrame[1] << ":" << lastIndex[1] << endl;
|
||||
//seenRight = true;
|
||||
if (seenRight && seenLeft)
|
||||
{
|
||||
outputLine(lastFrame[1], lastIndex[1], linkNum++,
|
||||
NULL, NULL, "rightOnly", lastLine[1]);
|
||||
++numDiffs;
|
||||
}
|
||||
lastFrame[1] = -1;
|
||||
}
|
||||
|
||||
if (numDiffs > 1000)
|
||||
break;
|
||||
}
|
||||
|
||||
Expander e("((", "))");
|
||||
e.addExpansion("LAST", intToString(linkNum-1));
|
||||
e.addExpansion("BOTTOM", intToString(linkNum));
|
||||
std::string out;
|
||||
e.expand(footer, out);
|
||||
outputLine(out.c_str());
|
||||
|
||||
if (ofp)
|
||||
{
|
||||
fclose(ofp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
152
Generals/Code/Tools/CRCDiff/CRCDiff.dsp
Normal file
152
Generals/Code/Tools/CRCDiff/CRCDiff.dsp
Normal file
|
@ -0,0 +1,152 @@
|
|||
# Microsoft Developer Studio Project File - Name="CRCDiff" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
||||
|
||||
CFG=CRCDiff - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "CRCDiff.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "CRCDiff.mak" CFG="CRCDiff - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "CRCDiff - Win32 Release" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE "CRCDiff - Win32 Debug" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName "CRCDiff"
|
||||
# PROP Scc_LocalPath "."
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "CRCDiff - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
|
||||
!ELSEIF "$(CFG)" == "CRCDiff - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "CRCDiff - Win32 Release"
|
||||
# Name "CRCDiff - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\CRCDiff.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\debug.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\expander.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\KVPair.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\debug.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\expander.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\KVPair.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\misc.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# Begin Group "html"
|
||||
|
||||
# PROP Default_Filter ".css;.html"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\bottom.html
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\out.html
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\row.html
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\style.css
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\top.html
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
197
Generals/Code/Tools/CRCDiff/KVPair.cpp
Normal file
197
Generals/Code/Tools/CRCDiff/KVPair.cpp
Normal file
|
@ -0,0 +1,197 @@
|
|||
/*
|
||||
** Command & Conquer Generals(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/>.
|
||||
*/
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// File: KVPair.cpp
|
||||
// Author: Matthew D. Campbell
|
||||
// Creation Date: 9/4/2002
|
||||
// Description: Key/Value Pair class
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#include "misc.h"
|
||||
#include "KVPair.h"
|
||||
#include "debug.h"
|
||||
#include <stdio.h>
|
||||
|
||||
std::string intToString(int val)
|
||||
{
|
||||
std::string s = "";
|
||||
bool neg = (val < 0);
|
||||
if (val < 0)
|
||||
{
|
||||
val = -val;
|
||||
}
|
||||
if (val == 0)
|
||||
return "0";
|
||||
|
||||
char buf[2];
|
||||
buf[1] = 0;
|
||||
while (val)
|
||||
{
|
||||
buf[0] = '0' + val%10;
|
||||
val /= 10;
|
||||
s.insert(0, buf);
|
||||
}
|
||||
if (neg)
|
||||
s.insert(0, "-");
|
||||
return s;
|
||||
}
|
||||
|
||||
static std::string trim(std::string s, const std::string& delim)
|
||||
{
|
||||
unsigned int i;
|
||||
i = s.find_first_not_of(delim);
|
||||
if (i != s.npos)
|
||||
{
|
||||
s = s.substr(i);
|
||||
}
|
||||
|
||||
i = s.find_last_not_of(delim);
|
||||
if (i>=0 && i<s.npos)
|
||||
{
|
||||
s = s.substr(0, i+1);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
static KeyValueMap parseIntoKVPairs( std::string s, const std::string& delim )
|
||||
{
|
||||
KeyValueMap m;
|
||||
bool done = false;
|
||||
std::string kv, k, v;
|
||||
while (!done)
|
||||
{
|
||||
int comma;
|
||||
comma = s.find_first_of(delim, 0);
|
||||
if (comma < 1)
|
||||
{
|
||||
done = true;
|
||||
kv = s;
|
||||
}
|
||||
else
|
||||
{
|
||||
kv = s.substr(0, comma);
|
||||
s = s.substr(comma+1);
|
||||
}
|
||||
s = trim(s, delim);
|
||||
kv = trim(kv, delim);
|
||||
|
||||
if (!kv.empty())
|
||||
{
|
||||
int equals = kv.find_first_of('=', 0);
|
||||
if (equals < 1)
|
||||
{
|
||||
done = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
k = trim(trim(kv.substr(0, equals), delim), " \t");
|
||||
v = trim(trim(kv.substr(equals+1), delim), " \t");
|
||||
|
||||
if (!k.empty() && !v.empty())
|
||||
{
|
||||
m[k] = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
KVPairClass::KVPairClass( void )
|
||||
{}
|
||||
|
||||
KVPairClass::KVPairClass( const std::string& in, const std::string& delim )
|
||||
{
|
||||
set( in, delim );
|
||||
}
|
||||
|
||||
void KVPairClass::set( const std::string& in, const std::string& delim )
|
||||
{
|
||||
m_map = parseIntoKVPairs( in, delim );
|
||||
}
|
||||
|
||||
void KVPairClass::readFromFile( const std::string& in, const std::string& delim )
|
||||
{
|
||||
m_map.clear();
|
||||
FILE *fp = fopen(in.c_str(), "rb");
|
||||
if (fp)
|
||||
{
|
||||
std::string s = "";
|
||||
fseek(fp, 0, SEEK_END);
|
||||
int len = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
|
||||
char *buf = new char[len + 1];
|
||||
memset(buf, 0, len+1);
|
||||
fread(buf, 1, len, fp);
|
||||
fclose(fp);
|
||||
|
||||
s.append(buf);
|
||||
delete[] buf;
|
||||
set(s, delim);
|
||||
}
|
||||
}
|
||||
|
||||
std::string KVPairClass::getStringVal( const std::string& key ) const
|
||||
{
|
||||
KeyValueMap::const_iterator it = m_map.find(key);
|
||||
if (it == m_map.end())
|
||||
{
|
||||
return "";
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
bool KVPairClass::getString( const std::string& key, std::string& val ) const
|
||||
{
|
||||
std::string tmp = getStringVal(key);
|
||||
if (tmp.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
val = tmp;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KVPairClass::getInt( const std::string& key, int& val ) const
|
||||
{
|
||||
std::string tmp = getStringVal(key);
|
||||
if (tmp.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
val = atoi(tmp.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KVPairClass::getUnsignedInt( const std::string& key, unsigned int& val ) const
|
||||
{
|
||||
std::string tmp = getStringVal(key);
|
||||
if (tmp.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
val = atoi(tmp.c_str());
|
||||
return true;
|
||||
}
|
||||
|
53
Generals/Code/Tools/CRCDiff/KVPair.h
Normal file
53
Generals/Code/Tools/CRCDiff/KVPair.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
** Command & Conquer Generals(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/>.
|
||||
*/
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// File: KVPair.h
|
||||
// Author: Matthew D. Campbell
|
||||
// Creation Date: 9/4/2002
|
||||
// Description: Key/Value Pair class
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#ifndef __KVPAIR_H__
|
||||
#define __KVPAIR_H__
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
typedef std::map<std::string, std::string> KeyValueMap;
|
||||
|
||||
class KVPairClass
|
||||
{
|
||||
public:
|
||||
KVPairClass( void );
|
||||
KVPairClass( const std::string& in, const std::string& delim );
|
||||
void set( const std::string& in, const std::string& delim );
|
||||
void readFromFile( const std::string& in, const std::string& delim );
|
||||
|
||||
std::string getStringVal( const std::string& key ) const;
|
||||
|
||||
bool getString( const std::string& key, std::string& val ) const;
|
||||
bool getInt( const std::string& key, int& val ) const;
|
||||
bool getUnsignedInt( const std::string& key, unsigned int& val ) const;
|
||||
|
||||
protected:
|
||||
KeyValueMap m_map;
|
||||
};
|
||||
|
||||
#endif // __KVPAIR_H__
|
||||
|
5
Generals/Code/Tools/CRCDiff/bottom.html
Normal file
5
Generals/Code/Tools/CRCDiff/bottom.html
Normal file
|
@ -0,0 +1,5 @@
|
|||
</table>
|
||||
<hr>
|
||||
<a name="#((BOTTOM))"><a name="#BOTTOM"><a href="#((LAST))">Last</a></a></a>
|
||||
</body>
|
||||
</html>
|
43
Generals/Code/Tools/CRCDiff/debug.cpp
Normal file
43
Generals/Code/Tools/CRCDiff/debug.cpp
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
** Command & Conquer Generals(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/>.
|
||||
*/
|
||||
|
||||
// FILE: debug.cpp ////////////////////////////////////////////////////////
|
||||
// Minmal debug info
|
||||
// Author: Matthew D. Campbell, Sept 2002
|
||||
|
||||
#include <windows.h>
|
||||
#include "debug.h"
|
||||
#include <cstdio>
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
void DebugLog(const char *fmt, ...)
|
||||
{
|
||||
static char buffer[1024];
|
||||
va_list va;
|
||||
va_start( va, fmt );
|
||||
vsnprintf(buffer, 1024, fmt, va );
|
||||
buffer[1023] = 0;
|
||||
va_end( va );
|
||||
|
||||
printf( "%s", buffer );
|
||||
OutputDebugString( buffer );
|
||||
}
|
||||
|
||||
#endif // DEBUG
|
||||
|
40
Generals/Code/Tools/CRCDiff/debug.h
Normal file
40
Generals/Code/Tools/CRCDiff/debug.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
** Command & Conquer Generals(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/>.
|
||||
*/
|
||||
|
||||
// FILE: debug.h //////////////////////////////////////////////////////////////
|
||||
// Minimal debug info
|
||||
// Author: Matthew D. Campbell, Sept 2002
|
||||
|
||||
#ifndef __DEBUG_H__
|
||||
#define __DEBUG_H__
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
#include <cstdarg>
|
||||
|
||||
void DebugLog( const char *fmt, ... );
|
||||
#define DEBUG_LOG(x) DebugLog x
|
||||
|
||||
#else // DEBUG
|
||||
|
||||
#define DEBUG_LOG(x) {}
|
||||
|
||||
#endif // DEBUG
|
||||
|
||||
#endif // __DEBUG_H__
|
||||
|
126
Generals/Code/Tools/CRCDiff/expander.cpp
Normal file
126
Generals/Code/Tools/CRCDiff/expander.cpp
Normal file
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
** Command & Conquer Generals(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/>.
|
||||
*/
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// File: expander.cpp
|
||||
// Author: Matthew D. Campbell
|
||||
// Creation Date: 9/13/2002
|
||||
// Description: Key/value pair template expansion class
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#include "debug.h"
|
||||
#include "expander.h"
|
||||
|
||||
Expander::Expander( const std::string& leftMarker, const std::string& rightMarker ) :
|
||||
m_left(leftMarker), m_right(rightMarker)
|
||||
{
|
||||
}
|
||||
|
||||
void Expander::addExpansion( const std::string& key, const std::string val )
|
||||
{
|
||||
m_expansions[key] = val;
|
||||
}
|
||||
|
||||
void Expander::clear( void )
|
||||
{
|
||||
m_expansions.clear();
|
||||
}
|
||||
|
||||
void Expander::expand( const std::string& input,
|
||||
std::string& output,
|
||||
bool stripUnknown )
|
||||
{
|
||||
output = "";
|
||||
unsigned int pos = input.find(m_left);
|
||||
unsigned int lastpos = input.npos;
|
||||
while (pos != input.npos)
|
||||
{
|
||||
// first, tack on the non-expansion part we just skipped over
|
||||
if (pos > 0)
|
||||
{
|
||||
if (lastpos == input.npos)
|
||||
{
|
||||
// first time
|
||||
output.append(input.substr(0, pos));
|
||||
//DEBUG_LOG(("First time, output='%s'\n", output.c_str()));
|
||||
}
|
||||
else
|
||||
{
|
||||
// done this before
|
||||
std::string sub = input.substr(lastpos, pos-lastpos);
|
||||
//DEBUG_LOG(("*** lastpos = %d, pos=%d, sub='%s'\n", lastpos, pos, sub.c_str()));
|
||||
output.append(sub);
|
||||
//DEBUG_LOG(("output='%s'\n", output.c_str()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//DEBUG_LOG(("pos == 0\n"));
|
||||
}
|
||||
|
||||
// pos is the first position of a possible expansion
|
||||
//DEBUG_LOG(("Looking for endpos via '%s' in '%s'\n", m_right.c_str(), input.substr(pos+m_left.length()).c_str()));
|
||||
unsigned int endpos = input.find(m_right, pos+m_left.length());
|
||||
//DEBUG_LOG(("substr is %d-%d of '%s'\n", pos, endpos, input.c_str()));
|
||||
if (endpos != input.npos)
|
||||
{
|
||||
// found a complete token - expand it
|
||||
std::string sub = input.substr(pos+m_left.length(), endpos-pos-m_left.length());
|
||||
//DEBUG_LOG(("found token: '%s'\n", sub.c_str()));
|
||||
|
||||
ExpansionMap::iterator it = m_expansions.find(sub);
|
||||
if (it == m_expansions.end())
|
||||
{
|
||||
// unknown key
|
||||
if (stripUnknown)
|
||||
{
|
||||
//output.append("<<CENSORED>>");
|
||||
}
|
||||
else
|
||||
{
|
||||
output.append(input.substr(pos, endpos-pos+m_right.length()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string toExpand = it->second;
|
||||
std::string expanded = "";
|
||||
//DEBUG_LOG(("###### expanding '%s'\n", toExpand.c_str()));
|
||||
expand(toExpand, expanded, stripUnknown);
|
||||
//DEBUG_LOG(("###### expanded '%s'\n", expanded.c_str()));
|
||||
output.append(expanded);
|
||||
}
|
||||
}
|
||||
|
||||
lastpos = endpos+m_right.length();
|
||||
|
||||
pos = input.find(m_left, pos+m_left.length());
|
||||
}
|
||||
|
||||
if (lastpos != input.npos)
|
||||
{
|
||||
// tack on last bit
|
||||
output.append(input.substr(lastpos));
|
||||
}
|
||||
else if (!output.length() && pos == input.npos && lastpos == input.npos)
|
||||
{
|
||||
output = input;
|
||||
}
|
||||
}
|
||||
|
||||
|
54
Generals/Code/Tools/CRCDiff/expander.h
Normal file
54
Generals/Code/Tools/CRCDiff/expander.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
** Command & Conquer Generals(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/>.
|
||||
*/
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// File: expander.h
|
||||
// Author: Matthew D. Campbell
|
||||
// Creation Date: 9/13/2002
|
||||
// Description: Key/value pair template expansion class
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#ifndef __EXPANDER_H__
|
||||
#define __EXPANDER_H__
|
||||
|
||||
#include <map>
|
||||
#include <hash_map>
|
||||
#include <string>
|
||||
|
||||
typedef std::map<std::string, std::string> ExpansionMap;
|
||||
|
||||
class Expander
|
||||
{
|
||||
public:
|
||||
Expander( const std::string& leftMarker, const std::string& rightMarker );
|
||||
|
||||
void addExpansion( const std::string& key, const std::string val );
|
||||
void clear( void );
|
||||
|
||||
void expand( const std::string& input,
|
||||
std::string& output,
|
||||
bool stripUnknown = false );
|
||||
|
||||
protected:
|
||||
ExpansionMap m_expansions;
|
||||
std::string m_left;
|
||||
std::string m_right;
|
||||
};
|
||||
|
||||
#endif // __EXPANDER_H__
|
||||
|
34
Generals/Code/Tools/CRCDiff/misc.h
Normal file
34
Generals/Code/Tools/CRCDiff/misc.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
** Command & Conquer Generals(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/>.
|
||||
*/
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// File: misc.h
|
||||
// Author: Matthew D. Campbell
|
||||
// Creation Date: 9/12/2002
|
||||
// Description: misc utils
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#ifndef __MISC_H__
|
||||
#define __MISC_H__
|
||||
|
||||
#include <string>
|
||||
|
||||
std::string intToString(int val);
|
||||
|
||||
#endif // __MISC_H__
|
||||
|
8
Generals/Code/Tools/CRCDiff/row.html
Normal file
8
Generals/Code/Tools/CRCDiff/row.html
Normal file
|
@ -0,0 +1,8 @@
|
|||
<tr>
|
||||
<td class=((LEFTCLASS))>((LEFTLINE))</td>
|
||||
<td><a name="#((NAME))"><a href="#((PREV))">Prev</a></a></td>
|
||||
<td><a href="#0">Top</a></td>
|
||||
<td><a href="#BOTTOM">Bottom</a></td>
|
||||
<td><a href="#((NEXT))">Next</a></td>
|
||||
<td class=((RIGHTCLASS))>((RIGHTLINE))</td>
|
||||
</tr>
|
5
Generals/Code/Tools/CRCDiff/style.css
Normal file
5
Generals/Code/Tools/CRCDiff/style.css
Normal file
|
@ -0,0 +1,5 @@
|
|||
td {font-family:monospace; font-size:x-small}
|
||||
td.leftHistory {color:blue}
|
||||
td.rightHistory {color:blue}
|
||||
td.leftDiff {color:red}
|
||||
td.rightDiff {color:red}
|
9
Generals/Code/Tools/CRCDiff/top.html
Normal file
9
Generals/Code/Tools/CRCDiff/top.html
Normal file
|
@ -0,0 +1,9 @@
|
|||
<html>
|
||||
<head>
|
||||
<LINK REL=StyleSheet HREF="style.css" TYPE="text/css">
|
||||
</head>
|
||||
<body>
|
||||
<a name="#0">Top</a>
|
||||
<a href="#1">First</a>
|
||||
<hr>
|
||||
<table width=100% border=2>
|
Reference in a new issue