Initial commit of Command & Conquer Renegade source code.

This commit is contained in:
LFeenanEA
2025-02-27 16:39:46 +00:00
parent 74ab8fa5e0
commit 58ed459113
4918 changed files with 1366710 additions and 0 deletions

Binary file not shown.

225
Code/wwutil/mathutil.cpp Normal file
View File

@@ -0,0 +1,225 @@
/*
** Command & Conquer Renegade(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/>.
*/
//
// Filename: mathutil.cpp
// Project: wwutil
// Author: Tom Spencer-Smith
// Date: June 1998
// Description:
//
//-----------------------------------------------------------------------------
#include "mathutil.h" // I WANNA BE FIRST!
#include <math.h>
#include <stdlib.h>
#include "wwmath.h"
#include "miscutil.h"
#include "wwdebug.h"
const double cMathUtil::PI = 3.1415927;
const double cMathUtil::PI_2 = 1.5707963;
//-----------------------------------------------------------------------------
//
// Returns a unit vector
//
void cMathUtil::Angle_To_Vector(double angle, double & dx, double & dy)
{
WWASSERT(angle > -WWMATH_EPSILON && angle < 360.0 + WWMATH_EPSILON);
double angleRadians;
if (angle >= 0 && angle < 90) {
angleRadians = angle * PI / 180.0;
dx = WWMath::Sin(angleRadians);
dy = WWMath::Cos(angleRadians);
} else if (angle >= 90 && angle < 180) {
angleRadians = (angle - 90) * PI / 180.0;
dx = WWMath::Cos(angleRadians);
dy = -WWMath::Sin(angleRadians);
} else if (angle >= 180 && angle < 270) {
angleRadians = (angle - 180) * PI / 180.0;
dx = -WWMath::Sin(angleRadians);
dy = -WWMath::Cos(angleRadians);
} else {
angleRadians = (angle - 270) * PI / 180.0;
dx = -WWMath::Cos(angleRadians);
dy = WWMath::Sin(angleRadians);
}
double len;
len = ::sqrt(dx * dx + dy * dy);
WWASSERT(::fabs(len - 1) < 0.0005);
//
// Correction for Irish nature of windows y coords
//
dy *= -1;
}
//-----------------------------------------------------------------------------
void cMathUtil::Vector_To_Angle(double dx, double dy, double & angle)
{
double theta;
if (dx == 0 && dy == 0) {
theta = 0;
}
if (dx == 0) {
if (dy <= 0) {
theta = 0;
} else {
theta = PI;
}
} else {
theta = WWMath::Atan(-dy / dx);
if (dx < 0) {
theta += PI;
}
theta += 3 * PI_2;
if (theta >= 2 * PI) {
theta -= 2 * PI;
}
theta = 2 * PI - theta;
if (theta == 2 * PI) {
theta = 0;
}
}
angle = theta * 180.0 / PI;
}
//-----------------------------------------------------------------------------
double cMathUtil::Simple_Distance(double x1, double y1, double x2, double y2)
{
double dx = x2 - x1;
double dy = y2 - y1;
return(::sqrt(dx * dx + dy * dy));
}
//-----------------------------------------------------------------------------
int cMathUtil::Round(double arg)
{
//return (int)(arg + 0.5);
if (arg > MISCUTIL_EPSILON) {
return (int) (arg + 0.5f);
} else if (arg < -MISCUTIL_EPSILON) {
return (int) (arg - 0.5f);
} else {
return 0;
}
}
//-----------------------------------------------------------------------------
void cMathUtil::Rotate_Vector(double & vx, double & vy, double angle)
{
double angle_radians = angle * PI / 180.0;
double vx1 = vx;
double vy1 = vy;
vx = vx1 * ::WWMath::Cos(angle_radians) - vy1 * ::WWMath::Sin(angle_radians);
vy = vx1 * ::WWMath::Sin(angle_radians) + vy1 * ::WWMath::Cos(angle_radians);
}
//-----------------------------------------------------------------------------
double cMathUtil::Get_Uniform_Pdf_Double(double lower, double upper)
{
WWASSERT(upper - lower > -MISCUTIL_EPSILON);
double x = lower + ::rand() / (double) RAND_MAX * (upper - lower);
WWASSERT(x - lower > -MISCUTIL_EPSILON && upper - x > -MISCUTIL_EPSILON);
return x;
}
//-----------------------------------------------------------------------------
double cMathUtil::Get_Normalized_Uniform_Pdf_Double()
{
return Get_Uniform_Pdf_Double(0, 1);
}
//-----------------------------------------------------------------------------
int cMathUtil::Get_Uniform_Pdf_Int(int lower, int upper)
{
WWASSERT(lower <= upper);
int x = lower + ::rand() % (upper - lower + 1);
WWASSERT(x >= lower && upper >= x);
return x;
}
//-----------------------------------------------------------------------------
double cMathUtil::Get_Hat_Pdf_Double(double lower, double upper)
{
WWASSERT(upper - lower > -MISCUTIL_EPSILON);
double x;
if (::fabs(upper - lower) < MISCUTIL_EPSILON) {
x = lower;
} else {
double dx = (upper - lower) / 2.0f;
double dy = 1 / dx;
double m = dy / dx;
double c = -m * lower;
x = Get_Uniform_Pdf_Double(lower, lower + dx);
double y = Get_Uniform_Pdf_Double(0, dy);
if (y > m * x + c) {
x += dx;
}
}
WWASSERT(x - lower > -MISCUTIL_EPSILON && upper - x > -MISCUTIL_EPSILON);
return x;
}
//-----------------------------------------------------------------------------
double cMathUtil::Get_Normalized_Hat_Pdf_Double()
{
return Get_Hat_Pdf_Double(0, 1);
}
//-----------------------------------------------------------------------------
int cMathUtil::Get_Hat_Pdf_Int(int lower, int upper)
{
return Round(Get_Hat_Pdf_Double(lower, upper));
}

