- BORLAND/: Borland C++ 4.52 (chosen over 4.5 by byte-match: CODE/RP/CW32.LIB
is identical to 4.52's install lib). BCC32/TLINK32/TLIB/MAKE run natively on
Win11; CODE/BT/OPT.MAK is the shipped BTL4OPT.EXE's exact flag recipe
(extender = Borland PowerPack DPMI32, not Phar Lap TNT).
- restoration/source410/: the literal 1995-form reconstruction of the missing
BT game source (never mixed into CODE/). Round 1-3 state:
* 6 of 10 surviving original TUs COMPILE CLEAN under the period toolchain
(BTMSSN, BTCNSL, BTSCNRL, BTTEAM, BTL4MODE, BTL4ARND) - first builds
since 1996.
* BT_L4/BTL4APP.CPP pilot reconstruction: 12/12 functions, Fail() lands on
its binary-recorded line 400 exactly.
* BT/BTCNSL.HPP: console wire IDs recovered from the binary's ctors
(Killed=9, Damaged=10, ScoreUpdate=13, DeathWithoutHonor=15 [T1];
TeamScore=12 flagged [T4]).
* MUNGA/: 8 engine-header backfills back-dated from the BT412 WinTesla tree
(VDATA numbering decomp-verified; AUDREND's OpenAL-era virtual removed -
the period compiler is the drift detector).
* Tooling: backdate.py (WinTesla->1995 header transform), compile410.sh
(per-TU verification sweep under authentic OPT.MAK flags).
* README: corrected roadmap - MECH.HPP is the capstone grown with the mech
TU reconstructions; BTREG.CPP green = the header-family milestone.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
413 lines
9.9 KiB
C++
413 lines
9.9 KiB
C++
// ---------------------------------------------------------------------------
|
|
// Copyright (C) 1994 Borland International
|
|
// ---------------------------------------------------------------------------
|
|
#include <iostream.h>
|
|
#include <strstrea.h>
|
|
#include <cstring.h>
|
|
#include <stdlib.h>
|
|
|
|
enum bool
|
|
{
|
|
false = 0,
|
|
true = 1
|
|
};
|
|
|
|
//
|
|
// AutomationMacro
|
|
// Abstract base class
|
|
//
|
|
class AutomationMacro {
|
|
public:
|
|
AutomationMacro() {}
|
|
virtual ~AutomationMacro() {}
|
|
|
|
virtual void Generate(strstream &stream, const bool voidReturnType, const int numArgs) = 0;
|
|
virtual const char* GetMacroName() const = 0;
|
|
virtual const int GetRequiredArgs() const = 0;
|
|
};
|
|
|
|
void
|
|
GenerateDefArgsMacro(strstream& stream, const int numArgs)
|
|
{
|
|
int i;
|
|
|
|
stream << "#define DEFARGS" << numArgs << "(";
|
|
for (i=1; i<=numArgs; i++) {
|
|
stream << "t" << i;
|
|
if (i != numArgs)
|
|
stream << ",";
|
|
}
|
|
stream << ") ";
|
|
|
|
for (i=1; i<=numArgs; i++)
|
|
stream << "t" << i << " Arg" << i << ";";
|
|
|
|
stream << endl;
|
|
}
|
|
|
|
void
|
|
GenerateBldArgsMacro(strstream& stream, const int numArgs)
|
|
{
|
|
int i;
|
|
|
|
stream << "#define BLDARGS" << numArgs << "(";
|
|
for (i=1; i<=numArgs; i++) {
|
|
stream << "t" << i;
|
|
if (i != numArgs)
|
|
stream << ",";
|
|
}
|
|
stream << ") ";
|
|
|
|
for (i=1; i<=numArgs; i++)
|
|
stream << ",(t" << i << ")args[" << (i-1) << "]";
|
|
|
|
stream << endl;
|
|
}
|
|
|
|
void
|
|
GenerateCtrArgsMacro(strstream& stream, const int numArgs)
|
|
{
|
|
int i;
|
|
|
|
stream << "#define CTRARGS" << numArgs << "(";
|
|
for (i=1; i<=numArgs; i++) {
|
|
stream << "t" << i;
|
|
if (i != numArgs)
|
|
stream << ",";
|
|
}
|
|
stream << ") ";
|
|
|
|
for (i=1; i<=numArgs; i++)
|
|
stream << ",t" << i << " arg" << i;
|
|
|
|
stream << endl;
|
|
}
|
|
|
|
void
|
|
GenerateSetArgsMacro(strstream& stream, const int numArgs)
|
|
{
|
|
int i;
|
|
|
|
stream << "#define SETARGS" << numArgs << " ";
|
|
|
|
for (i=1; i<=numArgs; i++)
|
|
stream << ",Arg" << i << "(arg" << i << ")";
|
|
|
|
stream << endl;
|
|
}
|
|
|
|
void
|
|
GenerateMacrosUsage(strstream& stream, const char* macroName, const int numArgs)
|
|
{
|
|
int i;
|
|
|
|
stream << macroName << numArgs << "(";
|
|
for (i=1; i<=numArgs; i++) {
|
|
stream << "t" << i;
|
|
if (i != numArgs)
|
|
stream << ",";
|
|
}
|
|
stream << ")";
|
|
}
|
|
|
|
|
|
//
|
|
// AutoFunc
|
|
//
|
|
class AutoFunc : public AutomationMacro {
|
|
public:
|
|
void Generate(strstream& stream, const bool voidReturnType, const int numArgs);
|
|
const char* GetMacroName() const { return "AutoFunc"; }
|
|
const int GetRequiredArgs() const { return 4; }
|
|
};
|
|
|
|
void
|
|
AutoFunc::Generate(strstream& stream, const bool voidReturnType, const int numArgs)
|
|
{
|
|
int i;
|
|
string returnTypeString;
|
|
|
|
if (voidReturnType == true) {
|
|
returnTypeString = "V";
|
|
} else {
|
|
returnTypeString = "";
|
|
}
|
|
|
|
GenerateDefArgsMacro(stream, numArgs);
|
|
GenerateBldArgsMacro(stream, numArgs);
|
|
GenerateCtrArgsMacro(stream, numArgs);
|
|
GenerateSetArgsMacro(stream, numArgs);
|
|
|
|
stream << "#define AUTOFUNC" << numArgs << returnTypeString << "(name, func";
|
|
if (voidReturnType != true)
|
|
stream << ", ret";
|
|
for (i=1; i<=numArgs; i++)
|
|
stream << ", t" << i;
|
|
stream << ", defs) \\" << endl;
|
|
|
|
stream << " AUTOFUNC_(name, ";
|
|
if (voidReturnType != true)
|
|
stream << "Val=";
|
|
stream << "This->func(";
|
|
for (i=1; i<=numArgs; i++) {
|
|
stream << "Arg" << i;
|
|
if (i!=numArgs)
|
|
stream << ", ";
|
|
}
|
|
stream << ");, defs, \\" << endl;
|
|
|
|
stream << " ";
|
|
if (voidReturnType != true)
|
|
stream << "RETARG(ret) ";
|
|
GenerateMacrosUsage(stream, "DEFARGS", numArgs);
|
|
stream << ", \\" << endl;
|
|
GenerateMacrosUsage(stream, " BLDARGS", numArgs);
|
|
stream << ", \\" << endl;
|
|
GenerateMacrosUsage(stream, " CTRARGS", numArgs);
|
|
stream << ", \\" << endl;
|
|
stream << " SETARGS" << numArgs << ")" << endl;
|
|
}
|
|
|
|
//
|
|
// AutoStat
|
|
//
|
|
class AutoStat : public AutomationMacro {
|
|
public:
|
|
void Generate(strstream& stream, const bool voidReturnType, const int numArgs);
|
|
const char* GetMacroName() const { return "AutoStat"; }
|
|
const int GetRequiredArgs() const { return 4; }
|
|
};
|
|
|
|
void
|
|
AutoStat::Generate(strstream& stream, const bool voidReturnType, const int numArgs)
|
|
{
|
|
int i;
|
|
string returnTypeString;
|
|
|
|
if (voidReturnType == true) {
|
|
returnTypeString = "V";
|
|
} else {
|
|
returnTypeString = "";
|
|
}
|
|
|
|
GenerateDefArgsMacro(stream, numArgs);
|
|
GenerateBldArgsMacro(stream, numArgs);
|
|
GenerateCtrArgsMacro(stream, numArgs);
|
|
GenerateSetArgsMacro(stream, numArgs);
|
|
|
|
stream << "#define AUTOSTAT" << numArgs << returnTypeString << "(name, func";
|
|
if (voidReturnType != true)
|
|
stream << ", ret";
|
|
for (i=1; i<=numArgs; i++)
|
|
stream << ", t" << i;
|
|
stream << ", defs) \\" << endl;
|
|
|
|
stream << " AUTOFUNC_(name, ";
|
|
if (voidReturnType != true)
|
|
stream << "Val=";
|
|
stream << "func(";
|
|
|
|
for (i=1; i<=numArgs; i++) {
|
|
stream << "Arg" << i;
|
|
if (i!=numArgs)
|
|
stream << ", ";
|
|
}
|
|
stream << ");, defs, \\" << endl;
|
|
|
|
stream << " ";
|
|
if (voidReturnType != true)
|
|
stream << "RETARG(ret) ";
|
|
GenerateMacrosUsage(stream, "DEFARGS", numArgs);
|
|
stream << ", \\" << endl;
|
|
GenerateMacrosUsage(stream, " BLDARGS", numArgs);
|
|
stream << ", \\" << endl;
|
|
GenerateMacrosUsage(stream, " CTRARGS", numArgs);
|
|
stream << ", \\" << endl;
|
|
stream << " SETARGS" << numArgs << ")" << endl;
|
|
}
|
|
|
|
|
|
//
|
|
// AutoBuild
|
|
//
|
|
class AutoBuild : public AutomationMacro {
|
|
public:
|
|
void Generate(strstream& stream, const bool voidReturnType, const int numArgs);
|
|
const char* GetMacroName() const { return "AutoBuild"; }
|
|
const int GetRequiredArgs() const { return 4; }
|
|
};
|
|
|
|
void
|
|
AutoBuild::Generate(strstream& stream, const bool /*voidReturnType*/, const int numArgs)
|
|
{
|
|
int i;
|
|
|
|
GenerateDefArgsMacro(stream, numArgs);
|
|
GenerateBldArgsMacro(stream, numArgs);
|
|
GenerateCtrArgsMacro(stream, numArgs);
|
|
GenerateSetArgsMacro(stream, numArgs);
|
|
|
|
stream << "#define AUTOBUILD" << numArgs << "(name, func";
|
|
for (i=1; i<=numArgs; i++)
|
|
stream << ", t" << i;
|
|
stream << ", defs) \\" << endl;
|
|
|
|
stream << " AUTOBUILD_(name, Val=new ThisClass(";
|
|
for (i=1; i<=numArgs; i++) {
|
|
stream << "Arg" << i;
|
|
if (i!=numArgs)
|
|
stream << ", ";
|
|
}
|
|
|
|
stream << ");, defs, \\" << endl;
|
|
|
|
GenerateMacrosUsage(stream, " DEFARGS", numArgs);
|
|
stream << ", \\" << endl;
|
|
GenerateMacrosUsage(stream, " BLDARGS", numArgs);
|
|
stream << ", \\" << endl;
|
|
GenerateMacrosUsage(stream, " CTRARGS", numArgs);
|
|
stream << ", \\" << endl;
|
|
stream << " SETARGS" << numArgs << ")" << endl;
|
|
}
|
|
|
|
|
|
//
|
|
// AutoNames
|
|
//
|
|
class AutoNames : public AutomationMacro {
|
|
public:
|
|
void Generate(strstream& stream, const bool voidReturnType, const int numArgs);
|
|
const char* GetMacroName() const { return "AutoNames"; }
|
|
const int GetRequiredArgs() const { return 6; }
|
|
};
|
|
|
|
void
|
|
AutoNames::Generate(strstream& stream, const bool /*voidReturnType*/, const int numArgs)
|
|
{
|
|
int i;
|
|
stream << "#define AUTONAMES" << numArgs << "(id";
|
|
|
|
for (i=1; i<=numArgs; i++) {
|
|
stream << ",n" << i;
|
|
}
|
|
stream << ") static TAutoDispIds<" << numArgs << "> i_(this, id, ";
|
|
for (i=numArgs; i>=1; i--) {
|
|
stream << "_A(n" << i << ")";
|
|
}
|
|
stream << ");" << endl;
|
|
}
|
|
|
|
|
|
//
|
|
// AutoArgs
|
|
//
|
|
class AutoArgs : public AutomationMacro {
|
|
public:
|
|
void Generate(strstream& stream, const bool voidReturnType,
|
|
const int numArgs);
|
|
const char* GetMacroName() const { return "AutoArgs"; }
|
|
const int GetRequiredArgs() const { return 6; }
|
|
};
|
|
|
|
void
|
|
AutoArgs::Generate(strstream& stream, const bool /*voidReturnType*/, const int numArgs)
|
|
{
|
|
int i;
|
|
stream << "#define AUTOARGS" << numArgs << "(";
|
|
|
|
for (i=1; i<=numArgs; i++) {
|
|
stream << "a" << i;
|
|
if (i != numArgs)
|
|
stream << ",";
|
|
}
|
|
stream << ") TAutoArgs<" << numArgs << ">a_; ";
|
|
for (i=1; i<=numArgs; i++) {
|
|
stream << "a_[" << i << "]=a" << i << "; ";
|
|
}
|
|
stream << endl;
|
|
}
|
|
|
|
|
|
//
|
|
// Global variables
|
|
//
|
|
AutoFunc GlobalAutoFunc;
|
|
AutoStat GlobalAutoStat;
|
|
AutoBuild GlobalAutoBuild;
|
|
AutoNames GlobalAutoNames;
|
|
AutoArgs GlobalAutoArgs;
|
|
|
|
AutomationMacro *Macros[] = {
|
|
&GlobalAutoFunc, &GlobalAutoStat, &GlobalAutoBuild,
|
|
&GlobalAutoNames, &GlobalAutoArgs
|
|
};
|
|
|
|
const int NumMacros = sizeof(Macros) / sizeof(Macros[0]);
|
|
|
|
void
|
|
PrintUsage()
|
|
{
|
|
cerr << "MacroGen Utility v1.0" << endl;
|
|
cerr << "Copyright (c) 1994, Borland International Inc" << endl;
|
|
cerr << "All Rights Reserved" << endl;
|
|
cerr << endl;
|
|
cerr << " MacroGen AutomationMacro [void] numArgs" << endl;
|
|
cerr << endl;
|
|
cerr << "where AutomationMacro is one of the following:" << endl;
|
|
cerr << endl;
|
|
for (int i=0; i<NumMacros; i++)
|
|
cerr << "\t" << Macros[i]->GetMacroName() << endl;
|
|
}
|
|
|
|
void
|
|
ErrorMsg(const char* msg, const int exitCode)
|
|
{
|
|
cerr << "Error: " << msg << endl;
|
|
cerr << endl;
|
|
PrintUsage();
|
|
exit(exitCode);
|
|
}
|
|
|
|
//
|
|
// starting point
|
|
//
|
|
int
|
|
main(int argc, char *argv[])
|
|
{
|
|
bool voidReturnType = false;
|
|
bool macroMatch = false;
|
|
int numArgs = 0;
|
|
|
|
if (argc <= 2 || 4 < argc)
|
|
ErrorMsg("Wrong number of arguments", 1);
|
|
|
|
if (strcmpi(argv[2], "void") == 0) {
|
|
if (argc == 3)
|
|
ErrorMsg("Missing 'numArgs' argument", 1);
|
|
voidReturnType = true;
|
|
numArgs = atoi(argv[3]);
|
|
} else {
|
|
if (argc == 4)
|
|
ErrorMsg("Extra argument", 1);
|
|
numArgs = atoi(argv[2]);
|
|
}
|
|
|
|
strstream outStream;
|
|
|
|
for (int i=0; i<NumMacros; i++) {
|
|
if (strcmpi(argv[1], Macros[i]->GetMacroName()) == 0) {
|
|
macroMatch = true;
|
|
if (numArgs <= Macros[i]->GetRequiredArgs())
|
|
ErrorMsg("Number of arguments specified for macro is already defined in automacr.h", 1);
|
|
Macros[i]->Generate(outStream, voidReturnType, numArgs);
|
|
// OutStream << ends;
|
|
cout << outStream.rdbuf();
|
|
}
|
|
}
|
|
|
|
if (macroMatch == false)
|
|
ErrorMsg("Macro not found", 1);
|
|
|
|
return 0;
|
|
}
|