58
Code/wwutil/mathutil.h Normal file
View File

@@ -0,0 +1,58 @@
/*
** Command & Conquer Renegade(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/>.
*/
//
// Filename: mathutil.h
// Project: wwutil
// Author: Tom Spencer-Smith
// Date: June 1998
// Description: static
//
//-----------------------------------------------------------------------------
#if defined(_MSV_VER)
#pragma once
#endif
#ifndef MATHUTIL_H
#define MATHUTIL_H
class cMathUtil
{
public:
static void Angle_To_Vector(double angle, double & dx, double & dy);
static void Vector_To_Angle(double dx, double dy, double & angle);
static double Simple_Distance(double x1, double y1, double x2, double y2);
static int Round(double arg);
static void Rotate_Vector(double & vx, double & vy, double angle);
//
// Random numbers generated according to simple
// Probability Density Functions
//
static double Get_Uniform_Pdf_Double(double lower, double upper);
static double Get_Normalized_Uniform_Pdf_Double();
static int Get_Uniform_Pdf_Int(int lower, int upper);
static double Get_Hat_Pdf_Double(double lower, double upper);
static double Get_Normalized_Hat_Pdf_Double();
static int Get_Hat_Pdf_Int(int lower, int upper);
static const double PI;
static const double PI_2;
};
#endif // MATHUTIL_H

326
Code/wwutil/miscutil.cpp Normal file
View File

@@ -0,0 +1,326 @@
/*
** Command & Conquer Renegade(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/>.
*/
//
// Filename: miscutil.cpp
// Project: wwutil
// Author: Tom Spencer-Smith
// Date: June 1998
// Description:
//
//-----------------------------------------------------------------------------
#include "miscutil.h" // I WANNA BE FIRST!
#include <time.h>
#include "rawfile.h"
#include "wwdebug.h"
#include "win.h"
#include "mmsys.h"
#include "ffactory.h"
//
// cMiscUtil statics
//
//---------------------------------------------------------------------------
LPCSTR cMiscUtil::Get_Text_Time(void)
{
//
// Returns a pointer to an internal statically allocated buffer...
// Subsequent time operations will destroy the contents of that buffer.
// Note: BoundsChecker reports 2 memory leaks in ctime here.
//
long time_now = ::time(NULL);
char * time_str = ::ctime(&time_now);
time_str[::strlen(time_str) - 1] = 0; // remove \n
return time_str;
}
//---------------------------------------------------------------------------
void cMiscUtil::Seconds_To_Hms(float seconds, int & h, int & m, int & s)
{
WWASSERT(seconds >= 0);
h = (int) (seconds / 3600);
seconds -= h * 3600;
m = (int) (seconds / 60);
seconds -= m * 60;
s = (int) seconds;
WWASSERT(h >= 0);
WWASSERT(m >= 0 && m < 60);
WWASSERT(s >= 0 && s < 60);
//WWASSERT(fabs((h * 3600 + m * 60 + s) / 60) - mins < WWMATH_EPSILON);
}
//-----------------------------------------------------------------------------
bool cMiscUtil::Is_String_Same(LPCSTR str1, LPCSTR str2)
{
WWASSERT(str1 != NULL);
WWASSERT(str2 != NULL);
return(::stricmp(str1, str2) == 0);
}
//-----------------------------------------------------------------------------
bool cMiscUtil::Is_String_Different(LPCSTR str1, LPCSTR str2)
{
WWASSERT(str1 != NULL);
WWASSERT(str2 != NULL);
return(::stricmp(str1, str2) != 0);
}
//-----------------------------------------------------------------------------
bool cMiscUtil::File_Exists(LPCSTR filename)
{
#if 0
WWASSERT(filename != NULL);
WIN32_FIND_DATA find_info;
HANDLE file_handle = ::FindFirstFile(filename, &find_info);
if (file_handle != INVALID_HANDLE_VALUE) {
::FindClose(file_handle);
return true;
} else {
return false;
}
#else
FileClass * file = _TheFileFactory->Get_File( filename );
if ( file && file->Is_Available() ) {
return true;
}
_TheFileFactory->Return_File( file );
return false;
#endif
}
//-----------------------------------------------------------------------------
bool cMiscUtil::File_Is_Read_Only(LPCSTR filename)
{
WWASSERT(filename != NULL);
DWORD attributes = ::GetFileAttributes(filename);
return ((attributes != 0xFFFFFFFF) && (attributes & FILE_ATTRIBUTE_READONLY));
}
//-----------------------------------------------------------------------------
bool cMiscUtil::Is_Alphabetic(char c)
{
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
}
//-----------------------------------------------------------------------------
bool cMiscUtil::Is_Numeric(char c)
{
return (c >= '0' && c <= '9');
}
//-----------------------------------------------------------------------------
bool cMiscUtil::Is_Alphanumeric(char c)
{
return Is_Alphabetic(c) || Is_Numeric(c);
}
//-----------------------------------------------------------------------------
bool cMiscUtil::Is_Whitespace(char c)
{
return c == ' ' || c == '\t';
}
//-----------------------------------------------------------------------------
void cMiscUtil::Trim_Trailing_Whitespace(char * text)
{
WWASSERT(text != NULL);
int length = ::strlen(text);
while (length > 0 && Is_Whitespace(text[length - 1])) {
text[--length] = 0;
}
}
//-----------------------------------------------------------------------------
void cMiscUtil::Get_File_Id_String(LPCSTR filename, StringClass & str)
{
WWASSERT(filename != NULL);
// WWDEBUG_SAY(("cMiscUtil::Get_File_Id_String for %s\n", filename));
//
// Get size
//
RawFileClass file(filename);
int filesize = file.Size();
//WWASSERT(filesize > 0);
if (filesize <= 0)
{
WWDEBUG_SAY(("Error: cMiscUtil::Get_File_Id_String for %s: filesize = %d\n",
filename, filesize));
DIE;
}
file.Close();
//
// Note... this timedatestamp is not present for all file types...
//
IMAGE_FILE_HEADER header = {0};
extern bool Get_Image_File_Header(LPCSTR filename, IMAGE_FILE_HEADER *file_header);
/*
bool success;
success = Get_Image_File_Header(filename, &header);
WWASSERT(success);
*/
Get_Image_File_Header(filename, &header);
int time_date_stamp = header.TimeDateStamp;
char working_filename[500];
strcpy(working_filename, filename);
::strupr(working_filename);
//
// Strip path off filename
//
char * p_start = &working_filename[strlen(working_filename)];
int num_chars = 1;
while (p_start > working_filename && *(p_start - 1) != '\\') {
p_start--;
num_chars++;
}
::memmove(working_filename, p_start, num_chars);
//
// Put all this data into a string
//
str.Format("%s %d %d", working_filename, filesize, time_date_stamp);
//WWDEBUG_SAY(("File id string: %s\n", str));
}
//-----------------------------------------------------------------------------
void cMiscUtil::Remove_File(LPCSTR filename)
{
WWASSERT(filename != NULL);
::DeleteFile(filename);
}
/*
#define SIZE_OF_NT_SIGNATURE sizeof(DWORD)
#define PEFHDROFFSET(a) ((LPVOID)((BYTE *)a + \
((PIMAGE_DOS_HEADER)a)->e_lfanew + SIZE_OF_NT_SIGNATURE))
*/
/*
int cMiscUtil::Get_Exe_Key(void)
{
//
// Get exe name
//
char filename[500];
int succeeded;
succeeded = ::GetModuleFileName(NULL, filename, sizeof(filename));
::strupr(filename);
WWASSERT(succeeded);
//
// Get size
//
RawFileClass file(filename);
int filesize = file.Size();
WWASSERT(filesize > 0);
file.Close();
//
// Strip path off filename
//
char * p_start = &filename[strlen(filename)];
int num_chars = 1;
while (*(p_start - 1) != '\\') {
p_start--;
num_chars++;
}
::memmove(filename, p_start, num_chars);
//
// Pull a time/date stamp out of the exe header
//
PIMAGE_FILE_HEADER p_header = (PIMAGE_FILE_HEADER) PEFHDROFFSET(ProgramInstance);
WWASSERT(p_header != NULL);
int time_date_stamp = p_header->TimeDateStamp;
//
// Put all this data into a string
//
char id_string[500];
::sprintf(id_string, "%s %d %d", filename, filesize, time_date_stamp);
WWDEBUG_SAY(("File id string: %s\n", id_string));
//
// return the crc of that string as the key
//
return CRCEngine()(id_string, strlen(id_string));
}
*/
//#include <stdio.h>
//#include "verchk.h"
/*
//-----------------------------------------------------------------------------
int cMiscUtil::Get_Exe_Key(void)
{
//
// Get exe name
//
char filename[500];
int succeeded;
succeeded = ::GetModuleFileName(NULL, filename, sizeof(filename));
::strupr(filename);
WWASSERT(succeeded);
StringClass string;
Get_File_Id_String(filename, string);
//
// return the crc of that string as the key
//
return CRCEngine()(string, strlen(string));
}
*/
//#include "crc.h"

70
Code/wwutil/miscutil.h Normal file
View File

@@ -0,0 +1,70 @@
/*
** Command & Conquer Renegade(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/>.
*/
//
// Filename: miscutil.h
// Project: wwutil
// Author: Tom Spencer-Smith
// Date: June 1998
// Description:
//
//-----------------------------------------------------------------------------
#if defined(_MSV_VER)
#pragma once
#endif
#ifndef MISCUTIL_H
#define MISCUTIL_H
#ifndef ALWAYS_H
#include "always.h"
#endif
#include "bittype.h"
#include "wwstring.h"
const float MISCUTIL_EPSILON = 0.0001f;
class cMiscUtil
{
public:
static LPCSTR Get_Text_Time(void);
static void Seconds_To_Hms(float seconds, int & h, int & m, int & s);
static bool Is_String_Same(LPCSTR str1, LPCSTR str2);
static bool Is_String_Different(LPCSTR str1, LPCSTR str2);
static void Get_File_Id_String(LPCSTR filename, StringClass & str);
static bool File_Exists(LPCSTR filename);
static bool File_Is_Read_Only(LPCSTR filename);
static bool Is_Alphabetic(char c);
static bool Is_Numeric(char c);
static bool Is_Alphanumeric(char c);
static bool Is_Whitespace(char c);
static void Trim_Trailing_Whitespace(char * text);
static void Remove_File(LPCSTR filename);
private:
};
#endif // MISCUTIL_H
//static int Get_Exe_Key(void);

286
Code/wwutil/stackdump.cpp Normal file
View File

@@ -0,0 +1,286 @@
/*
** Command & Conquer Renegade(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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/wwutil/stackdump.cpp $*
* *
* $Author:: Tom_s $*
* *
* $Modtime:: 9/29/01 1:13p $*
* *
* $Revision:: 1 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "stackdump.h"
#include <windows.h>
#include <imagehlp.h>
#include <conio.h>
#include <imagehlp.h>
#include <crtdbg.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "wwdebug.h"
typedef BOOL (WINAPI *SymCleanupType) (HANDLE hProcess);
typedef BOOL (WINAPI *SymGetSymFromAddrType) (HANDLE hProcess, DWORD Address, LPDWORD Displacement, PIMAGEHLP_SYMBOL Symbol);
typedef BOOL (WINAPI *SymInitializeType) (HANDLE hProcess, LPSTR UserSearchPath, BOOL fInvadeProcess);
typedef BOOL (WINAPI *SymLoadModuleType) (HANDLE hProcess, HANDLE hFile, LPSTR ImageName, LPSTR ModuleName, DWORD BaseOfDll, DWORD SizeOfDll);
typedef DWORD (WINAPI *SymSetOptionsType) (DWORD SymOptions);
typedef BOOL (WINAPI *SymUnloadModuleType) (HANDLE hProcess, DWORD BaseOfDll);
typedef BOOL (WINAPI *StackWalkType) (DWORD MachineType, HANDLE hProcess, HANDLE hThread, LPSTACKFRAME StackFrame, LPVOID ContextRecord, PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine, PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine, PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine, PTRANSLATE_ADDRESS_ROUTINE TranslateAddress);
typedef LPVOID (WINAPI *SymFunctionTableAccessType) (HANDLE hProcess, DWORD AddrBase);
typedef DWORD (WINAPI *SymGetModuleBaseType) (HANDLE hProcess, DWORD dwAddr);
static SymCleanupType _SymCleanup = NULL;
static SymGetSymFromAddrType _SymGetSymFromAddr = NULL;
static SymInitializeType _SymInitialize = NULL;
static SymLoadModuleType _SymLoadModule = NULL;
static SymSetOptionsType _SymSetOptions = NULL;
static SymUnloadModuleType _SymUnloadModule = NULL;
static StackWalkType _StackWalk = NULL;
static SymFunctionTableAccessType _SymFunctionTableAccess = NULL;
static SymGetModuleBaseType _SymGetModuleBase = NULL;
static char const * ImagehelpFunctionNames[] =
{
"SymCleanup",
"SymGetSymFromAddr",
"SymInitialize",
"SymLoadModule",
"SymSetOptions",
"SymUnloadModule",
"StackWalk",
"SymFunctionTableAccess",
"SymGetModuleBaseType",
NULL
};
//
// Class statics
//
//-----------------------------------------------------------------------------
static char const *
Last_Error_Text
(
void
)
{
static char message_buffer[256];
::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &message_buffer[0], 256, NULL);
return (message_buffer);
}
//-----------------------------------------------------------------------------
void
cStackDump::Print_Call_Stack
(
void
)
{
WWDEBUG_SAY(("cStackDump::Print_Call_Stack:\n"));
HINSTANCE imagehelp = ::LoadLibrary("IMAGEHLP.DLL");
if (imagehelp == NULL)
{
WWDEBUG_SAY((" Unable to load IMAGEHLP.DLL.\n"));
}
else
{
WWDEBUG_SAY((" Found IMAGEHLP.DLL - linking to required functions.\n"));
char const * function_name = NULL;
ULONG * fptr = (ULONG *) &_SymCleanup;
int count = 0;
do
{
function_name = ImagehelpFunctionNames[count];
if (function_name != NULL)
{
*fptr = (ULONG) ::GetProcAddress(imagehelp, function_name);
fptr++;
count++;
}
} while (function_name != NULL);
}
extern int Stack_Walk(ULONG * return_addresses, int num_addresses, CONTEXT * context);
ULONG return_addresses[256];
int num_addresses = Stack_Walk(return_addresses, 256, NULL);
unsigned char symbol[256];
IMAGEHLP_SYMBOL * symptr = (IMAGEHLP_SYMBOL*) &symbol;
int symload = 0;
bool symbols_available = false;
if (_SymInitialize != NULL && _SymInitialize(::GetCurrentProcess(), NULL, false))
{
WWDEBUG_SAY((" Symbols are available.\n"));
symbols_available = true;
if (_SymSetOptions != NULL)
{
_SymSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_UNDNAME);
}
char module_name[_MAX_PATH];
::GetModuleFileName(NULL, module_name, sizeof(module_name));
if (_SymLoadModule != NULL)
{
symload = _SymLoadModule(::GetCurrentProcess(), NULL, module_name, NULL, 0, 0);
}
if (symload == 0 && GetLastError() != 0)
{
assert(_SymLoadModule != NULL);
WWDEBUG_SAY((" SymLoad failed for module %s with code %d - %s.\n",
module_name, GetLastError(), Last_Error_Text()));
}
}
else
{
WWDEBUG_SAY((" Symbols are NOT available.\n"));
WWDEBUG_SAY((" SymInitialize failed with code %d - %s.\n", GetLastError(), Last_Error_Text()));
}
if (num_addresses > 0)
{
WWDEBUG_SAY((" Stack:\n"));
for (int s = 0 ; s < num_addresses; s++)
{
ULONG temp_addr = return_addresses[s];
for (int space = 0 ; space <= s ; space++)
{
WWDEBUG_SAY((" "));
}
if (symbols_available)
{
symptr->SizeOfStruct = sizeof(symbol);
symptr->MaxNameLength = 128;
symptr->Size = 0;
symptr->Address = temp_addr;
ULONG displacement = 0;
if (_SymGetSymFromAddr != NULL && _SymGetSymFromAddr(GetCurrentProcess(), temp_addr, &displacement, symptr))
{
char symbuf[256];
//::sprintf(symbuf, "%s + %08X\n", symptr->Name, displacement);
if (s == 0)
{
::sprintf(symbuf, "%s + %08X", symptr->Name, displacement);
}
else
{
::sprintf(symbuf, "%s", symptr->Name);
}
WWDEBUG_SAY((symbuf));
}
}
else
{
char symbuf[256];
::sprintf(symbuf, "%08x", temp_addr);
WWDEBUG_SAY((symbuf));
}
WWDEBUG_SAY(("\n"));
}
}
else
{
WWDEBUG_SAY((" Stack walk failed!\n"));
}
//
// Unload the symbols.
//
if (symbols_available)
{
if (_SymCleanup != NULL)
{
_SymCleanup(GetCurrentProcess());
}
if (symload && _SymUnloadModule != NULL)
{
_SymUnloadModule(GetCurrentProcess(), NULL);
}
}
if (imagehelp)
{
::FreeLibrary(imagehelp);
}
}
/*
//
// Determine the path to the executable
//
char path[MAX_PATH] = "";
DWORD gmf = ::GetModuleFileName(NULL, path, sizeof(path));
if (gmf != 0)
{
//
// Strip off the filename
//
char * filename = ::strrchr(path, '\\');
if (filename != NULL)
{
filename[0] = 0;
}
::SetCurrentDirectory(path);
}
*/

59
Code/wwutil/stackdump.h Normal file
View File

@@ -0,0 +1,59 @@
/*
** Command & Conquer Renegade(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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/wwutil/stackdump.h $*
* *
* $Author:: Tom_s $*
* *
* $Modtime:: 9/29/01 4:13p $*
* *
* $Revision:: 1 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef __STACKDUMP_H__
#define __STACKDUMP_H__
//
// Dump the call stack to the logfile. Based on Steve Tall's code.
//
#define LOG_CALL_STACK cStackDump::Print_Call_Stack()
//-----------------------------------------------------------------------------
class cStackDump
{
public:
static void Print_Call_Stack(void);
private:
};
//-----------------------------------------------------------------------------
#endif // __STACKDUMP_H__

135
Code/wwutil/wwutil.dsp Normal file
View File

@@ -0,0 +1,135 @@
# Microsoft Developer Studio Project File - Name="wwutil" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=wwutil - 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 "wwutil.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 "wwutil.mak" CFG="wwutil - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "wwutil - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "wwutil - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE "wwutil - Win32 Profile" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/Commando/Code/wwutil", ACDBAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "wwutil - 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 "_MBCS" /D "_LIB" /YX /FD /c
# ADD CPP /nologo /MT /W4 /Zi /O2 /Ob2 /I "..\wwlib" /I "..\wwdebug" /I "..\wwmath" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "WIN32" /D "_WINDOWS" /D "WIN32_LEAN_AND_MEAN" /FD /c
# SUBTRACT CPP /WX /YX
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"..\libs\release\wwutil.lib"
!ELSEIF "$(CFG)" == "wwutil - 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 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W4 /WX /Gm /Gi /ZI /Od /I "..\wwlib" /I "..\wwdebug" /I "..\wwmath" /D "_DEBUG" /D "WWDEBUG" /D "_MBCS" /D "_LIB" /D "WIN32" /D "_WINDOWS" /D "WIN32_LEAN_AND_MEAN" /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
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"..\Libs\Debug\wwutil.lib"
!ELSEIF "$(CFG)" == "wwutil - Win32 Profile"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Profile"
# PROP BASE Intermediate_Dir "Profile"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Profile"
# PROP Intermediate_Dir "Profile"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD CPP /nologo /MT /W4 /Zi /O2 /Op /Ob2 /I "..\wwlib" /I "..\wwdebug" /I "..\wwmath" /D "NDEBUG" /D "WWDEBUG" /D "_MBCS" /D "_LIB" /D "WIN32" /D "_WINDOWS" /D "WIN32_LEAN_AND_MEAN" /FD /c
# SUBTRACT CPP /WX /Fr /YX
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"..\libs\profile\wwutil.lib"
!ENDIF
# Begin Target
# Name "wwutil - Win32 Release"
# Name "wwutil - Win32 Debug"
# Name "wwutil - Win32 Profile"
# Begin Source File
SOURCE=.\mathutil.cpp
# End Source File
# Begin Source File
SOURCE=.\mathutil.h
# End Source File
# Begin Source File
SOURCE=.\miscutil.cpp
# End Source File
# Begin Source File
SOURCE=.\miscutil.h
# End Source File
# Begin Source File
SOURCE=.\stackdump.cpp
# End Source File
# Begin Source File
SOURCE=.\stackdump.h
# End Source File
# End Target
# End Project