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

341
Code/Tests/Bandy/bandy.cpp Normal file
View File

@@ -0,0 +1,341 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** 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 ***
***********************************************************************************************
* *
* Project Name : Bandwidth Tester Tester *
* *
* $Archive:: /Commando/Code/Tests/Bandy/bandy.cpp $*
* *
* $Author:: Steve_t $*
* *
* $Modtime:: 1/05/02 10:22p $*
* *
* $Revision:: 4 $*
* *
* *
*---------------------------------------------------------------------------------------------*
* *
* *
*---------------------------------------------------------------------------------------------*
* *
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include <winsock.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <bandtest\bandtest.h>
char *ErrorList[13] = {
"BANDTEST_OK",
"BANDTEST_NO_WINSOCK2",
"BANDTEST_NO_RAW_SOCKET_PERMISSION",
"BANDTEST_NO_RAW_SOCKET_CREATE",
"BANDTEST_NO_UDP_SOCKET_BIND",
"BANDTEST_NO_TTL_SET",
"BANDTEST_NO_PING_RESPONSE",
"BANDTEST_NO_FINAL_PING_TIME",
"BANDTEST_NO_EXTERNAL_ROUTER",
"BANDTEST_NO_IP_DETECT",
"BANDTEST_UNKNOWN_ERROR",
"BANDTEST_WRONG_API_VERSION",
"BANDTEST_BAD_PARAM"
};
#define NUM_BANDS 12
unsigned long Bandwidths [NUM_BANDS * 2] = {
12000, 14400,
25000, 28800,
33600, 33600,
53000, 57600,
62000, 67200,
105000, 115200,
125000, 128000,
250000, 256000,
500000, 512000,
999999, 1024000,
1999999, 2048000,
3999999, 4096000
};
char *BandwidthNames [NUM_BANDS] = {
"14400",
"28800",
"33600",
"57600",
"67200",
"115200",
"128k",
"256k",
"512k",
"1M",
"2M",
"4M"
};
BandtestSettingsStruct DefaultSettings = {
0, //AlwaysICMP
0, //TTLScatter
50, //FastPingPackets
12, //SlowPingPackets
25, //def =
0, //Ping profile
};
ULONG Enumerate_Nics(ULONG * addresses, ULONG max_nics)
{
assert(addresses != NULL);
assert(max_nics > 0);
ULONG num_addresses = 0;
//
// Get the local hostname
//
char local_host_name[300];
#ifdef _DEBUG
int gethostname_rc =
#endif //DEBUG
gethostname(local_host_name, sizeof(local_host_name));
assert(gethostname_rc != SOCKET_ERROR);
//
// Resolve hostname for local adapter addresses.
// This does a DNS lookup (name resolution)
//
LPHOSTENT p_hostent = gethostbyname(local_host_name);
if (p_hostent == NULL)
{
}
while (num_addresses < max_nics && p_hostent->h_addr_list[num_addresses] != NULL)
{
IN_ADDR in_addr;
memcpy(&in_addr, p_hostent->h_addr_list[num_addresses], sizeof(in_addr));
addresses[num_addresses] = in_addr.s_addr;
num_addresses++;
}
return num_addresses;
}
char * Addr_As_String(unsigned char *addr)
{
static char _string[128];
sprintf(_string, "%d.%d.%d.%d", (int)(addr[0]), (int)(addr[1]), (int)(addr[2]), (int)(addr[3]));
return(_string);
}
int main(int argc, char **argv)
{
unsigned long my_addresses[8];
int use_addr = -1;
int retries = 3;
int failure_code = BANDTEST_OK;
struct sockaddr_in address;
BandtestSettingsStruct *settings = &DefaultSettings;
WSADATA wsa_data;
if (WSAStartup(MAKEWORD(1,1), &wsa_data) != 0) {
printf("Bandy: WSAStartup failed: error code %d\n", GetLastError());
return(0);
}
int nics = Enumerate_Nics(&my_addresses[0], 8);
struct hostent *host = gethostbyname("www.ea.com");
/*
** Usage.
*/
printf("Bandwidth tester tester\n");
printf("Programmer: Steve Tall\n");
printf("V1.0\n");
printf("Usage: bandy.exe <options>\n");
printf("Options:\n");
printf(" -s<server> - Use specified server (def = www.ea.com)\n");
printf(" -i<ip index> - Use specified local ip index (def = auto discovery)\n");
printf(" -r<retrys> - Retry attempts after failure (def = 3)\n");
printf(" -l<packets> - Number of packets to send on low ping times (def = 50)\n");
printf(" -h<packets> - Number of packets to send on high ping times (def = 12)\n");
printf(" -p<time> - Fast ping threshold in ms (def = 25 ms)\n");
printf(" -a - Send bulk data as ICMP packets (def = UDP)\n");
printf(" -t - Scatter TTL on bulk data (def = no TTL scatter)\n");
printf(" -x - Do ping profiling (def = no profiling)\n\n");
printf("Available IPs : ");
for (int i=0 ; i<nics ; i++) {
printf("%d - %s\n ", i, Addr_As_String((unsigned char*)&my_addresses[i]));
}
printf("\n");
//WSACleanup();
//return(0);
for (int a=1 ; a<argc ; a++) {
if (argv[a][0] != '-' || strlen(&argv[a][0]) < 2) {
printf("Bad parameter %d\n", a);
WSACleanup();
return(0);
}
switch (toupper(argv[a][1])) {
case 'S':
host = gethostbyname(&argv[a][2]);
if (host == NULL) {
printf("Unable to resolve host name %s\n", &argv[a][2]);
WSACleanup();
return(0);
}
break;
case 'I':
use_addr = atoi(&argv[a][2]);
if (use_addr >= nics) {
printf("Bad IP index\n");
WSACleanup();
return(0);
}
break;
case 'R':
retries = atoi(&argv[a][2]);
break;
case 'L':
settings->FastPingPackets = atoi(&argv[a][2]);
break;
case 'H':
settings->SlowPingPackets = atoi(&argv[a][2]);
break;
case 'P':
settings->FastPingThreshold = atoi(&argv[a][2]);
break;
case 'A':
settings->AlwaysICMP = 1;
break;
case 'T':
settings->TTLScatter = 1;
break;
case 'X':
settings->PingProfile = 1;
break;
case 0:
default:
printf("Bad parameter %d\n", a);
WSACleanup();
return(0);
}
}
if (host == NULL) {
printf("Unable to resolve host name\n");
WSACleanup();
return(0);
}
memcpy(&(address.sin_addr), host->h_addr, host->h_length);
printf("Detecting bandwidth - please wait\n");
unsigned long downstream = 0;
unsigned long bw = Detect_Bandwidth(ntohl(address.sin_addr.s_addr), (use_addr == -1) ? 0 : ntohl(my_addresses[use_addr]), retries, failure_code, downstream, BANDTEST_API_VERSION, settings);
if (bw == 0) {
printf("Failed to get bandwidth - error code %s\n", ErrorList[failure_code]);
} else {
if (bw == 0xffffffff) {
printf("Upstream bandwidth is huge :-)\n");
} else {
if (bw > 100000) {
float floater = (float)bw / 1024;
printf("Upstream bandwidth to external router is %.1f kilobits per second\n", floater);
} else {
printf("Upstream bandwidth to external router is %d bits per second\n", bw);
}
bool got_bw_str = false;
for (int i=0 ; i<NUM_BANDS ; i++) {
if (bw < Bandwidths[i*2]) {
printf("Reported upstream connection bandwidth is %s bits per second\n", BandwidthNames[i]);
got_bw_str = true;
break;
}
}
if (!got_bw_str) {
printf("Reported upstream connection bandwidth is > 4M bits per second\n");
}
}
printf("\n");
if (downstream == 0xffffffff) {
printf("Downstream bandwidth is huge :-)\n");
} else {
if (downstream > 100000) {
float floater = (float)downstream / 1024;
printf("Downstream bandwidth to external router is %.1f kilobits per second\n", floater);
} else {
printf("Downstream bandwidth to external router is %d bits per second\n", downstream);
}
bool got_downstream_str = false;
for (int i=0 ; i<NUM_BANDS ; i++) {
if (downstream < Bandwidths[i*2]) {
printf("Reported downstream connection bandwidth is %s bits per second\n", BandwidthNames[i]);
got_downstream_str = true;
break;
}
}
if (!got_downstream_str) {
printf("Reported downstream connection bandwidth is > 4M bits per second\n");
}
}
}
WSACleanup();
return(0);
}

104
Code/Tests/Bandy/bandy.dsp Normal file
View File

@@ -0,0 +1,104 @@
# Microsoft Developer Studio Project File - Name="bandy" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=bandy - 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 "bandy.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 "bandy.mak" CFG="bandy - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "bandy - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "bandy - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "bandy - 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 Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W4 /GX- /O2 /Ob2 /I "..\..\\" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c
# SUBTRACT CPP /YX
# 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 bandtest.lib wsock32.lib /nologo /subsystem:console /debug /machine:I386 /libpath:"..\..\libs\release"
!ELSEIF "$(CFG)" == "bandy - 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 Ignore_Export_Lib 0
# 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 /W4 /Gm /GX- /ZI /Od /I "..\..\\" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /GZ /c
# SUBTRACT CPP /YX
# 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 bandtest.lib wsock32.lib /nologo /subsystem:console /debug /machine:I386 /libpath:"..\..\libs\debug"
!ENDIF
# Begin Target
# Name "bandy - Win32 Release"
# Name "bandy - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\bandy.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

View File

@@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "bandy"=.\bandy.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

View File

@@ -0,0 +1,109 @@
# Microsoft Developer Studio Project File - Name="BitPackTest" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=BitPackTest - 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 "BitPackTest.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 "BitPackTest.mak" CFG="BitPackTest - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "BitPackTest - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "BitPackTest - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/Commando/Code/Tests/BitPackTest", IXKDAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "BitPackTest - 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)" == "BitPackTest - 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 Ignore_Export_Lib 0
# 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 /MTd /W4 /WX /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /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 "BitPackTest - Win32 Release"
# Name "BitPackTest - Win32 Debug"
# Begin Source File
SOURCE=.\Code\BitPacker.cpp
# End Source File
# Begin Source File
SOURCE=.\Code\BitPacker.h
# End Source File
# Begin Source File
SOURCE=.\Code\Main.cpp
# End Source File
# Begin Source File
SOURCE=.\Code\TypeEncoder.cpp
# End Source File
# Begin Source File
SOURCE=.\Code\TypeEncoder.h
# End Source File
# Begin Source File
SOURCE=.\Code\UTypes.h
# End Source File
# End Target
# End Project

View File

@@ -0,0 +1,373 @@
/*
** 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/>.
*/
/****************************************************************************
*
* FILE
* $Archive: /Commando/Code/Tests/BitPackTest/Code/BitPacker.cpp $
*
* DESCRIPTION
* Provide bit level packing for bools, variable length intergers and
* floats.
*
* PROGRAMMER
* Denzil E. Long, Jr.
*
* VERSION INFO
* $Author: Denzil_l $
* $Revision: 2 $
* $Modtime: 5/31/00 9:22a $
*
****************************************************************************/
#include "bitpacker.h"
#include "utypes.h"
#include <assert.h>
/******************************************************************************
*
* NAME
* BitPacker::BitPacker
*
* DESCRIPTION
* Default constructor
*
* INPUTS
* NONE
*
* RESULTS
* NONE
*
******************************************************************************/
BitPacker::BitPacker()
: mBuffer(NULL),
mBufferSize(0),
mBytePosition(0),
mBitMask(0x80),
mStore(0)
{
}
/******************************************************************************
*
* NAME
* BitPacker::BitPacker
*
* DESCRIPTION
* Constructor
*
* INPUTS
* Buffer - Pointer to buffer to store BitPacker data.
* BufferSize - Size in bytes of buffer.
*
* RESULTS
* NONE
*
******************************************************************************/
BitPacker::BitPacker(void* buffer, unsigned int bufferSize)
: mBuffer(NULL),
mBufferSize(0),
mBytePosition(0),
mBitMask(0x80),
mStore(0)
{
SetBuffer(buffer, bufferSize);
}
/******************************************************************************
*
* NAME
* BitPacker::~BitPacker
*
* DESCRIPTION
* Destructor
*
* INPUTS
* NONE
*
* RESULTS
* NONE
*
******************************************************************************/
BitPacker::~BitPacker()
{
Flush();
}
/******************************************************************************
*
* NAME
* BitPacker::SetBuffer
*
* DESCRIPTION
*
* INPUTS
* Buffer - Pointer to buffer to hold bitpacked data.
* Size - Size of buffer in bytes.
*
* RESULTS
* NONE
*
******************************************************************************/
void BitPacker::SetBuffer(void* buffer, unsigned int bufferSize)
{
assert(buffer != NULL);
mBuffer = (unsigned char*)buffer;
assert(bufferSize > 0);
mBufferSize = bufferSize;
}
/******************************************************************************
*
* NAME
* BitPacker::Flush
*
* DESCRIPTION
*
* INPUTS
* NONE
*
* RESULTS
* NONE
*
******************************************************************************/
void BitPacker::Flush(void)
{
if (mBitMask != 0x80) {
mBuffer[mBytePosition] = mStore;
}
}
/******************************************************************************
*
* NAME
* BitPacker::Reset
*
* DESCRIPTION
* Reset the packing stream.
*
* INPUTS
* NONE
*
* RESULTS
* NONE
*
******************************************************************************/
void BitPacker::Reset(void)
{
mBytePosition = 0;
mBitMask = 0x80;
}
/******************************************************************************
*
* NAME
* BitPacker::GetPackedSize
*
* DESCRIPTION
* Retrieve the number of bytes used to packed the stream.
*
* INPUTS
* NONE
*
* RESULTS
* unsigned int
*
******************************************************************************/
unsigned int BitPacker::GetPackedSize(void)
{
unsigned int size = mBytePosition;
if (mBitMask != 0x80) {
size++;
}
return size;
}
/******************************************************************************
*
* NAME
* BitPacker::GetBit
*
* DESCRIPTION
* Retrieve a bit from the stream
*
* INPUTS
* NONE
*
* RESULTS
* Bit - bit value
*
******************************************************************************/
int BitPacker::GetBit(void)
{
if (mBitMask == 0x80) {
mStore = mBuffer[mBytePosition];
mBytePosition++;
}
int value = ((mStore & mBitMask) ? 1 : 0);
mBitMask >>= 1;
if (mBitMask == 0) {
mBitMask = 0x80;
}
return value;
}
/******************************************************************************
*
* NAME
* BitPacker::PutBit
*
* DESCRIPTION
* Write a bit to the stream.
*
* INPUTS
* Bit - Bit to write
*
* RESULTS
* Success - True if successful; false otherwise
*
******************************************************************************/
bool BitPacker::PutBit(int value)
{
if (value) {
mStore |= mBitMask;
}
mBitMask >>= 1;
if (mBitMask == 0) {
mBitMask = 0x80;
mBuffer[mBytePosition] = mStore;
mBytePosition++;
mStore = 0;
}
return true;
}
/******************************************************************************
*
* NAME
* BitPacker::GetBits
*
* DESCRIPTION
* Retrieve bits from the stream.
*
* INPUTS
* Bits - On return; bits retrieved from stream.
* NumBits - Number of bits to retrieve.
*
* RESULTS
* BitsRead - Number of bits read.
*
******************************************************************************/
int BitPacker::GetBits(unsigned long& outBits, unsigned int numBits)
{
outBits = 0;
unsigned long mask = (1L << (numBits - 1));
while (mask != 0) {
if (mBitMask == 0x80) {
mStore = mBuffer[mBytePosition];
mBytePosition++;
}
if (mStore & mBitMask) {
outBits |= mask;
}
mBitMask >>= 1;
if (mBitMask == 0) {
mBitMask = 0x80;
}
mask >>= 1;
}
return numBits;
}
/******************************************************************************
*
* NAME
* BitPacker::PutBits
*
* DESCRIPTION
* Write bits to the stream
*
* INPUTS
* Bits - Bits to write to stream.
* NumBits - Number of bits to write.
*
* RESULTS
* BitsWritten - Number of bits written.
*
******************************************************************************/
int BitPacker::PutBits(unsigned long bits, unsigned int numBits)
{
unsigned long mask = (1L << (numBits - 1));
while (mask != 0) {
if (bits & mask) {
mStore |= mBitMask;
}
mBitMask >>= 1;
if (mBitMask == 0) {
mBitMask = 0x80;
mBuffer[mBytePosition] = mStore;
mBytePosition++;
mStore = 0;
}
mask >>= 1;
}
return numBits;
}

View File

@@ -0,0 +1,80 @@
/*
** 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/>.
*/
/****************************************************************************
*
* FILE
* $Archive: /Commando/Code/Tests/BitPackTest/Code/BitPacker.h $
*
* DESCRIPTION
* Provide variable length bit packing.
*
* PROGRAMMER
* Denzil E. Long, Jr.
*
* VERSION INFO
* $Author: Denzil_l $
* $Revision: 2 $
* $Modtime: 5/31/00 9:21a $
*
****************************************************************************/
#ifndef _BITPACKER_H_
#define _BITPACKER_H_
class BitPacker
{
public:
BitPacker();
BitPacker(void* buffer, unsigned int bufferSize);
virtual ~BitPacker();
// Set the buffer to use for read / write of bit packed data.
void SetBuffer(void* buffer, unsigned int bufferSize);
// Flush remainder bits to the stream.
// (This must be called when finished writting)
void Flush(void);
// Reset the bitpacked stream.
void Reset(void);
// Retrieve the length of the packed stream (in bytes).
unsigned int GetPackedSize(void);
// Retrieve a bit from the stream,
int GetBit(void);
// Write a bit to the stream
bool PutBit(int value);
// Retrieve a series of bits from the stream (Max = 32)
int GetBits(unsigned long& outBits, unsigned int numBits);
// Write a series of bits to the stream (Max = 32)
int PutBits(unsigned long bits, unsigned int numBits);
private:
unsigned char* mBuffer;
unsigned int mBufferSize;
unsigned int mBytePosition;
unsigned int mBitMask;
unsigned char mStore;
};
#endif // _BITPACKER_H_

View File

@@ -0,0 +1,85 @@
/*
** 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/>.
*/
/****************************************************************************
*
* FILE
* Main.cpp
*
* DESCRIPTION
* Main entry point for console application
*
* PROGRAMMER
* Denzil E. Long, Jr.
*
* VERSION INFO
* $Author: Denzil_l $
* $Revision: 3 $
* $Modtime: 6/19/00 2:37p $
* $Archive: /Commando/Code/Tests/BitPackTest/Code/Main.cpp $
*
****************************************************************************/
#include "typeencoder.h"
#include "bitpacker.h"
#include <stdio.h>
#include <assert.h>
#define BUFFER_SIZE 2048
void main(int, void**)
{
void* buffer = new unsigned char[BUFFER_SIZE];
if (buffer == NULL) {
printf("Failed to allocate buffer\n");
}
TypeEncoder::SetTypePrecision(TypeEncoder::X_POSITION, 0.0f, 1000.0f, 0.1f);
TypeEncoder encoder(buffer, BUFFER_SIZE);
encoder.PutBool(true);
encoder.PutBool(true);
encoder.PutBool(false);
encoder.PutInt(5, 3);
encoder.PutInt(1000, 12);
encoder.PutInt(-67, 7);
encoder.PutBool(true);
encoder.PutType(TypeEncoder::X_POSITION, 99.9f);
encoder.Flush();
printf("Finished : %d\n", encoder.GetPackedSize());
bool b;
int i;
float f;
encoder.Reset();
b = encoder.GetBool();
b = encoder.GetBool();
b = encoder.GetBool();
i = encoder.GetInt(3);
i = encoder.GetInt(12);
i = encoder.GetInt(7);
b = encoder.GetBool();
f = encoder.GetType(TypeEncoder::X_POSITION);
delete[] buffer;
}

View File

@@ -0,0 +1,455 @@
/*
** 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/>.
*/
/****************************************************************************
*
* FILE
* $Archive: /Commando/Code/Tests/BitPackTest/Code/TypeEncoder.cpp $
*
* DESCRIPTION
*
* PROGRAMMER
* Denzil E. Long, Jr.
*
* VERSION INFO
* $Author: Denzil_l $
* $Revision: 2 $
* $Modtime: 5/31/00 9:33a $
*
****************************************************************************/
#include "typeencoder.h"
#include "bitpacker.h"
#include <limits.h>
#include <stdlib.h>
#include <assert.h>
TypeEncoder::EncoderTypeEntry TypeEncoder::_mEncoderTypes[MAX_ENCODERTYPES] =
{
{X_POSITION, -1000.0f, 1000.0f, 0.0305f, 16},
{Y_POSITION, -1000.0f, 1000.0f, 0.0305f, 16},
{Z_POSITION, -1000.0f, 1000.0f, 0.0305f, 16},
};
/******************************************************************************
*
* NAME
* TypeEncoder::SetTypePrecision
*
* DESCRIPTION
* No description provided,
*
* INPUTS
* Type - Type to set precision for.
* MinExtent - Minimum value of type
* MaxExtent - Maximum value of type
* Resolution - Unit resolution
*
* RESULTS
* NONE
*
******************************************************************************/
void TypeEncoder::SetTypePrecision(EncoderType type, float min, float max,
float resolution)
{
EncoderTypeEntry& entry = _mEncoderTypes[type];
entry.MinExtent = min;
entry.MaxExtent = max;
entry.Resolution = resolution;
entry.BitPrecision = CalcBitPrecision(min, max, resolution);
}
/******************************************************************************
*
* NAME
* TypeEncoder::SetTypePrecision
*
* DESCRIPTION
* Set the type precision based on a desired resolution
*
* INPUTS
* Type - Type to set precision for.
* MinExtent - Minimum value of type
* MaxExtent - Maximum value of type
* Resolution - Unit resolution
*
* RESULTS
* NONE
*
******************************************************************************/
void TypeEncoder::SetTypePrecision(EncoderType type, float min, float max,
unsigned int bitPrecision)
{
EncoderTypeEntry& entry = _mEncoderTypes[type];
entry.MinExtent = min;
entry.MaxExtent = max;
entry.Resolution = CalcResolution(min, max, bitPrecision);
entry.BitPrecision = bitPrecision;
}
/******************************************************************************
*
* NAME
* TypeEncoder::TypeEncoder
*
* DESCRIPTION
* Constructor
*
* INPUTS
* Buffer - Pointer to buffer to store bitpacked data.
* Size - Length of buffer in bytes.
*
* RESULTS
* NONE
*
******************************************************************************/
TypeEncoder::TypeEncoder(void* buffer, unsigned int size)
: BitPacker(buffer, size)
{
}
/******************************************************************************
*
* NAME
* TypeEncoder::~TypeEncoder
*
* DESCRIPTION
* Destructor
*
* INPUTS
* NONE
*
* RESULTS
* NONE
*
******************************************************************************/
TypeEncoder::~TypeEncoder()
{
}
/******************************************************************************
*
* NAME
* TypeEncoder::GetBool
*
* DESCRIPTION
* Retrieve a boolean value (1 bit)
*
* INPUTS
* NONE
*
* RESULTS
* Bool - Boolean value
*
******************************************************************************/
bool TypeEncoder::GetBool(void)
{
return (BitPacker::GetBit() == 1);
}
/******************************************************************************
*
* NAME
* TypeEncoder::PutBool
*
* DESCRIPTION
* Write a boolean value (1 bit)
*
* INPUTS
* Value - Boolean value
*
* RESULTS
* Success - True if successful; otherwise false
*
******************************************************************************/
bool TypeEncoder::PutBool(bool value)
{
return BitPacker::PutBit((int)value);
}
/******************************************************************************
*
* NAME
* TypeEncoder::GetInt
*
* DESCRIPTION
* Retrieve an integer value
*
* INPUTS
* BitPrecision - Number of bits to use to represent integer
*
* RESULTS
* Value - Integer value
*
******************************************************************************/
int TypeEncoder::GetInt(unsigned int bitPrecision)
{
// Get the sign
int sign = BitPacker::GetBit();
// Get the number
unsigned long code;
BitPacker::GetBits(code, bitPrecision);
// Adjust sign
if (sign) {
code = -((int)code);
}
return (int)code;
}
/******************************************************************************
*
* NAME
* TypeEncoder::PutInt
*
* DESCRIPTION
* Write an integer
*
* INPUTS
* Value - Numerical value to write
* BitPrecision - Number of bits to represent value.
*
* RESULTS
* Success - True if successful; False otherwise
*
******************************************************************************/
bool TypeEncoder::PutInt(int value, unsigned int bitPrecision)
{
BitPacker::PutBit(value < 0);
BitPacker::PutBits((unsigned long)abs(value), bitPrecision);
return true;
}
/******************************************************************************
*
* NAME
* TypeEncoder::GetFloat
*
* DESCRIPTION
* Retrieve a floating point value
*
* INPUTS
* Min - Mimimum extent of number
* Max - Maximum extent of number
* Resolution - Unit resolution
*
* RESULTS
* Value - Floating point value
*
******************************************************************************/
float TypeEncoder::GetFloat(float min, float max, float resolution)
{
unsigned int bitPrecision = CalcBitPrecision(min, max, resolution);
unsigned long code = 0;
BitPacker::GetBits(code, bitPrecision);
float value = (((float)code * resolution) + min);
return value;
}
/******************************************************************************
*
* NAME
* TypeEncoder::PutFloat
*
* DESCRIPTION
* Write a floating point value
*
* INPUTS
* Value - Value to write
* Min - Mimimum extent of number
* Max - Maximum extent of number
* Resolution - Unit resolution
*
* RESULTS
* Success - True if successful; False otherwise
*
******************************************************************************/
bool TypeEncoder::PutFloat(float value, float min, float max, float resolution)
{
unsigned int bitPrecision = CalcBitPrecision(min, max, resolution);
unsigned long code = (unsigned long)((value - min) / resolution);
BitPacker::PutBits(code, bitPrecision);
return true;
}
/******************************************************************************
*
* NAME
* TypeEncoder::GetType
*
* DESCRIPTION
* Retrieve number of specified type
*
* INPUTS
* Type - Precision type of number to retrieve
*
* RESULTS
* Value - Number of specified type
*
******************************************************************************/
float TypeEncoder::GetType(EncoderType type)
{
EncoderTypeEntry& entry = _mEncoderTypes[type];
unsigned long code = 0;
BitPacker::GetBits(code, entry.BitPrecision);
float value = (((float)code * entry.Resolution) + entry.MinExtent);
return value;
}
/******************************************************************************
*
* NAME
* TypeEncoder::PutType
*
* DESCRIPTION
* Write a number of the specified type
*
* INPUTS
* Type - Precision type to use to encode number
* Value - Number to encode.
*
* RESULTS
* Success - True if successful; False otherwise
*
******************************************************************************/
bool TypeEncoder::PutType(EncoderType type, float value)
{
EncoderTypeEntry& entry = _mEncoderTypes[type];
unsigned long code = (unsigned long)((value - entry.MinExtent) / entry.Resolution);
BitPacker::PutBits(code, entry.BitPrecision);
return true;
}
/******************************************************************************
*
* NAME
* TypeEncoder::CalcBitPrecision
*
* DESCRIPTION
* Calculate the minimum number of bits required to encode the value with
* the specified resolution.
*
* INPUTS
* Min - Minimum extent.
* Max - Maximum extent
* Resolution - Unit resolution
*
* RESULTS
* Bits - Number of bits to encode value
*
******************************************************************************/
unsigned int TypeEncoder::CalcBitPrecision(float min, float max, float resolution)
{
// Calculate the minimum number of bits required to encode this type with
// the specified resolution.
float range = (max - min);
unsigned int units = (unsigned int)((range / resolution) + 0.5);
unsigned int numBits = 32;
unsigned long bitMask = (1U << 31);
while (numBits > 0) {
if (units & bitMask) {
break;
}
numBits--;
bitMask >>= 1;
}
assert(numBits >= 1);
return numBits;
}
/******************************************************************************
*
* NAME
* TypeEncoder::CalcResolution
*
* DESCRIPTION
* No description provided,
*
* INPUTS
* float min
* float max
* unsigned int bitPrecision
*
* RESULTS
* float
*
******************************************************************************/
float TypeEncoder::CalcResolution(float min, float max, unsigned int bitPrecision)
{
static unsigned long _precisionRange[32] = {
0x00000001, 0x00000003, 0x00000007, 0x0000000F,
0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF,
0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF,
0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF,
0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 0x000FFFFF,
0x001FFFFF, 0x003FFFFF, 0x007FFFFF, 0x00FFFFFF,
0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF,
0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF
};
assert(bitPrecision >= 1);
assert(bitPrecision <= 32);
// Calculate the minimum resolution required to encode this type with
// the specified bits.
float range = (max - min);
float resolution = (range / _precisionRange[bitPrecision]);
return resolution;
}

View File

@@ -0,0 +1,106 @@
/*
** 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/>.
*/
/****************************************************************************
*
* FILE
* $Archive: /Commando/Code/Tests/BitPackTest/Code/TypeEncoder.h $
*
* DESCRIPTION
*
* PROGRAMMER
* Denzil E. Long, Jr.
*
* VERSION INFO
* $Author: Denzil_l $
* $Revision: 2 $
* $Modtime: 5/31/00 9:23a $
*
****************************************************************************/
#ifndef _TYPEENCODER_H_
#define _TYPEENCODER_H_
#include "bitpacker.h"
class TypeEncoder : public BitPacker
{
public:
typedef enum
{
X_POSITION = 0,
Y_POSITION,
Z_POSITION,
MAX_ENCODERTYPES
} EncoderType;
// Set the type precision based on a desired resolution
static void SetTypePrecision(EncoderType type, float min, float max,
float resolution);
// Set the type precision based on desired bit width.
static void SetTypePrecision(EncoderType type, float min, float max,
unsigned int bitPrecision);
TypeEncoder(void* buffer, unsigned int size);
~TypeEncoder();
// Retrieve a boolean value (1 bit)
bool GetBool(void);
// Write a boolean value (1 bit)
bool PutBool(bool value);
// Retrieve an integer
int GetInt(unsigned int bitPrecision);
// Write an integer with specified bit precision
bool PutInt(int value, unsigned int bitPrecision);
// Retrieve a floating point value
float GetFloat(float min, float max, float resolution);
// Write a floating point value
bool PutFloat(float value, float min, float max, float resolution);
// Retrieve a value of specified type
float GetType(EncoderType type);
// Write a value of specified type
bool PutType(EncoderType type, float value);
private:
// Calculate the number of bits required to encode a value. (Internal use)
static unsigned int CalcBitPrecision(float min, float max, float resolution);
// Calculate the minimum resolution possible with given bit width.(Internal use)
static float CalcResolution(float min, float max, unsigned int bitPrecision);
typedef struct
{
EncoderType Type;
float MinExtent;
float MaxExtent;
float Resolution;
unsigned int BitPrecision;
} EncoderTypeEntry;
static EncoderTypeEntry _mEncoderTypes[MAX_ENCODERTYPES];
};
#endif // _TYPEENCODER_H_

View File

@@ -0,0 +1,95 @@
/*
** 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/>.
*/
/****************************************************************************
*
* FILE
* UTypes.h
*
* DESCRIPTION
* Generic user type definitions
*
* PROGRAMMER
* Denzil E. Long, Jr.
*
* VERSION INFO
* $Author: Denzil_l $
* $Revision: 1 $
* $Modtime: 12/02/99 4:31p $
* $Archive: /Commando/Code/Tests/BitPackTest/Code/UTypes.h $
*
****************************************************************************/
#ifndef _UTYPES_H_
#define _UTYPES_H_
//! Signed integer value
typedef int Int;
//! Unsigned integer value
typedef unsigned int UInt;
//! Signed 8bit value (-127 - 128)
typedef char Int8;
//! Unsigned 8bit value (0 - 255)
typedef unsigned char UInt8;
//! Signed 16bit value (-32767 - 32768)
typedef short Int16;
//! Unsigned 16bit value (0 - 65535)
typedef unsigned short UInt16;
//! Signed 32bit value
typedef long Int32;
//! Unsigned 32bit value
typedef unsigned long UInt32;
//! Signed character
typedef char Char;
//! Unsigned character
typedef unsigned char UChar;
//! 32bit floating point value
typedef float Float32;
//! 64bit floating point value
typedef double Float64;
//! Floating point value
typedef Float32 Float;
//! TriState
typedef enum
{
OFF = false,
ON = true,
PENDING = -1
} TriState;
//! Empty pointer
#ifndef NULL
#define NULL (0L)
#endif
#endif // _UTYPES_H_

View File

@@ -0,0 +1,58 @@
# Microsoft Developer Studio Project File - Name="LocalHost" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=LocalHost - 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 "LocalHost.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 "LocalHost.mak" CFG="LocalHost - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "LocalHost - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/Commando/Code/Tests/LocalHost", GNCEAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
RSC=rc.exe
# 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 Ignore_Export_Lib 0
# 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 /W4 /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 winmm.lib wsock32.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 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
# Begin Target
# Name "LocalHost - Win32 Debug"
# Begin Source File
SOURCE=.\main.cpp
# End Source File
# End Target
# End Project

View File

@@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "LocalHost"=.\LocalHost.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

View File

@@ -0,0 +1,117 @@
/*
** 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/>.
*/
//*****************************************************************************
//
// Copyright (c) 2000 Westwood Studios. All Rights Reserved.
//
// localhost.cpp
//
// Created on 12 Apr 2001 by Tom Spencer-Smith (Westwood/Vegas)
//
// Description:
// Just a wee test to see if I can use localhost addressing (127.0.0.1)
// on non-networked systems...
//
//*****************************************************************************
#include <stdio.h>
#include <conio.h>
#include <winsock.h>
#include <assert.h>
//---------------------------------------------------------------------------
void main(void)
{
WSADATA winsock_data;
int rc_wsastartup = ::WSAStartup(MAKEWORD(1, 1), &winsock_data);
assert(rc_wsastartup == 0);
SOCKET sock = ::socket(AF_INET, SOCK_DGRAM, 0);
if (sock == INVALID_SOCKET)
{
::printf("::socket failed with error code %d\n", ::WSAGetLastError());
}
assert(sock != INVALID_SOCKET);
ULONG is_nonblocking = TRUE;
int rc_ioctl = ::ioctlsocket(sock, FIONBIO, &is_nonblocking);
assert(rc_ioctl == 0);
SOCKADDR_IN local_address;
local_address.sin_family = AF_INET;
local_address.sin_addr.s_addr = ::inet_addr("127.0.0.1"); // localhost
local_address.sin_port = ::htons(5555); // arbitrary
int rc_bind = ::bind(sock, reinterpret_cast<const SOCKADDR *>(&local_address),
sizeof(local_address));
assert(rc_bind == 0);
while (!::kbhit())
{
//
// Send a packet periodically
//
static DWORD last_send_time_ms = 0;
DWORD time_now_ms = ::timeGetTime();
const DWORD SEND_INTERVAL_MS = 500;
if (time_now_ms - last_send_time_ms > SEND_INTERVAL_MS)
{
last_send_time_ms = time_now_ms;
static int send_count = 0;
char send_data[200];
::sprintf(send_data, "packet_%d", send_count++);
int to_len = sizeof(local_address);
int rc_send = ::sendto(sock, send_data, ::strlen(send_data), 0,
(LPSOCKADDR) &local_address, to_len);
assert(rc_send != SOCKET_ERROR);
::printf("Sent %d bytes (%s) on socket %d\n", rc_send, send_data, sock);
}
//
// Receive all data available
//
int rc_recv = 0;
do
{
char recv_data[200];
::memset(recv_data, 0, sizeof(recv_data));
SOCKADDR_IN from_address;
int from_len = sizeof(from_address);
rc_recv = ::recvfrom(sock, recv_data, sizeof(recv_data), 0,
(LPSOCKADDR) &from_address, &from_len);
if (rc_recv > 0)
{
::printf("Recd %d bytes (%s) on socket %d\n", rc_recv, recv_data, sock);
}
else
{
assert(::WSAGetLastError() == WSAEWOULDBLOCK);
}
} while (rc_recv > 0);
}
int rc_cs = ::closesocket(sock);
assert(rc_cs == 0);
int rc_wsacleanup = ::WSACleanup();
assert(rc_wsacleanup == 0);
}

View File

@@ -0,0 +1,388 @@
/*
** 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/>.
*/
/* $Header: /Commando/Code/Tests/MeshTest/WINMAIN.CPP 9 12/10/98 5:53p Greg_h $ */
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Tests/MeshTest/WINMAIN.CPP $*
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 12/07/98 12:11p $*
* *
* $Revision:: 9 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* WinMain -- Win32 Program Entry Point! *
* WIN_resize -- Surrender-required function which resizes the main window *
* WIN_set_fullscreen -- Surrender-required function for toggling full-screen mode *
* Main_Window_Proc -- Windows Proc for the main game window *
* Create_Main_Window -- Creates the main game window *
* Focus_Loss -- this function is called when the application loses focus *
* Focus_Restore -- This function is called when the application gets focus *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#define NOMINMAX
#include "winmain.h"
#include <sr.hpp>
#include "win.h"
#include "wwmouse.h"
#include "init.h"
#include "mainloop.h"
#include "shutdown.h"
#include "_globals.h"
//----------------------------------------------------------------------------
// Globals
//----------------------------------------------------------------------------
extern "C"
{
HWND hWndMain;
bool WIN_fullscreen = true;
}
//----------------------------------------------------------------------------
// Local functions
//----------------------------------------------------------------------------
static BOOL Create_Main_Window(HANDLE hInstance, int nCmdShow);
long FAR PASCAL Main_Window_Proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
void Focus_Loss(void);
void Focus_Restore(void);
void Split_Command_Line_Args(HINSTANCE instance, char *path_to_exe, char *command_line);
void Set_Working_Directory(char *old_path, char *new_path);
/***********************************************************************************************
* WinMain -- Win32 Program Entry Point! *
* *
* INPUT: *
* *
* Standard WinMain inputs :-) *
* *
* OUTPUT: *
* *
* Standard WinMain output *
* *
* WARNINGS: *
* *
* HISTORY: *
* 07/18/1997 GH : Created. *
*=============================================================================================*/
int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
LPSTR command;
HANDLE prev;
char path_to_exe[_MAX_PATH];
char oldpath[_MAX_PATH];
command = lpCmdLine;
prev = hPrevInstance;
if (!Create_Main_Window(hInstance, nCmdShow)) return 0;
// Setup the keyboard system
Keyboard = new WWKeyboardClass();
// Setup the mouse system and take over the mouse.
MouseCursor = new WWMouseClass(NULL, MainWindow);
Split_Command_Line_Args(hInstance, &path_to_exe[0], lpCmdLine);
Set_Working_Directory(oldpath, &path_to_exe[0]);
Init();
Main_Loop();
Shutdown();
delete Keyboard;
delete MouseCursor;
return(EXIT_SUCCESS);
}
/***********************************************************************************************
* Main_Window_Proc -- Windows Proc for the main game window *
* *
* INPUT: *
* *
* Standard Windows Proc inputs *
* *
* OUTPUT: *
* *
* Standard Windows Proc output *
* *
* WARNINGS: *
* *
* HISTORY: *
* 07/18/1997 GH : Created. *
*=============================================================================================*/
long FAR PASCAL Main_Window_Proc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
{
PAINTSTRUCT ps;
HDC hdc;
/*
** Pass this message through to the keyboard handler. If the message
** was processed and requires no further action, then return with
** this information.
*/
if (Keyboard) {
Keyboard->Message_Handler(hwnd, message, wParam, lParam);
}
switch (message )
{
/*
** basic management messages
*/
case WM_ACTIVATEAPP:
if (WIN_fullscreen) {
GameInFocus = (wParam != 0);
if (!GameInFocus) {
Focus_Loss();
} else {
Focus_Restore();
}
} else {
GameInFocus = true;
if (wParam != 0) {
if (MouseCursor != NULL) MouseCursor->Capture_Mouse();
} else {
if (MouseCursor != NULL) MouseCursor->Release_Mouse();
}
}
return(0);
case WM_SETCURSOR:
SetCursor(NULL);
return 1;
case WM_ERASEBKGND:
return 1;
case WM_PAINT:
hdc = BeginPaint( hwnd, &ps);
EndPaint( hwnd, &ps);
return 1;
/*
** minimize/maximize
*/
case WM_SYSKEYDOWN:
if (wParam == VK_RETURN && ((lParam>>16) & KF_ALTDOWN) && !((lParam>>16) & KF_REPEAT))
{
WIN_fullscreen = !WIN_fullscreen;
}
break;
/*
** interface open and close
*/
case WM_CREATE:
break;
case WM_DESTROY:
ReleaseCapture();
PostQuitMessage( 0);
break;
case WM_SYSCOMMAND:
switch (wParam) {
case SC_CLOSE:
/*
** Windows sent us a close message. Probably in response to Alt-F4. Ignore it by
** pretending to handle the message and returning true;
*/
return (0);
case SC_SCREENSAVE:
/*
** Windoze is about to start the screen saver. If we just return without passing
** this message to DefWindowProc then the screen saver will not be allowed to start.
*/
return (0);
}
break;
default:
break;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
/***********************************************************************************************
* Create_Main_Window -- Creates the main game window *
* *
* INPUT: *
* *
* hInstance -- Instance handle of the application *
* nCmdShow -- how the window is to be shown *
* *
* OUTPUT: *
* *
* TRUE = success, FALSE = failure *
* *
* WARNINGS: *
* *
* HISTORY: *
* 07/18/1997 GH : Created. *
*=============================================================================================*/
static BOOL Create_Main_Window(HANDLE hInstance, int nCmdShow)
{
WNDCLASS wc;
BOOL rc;
ProgramInstance = (HINSTANCE)hInstance;
wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
wc.lpfnWndProc = Main_Window_Proc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = (HINSTANCE)hInstance;
wc.hIcon = LoadIcon( NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor( NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = "SRCLASS";
rc = RegisterClass( &wc);
if (!rc ) return FALSE;
MainWindow = hWndMain = CreateWindowEx(
0, // WS_EX_TOPMOST,
"SRClass",
"Commando",
WS_VISIBLE |
WS_CAPTION |
WS_BORDER |
WS_SYSMENU |
WS_MINIMIZEBOX |
WS_MAXIMIZEBOX |
WS_THICKFRAME,
0, 0, // top left corner
640,
480,
NULL, // no parent handle
NULL, // no menu handle
ProgramInstance, // main program instance
NULL); // creation parameters
if (!MainWindow) {
return FALSE;
}
return TRUE;
}
/***********************************************************************************************
* Focus_Loss -- this function is called when the application loses focus *
* *
* INPUT: Nothing *
* *
* OUTPUT: Nothing *
* *
* WARNINGS: None *
* *
* HISTORY: *
* 07/18/1997 GH : Created. *
*=============================================================================================*/
void Focus_Loss(void)
{
}
/***********************************************************************************************
* Focus_Restore -- This function is called when the application gets focus *
* *
* INPUT: Nothing *
* *
* OUTPUT: Nothing *
* *
* WARNINGS: None *
* *
* HISTORY: *
* 07/18/1997 GH : Created. *
*=============================================================================================*/
void Focus_Restore(void)
{
}
void Prog_End(void)
{
// Sound_End();
MouseCursor->Release_Mouse();
delete MouseCursor;
MouseCursor = NULL;
}
void Split_Command_Line_Args(HINSTANCE instance, char *path_to_exe, char *command_line)
{
// first arguement is the path to the executable including file name
GetModuleFileName (instance, &path_to_exe[0], 132);
Argv[0] = path_to_exe;
char * token = strtok(command_line, " ");
Argc = 1;
while (Argc < ARRAY_SIZE(Argv) && token != NULL) {
Argv[Argc++] = token;
token = strtok(NULL, " ");
}
}
void Set_Working_Directory(char *old_path, char *new_path)
{
char drive[_MAX_DRIVE];
char path[_MAX_PATH];
char dir[_MAX_DIR];
/*
** Remember the current working directory and drive.
*/
GetCurrentDirectory(_MAX_PATH, old_path);
/*
** Change directory to the where the executable is located. Handle the
** case where there is no path attached to argv[0].
*/
_splitpath(new_path, drive, dir, NULL, NULL);
_makepath(path, drive, dir, NULL, NULL);
SetCurrentDirectory(path);
}

View File

@@ -0,0 +1,46 @@
/*
** 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/>.
*/
#ifndef WINMAIN_H
#define WINMAIN_H
#ifndef ALWAYS_H
#include "always.h"
#endif
#ifndef WIN_H
#include "win.h"
#endif
#include <sr.hpp>
extern "C"
{
extern HWND hWndMain;
extern bool WIN_fullscreen;
#ifdef PORT130
SRBOOL SRCALL WIN_resize(SRLONG width, SRLONG height);
SRBOOL SRCALL WIN_set_fullscreen(SRBOOL state);
#endif
}
#endif

View File

@@ -0,0 +1,50 @@
/*
** 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/>.
*/
/* $Header: /Commando/Code/Tests/meshtest/_GLOBALS.CPP 4 11/06/97 8:01a Greg_h $ */
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Tests/meshtest/_GLOBALS.CPP $*
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 10/31/97 9:22a $*
* *
* $Revision:: 4 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "_globals.h"
bool GameInFocus;
Mouse * MouseCursor = NULL;
WWKeyboardClass * Keyboard = NULL;
SystemTimerClass SystemTimer;
int Argc;
char * Argv[20];

View File

@@ -0,0 +1,75 @@
/*
** 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/>.
*/
/* $Header: /Commando/Code/Tests/MeshTest/_GLOBALS.H 5 5/01/98 11:04a Greg_h $ */
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Tests/MeshTest/_GLOBALS.H $*
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 4/30/98 2:33p $*
* *
* $Revision:: 5 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef _GLOBALS_H
#define _GLOBALS_H
#ifndef ALWAYS_H
#include "always.h"
#endif
#ifndef KEYBOARD_H
#include "keyboard.h"
#endif
#ifndef XMOUSE_H
#include "xmouse.h"
#endif
#ifndef STIMER_H
#include "stimer.h"
#endif
extern bool GameInFocus;
extern Mouse * MouseCursor;
extern WWKeyboardClass * Keyboard;
extern int Argc;
extern char * Argv[20];
#if 0
// 60 Hz Timer
extern SystemTimerClass SystemTimer;
#define SYSTEM_TIMER_RATE TIMER_SECOND
#else
// 1 KHz Timer
#define SystemTimer() (int)timeGetTime()
#define SYSTEM_TIMER_RATE 1000
#endif
#endif

View File

@@ -0,0 +1,40 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** 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 ***
***********************************************************************************************
* *
* Project Name : MeshTest *
* *
* $Archive:: /Commando/Code/Tests/MeshTest/_scenes.cpp $*
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 4/02/98 2:33p $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "_scenes.h"
SimpleSceneClass * TheScene = NULL;

View File

@@ -0,0 +1,47 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** 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 ***
***********************************************************************************************
* *
* Project Name : MeshTest *
* *
* $Archive:: /Commando/Code/Tests/MeshTest/_scenes.h $*
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 4/02/98 2:32p $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef _SCENES_H
#define _SCENES_H
#ifndef SCENE_H
#include "scene.h"
#endif
extern SimpleSceneClass * TheScene;
#endif

View File

@@ -0,0 +1,67 @@
/*
** 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/>.
*/
/* $Header: /Commando/Code/Tests/meshtest/_viewpt.cpp 2 8/11/97 4:29p Greg_h $ */
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Tests/meshtest/_viewpt.cpp $*
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 7/18/97 10:47a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "_viewpt.h"
/*
** Current resolution of the screen / game window.
** (only the Width and Height fields are valid...)
*/
Rect ScreenResolution;
/*
** Rectangle within main window for the main viewport
*/
Rect MainViewport;
/*
** Rectangle within the main window for the status bar
*/
Rect StatusViewport;
/*
** Rectangle within the main window for the radar / map
*/
Rect RadarViewport;
/*
** Rectangle within the main window for the PIP viewport
*/
Rect PIPViewport;

View File

@@ -0,0 +1,72 @@
/*
** 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/>.
*/
/* $Header: /Commando/Code/Tests/meshtest/_viewpt.h 2 8/11/97 4:29p Greg_h $ */
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Tests/meshtest/_viewpt.h $*
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 7/19/97 10:12a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef _VIEWPT_H
#define _VIEWPT_H
#ifndef RECT_H
#include "rect.h"
#endif
/*
** Current resolution of the screen / game window.
*/
extern Rect ScreenResolution;
/*
** Rectangle within main window for the main viewport
*/
extern Rect MainViewport;
/*
** Rectangle within the main window for the status bar
*/
extern Rect StatusViewport;
/*
** Rectangle within the main window for the radar / map
*/
extern Rect RadarViewport;
/*
** Rectangle within the main window for the PIP viewport
*/
extern Rect PIPViewport;
#endif

View File

@@ -0,0 +1,56 @@
/*
** 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/>.
*/
/* $Header: /Commando/Code/Tests/MeshTest/init.cpp 9 10/12/98 5:59p Greg_h $ */
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Tests/MeshTest/init.cpp $*
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 10/07/98 2:50p $*
* *
* $Revision:: 9 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "init.h"
#include <sr.hpp>
#include "_viewpt.h"
#include "_scenes.h"
#include "ww3d.h"
#include "winmain.h"
bool Init(void)
{
if (WW3D::Init(hWndMain) != WW3D::WW3D_OK) {
return false;
}
WW3D::Create_Debug_Window();
return true;
}

View File

@@ -0,0 +1,43 @@
/*
** 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/>.
*/
/* $Header: /Commando/Code/Tests/meshtest/init.h 2 8/11/97 4:29p Greg_h $ */
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Tests/meshtest/init.h $*
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 7/18/97 9:11a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef INIT_H
#define INIT_H
bool Init(void);
#endif

View File

@@ -0,0 +1,503 @@
/*
** 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/>.
*/
/* $Header: /Commando/Code/Tests/MeshTest/mainloop.cpp 47 12/10/98 5:53p Greg_h $ */
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Tests/MeshTest/mainloop.cpp $*
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 12/07/98 1:30p $*
* *
* $Revision:: 47 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#define NOMINMAX
#include "mainloop.h"
#include "mono.h"
#include "msgloop.h"
#include "wwfile.h"
#include "rawfile.h"
#include "_globals.h"
#include "_viewpt.h"
#include <sr.hpp>
#include <assert.h>
#include "assetmgr.h"
#include "sr_util.h"
#include "_scenes.h"
#include "rendobj.h"
#include "r3dobj.h"
#include "mesh.h"
#include "hmodel.h"
#include "light.h"
#include "wwdebug.h"
#include "ww3d.h"
#define SPIN_MODEL
#define SPIN_LIGHT
//#define CAPTURE_BONE
//#define TEST_DAMAGE
//#define TEST_TEXTURE_ANIMATION
/*
** Globals
*/
WW3DAssetManager The3DAssetManager;
CameraClass * Camera;
LightClass * Light;
LightClass * Light2;
RenderObjClass * TestModel = NULL;
HAnimClass * TestAnim = NULL;
float CameraDist = 10.0f;
float CameraDir = 0.0f;
Quaternion ModelOrientation(1);
#ifdef SPIN_MODEL
Quaternion ModelRotation(Vector3(0,0,1),DEG_TO_RAD(1.5f));
#else
Quaternion ModelRotation(1);
#endif
Quaternion LightOrientation(1);
Quaternion LightRotation(Vector3(.2,1,.1),DEG_TO_RAD(3.0f));
/*
** Local functions
*/
void Render(void);
void Create_Scene(void);
void Create_Objects(void);
void Destroy_Scene(void);
void Destroy_Objects(void);
void Load_Data(void);
void Render_Scene(void);
void Time_Step(void);
void Init_Debug(void);
void Shutdown_Debug(void);
void wwdebug_message_handler(const char * message);
void wwdebug_assert_handler(const char * message);
bool wwdebug_trigger_handler(int trigger_num);
void Debug_Refs(void);
/*
** delay for time milliseconds
*/
void Wait( int time )
{
int start = SystemTimer();
while ( 1000 * ( SystemTimer() - start ) < ( time * SYSTEM_TIMER_RATE ) ) ;
}
/*
** MAIN GAME LOOP
*/
void Main_Loop(void)
{
Init_Debug();
Create_Scene();
Load_Data();
Create_Objects();
while (!Keyboard->Down(VK_ESCAPE)) {
Time_Step();
Render();
Windows_Message_Handler();
if (Keyboard->Down(VK_F1)) {
while(Keyboard->Down(VK_F1));
WW3D::Set_Next_Render_Device();
}
if (Keyboard->Down(VK_F2)) {
while(Keyboard->Down(VK_F2));
}
}
Destroy_Objects();
WW3DAssetManager::Get_Instance()->Free_Assets();
Destroy_Scene();
Shutdown_Debug();
Debug_Refs();
}
void Render(void)
{
ViewportClass view(Vector2(-1,-1),Vector2(1,1));
Light->Set_Diffuse(Vector3(1.0f,1.0f,1.0f));
TheScene->Set_Ambient_Light(Vector3(0.8f,0.8f,0.8f));
WW3D::Begin_Render(true,true,Vector3(0.2f,0.2f,0.5f));
WW3D::Gerd_Render(TheScene,Camera);
WW3D::End_Render();
}
void Create_Scene(void)
{
int rd_index = 0;
int width = 640;
int height = 480;
int color_depth = 16;
bool windowed = true;
WW3D::Set_Render_Device(rd_index,width,height,color_depth,windowed);
TheScene = new SimpleSceneClass();
}
/*
** Load initial game data
*/
void Load_Data(void)
{
// WW3DAssetManager::Get_Instance()->Load_3D_Assets(RawFileClass("crap.W3D"));
// WW3DAssetManager::Get_Instance()->Load_3D_Assets(RawFileClass("HUMAN.W3D"));
// WW3DAssetManager::Get_Instance()->Load_3D_Assets(RawFileClass("COMMANDO.W3D"));
// WW3DAssetManager::Get_Instance()->Load_3D_Assets(RawFileClass("Mtankl1.W3D"));
WW3DAssetManager::Get_Instance()->Load_3D_Assets(RawFileClass("Triangle.W3D"));
// WW3DAssetManager::Get_Instance()->Load_3D_Assets(RawFileClass("Sphere.W3D"));
// WW3DAssetManager::Get_Instance()->Load_3D_Assets(RawFileClass("new_mtl_test.W3D"));
}
/*
**
*/
void Create_Objects(void)
{
Camera = NEW_REF(CameraClass,());
Camera->Set_Viewport(Vector2(0,0),Vector2(640,480));
Camera->Set_Clip_Planes(1.0f, 200.0f);
Camera->Set_Environment_Range(1.0f, 200.0f);
// TestModel = WW3DAssetManager::Get_Instance()->Create_Render_Obj("Mtankl1");
// TestModel = WW3DAssetManager::Get_Instance()->Create_Render_Obj("Crap");
TestModel = WW3DAssetManager::Get_Instance()->Create_Render_Obj("triangle");
// TestModel = WW3DAssetManager::Get_Instance()->Create_Render_Obj("new_mtl_test");
assert(TestModel);
TestModel->Add(TheScene);
Light = NEW_REF(LightClass,());
Matrix3D lighttm(1);
lighttm.Set_Translation(Vector3(5,0,0));
Light->Set_Transform(lighttm);
Light->Add(TheScene);
}
/*
**
*/
void Destroy_Scene(void)
{
TheScene->Release_Ref();
TheScene = NULL;
}
/*
**
*/
void Destroy_Objects(void)
{
if (TestModel) {
TestModel->Remove();
TestModel->Release_Ref();
TestModel = NULL;
}
if (Camera) {
Camera->Release_Ref();
Camera = NULL;
}
if (Light) {
Light->Remove();
Light->Release_Ref();
Light = NULL;
}
if (Light2) {
Light2->Remove();
Light2->Release_Ref();
Light2 = NULL;
}
WW3DAssetManager::Get_Instance()->Free_Assets();
}
void Time_Step(void)
{
if (Keyboard->Down(VK_UP)) {
CameraDist = CameraDist * 0.9f;
}
if (Keyboard->Down(VK_DOWN)) {
CameraDist = CameraDist * 1.1f;
}
if (Keyboard->Down(VK_LEFT)) {
CameraDir -= (float)DEG_TO_RAD(10.0f);
}
if (Keyboard->Down(VK_RIGHT)) {
CameraDir += (float)DEG_TO_RAD(10.0f);
}
Matrix3D camtm(1);
camtm.Rotate_Z(CameraDir);
camtm.Rotate_X(DEG_TO_RAD(35.0f));
camtm.Translate(Vector3(0,0,CameraDist));
Camera->Set_Transform(camtm);
#ifdef SPIN_MODEL
ModelOrientation = ModelOrientation * ModelRotation;
ModelOrientation.Normalize();
if (TestModel) TestModel->Set_Transform(Build_Matrix3D(ModelOrientation));
#else
if (TestModel) TestModel->Set_Transform(Matrix3D(1));
#endif
#ifdef SPIN_LIGHT
LightOrientation = LightOrientation * LightRotation;
LightOrientation.Normalize();
Matrix3D ltm = Build_Matrix3D(LightOrientation);
ltm.Translate(Vector3(5.0f,0.0f,0.0f));
Light->Set_Transform(ltm);
#endif
#if 0
MeshClass * mesh = NULL;
static int _frame = 0;
if (TestAnim) {
_frame++;
if (_frame >= TestAnim->Get_Num_Frames()) {
_frame = 0;
}
TestModel->Set_Animation(TestAnim,_frame);
} else {
TestModel->Set_Animation();
}
#ifdef CAPTURE_BONE
int boneid = TestModel->Get_Bone_Index("Head");
if (boneid != -1) {
static float r = 10.0f;
static float theta = 0.0f;
theta += 0.05f;
Matrix3D tm(1);
tm.Rotate_Z(theta);
TestModel->Capture_Bone(boneid);
TestModel->Control_Bone(boneid,tm);
}
#endif
#ifdef SPIN_MODEL
ModelOrientation = ModelOrientation * ModelRotation;
ModelOrientation.Normalize();
TestModel->Set_Transform(Build_Matrix3D(ModelOrientation));
#else
TestModel->Set_Transform(Matrix3D(1));
#endif
Matrix3D camtm(1);
camtm.Rotate_X(DEG_TO_RAD(35.0f));
camtm.Translate(0,0,20.0f);
Camera->Set_Transform(camtm);
camtm.Make_Identity();
camtm.Translate(Vector3(0,0,20.0f));
Camera->Set_Transform(camtm);
Camera->Set_Viewport(Vector2(0,0),Vector2(320,200));
Camera->Set_View_Plane(60.0f,4.0f/3.0f * 60.0f);
Camera->Set_Clip_Planes(1.0f, 200.0f);
Camera->Set_Environment_Range(1.0f, 200.0f);
#ifdef SPIN_LIGHT
LightOrientation = LightOrientation * LightRotation;
LightOrientation.Normalize();
Matrix3D ltm = Build_Matrix3D(LightOrientation);
ltm.Translate(Vector3(5.0f,0.0f,0.0f));
Light->Set_Transform(ltm);
#endif
#ifdef TEST_DAMAGE
#define DAMAGE_RATE 0.03f;
static float _dam_amt = 0.0f;
static float _dam_chg = DAMAGE_RATE;
_dam_amt += _dam_chg;
if (_dam_amt >= 1.0f) {
_dam_amt = 1.0f;
_dam_chg = -DAMAGE_RATE;
}
if (_dam_amt <= 0.0f) {
_dam_amt = 0.0f;
_dam_chg = DAMAGE_RATE;
}
mesh = (MeshClass*)TestModel->Get_Sub_Object("Orca01");
if (mesh) {
mesh->Apply_Damage(0,_dam_amt);
mesh->Release_Ref();
}
#endif
#ifdef TEST_TEXTURE_ANIMATION
mesh = (MeshClass*)TestModel->Get_Sub_Object("Box01");
if (mesh) {
MaterialInfoClass * matinfo = mesh->Get_Material_Info();
if (matinfo) {
MaterialClass * mtl = matinfo->Get_Material(0);
if (mtl && (stricmp(mtl->Get_Name(),"Explosion Material") == 0)) {
#if 1
int curframe = mtl->Get_Channel_Anim_Frame(MaterialClass::DIFFUSE_COLOR);
curframe = (curframe+1) % mtl->Get_Channel_Anim_Frame_Count(MaterialClass::DIFFUSE_COLOR);
mtl->Set_Channel_Anim_Frame(MaterialClass::DIFFUSE_COLOR,curframe);
#else
TextureClass * tex = mtl->Get_Channel_Texture(MaterialClass::DIFFUSE_COLOR);
assert(tex);
int curframe = tex->Get_Anim_Frame();
curframe = (curframe+1) % tex->Get_Num_Frames();
tex->Set_Anim_Frame(curframe);
//tex->invalidate();
tex->Release_Ref();
#endif
}
matinfo->Release_Ref();
matinfo = NULL;
if (mtl) mtl->Release_Ref();
}
mesh->Release_Ref();
}
#endif
#endif
}
void Init_Debug(void)
{
/*
** Install message handler functions for the WWDebug messages
** and assertion failures.
*/
WWDebug_Install_Message_Handler(wwdebug_message_handler);
WWDebug_Install_Assert_Handler(wwdebug_assert_handler);
WWDebug_Install_Trigger_Handler(wwdebug_trigger_handler);
}
void Shutdown_Debug(void)
{
/*
** Remove message handler functions for the WWDebug messages
** and assertion failures.
*/
WWDebug_Install_Message_Handler(NULL);
WWDebug_Install_Assert_Handler(NULL);
WWDebug_Install_Trigger_Handler(NULL);
}
void wwdebug_message_handler(const char * message)
{
/*
** Hand the message off to the scrolling debug screen
*/
// Debug_Say((message));
}
void wwdebug_assert_handler(const char * message)
{
/*
** Hand the message off to the scrolling debug screen
*/
// Debug_Say((message));
/*
** break into the debugger
*/
_asm int 0x03;
}
bool wwdebug_trigger_handler(int trigger_num)
{
return Keyboard->Down(trigger_num);
}
void Debug_Refs(void)
{
#ifndef NDEBUG
char buf[1024];
if (RefCountClass::Total_Refs() != 0) {
sprintf(buf,"Main Loop End %d refs\n", RefCountClass::Total_Refs() );
MessageBox(NULL,buf,"Ref Debugging",MB_OK);
}
RefBaseNodeClass * node = RefBaseClass::ActiveRefList.First();
while (node->Is_Valid())
{
RefBaseClass * obj = node->Get();
ActiveRefStruct * ref = &(obj->ActiveRefInfo);
sprintf(buf,"Active Ref: %s\nLine: %d\nPointer %p\n", ref->File,ref->Line,obj);
if (MessageBox(NULL,buf,"Ref Debugging",MB_OKCANCEL) == IDCANCEL) {
break;
}
node = node->Next();
}
#endif
}

View File

@@ -0,0 +1,43 @@
/*
** 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/>.
*/
/* $Header: /Commando/Code/Tests/meshtest/mainloop.h 2 8/11/97 4:29p Greg_h $ */
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Tests/meshtest/mainloop.h $*
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 7/24/97 6:29p $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef MAINLOOP_H
#define MAINLOOP_H
void Main_Loop(void);
#endif

View File

@@ -0,0 +1,203 @@
# Microsoft Developer Studio Project File - Name="meshtest" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Application" 0x0101
CFG=MESHTEST - WIN32 RELEASE
!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 "meshtest.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 "meshtest.mak" CFG="MESHTEST - WIN32 RELEASE"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "meshtest - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "meshtest - Win32 Debug" (based on "Win32 (x86) Application")
!MESSAGE "meshtest - Win32 Profile" (based on "Win32 (x86) Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/Commando/Tests/meshtest", CHFAAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "meshtest - 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 Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\srsdk\include" /I "..\..\wwlib" /I "..\..\WWMath" /I "..\..\ww3d" /I "..\..\wwdebug" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "DIRECTX" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
# 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 /nologo /subsystem:windows /machine:I386
# ADD LINK32 sr.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib winmm.lib wwlib.lib wwmath.lib ww3d.lib wwdebug.lib vfw32.lib /nologo /subsystem:windows /machine:I386 /out:"Run/meshtest_r.exe" /libpath:"..\..\libs\Release" /libpath:"..\..\srsdk\lib"
# Begin Special Build Tool
SOURCE="$(InputPath)"
PostBuild_Desc=Copying Surrender DLL's
PostBuild_Cmds=REM del .\run\sr*.dll REM copy ..\..\srsdk\bin\*.dll .\run
# End Special Build Tool
!ELSEIF "$(CFG)" == "meshtest - 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 Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "..\..\srsdk\include" /I "..\..\wwlib" /I "..\..\WWMath" /I "..\..\ww3d" /I "..\..\wwdebug" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "DIRECTX" /FR /YX /FD /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
# 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 /nologo /subsystem:windows /debug /machine:I386
# ADD LINK32 srdb.lib ddraw.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib winmm.lib wwlib.lib wwmath.lib ww3d.lib wwdebug.lib vfw32.lib /nologo /subsystem:windows /profile /map /debug /machine:I386 /out:"Run/meshtest_d.exe" /libpath:"..\..\libs\Debug" /libpath:"..\..\srsdk\lib"
# Begin Special Build Tool
SOURCE="$(InputPath)"
PostBuild_Desc=Copying Surrender DLL's
PostBuild_Cmds=REM del .\run\sr*.dll REM copy ..\..\srsdk\bin\*.dll .\run
# End Special Build Tool
!ELSEIF "$(CFG)" == "meshtest - Win32 Profile"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "meshtest"
# PROP BASE Intermediate_Dir "meshtest"
# PROP BASE Ignore_Export_Lib 0
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Profile"
# PROP Intermediate_Dir "Profile"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\..\sr\sr.h" /I "..\..\Library" /I "..\..\WWMath" /I "..\..\ww3d" /I "..\..\wwdebug" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "DIRECTX" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "..\..\srsdk\include" /I "..\..\wwlib" /I "..\..\WWMath" /I "..\..\ww3d" /I "..\..\wwdebug" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "DIRECTX" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
# 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 sr.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib ddraw.lib winmm.lib library.lib wwmath.lib ww3d.lib wwdebug.lib /nologo /subsystem:windows /machine:I386 /out:"Run/meshtest_r.exe" /libpath:"..\..\libs\Release" /libpath:"..\..\sr\release"
# ADD LINK32 sr.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib winmm.lib wwlib.lib wwmath.lib ww3d.lib wwdebug.lib vfw32.lib /nologo /subsystem:windows /profile /debug /machine:I386 /out:"Run/meshtest_p.exe" /libpath:"..\..\libs\Profile" /libpath:"..\..\srsdk\lib"
# Begin Special Build Tool
SOURCE="$(InputPath)"
PostBuild_Desc=Copying Surrender DLL's
PostBuild_Cmds=REm del .\run\sr*.dll REM copy ..\..\srsdk\bin\*.dll .\run
# End Special Build Tool
!ENDIF
# Begin Target
# Name "meshtest - Win32 Release"
# Name "meshtest - Win32 Debug"
# Name "meshtest - Win32 Profile"
# Begin Group "Source"
# PROP Default_Filter "cpp;c"
# Begin Source File
SOURCE=.\_GLOBALS.CPP
# End Source File
# Begin Source File
SOURCE=.\_scenes.cpp
# End Source File
# Begin Source File
SOURCE=.\_viewpt.cpp
# End Source File
# Begin Source File
SOURCE=.\init.cpp
# End Source File
# Begin Source File
SOURCE=.\mainloop.cpp
# End Source File
# Begin Source File
SOURCE=.\shutdown.cpp
# End Source File
# Begin Source File
SOURCE=.\WINMAIN.CPP
# End Source File
# End Group
# Begin Group "Headers"
# PROP Default_Filter "h"
# Begin Source File
SOURCE=.\_GLOBALS.H
# End Source File
# Begin Source File
SOURCE=.\_scenes.h
# End Source File
# Begin Source File
SOURCE=.\_viewpt.h
# End Source File
# Begin Source File
SOURCE=.\init.h
# End Source File
# Begin Source File
SOURCE=.\mainloop.h
# End Source File
# Begin Source File
SOURCE=.\shutdown.h
# End Source File
# Begin Source File
SOURCE=.\WINMAIN.H
# End Source File
# End Group
# Begin Group "Resources"
# PROP Default_Filter "rc"
# End Group
# End Target
# End Project

View File

@@ -0,0 +1,47 @@
/*
** 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/>.
*/
/* $Header: /Commando/Code/Tests/MeshTest/shutdown.cpp 6 4/02/98 3:41p Greg_h $ */
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Tests/MeshTest/shutdown.cpp $*
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 4/02/98 2:37p $*
* *
* $Revision:: 6 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "shutdown.h"
#include "ww3d.h"
void Shutdown(void)
{
WW3D::Shutdown();
}

View File

@@ -0,0 +1,46 @@
/*
** 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/>.
*/
/* $Header: /Commando/Code/Tests/meshtest/shutdown.h 2 8/11/97 4:29p Greg_h $ */
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Tests/meshtest/shutdown.h $*
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 7/18/97 9:42a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef SHUTDOWN_H
#define SHUTDOWN_H
void Shutdown(void);
#endif

View File

@@ -0,0 +1,228 @@
/*
** 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/>.
*/
// DataView.cpp : implementation file
//
#include "stdafx.h"
#include "phystest.h"
#include "DataView.h"
#include "PhysTestDoc.h"
#include "assetmgr.h"
#include "rendobj.h"
#include "pscene.h"
#include "phys.h"
#include "physlist.h"
#include "mainfrm.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDataView
IMPLEMENT_DYNCREATE(CDataView, CTreeView)
CDataView::CDataView() :
ModelsRoot(NULL),
InstancesRoot(NULL)
{
}
CDataView::~CDataView()
{
}
void CDataView::Rebuild_Tree(void)
{
// Turn off repainting
GetTreeCtrl ().SetRedraw (FALSE);
// wipe clean
GetTreeCtrl().DeleteItem(ModelsRoot);
GetTreeCtrl().DeleteItem(InstancesRoot);
ModelsRoot = GetTreeCtrl().InsertItem("Models", NULL, NULL);
InstancesRoot = GetTreeCtrl().InsertItem ("Physics Object Instances", NULL, NULL);
// MODELS
// Get an iterator from the asset manager that we can
// use to enumerate the currently loaded assets
RenderObjIterator * obj_iterator = WW3DAssetManager::Get_Instance()->Create_Render_Obj_Iterator();
ASSERT(obj_iterator);
if (obj_iterator) {
// Loop through all the assets in the manager
for (obj_iterator->First (); !obj_iterator->Is_Done(); obj_iterator->Next()) {
// If the asset is an HLOD, add it to our possible model list
if (obj_iterator->Current_Item_Class_ID() == RenderObjClass::CLASSID_HLOD) {
const char * model_name = obj_iterator->Current_Item_Name();
// Add this entry to the tree
HTREEITEM hItem = GetTreeCtrl().InsertItem(model_name,NULL,0,ModelsRoot,TVI_SORT);
ASSERT (hItem != NULL);
ItemInfoClass * item_info = new ItemInfoClass(model_name,ItemInfoClass::MODEL);
GetTreeCtrl().SetItemData(hItem, (ULONG)item_info);
}
}
// Free the enumerator object we created earlier
WW3DAssetManager::Get_Instance()->Release_Render_Obj_Iterator(obj_iterator);
}
// PHYSICS OBJECT INSTANCES
CPhysTestDoc * doc = (CPhysTestDoc *)GetDocument();
RefPhysListIterator phys_iterator = PhysicsSceneClass::Get_Instance()->Get_Dynamic_Object_Iterator();
for (phys_iterator.First();!phys_iterator.Is_Done();phys_iterator.Next()) {
const char * instance_name = phys_iterator.Peek_Obj()->Get_Name();
if (instance_name != NULL) {
// Add this entry to the tree
HTREEITEM hItem = GetTreeCtrl().InsertItem(instance_name,NULL,0,InstancesRoot,TVI_SORT);
ASSERT (hItem != NULL);
ItemInfoClass * item_info = new ItemInfoClass(instance_name,ItemInfoClass::INSTANCE);
item_info->Instance = phys_iterator.Peek_Obj();
GetTreeCtrl().SetItemData(hItem, (ULONG)item_info);
}
}
// Turn;repainting back on and force a redraw
GetTreeCtrl().SetRedraw (TRUE);
Invalidate(FALSE);
UpdateWindow();
}
ItemInfoClass * CDataView::Get_Selected_Item(void)
{
ItemInfoClass * item_info = NULL;
// Get the currently selected node from the tree control
HTREEITEM htree_item = GetTreeCtrl ().GetSelectedItem ();
if (htree_item != NULL) {
// Get the data associated with this item
item_info = (ItemInfoClass *)GetTreeCtrl().GetItemData(htree_item);
}
// Return the asset information associated with the current item
return item_info;
}
void CDataView::Save(ChunkSaveClass & csave)
{
}
void CDataView::Load(ChunkLoadClass & cload)
{
}
BEGIN_MESSAGE_MAP(CDataView, CTreeView)
//{{AFX_MSG_MAP(CDataView)
ON_WM_CREATE()
ON_NOTIFY_REFLECT(TVN_DELETEITEM, OnDeleteitem)
ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelchanged)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDataView drawing
void CDataView::OnDraw(CDC* pDC)
{
CDocument* pDoc = GetDocument();
// TODO: add draw code here
}
/////////////////////////////////////////////////////////////////////////////
// CDataView diagnostics
#ifdef _DEBUG
void CDataView::AssertValid() const
{
CTreeView::AssertValid();
}
void CDataView::Dump(CDumpContext& dc) const
{
CTreeView::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CDataView message handlers
BOOL CDataView::PreCreateWindow(CREATESTRUCT& cs)
{
// Modify the style bits for the window so it will
// have buttons and lines between nodes.
cs.style |= TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_SHOWSELALWAYS;
return CTreeView::PreCreateWindow(cs);
}
int CDataView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CTreeView::OnCreate(lpCreateStruct) == -1)
return -1;
ModelsRoot = GetTreeCtrl().InsertItem("Models", NULL, NULL);
InstancesRoot = GetTreeCtrl().InsertItem ("Physics Object Instances", NULL, NULL);
return 0;
}
void CDataView::OnDeleteitem(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
ItemInfoClass * item_info = (ItemInfoClass *)pNMTreeView->itemOld.lParam;
// Free the asset information object
if (item_info != NULL) {
delete item_info;
}
// Reset the data associated with this entry
GetTreeCtrl().SetItemData(pNMTreeView->itemOld.hItem, NULL);
*pResult = 0;
}
void CDataView::OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult)
{
// just tell the main window that the selection changed so it
// can link/unlink the virtual joystick.
((CMainFrame *)::AfxGetMainWnd())->Notify_Selection_Changed();
*pResult = 0;
}

View File

@@ -0,0 +1,113 @@
/*
** 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/>.
*/
#if !defined(AFX_DATAVIEW_H__A9B6C2E1_E61E_11D2_802E_0040056350C8__INCLUDED_)
#define AFX_DATAVIEW_H__A9B6C2E1_E61E_11D2_802E_0040056350C8__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// DataView.h : header file
//
#include "AfxCView.H"
class PhysClass;
class ChunkSaveClass;
class ChunkLoadClass;
/////////////////////////////////////////////////////////////////////////////
//
// ItemInfoClass - stores info about all of the items in the CDataView
//
class ItemInfoClass
{
public:
enum { MODEL = 0, INSTANCE };
ItemInfoClass(const char * name,int type) : Instance(NULL) { Name = strdup(name); Type = type; }
~ItemInfoClass(void) { if (Name) free(Name); }
char * Name;
int Type;
PhysClass * Instance;
};
/////////////////////////////////////////////////////////////////////////////
//
// CDataView view
//
class CDataView : public CTreeView
{
protected:
CDataView(); // protected constructor used by dynamic creation
DECLARE_DYNCREATE(CDataView)
// Attributes
public:
// Operations
public:
void Rebuild_Tree(void);
ItemInfoClass * Get_Selected_Item(void);
void Save(ChunkSaveClass & csave);
void Load(ChunkLoadClass & cload);
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CDataView)
protected:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
//}}AFX_VIRTUAL
// Implementation
protected:
virtual ~CDataView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
///////////////////////////////////////////////////////
//
// Private member data
//
HTREEITEM ModelsRoot;
HTREEITEM InstancesRoot;
// Generated message map functions
protected:
//{{AFX_MSG(CDataView)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnDeleteitem(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_DATAVIEW_H__A9B6C2E1_E61E_11D2_802E_0040056350C8__INCLUDED_)

View File

@@ -0,0 +1,23 @@
/*
** 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/>.
*/
#include "stdafx.h"
#include "assetmgr.h"
WW3DAssetManager _TheAssetManager;

View File

@@ -0,0 +1,707 @@
/*
** 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/>.
*/
// GraphicView.cpp : implementation of the CGraphicView class
//
#include "stdafx.h"
#include "PhysTest.h"
#include "PhysTestDoc.h"
#include "GraphicView.h"
#include "MainFrm.h"
#include "mmsystem.h"
#include "pscene.h"
#include "ww3d.h"
#include "camera.h"
#include "quat.h"
#include "rcfile.h"
#include "assetmgr.h"
#include "rbody.h"
#include "chunkio.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define ORTHO_CAMERA 0
#define ORTHO_WIDTH 20
////////////////////////////////////////////////////////////////////////////
//
// CHUNK ID's used by GraphicView
//
enum
{
GRAPHICVIEW_CHUNK_VARIABLES = 0x00789931,
GRAPHICVIEW_VARIABLE_CAMERAMODE = 0x00,
GRAPHICVIEW_VARIABLE_DISPLAYBOXES,
GRAPHICVIEW_VARIABLE_RUNSIMULATION,
GRAPHICVIEW_VARIABLE_CAMERATM,
};
const float PIP_VIEW = 0.2f; // size of the pip viewport
////////////////////////////////////////////////////////////////////////////
//
// TimerCallback
//
void CALLBACK TimerCallback
(
UINT uID,
UINT uMsg,
DWORD dwUser,
DWORD dw1,
DWORD dw2
)
{
HWND hwnd = (HWND)dwUser;
if (IsWindow(hwnd)) {
// Send this event off to the view to process (hackish, but fine for now)
if ((GetProp (hwnd, "WaitingToProcess") == NULL) &&
(GetProp (hwnd, "Inactive") == NULL)) {
SetProp (hwnd, "WaitingToProcess", (HANDLE)1);
// Send the message to the view
::PostMessage (hwnd, WM_USER + 101, 0, 0L);
}
}
}
////////////////////////////////////////////////////////////////////////////
//
// WindowProc
//
LRESULT CGraphicView::WindowProc
(
UINT message,
WPARAM wParam,
LPARAM lParam
)
{
// Is this the repaint message we are expecting?
if (message == WM_USER+101) {
Timestep();
Repaint_View();
RemoveProp(m_hWnd,"WaitingToProcess");
}
// Allow the base class to process this message
return CView::WindowProc(message, wParam, lParam);
}
/////////////////////////////////////////////////////////////////////////////
// CGraphicView
IMPLEMENT_DYNCREATE(CGraphicView, CView)
BEGIN_MESSAGE_MAP(CGraphicView, CView)
//{{AFX_MSG_MAP(CGraphicView)
ON_WM_SIZE()
ON_WM_DESTROY()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_RBUTTONDOWN()
ON_WM_RBUTTONUP()
ON_WM_MOUSEMOVE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CGraphicView construction/destruction
CGraphicView::CGraphicView() :
Initialized(false),
Active(true),
RunSimulation(false),
DisplayBoxes(false),
CameraMode(CAMERA_FLY),
Camera(NULL),
TimerID(0),
LMouseDown(false),
RMouseDown(false),
LastPoint(0,0),
PipCamera(NULL),
PipScene(NULL),
Axes(NULL)
{
}
CGraphicView::~CGraphicView()
{
REF_PTR_RELEASE(Camera);
REF_PTR_RELEASE(PipCamera);
REF_PTR_RELEASE(PipScene);
REF_PTR_RELEASE(Axes);
}
BOOL CGraphicView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
BOOL CGraphicView::Initialize_WW3D(int device,int bits)
{
// Assume failure
BOOL ok = FALSE;
if (device < 0) {
return FALSE;
}
// Initialize the rendering engine with the information from
// this window.
RECT rect;
GetClientRect (&rect);
int cx = rect.right-rect.left;
int cy = rect.bottom-rect.top;
WW3DErrorType err = WW3D_ERROR_GENERIC;
while (err != WW3D_ERROR_OK) {
err = WW3D::Set_Render_Device(device,cx,cy,bits,true);
if (err != WW3D_ERROR_OK) {
device = (device + 1) % WW3D::Get_Render_Device_Count();
}
}
// Load some models that we're going to need into the asset manager
ResourceFileClass point_file(NULL, "Point.w3d");
WW3DAssetManager::Get_Instance()->Load_3D_Assets(point_file);
ResourceFileClass axes_file(NULL, "Axes.w3d");
WW3DAssetManager::Get_Instance()->Load_3D_Assets(axes_file);
if (Camera == NULL) {
Camera = NEW_REF(CameraClass,());
ASSERT(Camera);
// Init the camera
Matrix3D transform;
transform.Look_At(Vector3(0.0f,-15.0f,5.0f),Vector3(0,0,0),0);
Camera->Set_Transform(transform);
// update the camera FOV settings
// take the larger of the two dimensions, give it the
// full desired FOV, then give the other dimension an
// FOV proportional to its relative size
double hfov,vfov;
if (cy > cx) {
vfov = (float)DEG_TO_RAD(45.0f);
hfov = (double)cx / (double)cy * vfov;
} else {
hfov = (float)DEG_TO_RAD(45.0f);
vfov = (double)cy / (double)cx * hfov;
}
// Reset the field of view
Camera->Set_View_Plane(hfov,vfov);
#if ORTHO_CAMERA
Camera->Set_Projection_Type(CameraClass::ORTHO);
Camera->Set_View_Plane(Vector2(-ORTHO_WIDTH,-ORTHO_WIDTH),Vector2(ORTHO_WIDTH,ORTHO_WIDTH));
#endif
}
if (PipCamera == NULL) {
PipCamera = NEW_REF(CameraClass,());
ASSERT(PipCamera);
PipCamera->Set_Viewport(Vector2(0.0f,1.0f - PIP_VIEW),Vector2(PIP_VIEW,1.0f));
PipCamera->Set_View_Plane(Camera->Get_Horizontal_FOV(),Camera->Get_Vertical_FOV());
Update_Pip_Camera();
}
if (PipScene == NULL) {
PipScene = NEW_REF(SimpleSceneClass,());
PipScene->Set_Ambient_Light(Vector3(1,1,1));
ASSERT(PipScene);
}
if (Axes == NULL) {
Axes = WW3DAssetManager::Get_Instance()->Create_Render_Obj("Axes");
ASSERT(Axes);
Axes->Set_Transform(Matrix3D(1));
PipScene->Add_Render_Object(Axes);
}
// Kick off a timer that we can use to update
// the display (kinda like a game loop iterator)
if (TimerID == 0) {
#if 0
TimerID = (UINT)::timeSetEvent( 50,
50,
TimerCallback,
(DWORD)m_hWnd,
TIME_PERIODIC);
#else
TimerID = (UINT)::timeSetEvent( 66, // only update 15 times a second
50,
TimerCallback,
(DWORD)m_hWnd,
TIME_PERIODIC);
#endif
}
Initialized = true;
// Return the TRUE/FALSE result code
return TRUE;
}
void CGraphicView::Save(ChunkSaveClass & csave)
{
Matrix3D cameratm = Camera->Get_Transform();
csave.Begin_Chunk(GRAPHICVIEW_CHUNK_VARIABLES);
WRITE_MICRO_CHUNK(csave,GRAPHICVIEW_VARIABLE_CAMERAMODE,CameraMode);
WRITE_MICRO_CHUNK(csave,GRAPHICVIEW_VARIABLE_DISPLAYBOXES,DisplayBoxes);
WRITE_MICRO_CHUNK(csave,GRAPHICVIEW_VARIABLE_RUNSIMULATION,RunSimulation);
WRITE_MICRO_CHUNK(csave,GRAPHICVIEW_VARIABLE_CAMERATM,cameratm);
csave.End_Chunk();
}
void CGraphicView::Load(ChunkLoadClass & cload)
{
Matrix3D cameratm(1);
while (cload.Open_Chunk()) {
switch(cload.Cur_Chunk_ID()) {
case GRAPHICVIEW_CHUNK_VARIABLES:
while(cload.Open_Micro_Chunk()) {
switch(cload.Cur_Micro_Chunk_ID()) {
READ_MICRO_CHUNK(cload,GRAPHICVIEW_VARIABLE_CAMERAMODE,CameraMode);
READ_MICRO_CHUNK(cload,GRAPHICVIEW_VARIABLE_DISPLAYBOXES,DisplayBoxes);
READ_MICRO_CHUNK(cload,GRAPHICVIEW_VARIABLE_RUNSIMULATION,RunSimulation);
READ_MICRO_CHUNK(cload,GRAPHICVIEW_VARIABLE_CAMERATM,cameratm);
}
cload.Close_Micro_Chunk();
}
break;
default:
WWDEBUG_SAY(("Unhandled chunk: %d File: %s Line: %d\n",cload.Cur_Chunk_ID(),__FILE__,__LINE__));
}
cload.Close_Chunk();
}
Camera->Set_Transform(cameratm);
}
/////////////////////////////////////////////////////////////////////////////
// CGraphicView drawing
void CGraphicView::OnDraw(CDC* pDC)
{
Repaint_View();
}
/////////////////////////////////////////////////////////////////////////////
// CGraphicView diagnostics
#ifdef _DEBUG
void CGraphicView::AssertValid() const
{
CView::AssertValid();
}
void CGraphicView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CPhysTestDoc* CGraphicView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CPhysTestDoc)));
return (CPhysTestDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CGraphicView message handlers
void CGraphicView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
if (Initialized)
{
// Change the resolution of the rendering device to
// match that of the view's current dimensions
WW3D::Set_Resolution (cx, cy, -1, true);
// update the camera FOV settings
// take the larger of the two dimensions, give it the
// full desired FOV, then give the other dimension an
// FOV proportional to its relative size
double hfov,vfov;
if (cy > cx) {
vfov = (float)DEG_TO_RAD(45.0f);
hfov = (double)cx / (double)cy * vfov;
} else {
hfov = (float)DEG_TO_RAD(45.0f);
vfov = (double)cy / (double)cx * hfov;
}
// Reset the field of view
ASSERT(Camera);
Camera->Set_View_Plane(hfov, vfov);
#if ORTHO_CAMERA
Camera->Set_View_Plane(Vector2(-ORTHO_WIDTH,-ORTHO_WIDTH),Vector2(ORTHO_WIDTH,ORTHO_WIDTH));
#endif
PipCamera->Set_View_Plane(hfov,vfov);
// Force a repaint of the screen
Repaint_View();
}
}
void CGraphicView::OnInitialUpdate()
{
CView::OnInitialUpdate();
CPhysTestDoc * doc = (CPhysTestDoc *)GetDocument();
if (doc) {
// tell the document to create the scene
doc->Init_Scene();
}
}
void CGraphicView::Timestep(void)
{
const float FLY_VELOCITY = 10.0f;
// Compute the amount of time elapsed for this frame.
CPhysTestDoc * doc = (CPhysTestDoc *)GetDocument();
DWORD curtime = ::GetTickCount();
DWORD elapsedtime = curtime - doc->LastTime;
if (elapsedtime > 100) {
elapsedtime = 100;
}
float dt = (float)elapsedtime / 1000.0f;
doc->LastTime = curtime;
// fly forward when control is held
if (::GetAsyncKeyState('A') & 0x8000) {
Matrix3D transform = Camera->Get_Transform();
transform.Translate(Vector3(0,0,-FLY_VELOCITY * dt));
Camera->Set_Transform(transform);
}
if (::GetAsyncKeyState('Z') & 0x8000) {
Matrix3D transform = Camera->Get_Transform();
transform.Translate(Vector3(0,0,FLY_VELOCITY * dt));
Camera->Set_Transform(transform);
}
// if mode == follow and we have an object selected, look at it
if (CameraMode == CAMERA_FOLLOW) {
CMainFrame * wnd = (CMainFrame *)::AfxGetMainWnd();
PhysClass * obj = wnd->Peek_Selected_Object();
if (obj) {
Vector3 target;
obj->Get_Transform().Get_Translation(&target);
Vector3 pos;
Camera->Get_Transform().Get_Translation(&pos);
Matrix3D tm;
tm.Look_At(pos,target,0.0f);
Camera->Set_Transform(tm);
}
}
// if mode == tether and we have an object selected, tie the camera to it
if ((CameraMode == CAMERA_TETHER) || (CameraMode == CAMERA_RIGID_TETHER)) {
CMainFrame * wnd = (CMainFrame *)::AfxGetMainWnd();
PhysClass * obj = wnd->Peek_Selected_Object();
if (obj) {
const float TETHER_DIST = 15.0f;
const float TETHER_ANGLE = DEG_TO_RADF(-20.0f);
Vector3 pos;
float zrot = obj->Get_Transform().Get_Z_Rotation();
obj->Get_Transform().Get_Translation(&pos);
Matrix3D tm(1);
if (CameraMode == CAMERA_RIGID_TETHER) {
tm = obj->Get_Transform();
} else {
tm.Translate(pos);
tm.Rotate_Z(zrot);
}
tm.Rotate_Y(DEG_TO_RADF(-90.0f));
tm.Rotate_Z(DEG_TO_RADF(-90.0f));
tm.Rotate_X(TETHER_ANGLE);
tm.Translate(Vector3(0,0,TETHER_DIST));
Camera->Set_Transform(tm);
}
}
// update the PIP camera transform
Update_Pip_Camera();
// Allow the world to simulate (if enabled)
if (RunSimulation) {
doc->Scene->Update(1.0f/15.0f , 0); // 0.05f,0); //dt,0);
}
// DEBUG, print the contact point coordinates
#if 0
Vector3 pt = _LastContactPoint;
CString string;
string.Format("Contact Point: %10.5f %10.5f %10.5f StartBad: %d",pt.X,pt.Y,pt.Z,_StartBad);
((CMainFrame *)::AfxGetMainWnd())->Set_Status_Bar_Text(string);
#endif
}
void CGraphicView::Repaint_View(void)
{
static bool _already_painting = false;
if (_already_painting) return;
_already_painting = true;
// Get the document to display
CPhysTestDoc * doc = (CPhysTestDoc *)GetDocument();
// Are we in a valid state?
if (Initialized && doc->Scene) {
// Update the W3D frame times according to our elapsed tick count
//WW3D::Sync(WW3D::Get_Sync_Time() + (ticks_elapsed * m_animationSpeed));
// Render the scenes
WW3D::Begin_Render(TRUE, TRUE, Vector3(0,0,0));
WW3D::Render(doc->Scene,Camera,FALSE,FALSE);
WW3D::Render(PipScene,PipCamera,FALSE,TRUE);
WW3D::End_Render();
}
_already_painting = false;
}
void CGraphicView::Set_Active(bool onoff)
{
Active = onoff;
if (!Active) {
::SetProp(m_hWnd,"Inactive",(HANDLE)1);
} else {
RemoveProp(m_hWnd,"Inactive");
CPhysTestDoc * doc = (CPhysTestDoc *)GetDocument();
doc->LastTime = ::GetTickCount();
}
}
bool CGraphicView::Is_Collision_Box_Display_Enabled(void)
{
return DisplayBoxes;
}
void CGraphicView::Enable_Collision_Box_Display(bool onoff)
{
DisplayBoxes = onoff;
if (DisplayBoxes) {
WW3D::Set_Collision_Box_Display_Mask(COLLISION_TYPE_PHYSICAL);
} else {
WW3D::Set_Collision_Box_Display_Mask(0);
}
}
void CGraphicView::OnDestroy()
{
// remove our properties
::RemoveProp(m_hWnd,"Inactive");
::RemoveProp(m_hWnd,"WaitingToProcess");
CView::OnDestroy();
// Free the camera object
REF_PTR_RELEASE(Camera);
REF_PTR_RELEASE(PipScene);
REF_PTR_RELEASE(PipCamera);
REF_PTR_RELEASE(Axes);
// Is there an update thread running?
if (TimerID == 0) {
// Stop the timer
::timeKillEvent((UINT)TimerID);
TimerID = 0;
}
Initialized = FALSE;
}
void CGraphicView::OnLButtonDown(UINT nFlags, CPoint point)
{
// Capture all mouse messages
SetCapture();
// Left mouse button is down
LMouseDown = TRUE;
LastPoint = point;
// Allow the base class to process this message
CView::OnLButtonDown(nFlags, point);
}
void CGraphicView::OnLButtonUp(UINT nFlags, CPoint point)
{
// if both buttons are now up, release the mouse
if (!RMouseDown) {
ReleaseCapture();
}
// Left mouse button is now up
LMouseDown = false;
CView::OnLButtonUp(nFlags, point);
}
void CGraphicView::OnRButtonDown(UINT nFlags, CPoint point)
{
// Capture all mouse messages
SetCapture();
// Right mouse button is down
RMouseDown = TRUE;
LastPoint = point;
CView::OnRButtonDown(nFlags, point);
}
void CGraphicView::OnRButtonUp(UINT nFlags, CPoint point)
{
// if both buttons are now up, release the mouse
if (!LMouseDown) {
ReleaseCapture();
}
// Right mouse button is now up
RMouseDown = false;
CView::OnRButtonUp(nFlags, point);
}
void CGraphicView::OnMouseMove(UINT nFlags, CPoint point)
{
// Get the document to display
CPhysTestDoc * doc = (CPhysTestDoc *)GetDocument();
WWASSERT(doc);
#if 0
PhysicsSceneClass * scene = doc->Scene;
WWASSERT(scene);
#endif
// When Only the Left mouse button is down, we "look-around" with
// vertical locking (rotate about Z until Y points up)
if ((LMouseDown) && (!RMouseDown)) {
// Are we in a valid state?
if (Initialized && doc->Scene) {
RECT rect;
GetClientRect (&rect);
float mid_point_x = float(rect.right >> 1);
float mid_point_y = float(rect.bottom >> 1);
float last_point_x = ((float)LastPoint.x - mid_point_x) / mid_point_x;
float last_point_y = (mid_point_y - (float)LastPoint.y) / mid_point_y;
float point_x = ((float)point.x - mid_point_x) / mid_point_x;
float point_y = (mid_point_y - (float)point.y) / mid_point_y;
// invert the axes (being lazy here...)
point_x = -point_x;
point_y = -point_y;
last_point_x = -last_point_x;
last_point_y = -last_point_y;
// Rotate around the object (orbit) using a 0.00F - 1.00F percentage of
// the mouse coordinates
Quaternion rotation = ::Trackball (last_point_x,last_point_y,point_x,point_y, 0.8F);
// If we're not in CAMERA_FOLLOW mode, just rotate our view
if (CameraMode != CAMERA_FOLLOW) {
// Apply the rotation to the camera
Matrix3D transform = Camera->Get_Transform ();
Matrix3D::Multiply(transform,Build_Matrix3D(rotation),&transform);
// Straighten out the Y axis
Vector3 pos = transform.Get_Translation();
Vector3 target = transform * Vector3(0,0,-1);
transform.Look_At(pos,target,0.0f);
// Rotate and translate the camera
Camera->Set_Transform (transform);
} else {
// We're in camera follow mode, this means the camera is always going
// to point right at the object. We want to orbit the camera's position
// around the object.
Matrix3D camera_tm = Camera->Get_Transform();
Vector3 relative_obj_pos(0,0,-10);
CMainFrame * wnd = (CMainFrame *)::AfxGetMainWnd();
PhysClass * obj = wnd->Peek_Selected_Object();
if (obj) {
Vector3 obj_pos;
obj->Get_Transform().Get_Translation(&obj_pos);
Matrix3D::Inverse_Transform_Vector(camera_tm,obj_pos,&relative_obj_pos);
}
camera_tm.Translate(relative_obj_pos);
Matrix3D rotation_tm;
Build_Matrix3D(rotation).Get_Orthogonal_Inverse(rotation_tm);
Matrix3D::Multiply(camera_tm,rotation_tm,&camera_tm);
camera_tm.Translate(-relative_obj_pos);
Camera->Set_Transform(camera_tm);
}
}
}
LastPoint = point;
Update_Pip_Camera();
CView::OnMouseMove(nFlags, point);
}
void CGraphicView::Update_Pip_Camera(void)
{
if (PipCamera && Camera) {
Matrix3D transform = Camera->Get_Transform();
transform.Set_Translation(Vector3(0,0,0));
transform.Translate(Vector3(0,0,4));
PipCamera->Set_Transform(transform);
}
}

View File

@@ -0,0 +1,139 @@
/*
** 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/>.
*/
// GraphicView.h : interface of the CGraphicView class
//
/////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_PHYSTESTVIEW_H__616293EC_E4F0_11D2_802E_0040056350C8__INCLUDED_)
#define AFX_PHYSTESTVIEW_H__616293EC_E4F0_11D2_802E_0040056350C8__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CPhysTestDoc;
class RenderObjClass;
class CameraClass;
class SceneClass;
class ChunkSaveClass;
class ChunkLoadClass;
class CGraphicView : public CView
{
protected: // create from serialization only
CGraphicView();
DECLARE_DYNCREATE(CGraphicView)
// Attributes
public:
CPhysTestDoc* GetDocument();
void Save(ChunkSaveClass & csave);
void Load(ChunkLoadClass & cload);
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CGraphicView)
public:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
virtual void OnInitialUpdate();
protected:
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
//}}AFX_VIRTUAL
// Implementation
public:
enum {
CAMERA_FLY = 0,
CAMERA_FOLLOW,
CAMERA_TETHER,
CAMERA_RIGID_TETHER,
};
virtual ~CGraphicView();
BOOL Initialize_WW3D(int device,int bits);
bool Is_WW3D_Initialized(void) { return Initialized; }
void Repaint_View(void);
void Set_Active(bool onoff);
bool Is_Simulation_Enabled(void) { return RunSimulation; }
void Enable_Simulation(bool onoff) { RunSimulation = onoff; }
bool Is_Collision_Box_Display_Enabled(void);
void Enable_Collision_Box_Display(bool onoff);
void Set_Camera_Mode(int mode) { CameraMode = mode; }
int Get_Camera_Mode(void) { return CameraMode; }
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
bool Initialized;
bool Active;
bool RunSimulation;
bool DisplayBoxes;
int CameraMode;
CameraClass * Camera;
int TimerID;
bool LMouseDown;
bool RMouseDown;
CPoint LastPoint;
CameraClass * PipCamera;
SceneClass * PipScene;
RenderObjClass * Axes;
void Timestep(void);
void Update_Pip_Camera(void);
// Generated message map functions
protected:
//{{AFX_MSG(CGraphicView)
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnDestroy();
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
#ifndef _DEBUG // debug version in PhysTestView.cpp
inline CPhysTestDoc* CGraphicView::GetDocument()
{ return (CPhysTestDoc*)m_pDocument; }
#endif
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_PHYSTESTVIEW_H__616293EC_E4F0_11D2_802E_0040056350C8__INCLUDED_)

View File

@@ -0,0 +1,140 @@
/*
** 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/>.
*/
// InertiaDialog.cpp : implementation file
//
#include "stdafx.h"
#include "phystest.h"
#include "InertiaDialog.h"
#include "rbody.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
const int MIN_IBODY = 0;
const int MAX_IBODY = 255;
/////////////////////////////////////////////////////////////////////////////
// CInertiaDialog dialog
CInertiaDialog::CInertiaDialog(CWnd* pParent,RigidBodyClass * obj) :
CDialog(CInertiaDialog::IDD, pParent),
Object(obj)
{
//{{AFX_DATA_INIT(CInertiaDialog)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
ASSERT(Object != NULL);
}
void CInertiaDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CInertiaDialog)
DDX_Control(pDX, IDC_IBODYZ_SPIN, m_IBodyZSpin);
DDX_Control(pDX, IDC_IBODYY_SPIN, m_IBodyYSpin);
DDX_Control(pDX, IDC_IBODYX_SPIN, m_IBodyXSpin);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CInertiaDialog, CDialog)
//{{AFX_MSG_MAP(CInertiaDialog)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CInertiaDialog message handlers
BOOL CInertiaDialog::OnInitDialog()
{
CDialog::OnInitDialog();
m_IBodyXSpin.SetRange(MIN_IBODY * 100,MAX_IBODY * 100);
m_IBodyYSpin.SetRange(MIN_IBODY * 100,MAX_IBODY * 100);
m_IBodyZSpin.SetRange(MIN_IBODY * 100,MAX_IBODY * 100);
Matrix3 ibody;
Object->Get_Inertia(&ibody);
m_IBodyXSpin.SetPos(ibody[0][0] * 100);
m_IBodyYSpin.SetPos(ibody[1][1] * 100);
m_IBodyZSpin.SetPos(ibody[2][2] * 100);
SetDlgItemFloat(IDC_IBODYX_EDIT,ibody[0][0]);
SetDlgItemFloat(IDC_IBODYY_EDIT,ibody[1][1]);
SetDlgItemFloat(IDC_IBODYZ_EDIT,ibody[2][2]);
return TRUE;
}
BOOL CInertiaDialog::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
// make the spin controls work...
switch(wParam)
{
case IDC_IBODYX_SPIN:
case IDC_IBODYY_SPIN:
case IDC_IBODYZ_SPIN:
LPNMUPDOWN lpnmud = (LPNMUPDOWN) lParam;
if (lpnmud->hdr.code == UDN_DELTAPOS) {
HWND hwnd = (HWND)SendDlgItemMessage(LOWORD(wParam),UDM_GETBUDDY);
float curval = GetDlgItemFloat(GetWindowLong(hwnd,GWL_ID));
curval += (float)lpnmud->iDelta / 100.0f;
SetDlgItemFloat(GetWindowLong(hwnd,GWL_ID), curval);
}
break;
}
return CDialog::OnNotify(wParam, lParam, pResult);
}
void CInertiaDialog::OnOK()
{
Matrix3 ibody(1);
ibody[0][0] = GetDlgItemFloat(IDC_IBODYX_EDIT);
ibody[1][1] = GetDlgItemFloat(IDC_IBODYY_EDIT);
ibody[2][2] = GetDlgItemFloat(IDC_IBODYZ_EDIT);
Object->Set_Inertia(ibody);
CDialog::OnOK();
}
float CInertiaDialog::GetDlgItemFloat(int controlid)
{
CString string;
GetDlgItemText(controlid,string);
return atof(string);
}
void CInertiaDialog::SetDlgItemFloat(int controlid,float val)
{
CString string;
string.Format("%.2f",val);
SetDlgItemText(controlid,string);
}

View File

@@ -0,0 +1,74 @@
/*
** 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/>.
*/
#if !defined(AFX_INERTIADIALOG_H__33DD6AC4_E78D_11D2_9BD2_00A0C9988171__INCLUDED_)
#define AFX_INERTIADIALOG_H__33DD6AC4_E78D_11D2_9BD2_00A0C9988171__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// InertiaDialog.h : header file
//
class RigidBodyClass;
/////////////////////////////////////////////////////////////////////////////
// CInertiaDialog dialog
class CInertiaDialog : public CDialog
{
// Construction
public:
CInertiaDialog(CWnd* pParent,RigidBodyClass * obj);
// Dialog Data
//{{AFX_DATA(CInertiaDialog)
enum { IDD = IDD_INERTIA_DIALOG };
CSpinButtonCtrl m_IBodyZSpin;
CSpinButtonCtrl m_IBodyYSpin;
CSpinButtonCtrl m_IBodyXSpin;
//}}AFX_DATA
RigidBodyClass * Object;
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CInertiaDialog)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
//}}AFX_VIRTUAL
// Implementation
protected:
float GetDlgItemFloat(int controlid);
void SetDlgItemFloat(int controlid,float val);
// Generated message map functions
//{{AFX_MSG(CInertiaDialog)
virtual void OnOK();
virtual BOOL OnInitDialog();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_INERTIADIALOG_H__33DD6AC4_E78D_11D2_9BD2_00A0C9988171__INCLUDED_)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,176 @@
/*
** 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/>.
*/
// MainFrm.h : interface of the CMainFrame class
//
/////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_MAINFRM_H__616293E8_E4F0_11D2_802E_0040056350C8__INCLUDED_)
#define AFX_MAINFRM_H__616293E8_E4F0_11D2_802E_0040056350C8__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class Vector3;
class CVJoyDialog;
class PhysClass;
class MoveablePhysClass;
class RigidBodyClass;
class MotorVehicleClass;
class WheeledVehicleClass;
class MotorcycleClass;
class CPhysTestDoc;
class ChunkLoadClass;
class ChunkSaveClass;
class CMainFrame : public CFrameWnd
{
protected: // create from serialization only
CMainFrame();
DECLARE_DYNCREATE(CMainFrame)
// Attributes
protected:
CSplitterWnd Splitter;
CVJoyDialog * VirtualJoystick;
MoveablePhysClass * ControlledObject;
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMainFrame)
public:
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CMainFrame();
CView * Get_Pane(int iRow, int iCol) const { return (CView *)Splitter.GetPane(iRow, iCol); }
void Apply_Impulse(const Vector3 & imp);
void Apply_Couple(const Vector3 & p0,const Vector3 & i0,const Vector3 & p1,const Vector3 & i1);
void Set_Status_Bar_Text(const char * text);
void Notify_Selection_Changed(void);
const char * Peek_Selected_Model(void);
PhysClass * Peek_Selected_Object(void);
MoveablePhysClass * Peek_Selected_MoveablePhysClass(void);
RigidBodyClass * Peek_Selected_RigidBodyClass(void);
MotorVehicleClass * Peek_Selected_MotorVehicleClass(void);
WheeledVehicleClass * Peek_Selected_WheeledVehicleClass(void);
MotorcycleClass * Peek_Selected_MotorcycleClass(void);
void Add_Object(PhysClass * new_obj);
CPhysTestDoc * Get_Document(void);
void Save(ChunkSaveClass & csave);
void Load(ChunkLoadClass & cload);
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
CStatusBar m_wndStatusBar;
CToolBar m_wndToolBar;
CToolBar m_wndImpulseToolBar;
// Generated message map functions
protected:
//{{AFX_MSG(CMainFrame)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnActivateApp(BOOL bActive, HTASK hTask);
afx_msg void OnOptionsRunSimulation();
afx_msg void OnUpdateOptionsRunSimulation(CCmdUI* pCmdUI);
afx_msg void OnOptionsDisplayBoxes();
afx_msg void OnUpdateOptionsDisplayBoxes(CCmdUI* pCmdUI);
afx_msg void OnCreateRigidBody();
afx_msg void OnUpdateImpulseButton(CCmdUI* pCmdUI);
afx_msg void OnCoupleNegx();
afx_msg void OnCoupleNegy();
afx_msg void OnCoupleNegz();
afx_msg void OnCouplePosx();
afx_msg void OnCouplePosy();
afx_msg void OnCouplePosz();
afx_msg void OnImpulseNegx();
afx_msg void OnImpulseNegy();
afx_msg void OnImpulseNegz();
afx_msg void OnImpulsePosx();
afx_msg void OnImpulsePosy();
afx_msg void OnImpulsePosz();
afx_msg void OnViewImpulsetoolbar();
afx_msg void OnUpdateViewImpulsetoolbar(CCmdUI* pCmdUI);
afx_msg void OnProperties();
afx_msg void OnInertia();
afx_msg void OnOptionsPhysicsConstants();
afx_msg void OnFreezeObject();
afx_msg void OnDebugObject();
afx_msg void OnUpdateDebugObject(CCmdUI* pCmdUI);
afx_msg void OnViewVirtualjoystick();
afx_msg void OnUpdateViewVirtualjoystick(CCmdUI* pCmdUI);
afx_msg void OnDestroy();
afx_msg void OnOptionsFilled();
afx_msg void OnUpdateOptionsFilled(CCmdUI* pCmdUI);
afx_msg void OnOptionsPoints();
afx_msg void OnUpdateOptionsPoints(CCmdUI* pCmdUI);
afx_msg void OnOptionsWireframe();
afx_msg void OnUpdateOptionsWireframe(CCmdUI* pCmdUI);
afx_msg void OnMotorProperties();
afx_msg void OnWheelProperties();
afx_msg void OnUpdateWheelProperties(CCmdUI* pCmdUI);
afx_msg void OnUpdateMotorProperties(CCmdUI* pCmdUI);
afx_msg void OnCameraFollow();
afx_msg void OnUpdateCameraFollow(CCmdUI* pCmdUI);
afx_msg void OnCameraFly();
afx_msg void OnUpdateCameraFly(CCmdUI* pCmdUI);
afx_msg void OnCameraTether();
afx_msg void OnUpdateCameraTether(CCmdUI* pCmdUI);
afx_msg void OnCameraRigidTether();
afx_msg void OnUpdateCameraRigidTether(CCmdUI* pCmdUI);
afx_msg void OnCreateWheeledVehicle();
afx_msg void OnUpdateCreateRigidBody(CCmdUI* pCmdUI);
afx_msg void OnUpdateCreateWheeledVehicle(CCmdUI* pCmdUI);
afx_msg void OnUpdateProperties(CCmdUI* pCmdUI);
afx_msg void OnCreateMotorcycle();
afx_msg void OnUpdateCreateMotorcycle(CCmdUI* pCmdUI);
afx_msg void OnMotorcycleProperties();
afx_msg void OnUpdateMotorcycleProperties(CCmdUI* pCmdUI);
afx_msg void OnOptionsRenderDevice();
afx_msg void OnUpdateOptionsRenderDevice(CCmdUI* pCmdUI);
afx_msg void OnFileImportModel();
afx_msg void OnFileImportLev();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_MAINFRM_H__616293E8_E4F0_11D2_802E_0040056350C8__INCLUDED_)

View File

@@ -0,0 +1,119 @@
/*
** 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/>.
*/
// MotorVehicleDialog.cpp : implementation file
//
#include "stdafx.h"
#include "phystest.h"
#include "MotorVehicleDialog.h"
#include "motorvehicle.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
const float MIN_TORQUE = 1.0f;
const float MAX_TORQUE = 10000.0f;
/////////////////////////////////////////////////////////////////////////////
// CMotorVehicleDialog dialog
CMotorVehicleDialog::CMotorVehicleDialog(CWnd* pParent,MotorVehicleClass * obj)
: CDialog(CMotorVehicleDialog::IDD, pParent),
EditedObject(obj)
{
//{{AFX_DATA_INIT(CMotorVehicleDialog)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
void CMotorVehicleDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CMotorVehicleDialog)
DDX_Control(pDX, IDC_MVEHICLE_TORQUE_SPIN, m_TorqueSpin);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CMotorVehicleDialog, CDialog)
//{{AFX_MSG_MAP(CMotorVehicleDialog)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMotorVehicleDialog message handlers
float CMotorVehicleDialog::GetDlgItemFloat(int controlid)
{
CString string;
GetDlgItemText(controlid,string);
return atof(string);
}
void CMotorVehicleDialog::SetDlgItemFloat(int controlid,float val)
{
CString string;
string.Format("%.2f",val);
SetDlgItemText(controlid,string);
}
BOOL CMotorVehicleDialog::OnInitDialog()
{
CDialog::OnInitDialog();
m_TorqueSpin.SetRange(MIN_TORQUE * 100,MAX_TORQUE * 100);
float mt = EditedObject->Get_Max_Engine_Torque();
m_TorqueSpin.SetPos(mt * 100);
SetDlgItemFloat(IDC_MVEHICLE_TORQUE_EDIT,mt);
return TRUE;
}
BOOL CMotorVehicleDialog::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
// make the spin controls work...
switch(wParam)
{
case IDC_MVEHICLE_TORQUE_SPIN:
LPNMUPDOWN lpnmud = (LPNMUPDOWN) lParam;
if (lpnmud->hdr.code == UDN_DELTAPOS) {
HWND hwnd = (HWND)SendDlgItemMessage(LOWORD(wParam),UDM_GETBUDDY);
float curval = GetDlgItemFloat(GetWindowLong(hwnd,GWL_ID));
curval += (float)lpnmud->iDelta / 100.0f;
SetDlgItemFloat(GetWindowLong(hwnd,GWL_ID), curval);
}
break;
}
return CDialog::OnNotify(wParam, lParam, pResult);
}
void CMotorVehicleDialog::OnOK()
{
float mt = GetDlgItemFloat(IDC_MVEHICLE_TORQUE_EDIT);
EditedObject->Set_Max_Engine_Torque(mt);
CDialog::OnOK();
}

View File

@@ -0,0 +1,73 @@
/*
** 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/>.
*/
#if !defined(AFX_MOTORVEHICLEDIALOG_H__14B8CCA1_F28E_11D2_9BD8_00A0C9988171__INCLUDED_)
#define AFX_MOTORVEHICLEDIALOG_H__14B8CCA1_F28E_11D2_9BD8_00A0C9988171__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// MotorVehicleDialog.h : header file
//
class MotorVehicleClass;
/////////////////////////////////////////////////////////////////////////////
// CMotorVehicleDialog dialog
class CMotorVehicleDialog : public CDialog
{
// Construction
public:
CMotorVehicleDialog(CWnd* pParent,MotorVehicleClass * obj);
// Dialog Data
//{{AFX_DATA(CMotorVehicleDialog)
enum { IDD = IDD_MOTORVEHICLE_DIALOG };
CSpinButtonCtrl m_TorqueSpin;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMotorVehicleDialog)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
//}}AFX_VIRTUAL
// Implementation
protected:
MotorVehicleClass * EditedObject;
float GetDlgItemFloat(int controlid);
void SetDlgItemFloat(int controlid,float val);
// Generated message map functions
//{{AFX_MSG(CMotorVehicleDialog)
virtual BOOL OnInitDialog();
virtual void OnOK();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_MOTORVEHICLEDIALOG_H__14B8CCA1_F28E_11D2_9BD8_00A0C9988171__INCLUDED_)

View File

@@ -0,0 +1,132 @@
/*
** 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/>.
*/
// MotorcycleDialog.cpp : implementation file
//
#include "stdafx.h"
#include "phystest.h"
#include "MotorcycleDialog.h"
#include "motorcycle.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
const float MIN_K = 0.01f;
const float MAX_K = 100.0f;
/////////////////////////////////////////////////////////////////////////////
// CMotorcycleDialog dialog
CMotorcycleDialog::CMotorcycleDialog(CWnd* pParent,MotorcycleClass * obj)
: CDialog(CMotorcycleDialog::IDD, pParent),
EditedObject(obj)
{
//{{AFX_DATA_INIT(CMotorcycleDialog)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
void CMotorcycleDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CMotorcycleDialog)
DDX_Control(pDX, IDC_LEAN_K1_SPIN, m_LeanK1Spin);
DDX_Control(pDX, IDC_LEAN_K0_SPIN, m_LeanK0Spin);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CMotorcycleDialog, CDialog)
//{{AFX_MSG_MAP(CMotorcycleDialog)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMotorcycleDialog message handlers
float CMotorcycleDialog::GetDlgItemFloat(int controlid)
{
CString string;
GetDlgItemText(controlid,string);
return atof(string);
}
void CMotorcycleDialog::SetDlgItemFloat(int controlid,float val)
{
CString string;
string.Format("%.2f",val);
SetDlgItemText(controlid,string);
}
BOOL CMotorcycleDialog::OnInitDialog()
{
CDialog::OnInitDialog();
m_LeanK0Spin.SetRange(MIN_K * 100,MAX_K * 100);
m_LeanK1Spin.SetRange(MIN_K * 100,MAX_K * 100);
float k;
k = EditedObject->LeanK0;
m_LeanK0Spin.SetPos(k * 100);
SetDlgItemFloat(IDC_LEAN_K0_EDIT,k);
k = EditedObject->LeanK1;
m_LeanK1Spin.SetPos(k * 100);
SetDlgItemFloat(IDC_LEAN_K1_EDIT,k);
return TRUE;
}
BOOL CMotorcycleDialog::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
// make the spin controls work...
switch(wParam)
{
case IDC_LEAN_K0_SPIN:
case IDC_LEAN_K1_SPIN:
LPNMUPDOWN lpnmud = (LPNMUPDOWN) lParam;
if (lpnmud->hdr.code == UDN_DELTAPOS) {
HWND hwnd = (HWND)SendDlgItemMessage(LOWORD(wParam),UDM_GETBUDDY);
float curval = GetDlgItemFloat(GetWindowLong(hwnd,GWL_ID));
curval += (float)lpnmud->iDelta / 100.0f;
SetDlgItemFloat(GetWindowLong(hwnd,GWL_ID), curval);
}
break;
}
return CDialog::OnNotify(wParam, lParam, pResult);
}
void CMotorcycleDialog::OnOK()
{
float k;
k = GetDlgItemFloat(IDC_LEAN_K0_EDIT);
EditedObject->LeanK0 = k;
k = GetDlgItemFloat(IDC_LEAN_K1_EDIT);
EditedObject->LeanK1 = k;
CDialog::OnOK();
}

View File

@@ -0,0 +1,75 @@
/*
** 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/>.
*/
#if !defined(AFX_MOTORCYCLEDIALOG_H__AD117871_03C8_11D3_9BDD_00A0C9988171__INCLUDED_)
#define AFX_MOTORCYCLEDIALOG_H__AD117871_03C8_11D3_9BDD_00A0C9988171__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// MotorcycleDialog.h : header file
//
class MotorcycleClass;
/////////////////////////////////////////////////////////////////////////////
// CMotorcycleDialog dialog
class CMotorcycleDialog : public CDialog
{
// Construction
public:
CMotorcycleDialog(CWnd* pParent,MotorcycleClass * obj);
// Dialog Data
//{{AFX_DATA(CMotorcycleDialog)
enum { IDD = IDD_MOTORCYCLE_DIALOG };
CSpinButtonCtrl m_LeanK1Spin;
CSpinButtonCtrl m_LeanK0Spin;
CSpinButtonCtrl m_BalanceK0Spin;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMotorcycleDialog)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
//}}AFX_VIRTUAL
// Implementation
protected:
MotorcycleClass * EditedObject;
float GetDlgItemFloat(int controlid);
void SetDlgItemFloat(int controlid,float val);
// Generated message map functions
//{{AFX_MSG(CMotorcycleDialog)
virtual BOOL OnInitDialog();
virtual void OnOK();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_MOTORCYCLEDIALOG_H__AD117871_03C8_11D3_9BDD_00A0C9988171__INCLUDED_)

View File

@@ -0,0 +1,423 @@
/*
** 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/>.
*/
// PhysTest.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "PhysTest.h"
#include "MainFrm.h"
#include "PhysTestDoc.h"
#include "GraphicView.h"
#include "ww3d.h"
#include "assetmgr.h"
#include "refcount.h"
#include "wwdebug.h"
#include "wwphystrig.h"
#include "srRuntimeClass.hpp"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
const char * LOGFILE_NAME = "_logfile";
const char * LOGFILE_EXTENSION = "txt";
/////////////////////////////////////////////////////////////////////////////
//
// Local prototypes
//
BOOL CALLBACK fnTopLevelWindowSearch (HWND hwnd, LPARAM lParam);
void Debug_Refs(void);
void init_logfile(void);
void write_to_logfile(const char * string);
void wwdebug_message_handler(DebugType type,const char * message);
void wwdebug_assert_handler(const char * message);
bool wwdebug_trigger_handler(int trigger_num);
/////////////////////////////////////////////////////////////////////////////
// CPhysTestApp
BEGIN_MESSAGE_MAP(CPhysTestApp, CWinApp)
//{{AFX_MSG_MAP(CPhysTestApp)
ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
//}}AFX_MSG_MAP
// Standard file based document commands
ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CPhysTestApp construction
CPhysTestApp::CPhysTestApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
/////////////////////////////////////////////////////////////////////////////
// The one and only CPhysTestApp object
CPhysTestApp theApp;
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
virtual BOOL OnInitDialog();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BOOL CAboutDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
// App command to run the dialog
void CPhysTestApp::OnAppAbout()
{
CAboutDlg aboutDlg;
aboutDlg.DoModal();
}
/////////////////////////////////////////////////////////////////////////////
// CPhysTestApp initialization
BOOL CPhysTestApp::InitInstance()
{
AfxEnableControlContainer();
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.
#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif
// Is there already an instance of the viewer running?
HWND hprev_instance = NULL;
::EnumWindows (fnTopLevelWindowSearch, (LPARAM)&hprev_instance);
if (hprev_instance == NULL) {
// Change the registry key under which our settings are stored.
// You should modify this string to be something appropriate
// such as the name of your company or organization.
SetRegistryKey(_T("Westwood Studios"));
LoadStdProfileSettings(); // Load standard INI file options (including MRU)
// Register the application's document templates. Document templates
// serve as the connection between documents, frame windows and views.
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CPhysTestDoc),
RUNTIME_CLASS(CMainFrame), // main SDI frame window
RUNTIME_CLASS(CGraphicView));
AddDocTemplate(pDocTemplate);
// Parse command line for standard shell commands, DDE, file open
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
// Dispatch commands specified on the command line
if (!ProcessShellCommand(cmdInfo))
return FALSE;
// The one and only window has been initialized, so show and update it.
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
} else {
// Make the previous instance in the foreground
::ShowWindow (hprev_instance, SW_NORMAL);
::BringWindowToTop (hprev_instance);
::SetForegroundWindow (hprev_instance);
}
// Create the log file
init_logfile();
// Install message handler functions for the WWDebug messages
// and assertion failures.
WWDebug_Install_Message_Handler(wwdebug_message_handler);
WWDebug_Install_Assert_Handler(wwdebug_assert_handler);
//WWDebug_Install_Trigger_Handler(wwdebug_trigger_handler);
WWDEBUG_SAY(("Logging Begin:\r\n"));
return (hprev_instance == NULL);
}
/////////////////////////////////////////////////////////////////////////////
// CPhysTestApp message handlers
int CPhysTestApp::ExitInstance()
{
// Free any resources the WW3D engine allocated
WW3DAssetManager::Get_Instance()->Free_Assets();
if (WW3D::Is_Initted()) {
WW3D::Shutdown();
}
// Remove message handler functions for the WWDebug messages
// and assertion failures.
WWDebug_Install_Message_Handler(NULL);
WWDebug_Install_Assert_Handler(NULL);
//WWDebug_Install_Trigger_Handler(NULL);
// Check Active Refs
Debug_Refs();
return CWinApp::ExitInstance();
}
//////////////////////////////////////////////////////////////////////////////
//
// fnTopLevelWindowSearch
//
BOOL CALLBACK
fnTopLevelWindowSearch
(
HWND hwnd,
LPARAM lParam
)
{
BOOL bcontinue = TRUE;
// Is this a viewer window?
if (::GetProp (hwnd, "WW3DVIEWER") != 0) {
bcontinue = false;
(*((HWND *)lParam)) = hwnd;
}
// Return the TRUE/FALSE result code
return bcontinue;
}
//////////////////////////////////////////////////////////////////////////////
//
// Debug_Refs()
//
void Debug_Refs(void)
{
#ifndef NDEBUG
RefBaseNodeClass * first = RefBaseClass::ActiveRefList.First();
RefBaseNodeClass * node = first;
while (node->Is_Valid())
{
RefBaseClass * obj = node->Get();
ActiveRefStruct * ref = &(obj->ActiveRefInfo);
bool display = true;
int count = 0;
RefBaseNodeClass * search = first;
while (search->Is_Valid()) {
if (search == node) { // if this is not the first one
if (count != 0) {
display = false;
break;
}
}
RefBaseClass * search_obj = search->Get();
ActiveRefStruct * search_ref = &(search_obj->ActiveRefInfo);
if ( ref->File && search_ref->File &&
!strcmp(search_ref->File, ref->File) &&
(search_ref->Line == ref->Line) ) {
count++;
} else if ( (ref->File == NULL) && (search_ref->File == NULL) ) {
count++;
}
search = search->Next();
}
if ( display ) {
char buf[256];
sprintf(buf,"%d Active Ref: %s %d %p\n",count, ref->File,ref->Line,obj);
::MessageBox(NULL,buf,"Unreleased Object!",MB_OK);
static int num_printed = 0;
if (++num_printed > 20) {
::MessageBox(NULL,"And Many More......\n",NULL,MB_OK);
break;
}
}
node = node->Next();
}
#endif
}
//////////////////////////////////////////////////////////////////////////////
//
// get_log_filename
//
const char * get_log_filename(void)
{
static char log_name[_MAX_PATH];
char exe_name[_MAX_PATH];
::GetModuleFileName(::AfxGetInstanceHandle(),exe_name,sizeof(exe_name));
char drive[_MAX_DRIVE];
char dir[_MAX_DIR];
_splitpath(exe_name,drive,dir,NULL,NULL);
_makepath(log_name,drive,dir,LOGFILE_NAME,LOGFILE_EXTENSION);
return log_name;
}
//////////////////////////////////////////////////////////////////////////////
//
// init_logfile
//
void init_logfile(void)
{
// Destroy contents
FILE * file = fopen(get_log_filename(), "w");
fclose(file);
}
//////////////////////////////////////////////////////////////////////////////
//
// write_to_logfile
//
void write_to_logfile(const char * string)
{
// open/close for each write so as to maximize integrity of this file.
FILE * file = fopen(get_log_filename(), "a");
if (file != NULL) {
fwrite(string, 1, strlen(string), file);
fclose(file);
}
}
//////////////////////////////////////////////////////////////////////////////
//
// wwdebug_message_handler
//
void wwdebug_message_handler(DebugType type,const char * message)
{
/*
** dump the message into our log file
*/
write_to_logfile(message);
}
//////////////////////////////////////////////////////////////////////////////
//
// wwdebug assert handler
//
void wwdebug_assert_handler(const char * message)
{
/*
** dump the assert into our log file
*/
write_to_logfile(message);
/*
** break into the debugger
*/
_asm int 0x03;
}
//////////////////////////////////////////////////////////////////////////////
//
// wwdebug trigger handler
// Disables VIS!
//
bool wwdebug_trigger_handler(int trigger_num)
{
switch( trigger_num )
{
case WWPHYS_TRIGGER_DISABLE_VIS: return true;
}
return false;
}

View File

@@ -0,0 +1,264 @@
# Microsoft Developer Studio Project File - Name="PhysTest" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Application" 0x0101
CFG=PhysTest - 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 "PhysTest.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 "PhysTest.mak" CFG="PhysTest - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "PhysTest - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "PhysTest - Win32 Debug" (based on "Win32 (x86) Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/Commando/Code/Tests/PhysTest", QCOBAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "PhysTest - Win32 Release"
# PROP BASE Use_MFC 6
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 6
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\sr\sr.h" /I "..\..\srsdk1x\include" /I "..\..\wwdebug" /I "..\..\wwmath" /I "..\..\ww3d" /I "..\..\wwphys" /I "..\..\wwlib" /I "..\..\wwsaveload" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Yu"stdafx.h" /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL"
# ADD RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 /nologo /subsystem:windows /machine:I386
# ADD LINK32 sr.lib wwdebug.lib wwmath.lib ww3d.lib wwlib.lib wwphys.lib wwsaveload.lib vfw32.lib winmm.lib version.lib /nologo /subsystem:windows /machine:I386 /out:"Run/PhysTest.exe" /libpath:"..\..\Libs\release" /libpath:"..\..\srsdk1x\msvc6\lib\release"
!ELSEIF "$(CFG)" == "PhysTest - Win32 Debug"
# PROP BASE Use_MFC 6
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 6
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\..\srsdk1x\include" /I "..\..\wwdebug" /I "..\..\wwmath" /I "..\..\ww3d" /I "..\..\wwphys" /I "..\..\wwlib" /I "..\..\wwsaveload" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /D "WWDEBUG" /Yu"stdafx.h" /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL"
# ADD RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 /nologo /subsystem:windows /debug /machine:I386
# ADD LINK32 srdb.lib wwdebug.lib wwmath.lib ww3d.lib wwlib.lib wwphys.lib wwsaveload.lib vfw32.lib winmm.lib version.lib /nologo /subsystem:windows /debug /machine:I386 /out:"Run/PhysTestD.exe" /libpath:"..\..\Libs\debug" /libpath:"..\..\srsdk1x\msvc6\lib\debug"
!ENDIF
# Begin Target
# Name "PhysTest - Win32 Release"
# Name "PhysTest - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\DataView.cpp
# End Source File
# Begin Source File
SOURCE=.\Globals.cpp
# End Source File
# Begin Source File
SOURCE=.\GraphicView.cpp
# End Source File
# Begin Source File
SOURCE=.\InertiaDialog.cpp
# End Source File
# Begin Source File
SOURCE=.\MainFrm.cpp
# End Source File
# Begin Source File
SOURCE=.\MotorcycleDialog.cpp
# End Source File
# Begin Source File
SOURCE=.\MotorVehicleDialog.cpp
# End Source File
# Begin Source File
SOURCE=.\PhysicsConstantsDialog.cpp
# End Source File
# Begin Source File
SOURCE=.\PhysTest.cpp
# End Source File
# Begin Source File
SOURCE=.\PhysTestDoc.cpp
# End Source File
# Begin Source File
SOURCE=.\PhysTestSaveSystem.cpp
# End Source File
# Begin Source File
SOURCE=.\RbodyPropertiesDialog.cpp
# End Source File
# Begin Source File
SOURCE=.\RenderDeviceDialog.cpp
# End Source File
# Begin Source File
SOURCE=.\StdAfx.cpp
# ADD CPP /Yc"stdafx.h"
# End Source File
# Begin Source File
SOURCE=.\VJoyDialog.cpp
# End Source File
# Begin Source File
SOURCE=.\WheeledVehicleDialog.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\DataView.h
# End Source File
# Begin Source File
SOURCE=.\GraphicView.h
# End Source File
# Begin Source File
SOURCE=.\InertiaDialog.h
# End Source File
# Begin Source File
SOURCE=.\MainFrm.h
# End Source File
# Begin Source File
SOURCE=.\MotorcycleDialog.h
# End Source File
# Begin Source File
SOURCE=.\MotorVehicleDialog.h
# End Source File
# Begin Source File
SOURCE=.\PhysicsConstantsDialog.h
# End Source File
# Begin Source File
SOURCE=.\PhysTest.h
# End Source File
# Begin Source File
SOURCE=.\PhysTestDoc.h
# End Source File
# Begin Source File
SOURCE=.\PhysTestSaveSystem.h
# End Source File
# Begin Source File
SOURCE=.\RbodyPropertiesDialog.h
# End Source File
# Begin Source File
SOURCE=.\RenderDeviceDialog.h
# End Source File
# Begin Source File
SOURCE=.\StdAfx.h
# End Source File
# Begin Source File
SOURCE=.\VJoyDialog.h
# End Source File
# Begin Source File
SOURCE=.\WheeledVehicleDialog.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"
# Begin Source File
SOURCE=.\res\PhysTest.ico
# End Source File
# Begin Source File
SOURCE=.\PhysTest.rc
# End Source File
# Begin Source File
SOURCE=.\res\PhysTest.rc2
# End Source File
# Begin Source File
SOURCE=.\res\PhysTestDoc.ico
# End Source File
# Begin Source File
SOURCE=.\Resource.h
# End Source File
# Begin Source File
SOURCE=.\res\Toolbar.bmp
# End Source File
# Begin Source File
SOURCE=.\res\toolbar1.bmp
# End Source File
# End Group
# Begin Source File
SOURCE=.\res\Axes.w3d
# End Source File
# Begin Source File
SOURCE=.\res\Point.w3d
# End Source File
# End Target
# End Project

View File

@@ -0,0 +1,66 @@
/*
** 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/>.
*/
// PhysTest.h : main header file for the PHYSTEST application
//
#if !defined(AFX_PHYSTEST_H__616293E4_E4F0_11D2_802E_0040056350C8__INCLUDED_)
#define AFX_PHYSTEST_H__616293E4_E4F0_11D2_802E_0040056350C8__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#ifndef __AFXWIN_H__
#error include 'stdafx.h' before including this file for PCH
#endif
#include "resource.h" // main symbols
/////////////////////////////////////////////////////////////////////////////
// CPhysTestApp:
// See PhysTest.cpp for the implementation of this class
//
class CPhysTestApp : public CWinApp
{
public:
CPhysTestApp();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CPhysTestApp)
public:
virtual BOOL InitInstance();
virtual int ExitInstance();
//}}AFX_VIRTUAL
// Implementation
//{{AFX_MSG(CPhysTestApp)
afx_msg void OnAppAbout();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_PHYSTEST_H__616293E4_E4F0_11D2_802E_0040056350C8__INCLUDED_)

View File

@@ -0,0 +1,754 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"#define _AFX_NO_SPLITTER_RESOURCES\r\n"
"#define _AFX_NO_OLE_RESOURCES\r\n"
"#define _AFX_NO_TRACKER_RESOURCES\r\n"
"#define _AFX_NO_PROPERTY_RESOURCES\r\n"
"\r\n"
"#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
"#ifdef _WIN32\r\n"
"LANGUAGE 9, 1\r\n"
"#pragma code_page(1252)\r\n"
"#endif //_WIN32\r\n"
"#include ""res\\PhysTest.rc2"" // non-Microsoft Visual C++ edited resources\r\n"
"#include ""afxres.rc"" // Standard components\r\n"
"#endif\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDR_MAINFRAME ICON DISCARDABLE "res\\PhysTest.ico"
IDR_PHYSTETYPE ICON DISCARDABLE "res\\PhysTestDoc.ico"
/////////////////////////////////////////////////////////////////////////////
//
// Bitmap
//
IDR_MAINTOOLBAR BITMAP MOVEABLE PURE "res\\Toolbar.bmp"
IDR_IMPULSE_TOOLBAR BITMAP DISCARDABLE "res\\toolbar1.bmp"
/////////////////////////////////////////////////////////////////////////////
//
// Toolbar
//
IDR_MAINTOOLBAR TOOLBAR DISCARDABLE 24, 24
BEGIN
BUTTON ID_FILE_NEW
BUTTON ID_FILE_OPEN
SEPARATOR
BUTTON ID_OPTIONS_RUN_SIMULATION
SEPARATOR
BUTTON ID_OPTIONS_DISPLAY_BOXES
BUTTON ID_OPTIONS_PHYSICS_CONSTANTS
SEPARATOR
BUTTON ID_OPTIONS_FILLED
BUTTON ID_OPTIONS_WIREFRAME
BUTTON ID_OPTIONS_POINTS
SEPARATOR
BUTTON ID_CAMERA_FLY
BUTTON ID_CAMERA_FOLLOW
BUTTON ID_CAMERA_TETHER
BUTTON ID_CAMERA_RIGID_TETHER
SEPARATOR
BUTTON ID_CREATE_RIGID_BODY
BUTTON ID_CREATE_WHEELED_VEHICLE
BUTTON ID_CREATE_MOTORCYCLE
BUTTON ID_BUTTON32834
END
IDR_IMPULSE_TOOLBAR TOOLBAR DISCARDABLE 24, 24
BEGIN
BUTTON ID_COUPLE_POSX
BUTTON ID_COUPLE_NEGX
BUTTON ID_COUPLE_POSY
BUTTON ID_COUPLE_NEGY
BUTTON ID_COUPLE_POSZ
BUTTON ID_COUPLE_NEGZ
SEPARATOR
BUTTON ID_IMPULSE_POSX
BUTTON ID_IMPULSE_NEGX
BUTTON ID_IMPULSE_POSY
BUTTON ID_IMPULSE_NEGY
BUTTON ID_IMPULSE_POSZ
BUTTON ID_IMPULSE_NEGZ
SEPARATOR
BUTTON ID_FREEZE_OBJECT
BUTTON ID_DEBUG_OBJECT
SEPARATOR
BUTTON ID_INERTIA
BUTTON ID_PROPERTIES
BUTTON ID_MOTOR_PROPERTIES
BUTTON ID_WHEEL_PROPERTIES
BUTTON ID_MOTORCYCLE_PROPERTIES
END
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDR_MAINFRAME MENU PRELOAD DISCARDABLE
BEGIN
POPUP "&File"
BEGIN
MENUITEM "&New\tCtrl+N", ID_FILE_NEW
MENUITEM "&Open...\tCtrl+O", ID_FILE_OPEN
MENUITEM "&Save\tCtrl+S", ID_FILE_SAVE, GRAYED
MENUITEM "Save &As... ", ID_FILE_SAVE_AS, GRAYED
MENUITEM "Import Model", ID_FILE_IMPORT_MODEL
MENUITEM "Import LEV", ID_FILE_IMPORT_LEV
MENUITEM SEPARATOR
MENUITEM "Recent File", ID_FILE_MRU_FILE1, GRAYED
MENUITEM SEPARATOR
MENUITEM "E&xit", ID_APP_EXIT
END
POPUP "&Create"
BEGIN
MENUITEM "Rigid Body", ID_CREATE_RIGID_BODY
MENUITEM "Wheeled Vehicle", ID_CREATE_WHEELED_VEHICLE
MENUITEM "Motorcycle", ID_CREATE_MOTORCYCLE
END
POPUP "&Options"
BEGIN
MENUITEM "Run Simulation", ID_OPTIONS_RUN_SIMULATION
MENUITEM "Display Collision Boxes", ID_OPTIONS_DISPLAY_BOXES
MENUITEM "Change Physics Constants", ID_OPTIONS_PHYSICS_CONSTANTS
MENUITEM SEPARATOR
MENUITEM "Render Fill", ID_OPTIONS_FILLED
MENUITEM "Render Wireframe", ID_OPTIONS_WIREFRAME
MENUITEM "Render Points", ID_OPTIONS_POINTS
MENUITEM SEPARATOR
MENUITEM "Change Render Device", ID_OPTIONS_RENDER_DEVICE
END
POPUP "&View"
BEGIN
MENUITEM "&Toolbar", ID_VIEW_TOOLBAR
MENUITEM "&Status Bar", ID_VIEW_STATUS_BAR
MENUITEM "Impulse Toolbar", ID_VIEW_IMPULSETOOLBAR
MENUITEM "Virtual Joystick", ID_VIEW_VIRTUALJOYSTICK
END
POPUP "&Help"
BEGIN
MENUITEM "&About PhysTest...", ID_APP_ABOUT
END
POPUP "Camera"
BEGIN
MENUITEM "Fly", ID_CAMERA_FLY
MENUITEM "Follow", ID_CAMERA_FOLLOW
MENUITEM "Tether", ID_CAMERA_TETHER
MENUITEM "Rigid Tether", ID_CAMERA_RIGID_TETHER
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Accelerator
//
IDR_MAINFRAME ACCELERATORS PRELOAD MOVEABLE PURE
BEGIN
"N", ID_FILE_NEW, VIRTKEY, CONTROL
"O", ID_FILE_OPEN, VIRTKEY, CONTROL
"S", ID_FILE_SAVE, VIRTKEY, CONTROL
"Z", ID_EDIT_UNDO, VIRTKEY, CONTROL
"X", ID_EDIT_CUT, VIRTKEY, CONTROL
"C", ID_EDIT_COPY, VIRTKEY, CONTROL
"V", ID_EDIT_PASTE, VIRTKEY, CONTROL
VK_BACK, ID_EDIT_UNDO, VIRTKEY, ALT
VK_DELETE, ID_EDIT_CUT, VIRTKEY, SHIFT
VK_INSERT, ID_EDIT_COPY, VIRTKEY, CONTROL
VK_INSERT, ID_EDIT_PASTE, VIRTKEY, SHIFT
VK_F6, ID_NEXT_PANE, VIRTKEY
VK_F6, ID_PREV_PANE, VIRTKEY, SHIFT
END
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_ABOUTBOX DIALOG DISCARDABLE 0, 0, 235, 55
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "About PhysTest"
FONT 8, "MS Sans Serif"
BEGIN
ICON IDR_MAINFRAME,IDC_STATIC,11,17,20,20
LTEXT "PhysTest Version 1.0",IDC_STATIC,40,10,119,8,
SS_NOPREFIX
LTEXT "Copyright (C) 1999",IDC_STATIC,40,25,119,8
DEFPUSHBUTTON "OK",IDOK,178,7,50,14,WS_GROUP
END
IDD_RBODY_PROPERTIES_DIALOG DIALOG DISCARDABLE 0, 0, 217, 153
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Rigid Body Properties"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "Mass:",IDC_STATIC,7,13,20,8
EDITTEXT IDC_MASS_EDIT,49,7,40,14,ES_AUTOHSCROLL
CONTROL "Spin1",IDC_MASS_SPIN,"msctls_updown32",UDS_ALIGNRIGHT |
UDS_AUTOBUDDY | UDS_ARROWKEYS,89,7,10,14
LTEXT "Elasticity:",IDC_STATIC,7,28,30,8
EDITTEXT IDC_ELASTICITY_EDIT,49,22,40,14,ES_AUTOHSCROLL
CONTROL "Spin2",IDC_ELASTICITY_SPIN,"msctls_updown32",
UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,89,22,10,
14
LTEXT "Gravity:",IDC_STATIC,7,44,25,8
EDITTEXT IDC_GRAVITY_EDIT,49,38,40,14,ES_AUTOHSCROLL
CONTROL "Spin3",IDC_GRAVITY_SPIN,"msctls_updown32",
UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,89,38,10,
14
LTEXT "Position:",IDC_STATIC,7,62,28,8
EDITTEXT IDC_POSITIONX_EDIT,49,58,40,14,ES_AUTOHSCROLL
CONTROL "Spin3",IDC_POSITIONX_SPIN,"msctls_updown32",
UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,89,58,11,
14
EDITTEXT IDC_POSITIONY_EDIT,103,58,40,14,ES_AUTOHSCROLL
CONTROL "Spin3",IDC_POSITIONY_SPIN,"msctls_updown32",
UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,143,58,11,
14
EDITTEXT IDC_POSITIONZ_EDIT,157,58,40,14,ES_AUTOHSCROLL
CONTROL "Spin3",IDC_POSITIONZ_SPIN,"msctls_updown32",
UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,197,58,11,
14
DEFPUSHBUTTON "OK",IDOK,160,7,50,14
PUSHBUTTON "Cancel",IDCANCEL,160,24,50,14
EDITTEXT IDC_STIFFNESS_EDIT,79,84,40,14,ES_AUTOHSCROLL |
WS_DISABLED
CONTROL "Spin1",IDC_STIFFNESS_SPIN,"msctls_updown32",
UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,119,84,11,
14
LTEXT "Contact Stiffness:",IDC_STATIC,14,88,56,8
EDITTEXT IDC_DAMPING_EDIT,80,102,40,14,ES_AUTOHSCROLL |
WS_DISABLED
CONTROL "Spin1",IDC_DAMPING_SPIN,"msctls_updown32",
UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,120,102,
11,14
LTEXT "Contact Damping:",IDC_STATIC,15,106,58,8
EDITTEXT IDC_LENGTH_EDIT,79,121,40,14,ES_AUTOHSCROLL
CONTROL "Spin1",IDC_LENGTH_SPIN,"msctls_updown32",UDS_ALIGNRIGHT |
UDS_AUTOBUDDY | UDS_ARROWKEYS,119,121,11,14
LTEXT "Contact Thickness:",IDC_STATIC,14,125,62,8
END
IDD_INERTIA_DIALOG DIALOG DISCARDABLE 0, 0, 186, 94
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Inertia Tensor"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,35,73,50,14
PUSHBUTTON "Cancel",IDCANCEL,89,73,50,14
EDITTEXT IDC_IBODYX_EDIT,13,20,40,14,ES_AUTOHSCROLL
CONTROL "Spin3",IDC_IBODYX_SPIN,"msctls_updown32",UDS_ALIGNRIGHT |
UDS_AUTOBUDDY | UDS_ARROWKEYS,53,20,11,14
EDITTEXT IDC_IBODYY_EDIT,66,36,40,14,ES_AUTOHSCROLL
CONTROL "Spin3",IDC_IBODYY_SPIN,"msctls_updown32",UDS_ALIGNRIGHT |
UDS_AUTOBUDDY | UDS_ARROWKEYS,106,36,11,14
EDITTEXT IDC_IBODYZ_EDIT,120,52,40,14,ES_AUTOHSCROLL
CONTROL "Spin3",IDC_IBODYZ_SPIN,"msctls_updown32",UDS_ALIGNRIGHT |
UDS_AUTOBUDDY | UDS_ARROWKEYS,160,52,11,14
LTEXT "IBody:",IDC_STATIC,75,7,21,8
LTEXT "0.0",IDC_STATIC,85,23,11,8
LTEXT "0.0",IDC_STATIC,134,23,11,8
LTEXT "0.0",IDC_STATIC,134,40,11,8
LTEXT "0.0",IDC_STATIC,85,56,11,8
LTEXT "0.0",IDC_STATIC,26,56,11,8
LTEXT "0.0",IDC_STATIC,26,41,11,8
END
IDD_PHYSICS_CONSTANTS_DIALOG DIALOG DISCARDABLE 0, 0, 211, 78
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Physics Constants"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,154,7,50,14
PUSHBUTTON "Cancel",IDCANCEL,154,24,50,14
LTEXT "Acceleration of Gravity:",IDC_STATIC,14,21,74,8
LTEXT "Linear Damping:",IDC_STATIC,36,35,52,8
LTEXT "Angular Damping:",IDC_STATIC,31,49,57,8
EDITTEXT IDC_GRAVITYACCEL_EDIT,94,18,40,14,ES_AUTOHSCROLL
CONTROL "Spin1",IDC_GRAVITYACCEL_SPIN,"msctls_updown32",
UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,134,18,11,
14
EDITTEXT IDC_LDAMPING_EDIT,94,32,40,14,ES_AUTOHSCROLL
CONTROL "Spin1",IDC_LDAMPING_SPIN,"msctls_updown32",
UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,134,32,11,
14
EDITTEXT IDC_ADAMPING_EDIT,94,46,40,14,ES_AUTOHSCROLL
CONTROL "Spin1",IDC_ADAMPING_SPIN,"msctls_updown32",
UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,134,46,11,
14
END
IDD_VJOY_DIALOG DIALOG DISCARDABLE 0, 0, 212, 119
STYLE DS_MODALFRAME | WS_POPUP | WS_CLIPCHILDREN | WS_CAPTION
CAPTION "Virtual Joystick"
FONT 8, "MS Sans Serif"
BEGIN
CONTROL "",IDC_MOVEXY_STATIC,"Static",SS_BLACKFRAME,13,34,63,58
CONTROL "Slider1",IDC_MOVEZ_SLIDER,"msctls_trackbar32",TBS_VERT |
TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,81,35,16,53
CONTROL "",IDC_TURNXY_STATIC,"Static",SS_BLACKFRAME,104,33,63,58
CONTROL "Slider1",IDC_TURNZ_SLIDER,"msctls_trackbar32",TBS_VERT |
TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,176,35,16,53
END
IDD_MOTORVEHICLE_DIALOG DIALOG DISCARDABLE 0, 0, 206, 61
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Motor Properties"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,47,40,50,14
PUSHBUTTON "Cancel",IDCANCEL,108,40,50,14
EDITTEXT IDC_MVEHICLE_TORQUE_EDIT,79,8,40,14,ES_AUTOHSCROLL
CONTROL "Spin3",IDC_MVEHICLE_TORQUE_SPIN,"msctls_updown32",
UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,120,8,11,
14
LTEXT "Max Engine Torque:",IDC_STATIC,7,11,65,8
LTEXT "Newton-Meters",IDC_STATIC,137,11,49,8
END
IDD_WHEELEDVEHICLE_DIALOG DIALOG DISCARDABLE 0, 0, 163, 103
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Wheeled Vehicle Properties"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,27,80,50,14
PUSHBUTTON "Cancel",IDCANCEL,85,80,50,14
EDITTEXT IDC_WVEHICLE_KS_EDIT,79,7,40,14,ES_AUTOHSCROLL
CONTROL "Spin3",IDC_WVEHICLE_KS_SPIN,"msctls_updown32",
UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,119,7,11,
14
EDITTEXT IDC_WVEHICLE_KD_EDIT,79,25,40,14,ES_AUTOHSCROLL
CONTROL "Spin3",IDC_WVEHICLE_KD_SPIN,"msctls_updown32",
UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,119,25,11,
14
LTEXT "Spring Constant:",IDC_STATIC,7,11,53,8
LTEXT "Damping Coefficient:",IDC_STATIC,7,29,66,8
LTEXT "N/m",IDC_STATIC,135,11,15,8
LTEXT "N*s/m",IDC_STATIC,135,29,21,8
EDITTEXT IDC_WVEHICLE_LENGTH_EDIT,79,45,40,14,ES_AUTOHSCROLL
CONTROL "Spin3",IDC_WVEHICLE_LENGTH_SPIN,"msctls_updown32",
UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,119,45,11,
14
LTEXT "Spring Length:",IDC_STATIC,7,48,47,8
LTEXT "m",IDC_STATIC,135,49,8,8
END
IDD_MOTORCYCLE_DIALOG DIALOG DISCARDABLE 0, 0, 137, 70
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Motorcycle Properties"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "Lean k0",IDC_STATIC,18,11,27,8
EDITTEXT IDC_LEAN_K0_EDIT,61,7,40,14,ES_AUTOHSCROLL
CONTROL "Spin3",IDC_LEAN_K0_SPIN,"msctls_updown32",
UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,101,7,11,
14
LTEXT "Lean k1",IDC_STATIC,18,29,27,8
EDITTEXT IDC_LEAN_K1_EDIT,61,25,40,14,ES_AUTOHSCROLL
CONTROL "Spin3",IDC_LEAN_K1_SPIN,"msctls_updown32",
UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,101,25,11,
14
DEFPUSHBUTTON "OK",IDOK,12,49,50,14
PUSHBUTTON "Cancel",IDCANCEL,74,49,50,14
END
IDD_RENDER_DEVICE_DIALOG DIALOG DISCARDABLE 0, 0, 185, 47
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Select A Render Device"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,128,7,50,14
PUSHBUTTON "Cancel",IDCANCEL,128,24,50,14
COMBOBOX IDC_RENDER_DEVICE_COMBO,7,17,111,159,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
END
#ifndef _MAC
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,1
PRODUCTVERSION 1,0,0,1
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904B0"
BEGIN
VALUE "CompanyName", "\0"
VALUE "FileDescription", "PhysTest MFC Application\0"
VALUE "FileVersion", "1, 0, 0, 1\0"
VALUE "InternalName", "PhysTest\0"
VALUE "LegalCopyright", "Copyright (C) 1999\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "PhysTest.EXE\0"
VALUE "ProductName", "PhysTest Application\0"
VALUE "ProductVersion", "1, 0, 0, 1\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#endif // !_MAC
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_ABOUTBOX, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 228
TOPMARGIN, 7
BOTTOMMARGIN, 48
END
IDD_RBODY_PROPERTIES_DIALOG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 210
TOPMARGIN, 7
BOTTOMMARGIN, 146
END
IDD_INERTIA_DIALOG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 179
TOPMARGIN, 7
BOTTOMMARGIN, 87
END
IDD_PHYSICS_CONSTANTS_DIALOG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 204
TOPMARGIN, 7
BOTTOMMARGIN, 71
END
IDD_VJOY_DIALOG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 205
TOPMARGIN, 7
BOTTOMMARGIN, 112
END
IDD_MOTORVEHICLE_DIALOG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 199
TOPMARGIN, 7
BOTTOMMARGIN, 54
END
IDD_WHEELEDVEHICLE_DIALOG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 156
TOPMARGIN, 7
BOTTOMMARGIN, 96
END
IDD_MOTORCYCLE_DIALOG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 130
TOPMARGIN, 7
BOTTOMMARGIN, 63
END
IDD_RENDER_DEVICE_DIALOG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 178
TOPMARGIN, 7
BOTTOMMARGIN, 40
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// FILE
//
AXES.W3D FILE DISCARDABLE "res\\Axes.w3d"
POINT.W3D FILE DISCARDABLE "res\\Point.w3d"
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE PRELOAD DISCARDABLE
BEGIN
IDR_MAINFRAME "Physics Test App\nScene\nScene\nPhysics Test App Scenes (*.phy)\n.phy\nPhysTest.Document\nPhysTest Scene"
END
STRINGTABLE PRELOAD DISCARDABLE
BEGIN
AFX_IDS_APP_TITLE "PhysTest"
AFX_IDS_IDLEMESSAGE "Ready"
END
STRINGTABLE DISCARDABLE
BEGIN
ID_INDICATOR_EXT "EXT"
ID_INDICATOR_CAPS "CAP"
ID_INDICATOR_NUM "NUM"
ID_INDICATOR_SCRL "SCRL"
ID_INDICATOR_OVR "OVR"
ID_INDICATOR_REC "REC"
END
STRINGTABLE DISCARDABLE
BEGIN
ID_FILE_NEW "Create a new document\nNew"
ID_FILE_OPEN "Open an existing document\nOpen"
ID_FILE_CLOSE "Close the active document\nClose"
ID_FILE_SAVE "Save the active document\nSave"
ID_FILE_SAVE_AS "Save the active document with a new name\nSave As"
END
STRINGTABLE DISCARDABLE
BEGIN
ID_APP_ABOUT "Display program information, version number and copyright\nAbout"
ID_APP_EXIT "Quit the application; prompts to save documents\nExit"
END
STRINGTABLE DISCARDABLE
BEGIN
ID_FILE_MRU_FILE1 "Open this document"
ID_FILE_MRU_FILE2 "Open this document"
ID_FILE_MRU_FILE3 "Open this document"
ID_FILE_MRU_FILE4 "Open this document"
ID_FILE_MRU_FILE5 "Open this document"
ID_FILE_MRU_FILE6 "Open this document"
ID_FILE_MRU_FILE7 "Open this document"
ID_FILE_MRU_FILE8 "Open this document"
ID_FILE_MRU_FILE9 "Open this document"
ID_FILE_MRU_FILE10 "Open this document"
ID_FILE_MRU_FILE11 "Open this document"
ID_FILE_MRU_FILE12 "Open this document"
ID_FILE_MRU_FILE13 "Open this document"
ID_FILE_MRU_FILE14 "Open this document"
ID_FILE_MRU_FILE15 "Open this document"
ID_FILE_MRU_FILE16 "Open this document"
END
STRINGTABLE DISCARDABLE
BEGIN
ID_NEXT_PANE "Switch to the next window pane\nNext Pane"
ID_PREV_PANE "Switch back to the previous window pane\nPrevious Pane"
END
STRINGTABLE DISCARDABLE
BEGIN
ID_WINDOW_SPLIT "Split the active window into panes\nSplit"
END
STRINGTABLE DISCARDABLE
BEGIN
ID_EDIT_CLEAR "Erase the selection\nErase"
ID_EDIT_CLEAR_ALL "Erase everything\nErase All"
ID_EDIT_COPY "Copy the selection and put it on the Clipboard\nCopy"
ID_EDIT_CUT "Cut the selection and put it on the Clipboard\nCut"
ID_EDIT_FIND "Find the specified text\nFind"
ID_EDIT_PASTE "Insert Clipboard contents\nPaste"
ID_EDIT_REPEAT "Repeat the last action\nRepeat"
ID_EDIT_REPLACE "Replace specific text with different text\nReplace"
ID_EDIT_SELECT_ALL "Select the entire document\nSelect All"
ID_EDIT_UNDO "Undo the last action\nUndo"
ID_EDIT_REDO "Redo the previously undone action\nRedo"
END
STRINGTABLE DISCARDABLE
BEGIN
ID_VIEW_TOOLBAR "Show or hide the toolbar\nToggle ToolBar"
ID_VIEW_STATUS_BAR "Show or hide the status bar\nToggle StatusBar"
END
STRINGTABLE DISCARDABLE
BEGIN
AFX_IDS_SCSIZE "Change the window size"
AFX_IDS_SCMOVE "Change the window position"
AFX_IDS_SCMINIMIZE "Reduce the window to an icon"
AFX_IDS_SCMAXIMIZE "Enlarge the window to full size"
AFX_IDS_SCNEXTWINDOW "Switch to the next document window"
AFX_IDS_SCPREVWINDOW "Switch to the previous document window"
AFX_IDS_SCCLOSE "Close the active window and prompts to save the documents"
END
STRINGTABLE DISCARDABLE
BEGIN
AFX_IDS_SCRESTORE "Restore the window to normal size"
AFX_IDS_SCTASKLIST "Activate Task List"
END
STRINGTABLE DISCARDABLE
BEGIN
ID_CREATE_RIGID_BODY "Create a new Rigid Body object."
ID_OPTIONS_RUN_SIMULATION "Run or stop the simulation"
ID_OPTIONS_DISPLAY_BOXES "Toggle rendering of collision boxes"
ID_IMPULSE "Apply an impulse to the currently selected object"
ID_COUPLE "Apply a couple to the currently selected object"
ID_COUPLE_POSY "Apply a +Y couple to the object"
ID_COUPLE_NEGY "Apply a -Y couple to the object"
ID_COUPLE_POSZ "Apply a +Z couple to the object"
ID_COUPLE_NEGZ "Apply a -Z couple to the object"
ID_COUPLE_POSX "Apply a +X couple to the object"
ID_COUPLE_NEGX "Apply a negative X couple to the object"
ID_IMPULSE_POSX "Apply a +X impulse to the object"
END
STRINGTABLE DISCARDABLE
BEGIN
ID_IMPULSE_NEGX "Apply a -X impulse to the object"
ID_IMPULSE_POSY "Apply a +Y impulse to the object"
ID_IMPULSE_NEGY "Apply a -Y impulse to the object"
ID_IMPULSE_POSZ "Apply a +Z impulse to the object"
ID_IMPULSE_NEGZ "Apply a -Z impulse to the object"
END
STRINGTABLE DISCARDABLE
BEGIN
ID_PROPERTIES "Edit Rigid-Body properties of the currently selected object"
ID_INERTIA "Edit the Inertia Tensor for the currently selected object"
ID_OPTIONS_PHYSICS_CONSTANTS "Change the physics simulation constants."
ID_FREEZE_OBJECT "Freeze object. Zeros the momentum of the object"
ID_OPTIONS_PHYSICS_DEBUG_DISPLAY "Enable physics debugging."
ID_DEBUG_OBJECT "Enable/Disable debugging on the currently selected object"
ID_OPTIONS_FILLED "Use filled polygon rendering"
END
STRINGTABLE DISCARDABLE
BEGIN
ID_OPTIONS_WIREFRAME "Use Wireframe rendering"
ID_OPTIONS_POINT "Use point rendering"
ID_OPTIONS_POINTS "Render Points"
ID_MOTOR_PROPERTIES "Edit the Motor properties of the currently selected object"
ID_WHEEL_PROPERTIES "Edit the Wheeled Vehicle properties of the currently selected object"
ID_OPTIONS_FOLLOW_OBJECT "Camera follows selected object"
ID_CAMERA_FOLLOW "Camera looks at the current object"
ID_CAMERA_FLY "Camera is free to fly around"
ID_CAMERA_TETHER "Tether the camera to the selected object"
ID_CAMERA_RIGID_TETHER "Camera is rigidly tether to the selected object"
END
STRINGTABLE DISCARDABLE
BEGIN
ID_CREATE_WHEELED_VEHICLE "Create a new wheeled vehicle object"
ID_CREATE_PHYS4 "Create a new Phys4 object"
ID_CREATE_MOTORCYCLE "Create a new motorcycle object"
ID_MOTORCYCLE_PROPERTIES "Motorcycle properties"
ID_OPTIONS_RENDER_DEVICE "Select a render device"
ID_IMPORT_MODEL "Import a W3D model"
ID_IMPORT_LEV "Import an LEV file"
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#define _AFX_NO_SPLITTER_RESOURCES
#define _AFX_NO_OLE_RESOURCES
#define _AFX_NO_TRACKER_RESOURCES
#define _AFX_NO_PROPERTY_RESOURCES
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE 9, 1
#pragma code_page(1252)
#endif //_WIN32
#include "res\PhysTest.rc2" // non-Microsoft Visual C++ edited resources
#include "afxres.rc" // Standard components
#endif
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@@ -0,0 +1,405 @@
/*
** 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/>.
*/
// PhysTestDoc.cpp : implementation of the CPhysTestDoc class
//
#include "stdafx.h"
#include "PhysTest.h"
#include "PhysTestDoc.h"
#include "MainFrm.h"
#include "DataView.h"
#include "ww3d.h"
#include "ffactory.h"
#include "pscene.h"
#include "light.h"
#include "rcfile.h"
#include "assetmgr.h"
#include "rendobj.h"
#include "chunkio.h"
#include "lev_file.h"
#include "physlist.h"
#include "saveload.h"
#include "chunkio.h"
#include "rawfile.h"
#include "physstaticsavesystem.h"
#include "physdynamicsavesystem.h"
#include "PhysTestSaveSystem.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// Chunk ID's used by PhysTestDoc
enum
{
PHYSTESTDOC_CHUNK_MAINFRAME = 0x03321990,
PHYSTESTDOC_CHUNK_SYSTEMS,
};
/////////////////////////////////////////////////////////////////////////////
// CPhysTestDoc
IMPLEMENT_DYNCREATE(CPhysTestDoc, CDocument)
BEGIN_MESSAGE_MAP(CPhysTestDoc, CDocument)
//{{AFX_MSG_MAP(CPhysTestDoc)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CPhysTestDoc construction/destruction
CPhysTestDoc::CPhysTestDoc() :
Scene(NULL),
Light(NULL),
Origin(NULL)
{
}
CPhysTestDoc::~CPhysTestDoc()
{
if (Scene) {
Scene->Remove_All();
}
REF_PTR_RELEASE(Scene);
REF_PTR_RELEASE(Light);
REF_PTR_RELEASE(Origin);
}
void CPhysTestDoc::Init_Scene(void)
{
if (Scene == NULL)
{
// Instantiate a new scene
Scene = NEW_REF(PhysicsSceneClass,());
Scene->Enable_Dynamic_Projectors(true);
// Were we successful in instantiating the scene object?
ASSERT(Scene);
if (Scene != NULL) {
// Set up some collision groups.
Scene->Enable_All_Collision_Detections(0);
// Set some default ambient lighting
Scene->Set_Ambient_Light(Vector3 (0.5F, 0.5F, 0.5F));
// Create a new scene light
if (Light == NULL) {
Light = NEW_REF(LightClass,(LightClass::DIRECTIONAL));
ASSERT(Light);
if (Light) {
// Create some default light settings
Matrix3D transform(1);
transform.Look_At(Vector3(0,0,0),Vector3(10,10,10),0.0f);
Light->Set_Transform(transform);
Light->Set_Attenuation_Model(LightClass::ATTENUATION_NONE);
Light->Set_Flag (LightClass::NEAR_ATTENUATION, false);
Light->Set_Flag (LightClass::FAR_ATTENUATION, false);
Light->Set_Far_Attenuation_Range (1000000, 1000000);
Light->Set_Intensity(1.0F);
Light->Set_Force_Visible(true);
Light->Set_Ambient(Vector3(0,0,0));
Light->Set_Diffuse(Vector3(1, 1, 1));
Light->Set_Specular(Vector3(1, 1, 1));
// Add this light to the scene
Light->Add(Scene);
}
}
// Create an object at the Origin
if (Origin == NULL) {
ResourceFileClass mesh_file(NULL, "Axes.w3d");
WW3DAssetManager::Get_Instance()->Load_3D_Assets(mesh_file);
Origin = WW3DAssetManager::Get_Instance()->Create_Render_Obj("Axes");
Origin->Set_Transform(Matrix3D(1));
Scene->Add_Render_Object(Origin);
}
}
}
}
/////////////////////////////////////////////////////////////////////////////
// CPhysTestDoc serialization
void CPhysTestDoc::Serialize(CArchive& ar)
{
assert(0);
}
/////////////////////////////////////////////////////////////////////////////
// CPhysTestDoc diagnostics
#ifdef _DEBUG
void CPhysTestDoc::AssertValid() const
{
CDocument::AssertValid();
}
void CPhysTestDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CPhysTestDoc commands
BOOL CPhysTestDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
if (Scene) {
Scene->Remove_All();
WWASSERT(Light);
if (Light) {
Scene->Add_Render_Object(Light);
}
WWASSERT(Origin);
if (Origin) {
Scene->Add_Render_Object(Origin);
}
// rebuild the list view
Get_Data_View()->Rebuild_Tree();
}
return TRUE;
}
BOOL CPhysTestDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
Load_PHY_File(lpszPathName);
Get_Data_View()->Rebuild_Tree();
return TRUE;
}
BOOL CPhysTestDoc::OnSaveDocument(LPCTSTR lpszPathName)
{
Save_PHY_File(lpszPathName);
return TRUE;
}
///////////////////////////////////////////////////////////////
//
// Load_LEV_File
//
void CPhysTestDoc::Load_LEV_File(LPCTSTR lpszPathName)
{
#if 0
WWASSERT(Scene);
//
// HACK HACK -- Force the current directory to be the directory
// the file is located in.
//
if (::strrchr (lpszPathName, '\\')) {
CString stringTemp = lpszPathName;
stringTemp = stringTemp.Left ((long)::strrchr (lpszPathName, '\\') - (long)lpszPathName);
::SetCurrentDirectory (stringTemp);
WW3D::Add_Search_Path (stringTemp);
}
LPCTSTR extension = ::strrchr (lpszPathName, '.');
ASSERT(::lstrcmpi(extension,".lev") == 0);
// load the LEV
FileClass *file = DefaultFileFactory.Get_File (lpszPathName);
file->Open();
ChunkLoadClass cload(file);
// should see a LEV_CHUNK_LEVEL
cload.Open_Chunk();
WWASSERT(cload.Cur_Chunk_ID() == LEV_CHUNK_LEVEL);
// for now only look for a LEV_CHUNK_MAP
cload.Open_Chunk();
WWASSERT(cload.Cur_Chunk_ID() == LEV_CHUNK_MAP);
// Physics Scene handles the tile map loading
Scene->LEV_Load(cload);
// close the LEV_CHUNK_MAP
cload.Close_Chunk();
// close the LEV_CHUNK_LEVEL
cload.Close_Chunk();
// done with the file!
file->Close();
DefaultFileFactory.Return_File(file);
// Replace our default objects
WWASSERT(Light);
if (Light) {
Scene->Add_Render_Object(Light);
}
WWASSERT(Origin);
if (Origin) {
Scene->Add_Render_Object(Origin);
}
#endif
}
///////////////////////////////////////////////////////////////
//
// Load_W3D_File
//
void CPhysTestDoc::Load_W3D_File(LPCTSTR lpszPathName)
{
WW3DAssetManager::Get_Instance()->Load_3D_Assets(lpszPathName);
// rebuild the list view
Get_Data_View()->Rebuild_Tree();
}
///////////////////////////////////////////////////////////////
//
// Load_PHY_File
//
void CPhysTestDoc::Load_PHY_File(LPCTSTR lpszPathName)
{
RawFileClass file(lpszPathName);
WWASSERT(file);
file.Open(FileClass::READ);
ChunkLoadClass cload(&file);
while (cload.Open_Chunk()) {
switch(cload.Cur_Chunk_ID()) {
case PHYSTESTDOC_CHUNK_SYSTEMS:
SaveLoadSystemClass::Load( cload );
break;
};
cload.Close_Chunk();
}
file.Close();
}
///////////////////////////////////////////////////////////////
//
// Save_PHY_File
//
void CPhysTestDoc::Save_PHY_File(LPCTSTR lpszPathName)
{
RawFileClass file(lpszPathName);
WWASSERT(file);
file.Open(FileClass::WRITE);
ChunkSaveClass csave(&file);
csave.Begin_Chunk(PHYSTESTDOC_CHUNK_SYSTEMS);
SaveLoadSystemClass::Save( csave, _PhysTestSaveSystem );
SaveLoadSystemClass::Save( csave, _PhysStaticDataSaveSystem );
SaveLoadSystemClass::Save( csave, _PhysStaticObjectsSaveSystem );
SaveLoadSystemClass::Save( csave, _PhysDynamicSaveSystem );
csave.End_Chunk();
file.Close();
}
///////////////////////////////////////////////////////////////
//
// Get_Data_View
//
CDataView * CPhysTestDoc::Get_Data_View(void)
{
CDataView * view = NULL;
// Get a pointer to the main window
CMainFrame * mainwnd = (CMainFrame *)::AfxGetMainWnd();
if (mainwnd) {
// Get the pane from the main window
view = (CDataView *)mainwnd->Get_Pane(0,0);
}
// Return a pointer to the tree view
return view;
}
///////////////////////////////////////////////////////////////
//
// Get_Graphic_View
//
CGraphicView * CPhysTestDoc::Get_Graphic_View(void)
{
CGraphicView * view = NULL;
// Get a pointer to the main window
CMainFrame * mainwnd = (CMainFrame *)::AfxGetMainWnd();
if (mainwnd) {
// Get the pane from the main window
view = (CGraphicView *)mainwnd->Get_Pane(0,1);
}
// Return a pointer to the graphic view
return view;
}
///////////////////////////////////////////////////////////////
//
// Add_Physics_Object - add a new object to be simulated
//
void CPhysTestDoc::Add_Physics_Object(PhysClass * obj)
{
if (obj == NULL) return;
if (Scene == NULL) return;
Scene->Add_Dynamic_Object(obj);
// rebuild the list view
Get_Data_View()->Rebuild_Tree();
}
int CPhysTestDoc::Get_Physics_Object_Count(void)
{
PhysListIterator it = Scene->Get_Dynamic_Object_Iterator();
int count = 0;
for (it.First(); !it.Is_Done(); it.Next()) {
count++;
}
return count;
}

View File

@@ -0,0 +1,101 @@
/*
** 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/>.
*/
// PhysTestDoc.h : interface of the CPhysTestDoc class
//
/////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_PHYSTESTDOC_H__616293EA_E4F0_11D2_802E_0040056350C8__INCLUDED_)
#define AFX_PHYSTESTDOC_H__616293EA_E4F0_11D2_802E_0040056350C8__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CGraphicView;
class CDataView;
class PhysicsSceneClass;
class LightClass;
class RenderObjClass;
class PhysClass;
class CPhysTestDoc : public CDocument
{
protected: // create from serialization only
CPhysTestDoc();
DECLARE_DYNCREATE(CPhysTestDoc)
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CPhysTestDoc)
public:
virtual BOOL OnNewDocument();
virtual void Serialize(CArchive& ar);
virtual BOOL OnOpenDocument(LPCTSTR lpszPathName);
virtual BOOL OnSaveDocument(LPCTSTR lpszPathName);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CPhysTestDoc(void);
void Init_Scene(void);
void Load_LEV_File(LPCTSTR lpszPathName);
void Load_W3D_File(LPCTSTR lpszPathName);
void Load_PHY_File(LPCTSTR lpszPathName);
void Save_PHY_File(LPCTSTR lpszPathName);
CGraphicView * Get_Graphic_View(void);
CDataView * Get_Data_View(void);
void Add_Physics_Object(PhysClass * obj);
int Get_Physics_Object_Count(void);
#ifdef _DEBUG
virtual void AssertValid(void) const;
virtual void Dump(CDumpContext& dc) const;
#endif
PhysicsSceneClass * Scene;
LightClass * Light;
RenderObjClass * Origin;
DWORD LastTime;
protected:
// Generated message map functions
protected:
//{{AFX_MSG(CPhysTestDoc)
// NOTE - the ClassWizard will add and remove member functions here.
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_PHYSTESTDOC_H__616293EA_E4F0_11D2_802E_0040056350C8__INCLUDED_)

View File

@@ -0,0 +1,75 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** 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 ***
***********************************************************************************************
* *
* Project Name : PhysTest *
* *
* $Archive:: /Commando/Code/Tests/PhysTest/PhysTestSaveSystem.cpp $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 11/02/00 6:20p $*
* *
* $Revision:: 3 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "StdAfx.h"
#include "PhysTestSaveSystem.h"
#include "MainFrm.h"
#include "chunkio.h"
/*
** Instantiate the Save-System
*/
PhysTestSaveSystemClass _PhysTestSaveSystem;
uint32 PhysTestSaveSystemClass::Chunk_ID(void) const
{
return PHYSTEST_CHUNKID_SUBSYSTEM;
}
bool PhysTestSaveSystemClass::Save(ChunkSaveClass &csave)
{
csave.Begin_Chunk(CHUNKID_MAINFRAME);
((CMainFrame *)(::AfxGetMainWnd()))->Save(csave);
csave.End_Chunk();
return true;
}
bool PhysTestSaveSystemClass::Load(ChunkLoadClass &cload)
{
while (cload.Open_Chunk()) {
switch (cload.Cur_Chunk_ID()) {
case CHUNKID_MAINFRAME:
((CMainFrame *)(::AfxGetMainWnd()))->Load(cload);
break;
}
cload.Close_Chunk();
}
return true;
}

View File

@@ -0,0 +1,90 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** 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 ***
***********************************************************************************************
* *
* Project Name : PhysTest *
* *
* $Archive:: /Commando/Code/Tests/PhysTest/PhysTestSaveSystem.h $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 11/02/00 6:14p $*
* *
* $Revision:: 3 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef PHYSTESTSAVESYSTEM_H
#define PHYSTESTSAVESYSTEM_H
#include "always.h"
#include "saveloadsubsystem.h"
#include "saveloadids.h"
/******************************************************************************************
**
** PhysTestSaveSystem
** Saves all data for the PhysTest app
**
******************************************************************************************/
class PhysTestSaveSystemClass : public SaveLoadSubSystemClass
{
public:
virtual uint32 Chunk_ID (void) const;
protected:
virtual bool Save (ChunkSaveClass &csave);
virtual bool Load (ChunkLoadClass &cload);
/*
** internal chunk id's
*/
enum
{
CHUNKID_MAINFRAME = 0x00667001,
};
};
/*
** _PhysTestSaveSystem - global instance of the sub-system for PhysTest
*/
extern PhysTestSaveSystemClass _PhysTestSaveSystem;
/******************************************************************************************
**
** Chunk ID's used by PhysTest objects
**
******************************************************************************************/
enum
{
PHYSTEST_CHUNKID_SUBSYSTEM = CHUNKID_PHYSTEST_BEGIN,
};
#endif

View File

@@ -0,0 +1,135 @@
/*
** 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/>.
*/
// PhysicsConstantsDialog.cpp : implementation file
//
#include "stdafx.h"
#include "phystest.h"
#include "PhysicsConstantsDialog.h"
#include "physcon.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
const int MIN_DAMPING = 0;
const int MAX_DAMPING = 255;
const int MIN_GRAVITY = -100;
const int MAX_GRAVITY = 0;
/////////////////////////////////////////////////////////////////////////////
// CPhysicsConstantsDialog dialog
CPhysicsConstantsDialog::CPhysicsConstantsDialog(CWnd* pParent /*=NULL*/)
: CDialog(CPhysicsConstantsDialog::IDD, pParent)
{
//{{AFX_DATA_INIT(CPhysicsConstantsDialog)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
void CPhysicsConstantsDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CPhysicsConstantsDialog)
DDX_Control(pDX, IDC_LDAMPING_SPIN, m_LDampingSpin);
DDX_Control(pDX, IDC_GRAVITYACCEL_SPIN, m_GravityAccelSpin);
DDX_Control(pDX, IDC_ADAMPING_SPIN, m_ADampingSpin);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CPhysicsConstantsDialog, CDialog)
//{{AFX_MSG_MAP(CPhysicsConstantsDialog)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CPhysicsConstantsDialog message handlers
BOOL CPhysicsConstantsDialog::OnInitDialog()
{
CDialog::OnInitDialog();
m_LDampingSpin.SetRange(MIN_DAMPING * 100,MAX_DAMPING * 100);
m_ADampingSpin.SetRange(MIN_DAMPING * 100,MAX_DAMPING * 100);
m_GravityAccelSpin.SetRange(MIN_GRAVITY * 100,MAX_GRAVITY * 100);
m_LDampingSpin.SetPos(PhysicsConstants::LinearDamping * 100);
m_LDampingSpin.SetPos(PhysicsConstants::LinearDamping * 100);
m_GravityAccelSpin.SetPos(PhysicsConstants::GravityAcceleration.Z * 100);
SetDlgItemFloat(IDC_LDAMPING_EDIT,PhysicsConstants::LinearDamping);
SetDlgItemFloat(IDC_ADAMPING_EDIT,PhysicsConstants::AngularDamping);
SetDlgItemFloat(IDC_GRAVITYACCEL_EDIT,PhysicsConstants::GravityAcceleration.Z);
return TRUE;
}
BOOL CPhysicsConstantsDialog::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
// make the spin controls work...
switch(wParam)
{
case IDC_LDAMPING_SPIN:
case IDC_ADAMPING_SPIN:
case IDC_GRAVITYACCEL_SPIN:
LPNMUPDOWN lpnmud = (LPNMUPDOWN) lParam;
if (lpnmud->hdr.code == UDN_DELTAPOS) {
HWND hwnd = (HWND)SendDlgItemMessage(LOWORD(wParam),UDM_GETBUDDY);
float curval = GetDlgItemFloat(GetWindowLong(hwnd,GWL_ID));
curval += (float)lpnmud->iDelta / 100.0f;
SetDlgItemFloat(GetWindowLong(hwnd,GWL_ID), curval);
}
break;
}
return CDialog::OnNotify(wParam, lParam, pResult);
}
void CPhysicsConstantsDialog::OnOK()
{
PhysicsConstants::LinearDamping = GetDlgItemFloat(IDC_LDAMPING_EDIT);
PhysicsConstants::AngularDamping = GetDlgItemFloat(IDC_ADAMPING_EDIT);
PhysicsConstants::GravityAcceleration.Z = GetDlgItemFloat(IDC_GRAVITYACCEL_EDIT);
CDialog::OnOK();
}
float CPhysicsConstantsDialog::GetDlgItemFloat(int controlid)
{
CString string;
GetDlgItemText(controlid,string);
return atof(string);
}
void CPhysicsConstantsDialog::SetDlgItemFloat(int controlid,float val)
{
CString string;
string.Format("%.2f",val);
SetDlgItemText(controlid,string);
}

View File

@@ -0,0 +1,71 @@
/*
** 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/>.
*/
#if !defined(AFX_PHYSICSCONSTANTSDIALOG_H__33DD6AC5_E78D_11D2_9BD2_00A0C9988171__INCLUDED_)
#define AFX_PHYSICSCONSTANTSDIALOG_H__33DD6AC5_E78D_11D2_9BD2_00A0C9988171__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// PhysicsConstantsDialog.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CPhysicsConstantsDialog dialog
class CPhysicsConstantsDialog : public CDialog
{
// Construction
public:
CPhysicsConstantsDialog(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CPhysicsConstantsDialog)
enum { IDD = IDD_PHYSICS_CONSTANTS_DIALOG };
CSpinButtonCtrl m_LDampingSpin;
CSpinButtonCtrl m_GravityAccelSpin;
CSpinButtonCtrl m_ADampingSpin;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CPhysicsConstantsDialog)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
//}}AFX_VIRTUAL
// Implementation
protected:
float GetDlgItemFloat(int controlid);
void SetDlgItemFloat(int controlid,float val);
// Generated message map functions
//{{AFX_MSG(CPhysicsConstantsDialog)
virtual BOOL OnInitDialog();
virtual void OnOK();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_PHYSICSCONSTANTSDIALOG_H__33DD6AC5_E78D_11D2_9BD2_00A0C9988171__INCLUDED_)

View File

@@ -0,0 +1,192 @@
/*
** 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/>.
*/
// RbodyPropertiesDialog.cpp : implementation file
//
#include "stdafx.h"
#include "phystest.h"
#include "RbodyPropertiesDialog.h"
#include "movephys.h"
#include "rbody.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
const int MIN_MASS = 1;
const int MAX_MASS = 255;
const int MIN_ELASTICITY = 0;
const int MAX_ELASTICITY = 1;
const int MIN_GRAVITY = 0;
const int MAX_GRAVITY = 1;
const int MIN_POS = -255;
const int MAX_POS = 255;
const int MIN_CONTACT_STIFFNESS = 0;
const int MAX_CONTACT_STIFFNESS = 255;
const int MIN_CONTACT_DAMPING = 0;
const int MAX_CONTACT_DAMPING = 255;
const int MIN_CONTACT_LENGTH = 0;
const int MAX_CONTACT_LENGTH = 2;
/////////////////////////////////////////////////////////////////////////////
// CRbodyPropertiesDialog dialog
CRbodyPropertiesDialog::CRbodyPropertiesDialog(CWnd* pParent,MoveablePhysClass * object) :
CDialog(CRbodyPropertiesDialog::IDD, pParent),
Object(object)
{
//{{AFX_DATA_INIT(CRbodyPropertiesDialog)
//}}AFX_DATA_INIT
ASSERT(Object != NULL);
}
void CRbodyPropertiesDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CRbodyPropertiesDialog)
DDX_Control(pDX, IDC_LENGTH_SPIN, m_LengthSpin);
DDX_Control(pDX, IDC_STIFFNESS_SPIN, m_StiffnessSpin);
DDX_Control(pDX, IDC_DAMPING_SPIN, m_DampingSpin);
DDX_Control(pDX, IDC_POSITIONZ_SPIN, m_PositionZSpin);
DDX_Control(pDX, IDC_POSITIONY_SPIN, m_PositionYSpin);
DDX_Control(pDX, IDC_POSITIONX_SPIN, m_PositionXSpin);
DDX_Control(pDX, IDC_MASS_SPIN, m_MassSpin);
DDX_Control(pDX, IDC_GRAVITY_SPIN, m_GravitySpin);
DDX_Control(pDX, IDC_ELASTICITY_SPIN, m_ElasticitySpin);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CRbodyPropertiesDialog, CDialog)
//{{AFX_MSG_MAP(CRbodyPropertiesDialog)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CRbodyPropertiesDialog message handlers
void CRbodyPropertiesDialog::OnOK()
{
Object->Set_Mass(GetDlgItemFloat(IDC_MASS_EDIT));
Object->Set_Gravity_Multiplier(GetDlgItemFloat(IDC_GRAVITY_EDIT));
Object->Set_Elasticity(GetDlgItemFloat(IDC_ELASTICITY_EDIT));
Vector3 pos;
pos.X = GetDlgItemFloat(IDC_POSITIONX_EDIT);
pos.Y = GetDlgItemFloat(IDC_POSITIONY_EDIT);
pos.Z = GetDlgItemFloat(IDC_POSITIONZ_EDIT);
Object->Set_Position(pos);
float length = GetDlgItemFloat(IDC_LENGTH_EDIT);
// not letting the user override stiffness and damping for now
((RigidBodyClass *)Object)->Set_Contact_Parameters(length);
CDialog::OnOK();
}
BOOL CRbodyPropertiesDialog::OnInitDialog()
{
ASSERT(Object != NULL);
CDialog::OnInitDialog();
m_MassSpin.SetRange(MIN_MASS * 100,MAX_MASS * 100);
m_GravitySpin.SetRange(MIN_GRAVITY * 100,MAX_GRAVITY * 100);
m_ElasticitySpin.SetRange(MIN_ELASTICITY * 100,MAX_ELASTICITY * 100);
m_PositionXSpin.SetRange(MIN_POS * 100,MAX_POS * 100);
m_PositionYSpin.SetRange(MIN_POS * 100,MAX_POS * 100);
m_PositionZSpin.SetRange(MIN_POS * 100,MAX_POS * 100);
m_StiffnessSpin.SetRange(MIN_CONTACT_STIFFNESS * 100,MAX_CONTACT_STIFFNESS * 100);
m_DampingSpin.SetRange(MIN_CONTACT_DAMPING * 100,MAX_CONTACT_DAMPING * 100);
m_LengthSpin.SetRange(MIN_CONTACT_LENGTH * 100,MAX_CONTACT_LENGTH * 100);
m_MassSpin.SetPos(Object->Get_Mass() * 100);
m_GravitySpin.SetPos(Object->Get_Gravity_Multiplier() * 100);
m_ElasticitySpin.SetPos(Object->Get_Elasticity() * 100);
Vector3 position = Object->Get_Transform().Get_Translation();
m_PositionXSpin.SetPos(position.X * 100);
m_PositionYSpin.SetPos(position.Y * 100);
m_PositionZSpin.SetPos(position.Z * 100);
float stiffness,damping,length;
((RigidBodyClass *)Object)->Get_Contact_Parameters(&stiffness,&damping,&length);
m_StiffnessSpin.SetPos(stiffness * 100);
m_DampingSpin.SetPos(damping * 100);
m_LengthSpin.SetPos(length * 100);
SetDlgItemFloat(IDC_MASS_EDIT,Object->Get_Mass());
SetDlgItemFloat(IDC_GRAVITY_EDIT,Object->Get_Gravity_Multiplier());
SetDlgItemFloat(IDC_ELASTICITY_EDIT,Object->Get_Elasticity());
SetDlgItemFloat(IDC_POSITIONX_EDIT,position.X);
SetDlgItemFloat(IDC_POSITIONY_EDIT,position.Y);
SetDlgItemFloat(IDC_POSITIONZ_EDIT,position.Z);
SetDlgItemFloat(IDC_STIFFNESS_EDIT,stiffness);
SetDlgItemFloat(IDC_DAMPING_EDIT,damping);
SetDlgItemFloat(IDC_LENGTH_EDIT,length);
return TRUE;
}
float CRbodyPropertiesDialog::GetDlgItemFloat(int controlid)
{
CString string;
GetDlgItemText(controlid,string);
return atof(string);
}
void CRbodyPropertiesDialog::SetDlgItemFloat(int controlid,float val)
{
CString string;
string.Format("%.2f",val);
SetDlgItemText(controlid,string);
}
BOOL CRbodyPropertiesDialog::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
// make the spin controls work...
switch(wParam)
{
case IDC_MASS_SPIN:
case IDC_GRAVITY_SPIN:
case IDC_ELASTICITY_SPIN:
case IDC_POSITIONX_SPIN:
case IDC_POSITIONY_SPIN:
case IDC_POSITIONZ_SPIN:
case IDC_STIFFNESS_SPIN:
case IDC_DAMPING_SPIN:
case IDC_LENGTH_SPIN:
LPNMUPDOWN lpnmud = (LPNMUPDOWN) lParam;
if (lpnmud->hdr.code == UDN_DELTAPOS) {
HWND hwnd = (HWND)SendDlgItemMessage(LOWORD(wParam),UDM_GETBUDDY);
float curval = GetDlgItemFloat(GetWindowLong(hwnd,GWL_ID));
curval += (float)lpnmud->iDelta / 100.0f;
SetDlgItemFloat(GetWindowLong(hwnd,GWL_ID), curval);
}
break;
}
return CDialog::OnNotify(wParam, lParam, pResult);
}

View File

@@ -0,0 +1,80 @@
/*
** 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/>.
*/
#if !defined(AFX_RBODYPROPERTIESDIALOG_H__33DD6AC1_E78D_11D2_9BD2_00A0C9988171__INCLUDED_)
#define AFX_RBODYPROPERTIESDIALOG_H__33DD6AC1_E78D_11D2_9BD2_00A0C9988171__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// RbodyPropertiesDialog.h : header file
//
class MoveablePhysClass;
/////////////////////////////////////////////////////////////////////////////
// CRbodyPropertiesDialog dialog
class CRbodyPropertiesDialog : public CDialog
{
// Construction
public:
CRbodyPropertiesDialog(CWnd* pParent,MoveablePhysClass * obj);
// Dialog Data
//{{AFX_DATA(CRbodyPropertiesDialog)
enum { IDD = IDD_RBODY_PROPERTIES_DIALOG };
CSpinButtonCtrl m_LengthSpin;
CSpinButtonCtrl m_StiffnessSpin;
CSpinButtonCtrl m_DampingSpin;
CSpinButtonCtrl m_PositionZSpin;
CSpinButtonCtrl m_PositionYSpin;
CSpinButtonCtrl m_PositionXSpin;
CSpinButtonCtrl m_MassSpin;
CSpinButtonCtrl m_GravitySpin;
CSpinButtonCtrl m_ElasticitySpin;
//}}AFX_DATA
MoveablePhysClass * Object;
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CRbodyPropertiesDialog)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
//}}AFX_VIRTUAL
// Implementation
protected:
float GetDlgItemFloat(int controlid);
void SetDlgItemFloat(int controlid,float val);
// Generated message map functions
//{{AFX_MSG(CRbodyPropertiesDialog)
virtual void OnOK();
virtual BOOL OnInitDialog();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_RBODYPROPERTIESDIALOG_H__33DD6AC1_E78D_11D2_9BD2_00A0C9988171__INCLUDED_)

View File

@@ -0,0 +1,98 @@
/*
** 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/>.
*/
// RenderDeviceDialog.cpp : implementation file
//
#include "stdafx.h"
#include "phystest.h"
#include "RenderDeviceDialog.h"
#include "ww3d.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CRenderDeviceDialog dialog
CRenderDeviceDialog::CRenderDeviceDialog(CWnd* pParent /*=NULL*/)
: CDialog(CRenderDeviceDialog::IDD, pParent)
{
//{{AFX_DATA_INIT(CRenderDeviceDialog)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
void CRenderDeviceDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CRenderDeviceDialog)
DDX_Control(pDX, IDC_RENDER_DEVICE_COMBO, m_RenderDeviceCombo);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CRenderDeviceDialog, CDialog)
//{{AFX_MSG_MAP(CRenderDeviceDialog)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CRenderDeviceDialog message handlers
BOOL CRenderDeviceDialog::OnInitDialog()
{
CDialog::OnInitDialog();
// plug all of the render device names into the combo box
for (int i=0; i<WW3D::Get_Render_Device_Count(); i++) {
const char * name = WW3D::Get_Render_Device_Name(i);
m_RenderDeviceCombo.AddString(name);
}
m_RenderDeviceCombo.SetCurSel(WW3D::Get_Render_Device());
return TRUE;
}
void CRenderDeviceDialog::OnOK()
{
// get the index of the currently selected render device and set ww3d to use it
int device = m_RenderDeviceCombo.GetCurSel();
if (device != CB_ERR) {
// keep trying to set a device until one works
WW3DErrorType err = WW3D_ERROR_GENERIC;
int count = 0;
while ((err != WW3D_ERROR_OK) && (count < WW3D::Get_Render_Device_Count())) {
err = WW3D::Set_Render_Device(device);
count++;
if (err != WW3D_ERROR_OK) {
device = (device + 1) % WW3D::Get_Render_Device_Count();
}
}
assert(err == WW3D_ERROR_OK);
}
CDialog::OnOK();
}

View File

@@ -0,0 +1,65 @@
/*
** 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/>.
*/
#if !defined(AFX_RENDERDEVICEDIALOG_H__7CD32C1C_0E2E_11D3_BADB_00902742EA14__INCLUDED_)
#define AFX_RENDERDEVICEDIALOG_H__7CD32C1C_0E2E_11D3_BADB_00902742EA14__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// RenderDeviceDialog.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CRenderDeviceDialog dialog
class CRenderDeviceDialog : public CDialog
{
// Construction
public:
CRenderDeviceDialog(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CRenderDeviceDialog)
enum { IDD = IDD_RENDER_DEVICE_DIALOG };
CComboBox m_RenderDeviceCombo;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CRenderDeviceDialog)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CRenderDeviceDialog)
virtual void OnOK();
virtual BOOL OnInitDialog();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_RENDERDEVICEDIALOG_H__7CD32C1C_0E2E_11D3_BADB_00902742EA14__INCLUDED_)

View File

@@ -0,0 +1,26 @@
/*
** 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/>.
*/
// stdafx.cpp : source file that includes just the standard includes
// PhysTest.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"

View File

@@ -0,0 +1,45 @@
/*
** 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/>.
*/
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#if !defined(AFX_STDAFX_H__616293E6_E4F0_11D2_802E_0040056350C8__INCLUDED_)
#define AFX_STDAFX_H__616293E6_E4F0_11D2_802E_0040056350C8__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
#include <afxwin.h> // MFC core and standard components
#include <afxext.h> // MFC extensions
#include <afxdisp.h> // MFC Automation classes
#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h> // MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__616293E6_E4F0_11D2_802E_0040056350C8__INCLUDED_)

View File

@@ -0,0 +1,234 @@
/*
** 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/>.
*/
// VJoyDialog.cpp : implementation file
//
#include "stdafx.h"
#include "phystest.h"
#include "VJoyDialog.h"
#include "vector2.h"
#include "vector3.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define JOYSTICK_UPDATE_COMMAND WM_USER+101
#define SLIDER_RESOLUTION 255
/////////////////////////////////////////////////////////////////////////////
// CVJoyDialog dialog
CVJoyDialog::CVJoyDialog(CWnd* pParent /*=NULL*/)
: CDialog(CVJoyDialog::IDD, pParent)
{
//{{AFX_DATA_INIT(CVJoyDialog)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
Controller.Reset();
}
CVJoyDialog::~CVJoyDialog(void)
{
}
void CVJoyDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CVJoyDialog)
DDX_Control(pDX, IDC_TURNZ_SLIDER, m_TurnZSlider);
DDX_Control(pDX, IDC_MOVEZ_SLIDER, m_MoveZSlider);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CVJoyDialog, CDialog)
//{{AFX_MSG_MAP(CVJoyDialog)
ON_WM_VSCROLL()
ON_WM_DESTROY()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/*
** Joystick Window Proc
*/
LRESULT CALLBACK JoystickWndProc(HWND hwnd,unsigned int message,WPARAM wparam,LPARAM lparam)
{
Vector2 point;
const int RADIUS = 4;
switch (message)
{
case WM_LBUTTONDOWN:
::SetCapture(hwnd);
break;
case WM_LBUTTONUP:
::ReleaseCapture();
break;
case WM_MOUSEMOVE:
if (wparam & MK_LBUTTON) {
float ex,ey,cx,cy;
short x = LOWORD(lparam);
short y = HIWORD(lparam);
RECT rect;
GetClientRect(hwnd,&rect);
if (x > rect.right) x = rect.right;
if (x < rect.left) x = rect.left;
if (y > rect.bottom) y = rect.bottom;
if (y < rect.top) y = rect.top;
ex = (float)(rect.right - rect.left) / 2.0f;
cx = (float)(rect.right + rect.left) / 2.0f;
ey = (float)(rect.bottom - rect.top) / 2.0f;
cy = (float)(rect.bottom + rect.top) / 2.0f;
point.X = ((float)x - cx) / ex;
point.Y = ((float)y - cy) / ey;
::SendMessage(GetParent(hwnd),JOYSTICK_UPDATE_COMMAND,GetWindowLong(hwnd,GWL_ID),(long)&point);
::InvalidateRect(hwnd,NULL,FALSE);
::UpdateWindow(hwnd);
SetProp(hwnd,"XCOORD",(HANDLE)x);
SetProp(hwnd,"YCOORD",(HANDLE)y);
}
break;
case WM_PAINT:
{
RECT rect;
GetClientRect(hwnd,&rect);
HDC hdc = GetDC(hwnd);
FillRect(hdc,&rect,(HBRUSH)GetStockObject(WHITE_BRUSH));
FrameRect(hdc,&rect,(HBRUSH)GetStockObject(BLACK_BRUSH));
MoveToEx(hdc,rect.right/2,0,NULL);
LineTo(hdc,rect.right/2,rect.bottom);
MoveToEx(hdc,0,rect.bottom/2,NULL);
LineTo(hdc,rect.right,rect.bottom/2);
int x = (int)GetProp(hwnd,"XCOORD");
int y = (int)GetProp(hwnd,"YCOORD");
if (x < RADIUS) x = RADIUS;
if (x > rect.right-RADIUS) x = rect.right-RADIUS;
if (y < RADIUS) y = RADIUS;
if (y > rect.bottom-RADIUS) y = rect.bottom-RADIUS;
MoveToEx(hdc,rect.bottom/2,rect.right/2,NULL);
LineTo(hdc,x,y);
Ellipse(hdc,x-RADIUS,y-RADIUS,x+RADIUS,y+RADIUS);
ReleaseDC(hwnd,hdc);
}
break;
}
WNDPROC oldwndproc = (WNDPROC)GetProp(hwnd,"OldWndProc");
//return CallWindowProc(oldwndproc,hwnd,message,wparam,lparam);
return DefWindowProc (hwnd, message, wparam, lparam);
}
/////////////////////////////////////////////////////////////////////////////
// CVJoyDialog message handlers
BOOL CVJoyDialog::OnInitDialog()
{
CDialog::OnInitDialog();
RECT rect;
HWND movexy_wnd = ::GetDlgItem(m_hWnd,IDC_MOVEXY_STATIC);
long oldproc = SetWindowLong(movexy_wnd,GWL_WNDPROC,(long)JoystickWndProc);
SetProp(movexy_wnd,"OldWndProc",(void*)oldproc);
::GetClientRect(movexy_wnd,&rect);
SetProp(movexy_wnd,"XCOORD",(HANDLE)(rect.right/2));
SetProp(movexy_wnd,"YCOORD",(HANDLE)(rect.bottom/2));
HWND turnxy_wnd = ::GetDlgItem(m_hWnd,IDC_TURNXY_STATIC);
oldproc = SetWindowLong(turnxy_wnd,GWL_WNDPROC,(long)JoystickWndProc);
SetProp(turnxy_wnd,"OldWndProc",(void*)oldproc);
::GetClientRect(movexy_wnd,&rect);
SetProp(turnxy_wnd,"XCOORD",(HANDLE)(rect.right/2));
SetProp(turnxy_wnd,"YCOORD",(HANDLE)(rect.bottom/2));
m_MoveZSlider.SetRange(0,SLIDER_RESOLUTION);
m_TurnZSlider.SetRange(0,SLIDER_RESOLUTION);
return TRUE;
}
LRESULT CVJoyDialog::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
if (message == JOYSTICK_UPDATE_COMMAND) {
Vector2 * point = (Vector2*)lParam;
if (wParam == IDC_MOVEXY_STATIC) {
Controller.Set_Move_Forward(-point->Y);
Controller.Set_Turn_Left(-point->X);
} else if (wParam == IDC_TURNXY_STATIC) {
// Nothing to do here anymore...
}
}
return CDialog::WindowProc(message, wParam, lParam);
}
void CVJoyDialog::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
if (pScrollBar == GetDlgItem(IDC_MOVEZ_SLIDER)) {
Controller.Set_Move_Up(1.0f - 2.0f * (float)m_MoveZSlider.GetPos() / (float)SLIDER_RESOLUTION);
}
#if 0
else if (pScrollBar == GetDlgItem(IDC_TURNZ_SLIDER)) {
Controller.Set_Turn_Left(1.0f - 2.0f * (float)m_TurnZSlider.GetPos() / (float)SLIDER_RESOLUTION);
}
#endif
CDialog::OnVScroll(nSBCode, nPos, pScrollBar);
}
void CVJoyDialog::OnDestroy()
{
HWND movexy_wnd = ::GetDlgItem(m_hWnd,IDC_MOVEXY_STATIC);
RemoveProp(movexy_wnd,"OldWndProc");
RemoveProp(movexy_wnd,"XCOORD");
RemoveProp(movexy_wnd,"YCOORD");
HWND turnxy_wnd = ::GetDlgItem(m_hWnd,IDC_TURNXY_STATIC);
RemoveProp(turnxy_wnd,"OldWndProc");
RemoveProp(turnxy_wnd,"XCOORD");
RemoveProp(turnxy_wnd,"YCOORD");
CDialog::OnDestroy();
}

View File

@@ -0,0 +1,72 @@
/*
** 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/>.
*/
#if !defined(AFX_VJOYDIALOG_H__70FBC231_F1C1_11D2_9BD8_00A0C9988171__INCLUDED_)
#define AFX_VJOYDIALOG_H__70FBC231_F1C1_11D2_9BD8_00A0C9988171__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// VJoyDialog.h : header file
//
#include "physcontrol.h"
/////////////////////////////////////////////////////////////////////////////
// CVJoyDialog dialog
class CVJoyDialog : public CDialog
{
// Construction
public:
CVJoyDialog(CWnd* pParent = NULL); // standard constructor
~CVJoyDialog(void);
// Dialog Data
//{{AFX_DATA(CVJoyDialog)
enum { IDD = IDD_VJOY_DIALOG };
CSliderCtrl m_TurnZSlider;
CSliderCtrl m_MoveZSlider;
//}}AFX_DATA
PhysControllerClass Controller;
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CVJoyDialog)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CVJoyDialog)
virtual BOOL OnInitDialog();
afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
afx_msg void OnDestroy();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_VJOYDIALOG_H__70FBC231_F1C1_11D2_9BD8_00A0C9988171__INCLUDED_)

View File

@@ -0,0 +1,146 @@
/*
** 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/>.
*/
// WheeledVehicleDialog.cpp : implementation file
//
#include "stdafx.h"
#include "phystest.h"
#include "WheeledVehicleDialog.h"
#include "wheelvehicle.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
const float MIN_KS = 0.01f;
const float MAX_KS = 1000.0f;
const float MIN_KD = 0.01f;
const float MAX_KD = 1000.0f;
const float MIN_LENGTH = 0.1f;
const float MAX_LENGTH = 32.0f;
/////////////////////////////////////////////////////////////////////////////
// CWheeledVehicleDialog dialog
CWheeledVehicleDialog::CWheeledVehicleDialog(CWnd* pParent,WheeledVehicleClass * obj)
: CDialog(CWheeledVehicleDialog::IDD, pParent),
EditedObject(obj)
{
//{{AFX_DATA_INIT(CWheeledVehicleDialog)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
void CWheeledVehicleDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CWheeledVehicleDialog)
DDX_Control(pDX, IDC_WVEHICLE_LENGTH_SPIN, m_LengthSpin);
DDX_Control(pDX, IDC_WVEHICLE_KS_SPIN, m_KSSpin);
DDX_Control(pDX, IDC_WVEHICLE_KD_SPIN, m_KDSpin);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CWheeledVehicleDialog, CDialog)
//{{AFX_MSG_MAP(CWheeledVehicleDialog)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CWheeledVehicleDialog message handlers
BOOL CWheeledVehicleDialog::OnInitDialog()
{
CDialog::OnInitDialog();
m_KSSpin.SetRange(MIN_KS * 100,MAX_KS * 100);
m_KDSpin.SetRange(MIN_KD * 100,MAX_KD * 100);
m_LengthSpin.SetRange(MIN_LENGTH * 100,MAX_LENGTH * 100);
float ks,kd,len;
EditedObject->Get_Suspension_Parameters(&ks,&kd,&len);
m_KSSpin.SetPos(ks * 100);
m_KDSpin.SetPos(kd * 100);
m_LengthSpin.SetPos(len * 100);
SetDlgItemFloat(IDC_WVEHICLE_KS_EDIT,ks);
SetDlgItemFloat(IDC_WVEHICLE_KD_EDIT,kd);
SetDlgItemFloat(IDC_WVEHICLE_LENGTH_EDIT,len);
return TRUE;
}
BOOL CWheeledVehicleDialog::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
// make the spin controls work...
switch(wParam)
{
case IDC_WVEHICLE_KS_SPIN:
case IDC_WVEHICLE_KD_SPIN:
case IDC_WVEHICLE_LENGTH_SPIN:
LPNMUPDOWN lpnmud = (LPNMUPDOWN) lParam;
if (lpnmud->hdr.code == UDN_DELTAPOS) {
HWND hwnd = (HWND)SendDlgItemMessage(LOWORD(wParam),UDM_GETBUDDY);
float curval = GetDlgItemFloat(GetWindowLong(hwnd,GWL_ID));
curval += (float)lpnmud->iDelta / 100.0f;
SetDlgItemFloat(GetWindowLong(hwnd,GWL_ID), curval);
}
break;
}
return CDialog::OnNotify(wParam, lParam, pResult);
}
void CWheeledVehicleDialog::OnOK()
{
float ks,kd,len;
ks = GetDlgItemFloat(IDC_WVEHICLE_KS_EDIT);
kd = GetDlgItemFloat(IDC_WVEHICLE_KD_EDIT);
len = GetDlgItemFloat(IDC_WVEHICLE_LENGTH_EDIT);
EditedObject->Set_Suspension_Parameters(ks,kd,len);
CDialog::OnOK();
}
float CWheeledVehicleDialog::GetDlgItemFloat(int controlid)
{
CString string;
GetDlgItemText(controlid,string);
return atof(string);
}
void CWheeledVehicleDialog::SetDlgItemFloat(int controlid,float val)
{
CString string;
string.Format("%.2f",val);
SetDlgItemText(controlid,string);
}

View File

@@ -0,0 +1,75 @@
/*
** 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/>.
*/
#if !defined(AFX_WHEELEDVEHICLEDIALOG_H__14B8CCA2_F28E_11D2_9BD8_00A0C9988171__INCLUDED_)
#define AFX_WHEELEDVEHICLEDIALOG_H__14B8CCA2_F28E_11D2_9BD8_00A0C9988171__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// WheeledVehicleDialog.h : header file
//
class WheeledVehicleClass;
/////////////////////////////////////////////////////////////////////////////
// CWheeledVehicleDialog dialog
class CWheeledVehicleDialog : public CDialog
{
// Construction
public:
CWheeledVehicleDialog(CWnd* pParent,WheeledVehicleClass * obj);
// Dialog Data
//{{AFX_DATA(CWheeledVehicleDialog)
enum { IDD = IDD_WHEELEDVEHICLE_DIALOG };
CSpinButtonCtrl m_LengthSpin;
CSpinButtonCtrl m_KSSpin;
CSpinButtonCtrl m_KDSpin;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CWheeledVehicleDialog)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
//}}AFX_VIRTUAL
// Implementation
protected:
WheeledVehicleClass * EditedObject;
float GetDlgItemFloat(int controlid);
void SetDlgItemFloat(int controlid,float val);
// Generated message map functions
//{{AFX_MSG(CWheeledVehicleDialog)
virtual void OnOK();
virtual BOOL OnInitDialog();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_WHEELEDVEHICLEDIALOG_H__14B8CCA2_F28E_11D2_9BD8_00A0C9988171__INCLUDED_)

View File

@@ -0,0 +1,81 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** 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 ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/Commando/lev_file.h $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 3/08/00 8:16p $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef LEV_FILE_H
#define LEV_FILE_H
#if 0 //OBSOLETE!!!
/*
LEV File Format.
This is another chunk-based file format which will initially describe the map for
a commando level and may eventually expand to include the description of the entire
level. Due to the structure of our code, this file format will define several
"wrapper" chunks whose contents are defined in another header file in the physics
library (physchunks.h). Game code will make calls to the physics library when it
encounters those chunks.
The chunk 'LEV_CHUNK_STATIC_SCENE' can be handled by the physics scene's Load_Static_Scene
function and the 'LEV_CHUNK_DYNAMIC_SCENE' can be handled by the physics scene's
Load_Dynamic_Scene function. The definitions for the data inside those chunks can be
found inside the header file 'physchunks.h'
*/
enum {
LEV_CHUNK_LEVEL = 0x00000000, // wraps entire level definition
LEV_CHUNK_MAP = 0x00000100, // wraps the map definition
LEV_CHUNK_STATIC_SCENE = 0x00000102, // wraps physics definition of static objs (terrain)
LEV_CHUNK_STATIC_GAMEOBJS = 0x00000103, // game object definitions which link to above phys objs
LEV_CHUNK_OBJECTS = 0x00000200, // wraps defintion of all of the dynamic objects
LEV_CHUNK_DYNAMIC_SCENE = 0x00000201, // wraps physics definition of dynamic objs
LEV_CHUNK_DYNAMIC_GAMEOBJS = 0x00000202, // game obj definitions which link to above phys objs
};
#endif 0 // OBSOLETE!!!
#endif

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

View File

@@ -0,0 +1,13 @@
//
// PHYSTEST.RC2 - resources Microsoft Visual C++ does not edit directly
//
#ifdef APSTUDIO_INVOKED
#error this file is not editable by Microsoft Visual C++
#endif //APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
// Add manually edited resources here...
/////////////////////////////////////////////////////////////////////////////

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@@ -0,0 +1,125 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by PhysTest.rc
//
#define IDD_ABOUTBOX 100
#define IDR_MAINFRAME 128
#define IDR_MAINTOOLBAR 128
#define IDR_PHYSTETYPE 129
#define IDR_IMPULSE_TOOLBAR 134
#define IDD_RBODY_PROPERTIES_DIALOG 136
#define IDD_INERTIA_DIALOG 138
#define IDD_PHYSICS_CONSTANTS_DIALOG 139
#define IDD_VJOY_DIALOG 143
#define IDD_MOTORVEHICLE_DIALOG 144
#define IDD_WHEELEDVEHICLE_DIALOG 145
#define IDD_MOTORCYCLE_DIALOG 149
#define IDD_RENDER_DEVICE_DIALOG 150
#define IDC_CURSOR1 151
#define IDC_MASS_EDIT 1000
#define IDC_ELASTICITY_EDIT 1001
#define IDC_LDAMPING_EDIT 1001
#define IDC_GRAVITY_EDIT 1002
#define IDC_ADAMPING_EDIT 1002
#define IDC_MASS_SPIN 1003
#define IDC_ELASTICITY_SPIN 1004
#define IDC_LDAMPING_SPIN 1004
#define IDC_GRAVITY_SPIN 1005
#define IDC_ADAMPING_SPIN 1005
#define IDC_IBODYX_EDIT 1006
#define IDC_POSITIONX_EDIT 1006
#define IDC_IBODYX_SPIN 1007
#define IDC_POSITIONX_SPIN 1007
#define IDC_IBODYY_EDIT 1008
#define IDC_POSITIONY_EDIT 1008
#define IDC_WVEHICLE_KD_EDIT 1008
#define IDC_IBODYY_SPIN 1009
#define IDC_POSITIONY_SPIN 1009
#define IDC_WVEHICLE_KD_SPIN 1009
#define IDC_IBODYZ_EDIT 1010
#define IDC_POSITIONZ_EDIT 1010
#define IDC_WVEHICLE_LENGTH_EDIT 1010
#define IDC_IBODYZ_SPIN 1011
#define IDC_POSITIONZ_SPIN 1011
#define IDC_WVEHICLE_LENGTH_SPIN 1011
#define IDC_STIFFNESS_EDIT 1012
#define IDC_STIFFNESS_SPIN 1013
#define IDC_DAMPING_EDIT 1014
#define IDC_GRAVITYACCEL_EDIT 1015
#define IDC_DAMPING_SPIN 1015
#define IDC_GRAVITYACCEL_SPIN 1016
#define IDC_LENGTH_EDIT 1016
#define IDC_MOVEZ_SLIDER 1017
#define IDC_LENGTH_SPIN 1017
#define IDC_MOVEXY_STATIC 1018
#define IDC_TURNXY_STATIC 1019
#define IDC_WVEHICLE_KS_EDIT 1019
#define IDC_TURNZ_SLIDER 1020
#define IDC_WVEHICLE_KS_SPIN 1020
#define IDC_MVEHICLE_TORQUE_EDIT 1021
#define IDC_MVEHICLE_TORQUE_SPIN 1022
#define IDC_LEAN_K0_EDIT 1023
#define IDC_LEAN_K0_SPIN 1024
#define IDC_LEAN_K1_EDIT 1025
#define IDC_LEAN_K1_SPIN 1026
#define IDC_BALANCE_K0_EDIT 1027
#define IDC_BALANCE_K0_SPIN 1028
#define IDC_RENDER_DEVICE_COMBO 1029
#define ID_CREATE_RIGID_BODY 32771
#define ID_OPTIONS_RUN_SIMULATION 32772
#define ID_OPTIONS_DISPLAY_BOXES 32773
#define ID_IMPULSE 32775
#define ID_COUPLE 32776
#define ID_COUPLE_POSY 32777
#define ID_COUPLE_NEGY 32778
#define ID_COUPLE_POSZ 32779
#define ID_COUPLE_NEGZ 32780
#define ID_COUPLE_POSX 32781
#define ID_COUPLE_NEGX 32782
#define ID_IMPULSE_POSX 32783
#define ID_IMPULSE_NEGX 32784
#define ID_IMPULSE_POSY 32785
#define ID_IMPULSE_NEGY 32786
#define ID_IMPULSE_POSZ 32787
#define ID_IMPULSE_NEGZ 32788
#define ID_VIEW_IMPULSETOOLBAR 32802
#define ID_PROPERTIES 32804
#define ID_INERTIA 32805
#define ID_OPTIONS_PHYSICS_CONSTANTS 32806
#define ID_FREEZE_OBJECT 32807
#define ID_OPTIONS_PHYSICS_DEBUG_DISPLAY 32810
#define ID_DEBUG_OBJECT 32812
#define ID_VIEW_VIRTUALJOYSTICK 32813
#define ID_OPTIONS_FILLED 32815
#define ID_OPTIONS_WIREFRAME 32816
#define ID_OPTIONS_POINT 32817
#define ID_OPTIONS_POINTS 32819
#define ID_MOTOR_PROPERTIES 32821
#define ID_WHEEL_PROPERTIES 32822
#define ID_OPTIONS_FOLLOW_OBJECT 32823
#define ID_CAMERA_FOLLOW 32826
#define ID_CAMERA_FLY 32827
#define ID_CAMERA_TETHER 32829
#define ID_CAMERA_RIGID_TETHER 32830
#define ID_CREATE_WHEELED_VEHICLE 32833
#define ID_BUTTON32834 32834
#define ID_CREATE_PHYS4 32835
#define ID_CREATE_MOTORCYCLE 32836
#define ID_MOTORCYCLE_PROPERTIES 32838
#define ID_OPTIONS_RENDER_DEVICE 32839
#define ID_IMPORT_MODEL 32840
#define ID_IMPORT_LEV 32841
#define ID_FILE_IMPORT_MODEL 32842
#define ID_FILE_IMPORT_LEV 32843
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_3D_CONTROLS 1
#define _APS_NEXT_RESOURCE_VALUE 152
#define _APS_NEXT_COMMAND_VALUE 32844
#define _APS_NEXT_CONTROL_VALUE 1030
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@@ -0,0 +1,97 @@
/*
** 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/>.
*/
// CardinalDialog.cpp : implementation file
//
#include "stdafx.h"
#include "SplineTest.h"
#include "CardinalDialog.h"
#include "curve.h"
#include "hermitespline.h"
#include "catmullromspline.h"
#include "cardinalspline.h"
#include "tcbspline.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CCardinalDialog dialog
CCardinalDialog::CCardinalDialog(CWnd* pParent /*=NULL*/,CardinalSpline3DClass * curve,int key)
: CDialog(CCardinalDialog::IDD, pParent)
{
//{{AFX_DATA_INIT(CCardinalDialog)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
Curve = curve;
Key = key;
}
void CCardinalDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CCardinalDialog)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CCardinalDialog, CDialog)
//{{AFX_MSG_MAP(CCardinalDialog)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCardinalDialog message handlers
BOOL CCardinalDialog::OnInitDialog()
{
CDialog::OnInitDialog();
SetDlgItemFloat(IDC_TIGHTNESS_EDIT,Curve->Get_Tightness(Key));
return TRUE;
}
void CCardinalDialog::OnOK()
{
Curve->Set_Tightness(Key,GetDlgItemFloat(IDC_TIGHTNESS_EDIT));
CDialog::OnOK();
}
float CCardinalDialog::GetDlgItemFloat(int controlid)
{
CString string;
GetDlgItemText(controlid,string);
return atof(string);
}
void CCardinalDialog::SetDlgItemFloat(int controlid,float val)
{
CString string;
string.Format("%.2f",val);
SetDlgItemText(controlid,string);
}

View File

@@ -0,0 +1,73 @@
/*
** 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/>.
*/
#if !defined(AFX_CARDINALDIALOG_H__2AE09FE7_FBEF_11D2_9BD9_00A0C9988171__INCLUDED_)
#define AFX_CARDINALDIALOG_H__2AE09FE7_FBEF_11D2_9BD9_00A0C9988171__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// CardinalDialog.h : header file
//
class CardinalSpline3DClass;
/////////////////////////////////////////////////////////////////////////////
// CCardinalDialog dialog
class CCardinalDialog : public CDialog
{
// Construction
public:
CCardinalDialog(CWnd* pParent,CardinalSpline3DClass * curve,int key);
// Dialog Data
//{{AFX_DATA(CCardinalDialog)
enum { IDD = IDD_CARDINAL_DIALOG };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CCardinalDialog)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
CardinalSpline3DClass * Curve;
int Key;
float GetDlgItemFloat(int controlid);
void SetDlgItemFloat(int controlid,float val);
// Generated message map functions
//{{AFX_MSG(CCardinalDialog)
virtual void OnOK();
virtual BOOL OnInitDialog();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_CARDINALDIALOG_H__2AE09FE7_FBEF_11D2_9BD9_00A0C9988171__INCLUDED_)

View File

@@ -0,0 +1,39 @@
/*
** 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/>.
*/
#include "stdafx.h"
#include "CurvePoints.h"
float _ControlPoints[CONTROL_POINT_COUNT][4] =
{
{ 0.0f,0.0f,0.0f,0.0f },
{ 2.0f,1.0f,0.0f,1.0f },
{ 4.0f,3.0f,0.0f,2.0f },
{ 5.0f,5.0f,0.0f,3.0f },
{ 7.0f,2.0f,0.0f,4.0f },
};
float _TCBParams[CONTROL_POINT_COUNT][3] =
{
{ 0.0f,1.0f,0.0f },
{ 0.0f,1.0f,0.0f },
{ 0.0f,1.0f,0.0f },
{ 0.0f,1.0f,0.0f },
{ 0.0f,1.0f,0.0f },
};

View File

@@ -0,0 +1,25 @@
/*
** 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/>.
*/
#ifndef CURVEPOINTS_H
const int CONTROL_POINT_COUNT = 5;
extern float _ControlPoints[CONTROL_POINT_COUNT][4];
extern float _TCBParams[CONTROL_POINT_COUNT][3];
#endif

View File

@@ -0,0 +1,272 @@
/*
** 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/>.
*/
// MainFrm.cpp : implementation of the CMainFrame class
//
#include "stdafx.h"
#include "SplineTest.h"
#include "MainFrm.h"
#include "SplineTestDoc.h"
#include "SplineTestView.h"
#include "curve.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CMainFrame
IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
ON_WM_CREATE()
ON_COMMAND(ID_CURVE_CARDINAL, OnCurveCardinal)
ON_UPDATE_COMMAND_UI(ID_CURVE_CARDINAL, OnUpdateCurveCardinal)
ON_COMMAND(ID_CURVE_CATMULL_ROM, OnCurveCatmullRom)
ON_UPDATE_COMMAND_UI(ID_CURVE_CATMULL_ROM, OnUpdateCurveCatmullRom)
ON_COMMAND(ID_CURVE_LINEAR, OnCurveLinear)
ON_UPDATE_COMMAND_UI(ID_CURVE_LINEAR, OnUpdateCurveLinear)
ON_COMMAND(ID_CURVE_TCB, OnCurveTcb)
ON_UPDATE_COMMAND_UI(ID_CURVE_TCB, OnUpdateCurveTcb)
ON_COMMAND(ID_CURVE_RESET, OnCurveReset)
ON_COMMAND(ID_CURVE_DRAW_TANGENTS, OnCurveDrawTangents)
ON_UPDATE_COMMAND_UI(ID_CURVE_DRAW_TANGENTS, OnUpdateCurveDrawTangents)
ON_COMMAND(ID_CURVE_LOOP, OnCurveLoop)
ON_UPDATE_COMMAND_UI(ID_CURVE_LOOP, OnUpdateCurveLoop)
ON_COMMAND(IDM_VEHICLE_CURVE, OnVehicleCurve)
ON_UPDATE_COMMAND_UI(IDM_VEHICLE_CURVE, OnUpdateVehicleCurve)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
static UINT indicators[] =
{
ID_SEPARATOR, // status line indicator
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
};
/////////////////////////////////////////////////////////////////////////////
// CMainFrame construction/destruction
CMainFrame::CMainFrame()
{
// TODO: add member initialization code here
}
CMainFrame::~CMainFrame()
{
}
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
#if 0
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
#endif
if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("Failed to create status bar\n");
return -1; // fail to create
}
// TODO: Delete these three lines if you don't want the toolbar to
// be dockable
#if 0
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
#endif
return 0;
}
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CMainFrame diagnostics
#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
CFrameWnd::AssertValid();
}
void CMainFrame::Dump(CDumpContext& dc) const
{
CFrameWnd::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CMainFrame message handlers
void CMainFrame::OnCurveCardinal()
{
CSplineTestDoc * doc = (CSplineTestDoc *)GetActiveDocument();
if (doc) {
doc->Set_Curve_Type(CSplineTestDoc::CARDINAL);
}
}
void CMainFrame::OnUpdateCurveCardinal(CCmdUI* pCmdUI)
{
CSplineTestDoc * doc = (CSplineTestDoc *)GetActiveDocument();
if (doc != NULL) {
pCmdUI->SetCheck(doc->Get_Curve_Type() == CSplineTestDoc::CARDINAL);
}
}
void CMainFrame::OnCurveCatmullRom()
{
CSplineTestDoc * doc = (CSplineTestDoc *)GetActiveDocument();
if (doc) {
doc->Set_Curve_Type(CSplineTestDoc::CATMULL_ROM);
}
}
void CMainFrame::OnUpdateCurveCatmullRom(CCmdUI* pCmdUI)
{
CSplineTestDoc * doc = (CSplineTestDoc *)GetActiveDocument();
if (doc != NULL) {
pCmdUI->SetCheck(doc->Get_Curve_Type() == CSplineTestDoc::CATMULL_ROM);
}
}
void CMainFrame::OnCurveLinear()
{
CSplineTestDoc * doc = (CSplineTestDoc *)GetActiveDocument();
if (doc) {
doc->Set_Curve_Type(CSplineTestDoc::LINEAR);
}
}
void CMainFrame::OnUpdateCurveLinear(CCmdUI* pCmdUI)
{
CSplineTestDoc * doc = (CSplineTestDoc *)GetActiveDocument();
if (doc != NULL) {
pCmdUI->SetCheck(doc->Get_Curve_Type() == CSplineTestDoc::LINEAR);
}
}
void CMainFrame::OnCurveTcb()
{
CSplineTestDoc * doc = (CSplineTestDoc *)GetActiveDocument();
if (doc) {
doc->Set_Curve_Type(CSplineTestDoc::TCB);
}
}
void CMainFrame::OnUpdateCurveTcb(CCmdUI* pCmdUI)
{
CSplineTestDoc * doc = (CSplineTestDoc *)GetActiveDocument();
if (doc != NULL) {
pCmdUI->SetCheck(doc->Get_Curve_Type() == CSplineTestDoc::TCB);
}
}
void CMainFrame::OnCurveReset()
{
CSplineTestDoc * doc = (CSplineTestDoc *)GetActiveDocument();
if (doc != NULL) {
doc->Reset_Curve();
}
}
void CMainFrame::OnCurveDrawTangents()
{
CSplineTestView * view = (CSplineTestView *)GetActiveView();
if (view) {
view->Enable_Draw_Tangents(!view->Is_Draw_Tangents_Enabled());
}
}
void CMainFrame::OnUpdateCurveDrawTangents(CCmdUI* pCmdUI)
{
CSplineTestView * view = (CSplineTestView *)GetActiveView();
if (view) {
pCmdUI->SetCheck(view->Is_Draw_Tangents_Enabled());
}
}
void CMainFrame::OnCurveLoop()
{
CSplineTestDoc * doc = (CSplineTestDoc *)GetActiveDocument();
if (doc != NULL) {
Curve3DClass * curve = doc->Get_Curve();
if (curve) {
curve->Set_Looping(!curve->Is_Looping());
}
doc->UpdateAllViews(NULL);
}
}
void CMainFrame::OnUpdateCurveLoop(CCmdUI* pCmdUI)
{
CSplineTestDoc * doc = (CSplineTestDoc *)GetActiveDocument();
if (doc != NULL) {
Curve3DClass * curve = doc->Get_Curve();
if (curve) {
pCmdUI->SetCheck(curve->Is_Looping());
}
}
}
void CMainFrame::OnVehicleCurve()
{
CSplineTestDoc * doc = (CSplineTestDoc *)GetActiveDocument();
if (doc) {
doc->Set_Curve_Type(CSplineTestDoc::VEHICLE );
}
}
void CMainFrame::OnUpdateVehicleCurve(CCmdUI* pCmdUI)
{
CSplineTestDoc * doc = (CSplineTestDoc *)GetActiveDocument();
if (doc != NULL) {
pCmdUI->SetCheck(doc->Get_Curve_Type() == CSplineTestDoc::VEHICLE);
}
}

View File

@@ -0,0 +1,89 @@
/*
** 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/>.
*/
// MainFrm.h : interface of the CMainFrame class
//
/////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_MAINFRM_H__2AE09FD9_FBEF_11D2_9BD9_00A0C9988171__INCLUDED_)
#define AFX_MAINFRM_H__2AE09FD9_FBEF_11D2_9BD9_00A0C9988171__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CMainFrame : public CFrameWnd
{
protected: // create from serialization only
CMainFrame();
DECLARE_DYNCREATE(CMainFrame)
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMainFrame)
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CMainFrame();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected: // control bar embedded members
CStatusBar m_wndStatusBar;
// CToolBar m_wndToolBar;
// Generated message map functions
protected:
//{{AFX_MSG(CMainFrame)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnCurveCardinal();
afx_msg void OnUpdateCurveCardinal(CCmdUI* pCmdUI);
afx_msg void OnCurveCatmullRom();
afx_msg void OnUpdateCurveCatmullRom(CCmdUI* pCmdUI);
afx_msg void OnCurveLinear();
afx_msg void OnUpdateCurveLinear(CCmdUI* pCmdUI);
afx_msg void OnCurveTcb();
afx_msg void OnUpdateCurveTcb(CCmdUI* pCmdUI);
afx_msg void OnCurveReset();
afx_msg void OnCurveDrawTangents();
afx_msg void OnUpdateCurveDrawTangents(CCmdUI* pCmdUI);
afx_msg void OnCurveLoop();
afx_msg void OnUpdateCurveLoop(CCmdUI* pCmdUI);
afx_msg void OnVehicleCurve();
afx_msg void OnUpdateVehicleCurve(CCmdUI* pCmdUI);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_MAINFRM_H__2AE09FD9_FBEF_11D2_9BD9_00A0C9988171__INCLUDED_)

View File

@@ -0,0 +1,170 @@
/*
** 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/>.
*/
// SplineTest.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "SplineTest.h"
#include "MainFrm.h"
#include "SplineTestDoc.h"
#include "SplineTestView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CSplineTestApp
BEGIN_MESSAGE_MAP(CSplineTestApp, CWinApp)
//{{AFX_MSG_MAP(CSplineTestApp)
ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
// Standard file based document commands
ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSplineTestApp construction
CSplineTestApp::CSplineTestApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
/////////////////////////////////////////////////////////////////////////////
// The one and only CSplineTestApp object
CSplineTestApp theApp;
/////////////////////////////////////////////////////////////////////////////
// CSplineTestApp initialization
BOOL CSplineTestApp::InitInstance()
{
AfxEnableControlContainer();
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.
#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif
// Change the registry key under which our settings are stored.
// TODO: You should modify this string to be something appropriate
// such as the name of your company or organization.
SetRegistryKey(_T("Local AppWizard-Generated Applications"));
LoadStdProfileSettings(); // Load standard INI file options (including MRU)
// Register the application's document templates. Document templates
// serve as the connection between documents, frame windows and views.
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CSplineTestDoc),
RUNTIME_CLASS(CMainFrame), // main SDI frame window
RUNTIME_CLASS(CSplineTestView));
AddDocTemplate(pDocTemplate);
// Parse command line for standard shell commands, DDE, file open
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
// Dispatch commands specified on the command line
if (!ProcessShellCommand(cmdInfo))
return FALSE;
// The one and only window has been initialized, so show and update it.
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
// No message handlers
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
// App command to run the dialog
void CSplineTestApp::OnAppAbout()
{
CAboutDlg aboutDlg;
aboutDlg.DoModal();
}
/////////////////////////////////////////////////////////////////////////////
// CSplineTestApp message handlers

View File

@@ -0,0 +1,196 @@
# Microsoft Developer Studio Project File - Name="SplineTest" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Application" 0x0101
CFG=SplineTest - 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 "SplineTest.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 "SplineTest.mak" CFG="SplineTest - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "SplineTest - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "SplineTest - Win32 Debug" (based on "Win32 (x86) Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/Commando/Code/Tests/SplineTest", KGQBAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "SplineTest - Win32 Release"
# PROP BASE Use_MFC 6
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 6
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\wwmath" /I "..\..\wwlib" /I "..\..\wwdebug" /I "..\..\wwsaveload" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Yu"stdafx.h" /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL"
# ADD RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 /nologo /subsystem:windows /machine:I386
# ADD LINK32 wwmath.lib wwdebug.lib wwlib.lib wwsaveload.lib /nologo /subsystem:windows /machine:I386 /libpath:"..\..\Libs\release"
!ELSEIF "$(CFG)" == "SplineTest - Win32 Debug"
# PROP BASE Use_MFC 6
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 6
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\..\wwsaveload" /I "..\..\wwmath" /I "..\..\wwlib" /I "..\..\wwdebug" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL"
# ADD RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 /nologo /subsystem:windows /debug /machine:I386
# ADD LINK32 wwmath.lib wwdebug.lib wwlib.lib wwsaveload.lib /nologo /subsystem:windows /debug /machine:I386 /libpath:"..\..\Libs\debug"
!ENDIF
# Begin Target
# Name "SplineTest - Win32 Release"
# Name "SplineTest - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\CardinalDialog.cpp
# End Source File
# Begin Source File
SOURCE=.\CurvePoints.cpp
# End Source File
# Begin Source File
SOURCE=.\MainFrm.cpp
# End Source File
# Begin Source File
SOURCE=.\SplineTest.cpp
# End Source File
# Begin Source File
SOURCE=.\SplineTest.rc
# End Source File
# Begin Source File
SOURCE=.\SplineTestDoc.cpp
# End Source File
# Begin Source File
SOURCE=.\SplineTestView.cpp
# End Source File
# Begin Source File
SOURCE=.\StdAfx.cpp
# ADD CPP /Yc"stdafx.h"
# End Source File
# Begin Source File
SOURCE=.\TCBDialog.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\CardinalDialog.h
# End Source File
# Begin Source File
SOURCE=.\CurvePoints.h
# End Source File
# Begin Source File
SOURCE=.\MainFrm.h
# End Source File
# Begin Source File
SOURCE=.\Resource.h
# End Source File
# Begin Source File
SOURCE=.\SplineTest.h
# End Source File
# Begin Source File
SOURCE=.\SplineTestDoc.h
# End Source File
# Begin Source File
SOURCE=.\SplineTestView.h
# End Source File
# Begin Source File
SOURCE=.\StdAfx.h
# End Source File
# Begin Source File
SOURCE=.\TCBDialog.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"
# Begin Source File
SOURCE=.\res\SplineTest.ico
# End Source File
# Begin Source File
SOURCE=.\res\SplineTest.rc2
# End Source File
# Begin Source File
SOURCE=.\res\SplineTestDoc.ico
# End Source File
# Begin Source File
SOURCE=.\res\Toolbar.bmp
# End Source File
# End Group
# Begin Source File
SOURCE=.\ReadMe.txt
# End Source File
# End Target
# End Project

View File

@@ -0,0 +1,67 @@
/*
** 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/>.
*/
// SplineTest.h : main header file for the SPLINETEST application
//
#if !defined(AFX_SPLINETEST_H__2AE09FD5_FBEF_11D2_9BD9_00A0C9988171__INCLUDED_)
#define AFX_SPLINETEST_H__2AE09FD5_FBEF_11D2_9BD9_00A0C9988171__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#ifndef __AFXWIN_H__
#error include 'stdafx.h' before including this file for PCH
#endif
#include "resource.h" // main symbols
/////////////////////////////////////////////////////////////////////////////
// CSplineTestApp:
// See SplineTest.cpp for the implementation of this class
//
class CSplineTestApp : public CWinApp
{
public:
CSplineTestApp();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CSplineTestApp)
public:
virtual BOOL InitInstance();
//}}AFX_VIRTUAL
// Implementation
//{{AFX_MSG(CSplineTestApp)
afx_msg void OnAppAbout();
// NOTE - the ClassWizard will add and remove member functions here.
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_SPLINETEST_H__2AE09FD5_FBEF_11D2_9BD9_00A0C9988171__INCLUDED_)

View File

@@ -0,0 +1,408 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"#define _AFX_NO_SPLITTER_RESOURCES\r\n"
"#define _AFX_NO_OLE_RESOURCES\r\n"
"#define _AFX_NO_TRACKER_RESOURCES\r\n"
"#define _AFX_NO_PROPERTY_RESOURCES\r\n"
"\r\n"
"#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
"#ifdef _WIN32\r\n"
"LANGUAGE 9, 1\r\n"
"#pragma code_page(1252)\r\n"
"#endif //_WIN32\r\n"
"#include ""res\\SplineTest.rc2"" // non-Microsoft Visual C++ edited resources\r\n"
"#include ""afxres.rc"" // Standard components\r\n"
"#endif\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDR_MAINFRAME ICON DISCARDABLE "res\\SplineTest.ico"
IDR_SPLINETYPE ICON DISCARDABLE "res\\SplineTestDoc.ico"
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDR_MAINFRAME MENU PRELOAD DISCARDABLE
BEGIN
POPUP "&File"
BEGIN
MENUITEM "&New\tCtrl+N", ID_FILE_NEW
MENUITEM "&Open...\tCtrl+O", ID_FILE_OPEN
MENUITEM "&Save\tCtrl+S", ID_FILE_SAVE
MENUITEM "Save &As...", ID_FILE_SAVE_AS
MENUITEM SEPARATOR
MENUITEM "Recent File", ID_FILE_MRU_FILE1, GRAYED
MENUITEM SEPARATOR
MENUITEM "E&xit", ID_APP_EXIT
END
POPUP "&View"
BEGIN
MENUITEM "&Toolbar", ID_VIEW_TOOLBAR
MENUITEM "&Status Bar", ID_VIEW_STATUS_BAR
END
POPUP "&Help"
BEGIN
MENUITEM "&About SplineTest...", ID_APP_ABOUT
END
POPUP "Curve"
BEGIN
MENUITEM "Reset", ID_CURVE_RESET
MENUITEM SEPARATOR
MENUITEM "Linear", ID_CURVE_LINEAR
MENUITEM "Catmull Rom", ID_CURVE_CATMULL_ROM
MENUITEM "Cardinal", ID_CURVE_CARDINAL
MENUITEM "TCB", ID_CURVE_TCB
MENUITEM "Vehicle Curve", IDM_VEHICLE_CURVE
MENUITEM SEPARATOR
MENUITEM "Draw Tangents", ID_CURVE_DRAW_TANGENTS
MENUITEM "Loop", ID_CURVE_LOOP
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Accelerator
//
IDR_MAINFRAME ACCELERATORS PRELOAD MOVEABLE PURE
BEGIN
"N", ID_FILE_NEW, VIRTKEY, CONTROL
"O", ID_FILE_OPEN, VIRTKEY, CONTROL
"S", ID_FILE_SAVE, VIRTKEY, CONTROL
"Z", ID_EDIT_UNDO, VIRTKEY, CONTROL
"X", ID_EDIT_CUT, VIRTKEY, CONTROL
"C", ID_EDIT_COPY, VIRTKEY, CONTROL
"V", ID_EDIT_PASTE, VIRTKEY, CONTROL
VK_BACK, ID_EDIT_UNDO, VIRTKEY, ALT
VK_DELETE, ID_EDIT_CUT, VIRTKEY, SHIFT
VK_INSERT, ID_EDIT_COPY, VIRTKEY, CONTROL
VK_INSERT, ID_EDIT_PASTE, VIRTKEY, SHIFT
VK_F6, ID_NEXT_PANE, VIRTKEY
VK_F6, ID_PREV_PANE, VIRTKEY, SHIFT
END
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_ABOUTBOX DIALOG DISCARDABLE 0, 0, 235, 55
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "About SplineTest"
FONT 8, "MS Sans Serif"
BEGIN
ICON IDR_MAINFRAME,IDC_STATIC,11,17,20,20
LTEXT "SplineTest Version 1.0",IDC_STATIC,40,10,119,8,
SS_NOPREFIX
LTEXT "Copyright (C) 1999",IDC_STATIC,40,25,119,8
DEFPUSHBUTTON "OK",IDOK,178,7,50,14,WS_GROUP
END
IDD_CARDINAL_DIALOG DIALOG DISCARDABLE 0, 0, 186, 50
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Cardinal Spline Key Properties"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,129,7,50,14
PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14
EDITTEXT IDC_TIGHTNESS_EDIT,61,15,40,14,ES_AUTOHSCROLL
LTEXT "Tightness:",IDC_STATIC,7,18,34,8
END
IDD_TCB_DIALOG DIALOG DISCARDABLE 0, 0, 157, 66
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "TCB Parameters Dialog"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,100,7,50,14
PUSHBUTTON "Cancel",IDCANCEL,100,24,50,14
EDITTEXT IDC_TENSION_EDIT,50,7,40,14,ES_AUTOHSCROLL
EDITTEXT IDC_CONTINUITY_EDIT,50,25,40,14,ES_AUTOHSCROLL
EDITTEXT IDC_BIAS_EDIT,50,44,40,14,ES_AUTOHSCROLL
LTEXT "Tension:",IDC_STATIC,7,11,28,8
LTEXT "Continuity:",IDC_STATIC,7,29,34,8
LTEXT "Bias:",IDC_STATIC,7,48,16,8
END
#ifndef _MAC
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,1
PRODUCTVERSION 1,0,0,1
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904B0"
BEGIN
VALUE "CompanyName", "\0"
VALUE "FileDescription", "SplineTest MFC Application\0"
VALUE "FileVersion", "1, 0, 0, 1\0"
VALUE "InternalName", "SplineTest\0"
VALUE "LegalCopyright", "Copyright (C) 1999\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "SplineTest.EXE\0"
VALUE "ProductName", "SplineTest Application\0"
VALUE "ProductVersion", "1, 0, 0, 1\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#endif // !_MAC
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_ABOUTBOX, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 228
TOPMARGIN, 7
BOTTOMMARGIN, 48
END
IDD_CARDINAL_DIALOG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 179
TOPMARGIN, 7
BOTTOMMARGIN, 43
END
IDD_TCB_DIALOG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 150
TOPMARGIN, 7
BOTTOMMARGIN, 59
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE PRELOAD DISCARDABLE
BEGIN
IDR_MAINFRAME "SplineTest\n\nSpline\n\n\nSplineTest.Document\nSpline Document"
END
STRINGTABLE PRELOAD DISCARDABLE
BEGIN
AFX_IDS_APP_TITLE "SplineTest"
AFX_IDS_IDLEMESSAGE "Ready"
END
STRINGTABLE DISCARDABLE
BEGIN
ID_INDICATOR_EXT "EXT"
ID_INDICATOR_CAPS "CAP"
ID_INDICATOR_NUM "NUM"
ID_INDICATOR_SCRL "SCRL"
ID_INDICATOR_OVR "OVR"
ID_INDICATOR_REC "REC"
END
STRINGTABLE DISCARDABLE
BEGIN
ID_FILE_NEW "Create a new document\nNew"
ID_FILE_OPEN "Open an existing document\nOpen"
ID_FILE_CLOSE "Close the active document\nClose"
ID_FILE_SAVE "Save the active document\nSave"
ID_FILE_SAVE_AS "Save the active document with a new name\nSave As"
END
STRINGTABLE DISCARDABLE
BEGIN
ID_APP_ABOUT "Display program information, version number and copyright\nAbout"
ID_APP_EXIT "Quit the application; prompts to save documents\nExit"
END
STRINGTABLE DISCARDABLE
BEGIN
ID_FILE_MRU_FILE1 "Open this document"
ID_FILE_MRU_FILE2 "Open this document"
ID_FILE_MRU_FILE3 "Open this document"
ID_FILE_MRU_FILE4 "Open this document"
ID_FILE_MRU_FILE5 "Open this document"
ID_FILE_MRU_FILE6 "Open this document"
ID_FILE_MRU_FILE7 "Open this document"
ID_FILE_MRU_FILE8 "Open this document"
ID_FILE_MRU_FILE9 "Open this document"
ID_FILE_MRU_FILE10 "Open this document"
ID_FILE_MRU_FILE11 "Open this document"
ID_FILE_MRU_FILE12 "Open this document"
ID_FILE_MRU_FILE13 "Open this document"
ID_FILE_MRU_FILE14 "Open this document"
ID_FILE_MRU_FILE15 "Open this document"
ID_FILE_MRU_FILE16 "Open this document"
END
STRINGTABLE DISCARDABLE
BEGIN
ID_NEXT_PANE "Switch to the next window pane\nNext Pane"
ID_PREV_PANE "Switch back to the previous window pane\nPrevious Pane"
END
STRINGTABLE DISCARDABLE
BEGIN
ID_WINDOW_SPLIT "Split the active window into panes\nSplit"
END
STRINGTABLE DISCARDABLE
BEGIN
ID_EDIT_CLEAR "Erase the selection\nErase"
ID_EDIT_CLEAR_ALL "Erase everything\nErase All"
ID_EDIT_COPY "Copy the selection and put it on the Clipboard\nCopy"
ID_EDIT_CUT "Cut the selection and put it on the Clipboard\nCut"
ID_EDIT_FIND "Find the specified text\nFind"
ID_EDIT_PASTE "Insert Clipboard contents\nPaste"
ID_EDIT_REPEAT "Repeat the last action\nRepeat"
ID_EDIT_REPLACE "Replace specific text with different text\nReplace"
ID_EDIT_SELECT_ALL "Select the entire document\nSelect All"
ID_EDIT_UNDO "Undo the last action\nUndo"
ID_EDIT_REDO "Redo the previously undone action\nRedo"
END
STRINGTABLE DISCARDABLE
BEGIN
ID_VIEW_TOOLBAR "Show or hide the toolbar\nToggle ToolBar"
ID_VIEW_STATUS_BAR "Show or hide the status bar\nToggle StatusBar"
END
STRINGTABLE DISCARDABLE
BEGIN
AFX_IDS_SCSIZE "Change the window size"
AFX_IDS_SCMOVE "Change the window position"
AFX_IDS_SCMINIMIZE "Reduce the window to an icon"
AFX_IDS_SCMAXIMIZE "Enlarge the window to full size"
AFX_IDS_SCNEXTWINDOW "Switch to the next document window"
AFX_IDS_SCPREVWINDOW "Switch to the previous document window"
AFX_IDS_SCCLOSE "Close the active window and prompts to save the documents"
END
STRINGTABLE DISCARDABLE
BEGIN
AFX_IDS_SCRESTORE "Restore the window to normal size"
AFX_IDS_SCTASKLIST "Activate Task List"
END
STRINGTABLE DISCARDABLE
BEGIN
ID_CURVE_LINEAR "Use linear interpolation"
ID_CURVE_CATMULL_ROM "Use a Catmull-Rom spline"
ID_CURVE_CARDINAL "Use a cardinal spline"
ID_CURVE_TCB "Use a Tension-Continuity-Bias spline (Konachek-Bartels)"
ID_CURVE_RESET "Reset the curve"
ID_CURVE_DRAW_TANGENTS "Display the tangent vectors"
ID_CURVE_LOOP "Make the curve a loop"
IDM_VEHICLE_CURVE "Test a simulated vehicle path"
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#define _AFX_NO_SPLITTER_RESOURCES
#define _AFX_NO_OLE_RESOURCES
#define _AFX_NO_TRACKER_RESOURCES
#define _AFX_NO_PROPERTY_RESOURCES
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE 9, 1
#pragma code_page(1252)
#endif //_WIN32
#include "res\SplineTest.rc2" // non-Microsoft Visual C++ edited resources
#include "afxres.rc" // Standard components
#endif
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@@ -0,0 +1,279 @@
/*
** 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/>.
*/
// SplineTestDoc.cpp : implementation of the CSplineTestDoc class
//
#include "stdafx.h"
#include "SplineTest.h"
#include "SplineTestDoc.h"
#include "CurvePoints.h"
#include "curve.h"
#include "hermitespline.h"
#include "catmullromspline.h"
#include "cardinalspline.h"
#include "tcbspline.h"
#include "wwmath.h"
#include "CardinalDialog.h"
#include "TCBDialog.h"
#include "Matrix3D.h"
#include "vehiclecurve.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
const float GRAB_DIST = 0.25f;
/////////////////////////////////////////////////////////////////////////////
// CSplineTestDoc
IMPLEMENT_DYNCREATE(CSplineTestDoc, CDocument)
BEGIN_MESSAGE_MAP(CSplineTestDoc, CDocument)
//{{AFX_MSG_MAP(CSplineTestDoc)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSplineTestDoc construction/destruction
CSplineTestDoc::CSplineTestDoc()
{
CurveType = LINEAR;
Curve = new LinearCurve3DClass;
DragIndex = -1;
}
CSplineTestDoc::~CSplineTestDoc()
{
if (Curve != NULL) {
delete Curve;
}
}
BOOL CSplineTestDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
// TODO: add reinitialization code here
// (SDI documents will reuse this document)
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CSplineTestDoc serialization
void CSplineTestDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// TODO: add storing code here
}
else
{
// TODO: add loading code here
}
}
/////////////////////////////////////////////////////////////////////////////
// CSplineTestDoc diagnostics
#ifdef _DEBUG
void CSplineTestDoc::AssertValid() const
{
CDocument::AssertValid();
}
void CSplineTestDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CSplineTestDoc commands
void CSplineTestDoc::Reset_Curve(void)
{
if (Curve != NULL) {
delete Curve;
}
Curve = Create_Curve(CurveType);
DragIndex = -1;
UpdateAllViews(NULL);
}
void CSplineTestDoc::Set_Curve_Type(int type)
{
assert (Curve != NULL);
if (type != CurveType) {
Curve3DClass * new_curve = NULL;
new_curve = Create_Curve(type);
for (int i=0; i<Curve->Key_Count(); i++) {
Vector3 pt;
float t;
Curve->Get_Key(i,&pt,&t);
new_curve->Add_Key(pt,t);
UpdateAllViews(NULL);
}
delete Curve;
Curve = new_curve;
CurveType = type;
}
}
int CSplineTestDoc::Get_Curve_Type(void)
{
return CurveType;
}
Curve3DClass * CSplineTestDoc::Get_Curve(void)
{
return Curve;
}
Curve3DClass * CSplineTestDoc::Create_Curve(int type)
{
Curve3DClass * new_curve = NULL;
switch (type) {
case LINEAR:
new_curve = new LinearCurve3DClass;
break;
case VEHICLE:
new_curve = new VehicleCurveClass (1.0F);
break;
case CATMULL_ROM:
new_curve = new CatmullRomSpline3DClass;
break;
case CARDINAL:
new_curve = new CardinalSpline3DClass;
break;
case TCB:
new_curve = new TCBSpline3DClass;
break;
}
return new_curve;
}
bool CSplineTestDoc::Grab_Point(const Vector3 & pos)
{
DragIndex = -1;
if (Curve) {
DragIndex = Pick(pos);
}
return (DragIndex != -1);
}
bool CSplineTestDoc::Drag_Point(const Vector3 & pos)
{
if (DragIndex == -1) {
return false;
} else {
if (Curve) {
Curve->Set_Key(DragIndex,pos);
UpdateAllViews(NULL);
}
return true;
}
}
bool CSplineTestDoc::Release_Point(void)
{
DragIndex = -1;
return true;
}
bool CSplineTestDoc::Is_Dragging(void)
{
return (DragIndex != -1);
}
bool CSplineTestDoc::Add_Point(const Vector3 & pos)
{
if (Curve == NULL) return false;
if (Curve->Key_Count() == 0) {
Curve->Add_Key(pos,0.0f);
} else {
// make dt random for testing
Curve->Add_Key(pos,Curve->Get_End_Time() + 1.0f); //WWMath::Random_Float(0.1f,5.0f));
}
UpdateAllViews(NULL);
return true;
}
int CSplineTestDoc::Pick(const Vector3 & pos)
{
int index = -1;
for (int pi=0; pi<Curve->Key_Count(); pi++) {
Vector3 keypt;
Curve->Get_Key(pi,&keypt,NULL);
if ((keypt - pos).Length() < GRAB_DIST) {
index = pi;
break;
}
}
return index;
}
void CSplineTestDoc::Edit_Point(const Vector3 & pos)
{
int index = Pick(pos);
if (index == -1) return;
switch (CurveType) {
case LINEAR:
case CATMULL_ROM:
case VEHICLE:
break;
case CARDINAL:
{
CCardinalDialog dlg(::AfxGetMainWnd(),(CardinalSpline3DClass *)Curve,index);
dlg.DoModal();
break;
}
case TCB:
{
CTCBDialog dlg(::AfxGetMainWnd(),(TCBSpline3DClass *)Curve,index);
dlg.DoModal();
break;
}
}
UpdateAllViews(NULL);
return;
}
void CSplineTestDoc::Simulate_Turn_Radius (void)
{
return ;
}

View File

@@ -0,0 +1,103 @@
/*
** 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/>.
*/
// SplineTestDoc.h : interface of the CSplineTestDoc class
//
/////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_SPLINETESTDOC_H__2AE09FDB_FBEF_11D2_9BD9_00A0C9988171__INCLUDED_)
#define AFX_SPLINETESTDOC_H__2AE09FDB_FBEF_11D2_9BD9_00A0C9988171__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "vector.h"
class Curve3DClass;
class Vector3;
class CSplineTestDoc : public CDocument
{
protected: // create from serialization only
CSplineTestDoc();
DECLARE_DYNCREATE(CSplineTestDoc)
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CSplineTestDoc)
public:
virtual BOOL OnNewDocument();
virtual void Serialize(CArchive& ar);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CSplineTestDoc();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
enum { LINEAR=0,CATMULL_ROM,CARDINAL,TCB,VEHICLE };
void Reset_Curve(void);
void Set_Curve_Type(int type);
int Get_Curve_Type(void);
Curve3DClass * Get_Curve(void);
bool Grab_Point(const Vector3 & pos);
bool Drag_Point(const Vector3 & pos);
bool Release_Point(void);
bool Is_Dragging(void);
bool Add_Point(const Vector3 & pos);
void Edit_Point(const Vector3 & pos);
void Simulate_Turn_Radius (void);
protected:
int Pick(const Vector3 & pos);
Curve3DClass * Create_Curve(int type);
int CurveType;
Curve3DClass * Curve;
int DragIndex;
// Generated message map functions
protected:
//{{AFX_MSG(CSplineTestDoc)
// NOTE - the ClassWizard will add and remove member functions here.
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_SPLINETESTDOC_H__2AE09FDB_FBEF_11D2_9BD9_00A0C9988171__INCLUDED_)

View File

@@ -0,0 +1,317 @@
/*
** 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/>.
*/
// SplineTestView.cpp : implementation of the CSplineTestView class
//
#include "stdafx.h"
#include "SplineTest.h"
#include "SplineTestDoc.h"
#include "SplineTestView.h"
#include "curve.h"
#include "hermitespline.h"
#include "catmullromspline.h"
#include "cardinalspline.h"
#include "tcbspline.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
const float MIN_X = -10.0f;
const float MIN_Y = -10.0f;
const float MIN_Z = -10.0f;
const float MAX_X = 10.0f;
const float MAX_Y = 10.0f;
const float MAX_Z = 10.0f;
/////////////////////////////////////////////////////////////////////////////
// CSplineTestView
IMPLEMENT_DYNCREATE(CSplineTestView, CView)
BEGIN_MESSAGE_MAP(CSplineTestView, CView)
//{{AFX_MSG_MAP(CSplineTestView)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_RBUTTONUP()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSplineTestView construction/destruction
CSplineTestView::CSplineTestView()
{
DrawTangents = false;
}
CSplineTestView::~CSplineTestView()
{
}
BOOL CSplineTestView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CSplineTestView drawing
void CSplineTestView::OnDraw(CDC* pDC)
{
CSplineTestDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
Curve3DClass * curve = pDoc->Get_Curve();
if (curve == NULL) return;
Vector3 pt;
int x,y;
// draw coordinate axes
CPen blackpen;
blackpen.CreatePen(PS_DASH,1,RGB(0,0,0));
pDC->SelectObject(&blackpen);
Map_Point(Vector3(0,10,0),&x,&y);
pDC->MoveTo(x,y);
Map_Point(Vector3(0,-10,0),&x,&y);
pDC->LineTo(x,y);
Map_Point(Vector3(10,0,0),&x,&y);
pDC->MoveTo(x,y);
Map_Point(Vector3(-10,0,0),&x,&y);
pDC->LineTo(x,y);
// draw the spline
CPen greenpen;
greenpen.CreatePen(PS_SOLID,2,RGB(0,255,0));
pDC->SelectObject(&greenpen);
if (curve->Key_Count() >= 2) {
float t0 = curve->Get_Start_Time();
float t1 = curve->Get_End_Time();
float dt = (t1 - t0) / 500.0f;
curve->Evaluate(t0,&pt);
Map_Point(pt,&x,&y);
pDC->MoveTo(x,y);
for (float t=t0; t<t1; t+=dt) {
curve->Evaluate(t,&pt);
Map_Point(pt,&x,&y);
pDC->LineTo(x,y);
}
}
// draw the control points
for (int pi=0; pi<curve->Key_Count(); pi++) {
curve->Get_Key(pi,&pt,NULL);
Map_Point(pt,&x,&y);
pDC->FillSolidRect(x-2,y-2,4,4, RGB(255,0,0));
}
// draw the tangents
if ((DrawTangents) && (pDoc->Get_Curve_Type() > CSplineTestDoc::LINEAR)) {
HermiteSpline3DClass * spline = (HermiteSpline3DClass *)curve;
CPen blackpen;
blackpen.CreatePen(PS_SOLID,1,RGB(0,0,0));
pDC->SelectObject(&blackpen);
for (int pi=0; pi<spline->Key_Count(); pi++) {
int cx,cy;
spline->Get_Key(pi,&pt,NULL);
Map_Point(pt,&cx,&cy);
Vector3 in,out;
spline->Get_Tangents(pi,&in,&out);
Map_Point(pt-in,&x,&y);
pDC->MoveTo(cx,cy);
pDC->LineTo(x,y);
Map_Point(pt+out,&x,&y);
pDC->MoveTo(cx,cy);
pDC->LineTo(x,y);
}
}
}
void CSplineTestView::Map_Point(const Vector3 & point,int * set_x,int * set_y)
{
RECT rect;
GetClientRect(&rect);
float nx,ny;
nx = (point.X - MIN_X) / (MAX_X - MIN_X);
ny = (point.Y - MIN_Y) / (MAX_Y - MIN_Y);
*set_x = (float)(rect.right - rect.left) * nx + rect.left;
*set_y = (float)(rect.top - rect.bottom) * ny + rect.bottom;
}
void CSplineTestView::Un_Map_Point(int x,int y,Vector3 * set_point)
{
RECT rect;
GetClientRect(&rect);
float nx,ny;
nx = (float)(x - rect.left) / (float)(rect.right - rect.left);
ny = (float)(y - rect.bottom) / (float)(rect.top - rect.bottom);
set_point->X = MIN_X + (MAX_X - MIN_X) * nx;
set_point->Y = MIN_Y + (MAX_Y - MIN_Y) * ny;
set_point->Z = 0.0f;
*set_point = Clamp_Point(*set_point);
}
/////////////////////////////////////////////////////////////////////////////
// CSplineTestView diagnostics
#ifdef _DEBUG
void CSplineTestView::AssertValid() const
{
CView::AssertValid();
}
void CSplineTestView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CSplineTestDoc* CSplineTestView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CSplineTestDoc)));
return (CSplineTestDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CSplineTestView message handlers
void CSplineTestView::OnLButtonDown(UINT nFlags, CPoint point)
{
CSplineTestDoc* pDoc = GetDocument();
if (pDoc) {
// map the point
Vector3 pt;
Un_Map_Point(point.x,point.y,&pt);
// try to go into drag mode
bool gotone = pDoc->Grab_Point(pt);
if (gotone) {
::SetCapture(m_hWnd);
}
}
CView::OnLButtonDown(nFlags, point);
}
void CSplineTestView::OnLButtonUp(UINT nFlags, CPoint point)
{
// were we dragging something? if so release it
// otherwise add a point to the curve
CSplineTestDoc* pDoc = GetDocument();
if (pDoc != NULL) {
if (pDoc->Is_Dragging()) {
pDoc->Release_Point();
::ReleaseCapture();
} else {
Vector3 pt;
Un_Map_Point(point.x,point.y,&pt);
pDoc->Add_Point(pt);
}
}
CView::OnLButtonUp(nFlags, point);
}
void CSplineTestView::OnMouseMove(UINT nFlags, CPoint point)
{
CSplineTestDoc* pDoc = GetDocument();
// are we dragging?
// if so tell the doc where the point should go
if (pDoc && pDoc->Is_Dragging()) {
Vector3 pt;
Un_Map_Point(point.x,point.y,&pt);
pDoc->Drag_Point(pt);
}
CView::OnMouseMove(nFlags, point);
}
void CSplineTestView::OnRButtonUp(UINT nFlags, CPoint point)
{
Vector3 pt;
Un_Map_Point(point.x,point.y,&pt);
CSplineTestDoc* pDoc = GetDocument();
if (pDoc) {
pDoc->Edit_Point(pt);
}
CView::OnRButtonUp(nFlags, point);
}
Vector3 CSplineTestView::Clamp_Point(const Vector3 & input)
{
Vector3 output = input;
if (output.X < MIN_X) output.X = MIN_X;
if (output.Y < MIN_Y) output.Y = MIN_Y;
if (output.Z < MIN_Z) output.Z = MIN_Z;
if (output.X > MAX_X) output.X = MAX_X;
if (output.Y > MAX_Y) output.Y = MAX_Y;
if (output.Z > MAX_Z) output.Z = MAX_Z;
return output;
}
void CSplineTestView::Enable_Draw_Tangents(bool onoff)
{
DrawTangents = onoff;
CSplineTestDoc* pDoc = GetDocument();
if (pDoc) {
pDoc->UpdateAllViews(NULL);
}
}
bool CSplineTestView::Is_Draw_Tangents_Enabled(void)
{
return DrawTangents;
}

View File

@@ -0,0 +1,93 @@
/*
** 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/>.
*/
// SplineTestView.h : interface of the CSplineTestView class
//
/////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_SPLINETESTVIEW_H__2AE09FDD_FBEF_11D2_9BD9_00A0C9988171__INCLUDED_)
#define AFX_SPLINETESTVIEW_H__2AE09FDD_FBEF_11D2_9BD9_00A0C9988171__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class Vector3;
class CSplineTestView : public CView
{
protected: // create from serialization only
CSplineTestView();
DECLARE_DYNCREATE(CSplineTestView)
// Attributes
public:
CSplineTestDoc* GetDocument();
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CSplineTestView)
public:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CSplineTestView();
void Map_Point(const Vector3 & point,int * set_x,int * set_y);
void Un_Map_Point(int x,int y,Vector3 * set_point);
Vector3 Clamp_Point(const Vector3 & input);
void Enable_Draw_Tangents(bool onoff);
bool Is_Draw_Tangents_Enabled(void);
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
bool DrawTangents;
// Generated message map functions
protected:
//{{AFX_MSG(CSplineTestView)
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
#ifndef _DEBUG // debug version in SplineTestView.cpp
inline CSplineTestDoc* CSplineTestView::GetDocument()
{ return (CSplineTestDoc*)m_pDocument; }
#endif
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_SPLINETESTVIEW_H__2AE09FDD_FBEF_11D2_9BD9_00A0C9988171__INCLUDED_)

View File

@@ -0,0 +1,26 @@
/*
** 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/>.
*/
// stdafx.cpp : source file that includes just the standard includes
// SplineTest.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"

View File

@@ -0,0 +1,45 @@
/*
** 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/>.
*/
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#if !defined(AFX_STDAFX_H__2AE09FD7_FBEF_11D2_9BD9_00A0C9988171__INCLUDED_)
#define AFX_STDAFX_H__2AE09FD7_FBEF_11D2_9BD9_00A0C9988171__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
#include <afxwin.h> // MFC core and standard components
#include <afxext.h> // MFC extensions
#include <afxdisp.h> // MFC Automation classes
#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h> // MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__2AE09FD7_FBEF_11D2_9BD9_00A0C9988171__INCLUDED_)

View File

@@ -0,0 +1,105 @@
/*
** 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/>.
*/
// TCBDialog.cpp : implementation file
//
#include "stdafx.h"
#include "SplineTest.h"
#include "TCBDialog.h"
#include "curve.h"
#include "hermitespline.h"
#include "catmullromspline.h"
#include "cardinalspline.h"
#include "tcbspline.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CTCBDialog dialog
CTCBDialog::CTCBDialog(CWnd* pParent,TCBSpline3DClass * curve,int key)
: CDialog(CTCBDialog::IDD, pParent)
{
//{{AFX_DATA_INIT(CTCBDialog)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
Curve = curve;
Key = key;
}
void CTCBDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CTCBDialog)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CTCBDialog, CDialog)
//{{AFX_MSG_MAP(CTCBDialog)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CTCBDialog message handlers
BOOL CTCBDialog::OnInitDialog()
{
CDialog::OnInitDialog();
float t,c,b;
Curve->Get_TCB_Params(Key,&t,&c,&b);
SetDlgItemFloat(IDC_TENSION_EDIT,t);
SetDlgItemFloat(IDC_CONTINUITY_EDIT,c);
SetDlgItemFloat(IDC_BIAS_EDIT,b);
return TRUE;
}
void CTCBDialog::OnOK()
{
float t,c,b;
t = GetDlgItemFloat(IDC_TENSION_EDIT);
c = GetDlgItemFloat(IDC_CONTINUITY_EDIT);
b = GetDlgItemFloat(IDC_BIAS_EDIT);
Curve->Set_TCB_Params(Key,t,c,b);
CDialog::OnOK();
}
float CTCBDialog::GetDlgItemFloat(int controlid)
{
CString string;
GetDlgItemText(controlid,string);
return atof(string);
}
void CTCBDialog::SetDlgItemFloat(int controlid,float val)
{
CString string;
string.Format("%.2f",val);
SetDlgItemText(controlid,string);
}

View File

@@ -0,0 +1,74 @@
/*
** 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/>.
*/
#if !defined(AFX_TCBDIALOG_H__2AE09FE8_FBEF_11D2_9BD9_00A0C9988171__INCLUDED_)
#define AFX_TCBDIALOG_H__2AE09FE8_FBEF_11D2_9BD9_00A0C9988171__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// TCBDialog.h : header file
//
class TCBSpline3DClass;
/////////////////////////////////////////////////////////////////////////////
// CTCBDialog dialog
class CTCBDialog : public CDialog
{
// Construction
public:
CTCBDialog(CWnd* pParent,TCBSpline3DClass * curve,int key);
// Dialog Data
//{{AFX_DATA(CTCBDialog)
enum { IDD = IDD_TCB_DIALOG };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CTCBDialog)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
TCBSpline3DClass * Curve;
int Key;
float GetDlgItemFloat(int controlid);
void SetDlgItemFloat(int controlid,float val);
// Generated message map functions
//{{AFX_MSG(CTCBDialog)
virtual void OnOK();
virtual BOOL OnInitDialog();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_TCBDIALOG_H__2AE09FE8_FBEF_11D2_9BD9_00A0C9988171__INCLUDED_)

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,13 @@
//
// SPLINETEST.RC2 - resources Microsoft Visual C++ does not edit directly
//
#ifdef APSTUDIO_INVOKED
#error this file is not editable by Microsoft Visual C++
#endif //APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
// Add manually edited resources here...
/////////////////////////////////////////////////////////////////////////////

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,33 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by SplineTest.rc
//
#define IDD_ABOUTBOX 100
#define IDR_MAINFRAME 128
#define IDR_SPLINETYPE 129
#define IDD_CARDINAL_DIALOG 130
#define IDD_TCB_DIALOG 131
#define IDC_TIGHTNESS_EDIT 1000
#define IDC_TENSION_EDIT 1001
#define IDC_CONTINUITY_EDIT 1002
#define IDC_BIAS_EDIT 1003
#define ID_CURVE_LINEAR 32772
#define ID_CURVE_CATMULL_ROM 32773
#define ID_CURVE_CARDINAL 32774
#define ID_CURVE_TCB 32775
#define ID_CURVE_RESET 32776
#define ID_CURVE_DRAW_TANGENTS 32777
#define ID_CURVE_LOOP 32778
#define IDM_VEHICLE_CURVE 32780
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_3D_CONTROLS 1
#define _APS_NEXT_RESOURCE_VALUE 132
#define _APS_NEXT_COMMAND_VALUE 32781
#define _APS_NEXT_CONTROL_VALUE 1002
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@@ -0,0 +1,316 @@
/*
** 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/>.
*/
#include <math.h>
#include "matrix3d.h"
#include "vector3.h"
#include "col.h"
#include "cvec.h"
#include "mpu.h"
void benchmark_transformations(void);
//---------------------------------------------------------------------------
#include <fstream.h>
#include <stdlib.h>
#define FRAND (-1.0f+2.0f*rand()/float(RAND_MAX))
ofstream ostr("data1.txt");
void Rotate3D (float line[3], float angle, float rotate[3][3])
{
int row, col, mid;
float I[3][3], A[3][3], A2[3][3];
float sn, omcs;
/* identity matrix */
I[0][0] = 1; I[0][1] = 0; I[0][2] = 0;
I[1][0] = 0; I[1][1] = 1; I[1][2] = 0;
I[2][0] = 0; I[2][1] = 0; I[2][2] = 1;
/* infinitesimal rotation about line */
A[0][0] = 0; A[0][1] = +line[2]; A[0][2] = -line[1];
A[1][0] = -line[2]; A[1][1] = 0; A[1][2] = +line[0];
A[2][0] = +line[1]; A[2][1] = -line[0]; A[2][2] = 0;
/* A2 = A*A */
for (row = 0; row < 3; row++)
for (col = 0; col < 3; col++) {
A2[row][col] = 0;
for (mid = 0; mid < 3; mid++)
A2[row][col] += A[row][mid]*A[mid][col];
}
sn = float(sin(angle));
omcs = float(1.0-cos(angle));
/* rotation is I+sin(angle)*A+[1-cos(angle)]*A*A */
for (row = 0; row < 3; row++)
for (col = 0; col < 3; col++)
rotate[row][col] = I[row][col]+sn*A[row][col]+omcs*A2[row][col];
}
void main ()
{
Box box0, box1;
// create box0
box0.center[0] = 0.0f;
box0.center[1] = 0.0f;
box0.center[2] = 0.0f;
box0.basis[0][0] = 1.0f;
box0.basis[0][1] = 0.0f;
box0.basis[0][2] = 0.0f;
box0.basis[1][0] = 0.0f;
box0.basis[1][1] = 1.0f;
box0.basis[1][2] = 0.0f;
box0.basis[2][0] = 0.0f;
box0.basis[2][1] = 0.0f;
box0.basis[2][2] = 1.0f;
box0.extent[0] = 4.0f;
box0.extent[1] = 4.0f;
box0.extent[2] = 4.0f;
box0.velocity[0] = 0.0f;
box0.velocity[1] = 0.0f;
box0.velocity[2] = 0.0f;
// create box1
box1.center[0] = 0.0f;
box1.center[1] = -10.0f;
box1.center[2] = 20.0f;
float line[3] = { 0.0f, 0.707f, 0.707f };
float length = float(sqrt(line[0]*line[0]+line[1]*line[1]+line[2]*line[2]));
line[0] /= length;
line[1] /= length;
line[2] /= length;
float angle = (float)DEG_TO_RAD(45.0f);
Rotate3D(line,angle,box1.basis);
/*
box1.basis[0][0] = 1.0f;
box1.basis[0][1] = 0.0f;
box1.basis[0][2] = 0.0f;
box1.basis[1][0] = 0.0f;
box1.basis[1][1] = 1.0f;
box1.basis[1][2] = 0.0f;
box1.basis[2][0] = 0.0f;
box1.basis[2][1] = 0.0f;
box1.basis[2][2] = 1.0f;
*/
box1.extent[0] = 10.0f;
box1.extent[1] = 4.0f;
box1.extent[2] = 4.0f;
box1.velocity[0] = 0.0f;
box1.velocity[1] = 0.0f;
box1.velocity[2] = 0.0f;
BoxClass mybox0(box0);
BoxClass mybox1(box1);
unsigned long high;
unsigned long cycles0;
unsigned long cycles1;
unsigned long cycles2;
while (box1.center[2] > -20.0f) {
cycles0 = Get_CPU_Clock(high);
IntersectType type = BoxesIntersect(1.0f,box0,box1);
cycles0 = Get_CPU_Clock(high) - cycles0;
cycles1 = Get_CPU_Clock(high);
IntersectType mytype = Boxes_Intersect(mybox0,mybox1,1.0f);
cycles1 = Get_CPU_Clock(high) - cycles1;
cycles2 = Get_CPU_Clock(high);
IntersectType mytype2 = Boxes_Intersect(mybox0,mybox1);
cycles2 = Get_CPU_Clock(high) - cycles2;
cout << cycles0 << " "<< cycles1 << " " << cycles2 << " " << type << " " << mytype<< " " << mytype2 << endl;
box1.center[2] -= 1.0f;
mybox1.Center[2] -= 1.0f;
}
// if (type == itIntersects) {
// ostr << "type = " << type << endl;
// }
benchmark_transformations();
#if 0
float line[3] = { FRAND, FRAND, FRAND };
float length = float(sqrt(line[0]*line[0]+line[1]*line[1]+line[2]*line[2]));
line[0] /= length;
line[1] /= length;
line[2] /= length;
float angle = FRAND;
Rotate3D(line,angle,box0.basis);
box0.extent[0] = 1.0f;
box0.extent[1] = 1.0f;
box0.extent[2] = 1.0f;
box0.velocity[0] = 0.0f;
box0.velocity[1] = 0.0f;
box0.velocity[2] = 0.0f;
for (int i = 0; i < 100; i++)
{
box1.center[0] = 2.0f;
box1.center[1] = 0.0f;
box1.center[2] = 0.0f;
line[0] = FRAND;
line[1] = FRAND;
line[2] = FRAND;
length = float(sqrt(line[0]*line[0]+line[1]*line[1]+line[2]*line[2]));
line[0] /= length;
line[1] /= length;
line[2] /= length;
angle = FRAND;
Rotate3D(line,angle,box1.basis);
box1.extent[0] = 1.0f;
box1.extent[1] = 1.0f;
box1.extent[2] = 1.0f;
box1.velocity[0] = 0.0f;
box1.velocity[1] = 0.0f;
box1.velocity[2] = 0.0f;
IntersectType type = BoxesIntersect(1.0f,box0,box1);
ostr << "i = " << i << ' ' << "type = " << type << endl;
}
#endif
/*
** box0
*/
box0.center[0] = 6.1978f;
box0.center[1] = 2.6640f;
box0.center[2] = 0.840f;
box0.extent[0] = 0.1341f;
box0.extent[1] = 0.320672f;
box0.extent[2] = 0.840f;
box0.velocity[0] = box0.velocity[1] = box0.velocity[2] = 0.0f;
box0.basis[0][0] = 0.857709f;
box0.basis[0][1] = -0.514136f;
box0.basis[0][2] = 0.0f;
box0.basis[1][0] = 0.514136f;
box0.basis[1][1] = 0.857709f;
box0.basis[1][2] = 0.0f;
box0.basis[2][0] = 0.0f;
box0.basis[2][1] = 0.0f;
box0.basis[2][2] = 1.0f;
/*
** box1
*/
box1.center[0] = 10.0f;
box1.center[1] = 4.0f;
box1.center[2] = 2.8f;
box1.extent[0] = 4.5f;
box1.extent[1] = 1.966f;
box1.extent[2] = 2.868f;
box1.velocity[0] = box1.velocity[1] = box1.velocity[2] = 0.0f;
box1.basis[0][0] = 1.0f;
box1.basis[0][1] = 0.0f;
box1.basis[0][2] = 0.0f;
box1.basis[1][0] = 0.0f;
box1.basis[1][1] = 1.0f;
box1.basis[1][2] = 0.0f;
box1.basis[2][0] = 0.0f;
box1.basis[2][1] = 0.0f;
box1.basis[2][2] = 1.0f;
IntersectType type = BoxesIntersect(1.0f,box0,box1);
}
void benchmark_transformations(void)
{
unsigned long high;
unsigned long cycles0;
unsigned long cycles1;
/*
** Testing speed of the matrix library...
*/
Vector v = { 4.0f, -2.5f, 100.4f };
float mat[3][3];
float line[3] = { 0.0f, 0.0f, 1.0f };
float length = float(sqrt(line[0]*line[0]+line[1]*line[1]+line[2]*line[2]));
line[0] /= length;
line[1] /= length;
line[2] /= length;
float angle = (float)DEG_TO_RAD(45.0f);
Rotate3D(line,angle,mat);
Vector3 myv(4.0,-2.5,100.4);
Matrix3 mymat;
mymat[0][0] = mat[0][0];
mymat[0][1] = mat[0][1];
mymat[0][2] = mat[0][2];
mymat[1][0] = mat[1][0];
mymat[1][1] = mat[1][1];
mymat[1][2] = mat[1][2];
mymat[2][0] = mat[2][0];
mymat[2][1] = mat[2][1];
mymat[2][2] = mat[2][2];
Vector res;
Vector3 myres;
cycles0 = Get_CPU_Clock(high);
MultiplyVM (v,mat,res);
cycles0 = Get_CPU_Clock(high) - cycles0;
cycles1 = Get_CPU_Clock(high);
myres = mymat * myv;
cycles1 = Get_CPU_Clock(high) - cycles1;
cout << "c cycles = " << cycles0 << endl;
cout << "c++ cycles = " << cycles1 << endl;
}

531
Code/Tests/collide/col.cpp Normal file
View File

@@ -0,0 +1,531 @@
/*
** 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/>.
*/
#include "col.h"
#include "matrix3.h"
#include "vector3.h"
BoxClass::BoxClass(Box box)
{
Center.X = box.center[0];
Center.Y = box.center[1];
Center.Z = box.center[2];
Extent.X = box.extent[0];
Extent.Y = box.extent[1];
Extent.Z = box.extent[2];
Velocity.X = box.velocity[0];
Velocity.Y = box.velocity[1];
Velocity.Z = box.velocity[2];
Basis[0][0] = box.basis[0][0];
Basis[0][1] = box.basis[0][1];
Basis[0][2] = box.basis[0][2];
Basis[1][0] = box.basis[1][0];
Basis[1][1] = box.basis[1][1];
Basis[1][2] = box.basis[1][2];
Basis[2][0] = box.basis[2][0];
Basis[2][1] = box.basis[2][1];
Basis[2][2] = box.basis[2][2];
}
//---------------------------------------------------------------------------
IntersectType Boxes_Intersect(const BoxClass & box0, const BoxClass & box1,float dt)
{
// memoized values for Dot_Product(box0.Basis[i],box1.Basis[j]),
Matrix3 AB;
// calculate difference of centers
Vector3 C = box1.Center - box0.Center;
Vector3 V = box1.Velocity - box0.Velocity;
float ra, rb, rsum, u0, u1;
/////////////////////////////////////////////////////////////////////////
// L = A0
//
// Projecting the two boxes onto Box0's X axis. If their intervals
// on this line do not intersect, the boxes are not intersecting!
// Each of the tests in this function work in a similar way.
/////////////////////////////////////////////////////////////////////////
AB[0][0] = Dot_Product(box0.Basis[0],box1.Basis[0]);
AB[0][1] = Dot_Product(box0.Basis[0],box1.Basis[1]);
AB[0][2] = Dot_Product(box0.Basis[0],box1.Basis[2]);
ra = FABS(box0.Extent[0]);
rb = FABS(box1.Extent[0]*AB[0][0])+FABS(box1.Extent[1]*AB[0][1])+FABS(box1.Extent[2]*AB[0][2]);
rsum = ra+rb;
// u0 = projected distance between the box centers at t0
// u1 = projected distance between the box centers at t1
u0 = Dot_Product(C,box0.Basis[0]);
u1 = u0+dt*Dot_Product(V,box0.Basis[0]);
if ((u0 > rsum && u1 > rsum) || (u0 < -rsum && u1 < -rsum) )
return itA0;
/////////////////////////////////////////////////////////////////////////
// L = A1
// Separating Axis is Box0's Y axis
/////////////////////////////////////////////////////////////////////////
AB[1][0] = Dot_Product(box0.Basis[1],box1.Basis[0]);
AB[1][1] = Dot_Product(box0.Basis[1],box1.Basis[1]);
AB[1][2] = Dot_Product(box0.Basis[1],box1.Basis[2]);
ra = FABS(box0.Extent[1]);
rb = FABS(box1.Extent[0]*AB[1][0])+FABS(box1.Extent[1]*AB[1][1])+FABS(box1.Extent[2]*AB[1][2]);
rsum = ra+rb;
u0 = Dot_Product(C,box0.Basis[1]);
u1 = u0+dt*Dot_Product(V,box0.Basis[1]);
if ((u0 > rsum && u1 > rsum) || (u0 < -rsum && u1 < -rsum) )
return itA1;
/////////////////////////////////////////////////////////////////////////
// L = A2
// Separating Axis is Box0's Y axis
/////////////////////////////////////////////////////////////////////////
AB[2][0] = Dot_Product(box0.Basis[2],box1.Basis[0]);
AB[2][1] = Dot_Product(box0.Basis[2],box1.Basis[1]);
AB[2][2] = Dot_Product(box0.Basis[2],box1.Basis[2]);
ra = FABS(box0.Extent[2]);
rb = FABS(box1.Extent[0]*AB[2][0])+FABS(box1.Extent[1]*AB[2][1])+FABS(box1.Extent[2]*AB[2][2]);
rsum = ra+rb;
u0 = Dot_Product(C,box0.Basis[2]);
u1 = u0+dt*Dot_Product(V,box0.Basis[2]);
if ((u0 > rsum && u1 > rsum) || (u0 < -rsum && u1 < -rsum) )
return itA2;
/////////////////////////////////////////////////////////////////////////
// L = B0
// Separating Axis is Box1's X axis
/////////////////////////////////////////////////////////////////////////
ra = FABS(box0.Extent[0]*AB[0][0])+FABS(box0.Extent[1]*AB[1][0])+FABS(box0.Extent[2]*AB[2][0]);
rb = FABS(box1.Extent[0]);
rsum = ra+rb;
u0 = Dot_Product(C,box1.Basis[0]);
u1 = u0+dt*Dot_Product(V,box1.Basis[0]);
if ((u0 > rsum && u1 > rsum) || (u0 < -rsum && u1 < -rsum) )
return itB0;
/////////////////////////////////////////////////////////////////////////
// L = B1
// Separating Axis is Box1's Y axis
/////////////////////////////////////////////////////////////////////////
ra = FABS(box0.Extent[0]*AB[0][1])+FABS(box0.Extent[1]*AB[1][1])+FABS(box0.Extent[2]*AB[2][1]);
rb = FABS(box1.Extent[1]);
rsum = ra+rb;
u0 = Dot_Product(C,box1.Basis[1]);
u1 = u0+dt*Dot_Product(V,box1.Basis[1]);
if ((u0 > rsum && u1 > rsum) || (u0 < -rsum && u1 < -rsum) )
return itB1;
/////////////////////////////////////////////////////////////////////////
// L = B2
// Separating Axis is Box1's Z axis
/////////////////////////////////////////////////////////////////////////
ra = FABS(box0.Extent[0]*AB[0][2])+FABS(box0.Extent[1]*AB[1][2])+FABS(box0.Extent[2]*AB[2][2]);
rb = FABS(box1.Extent[2]);
rsum = ra+rb;
u0 = Dot_Product(C,box1.Basis[2]);
u1 = u0+dt*Dot_Product(V,box1.Basis[2]);
if ((u0 > rsum && u1 > rsum) || (u0 < -rsum && u1 < -rsum) )
return itB2;
/////////////////////////////////////////////////////////////////////////
// None of the aligned axes turned out to be separating axes. Now
// we check all combinations of cross products of the two boxes axes.
/////////////////////////////////////////////////////////////////////////
Matrix3 Ainv = box0.Basis.Transpose();
Matrix3 coeff = AB.Transpose();
// difference of centers in box0's-basis
Vector3 d0, d1, product;
d0 = Ainv * C;
d1 = Ainv * V;
product = dt*d1;
d1 = d0 + product;
/////////////////////////////////////////////////////////////////////////
// L = A0xB0
/////////////////////////////////////////////////////////////////////////
ra = FABS(box0.Extent[1]*coeff[0][2])+FABS(box0.Extent[2]*coeff[0][1]);
rb = FABS(box1.Extent[1]*coeff[2][0])+FABS(box1.Extent[2]*coeff[1][0]);
rsum = ra+rb;
u0 = d0[2]*coeff[1][0]-d0[1]*coeff[2][0];
u1 = d1[2]*coeff[1][0]-d1[1]*coeff[2][0];
if ((u0 > rsum && u1 > rsum) || (u0 < -rsum && u1 < -rsum) )
return itA0B0;
/////////////////////////////////////////////////////////////////////////
// L = A0xB1
/////////////////////////////////////////////////////////////////////////
ra = FABS(box0.Extent[1]*coeff[1][2])+FABS(box0.Extent[2]*coeff[1][1]);
rb = FABS(box1.Extent[0]*coeff[2][0])+FABS(box1.Extent[2]*coeff[0][0]);
rsum = ra+rb;
u0 = d0[2]*coeff[1][1]-d0[1]*coeff[1][2];
u1 = d1[2]*coeff[1][1]-d1[1]*coeff[1][2];
if ((u0 > rsum && u1 > rsum) || (u0 < -rsum && u1 < -rsum) )
return itA0B1;
/////////////////////////////////////////////////////////////////////////
// L = A0xB2
/////////////////////////////////////////////////////////////////////////
ra = FABS(box0.Extent[1]*coeff[2][2])+FABS(box0.Extent[2]*coeff[2][1]);
rb = FABS(box1.Extent[0]*coeff[1][0])+FABS(box1.Extent[1]*coeff[0][0]);
rsum = ra+rb;
u0 = d0[2]*coeff[2][1]-d0[1]*coeff[2][2];
u1 = d1[2]*coeff[2][1]-d1[1]*coeff[2][2];
if ((u0 > rsum && u1 > rsum) || (u0 < -rsum && u1 < -rsum) )
return itA0B2;
/////////////////////////////////////////////////////////////////////////
// L = A1xB0
/////////////////////////////////////////////////////////////////////////
ra = FABS(box0.Extent[0]*coeff[0][2])+FABS(box0.Extent[2]*coeff[0][0]);
rb = FABS(box1.Extent[1]*coeff[2][1])+FABS(box1.Extent[2]*coeff[1][1]);
rsum = ra+rb;
u0 = d0[0]*coeff[0][2]-d0[2]*coeff[0][0];
u1 = d1[0]*coeff[0][2]-d1[2]*coeff[0][0];
if ((u0 > rsum && u1 > rsum) || (u0 < -rsum && u1 < -rsum) )
return itA1B0;
/////////////////////////////////////////////////////////////////////////
// L = A1xB1
/////////////////////////////////////////////////////////////////////////
ra = FABS(box0.Extent[0]*coeff[1][2])+FABS(box0.Extent[2]*coeff[1][0]);
rb = FABS(box1.Extent[0]*coeff[2][1])+FABS(box1.Extent[2]*coeff[0][1]);
rsum = ra+rb;
u0 = d0[0]*coeff[1][2]-d0[2]*coeff[1][0];
u1 = d1[0]*coeff[1][2]-d1[2]*coeff[1][0];
if ((u0 > rsum && u1 > rsum) || (u0 < -rsum && u1 < -rsum) )
return itA1B1;
/////////////////////////////////////////////////////////////////////////
// L = A1xB2
/////////////////////////////////////////////////////////////////////////
ra = FABS(box0.Extent[0]*coeff[2][2])+FABS(box0.Extent[2]*coeff[2][0]);
rb = FABS(box1.Extent[0]*coeff[1][1])+FABS(box1.Extent[1]*coeff[0][1]);
rsum = ra+rb;
u0 = d0[0]*coeff[2][2]-d0[2]*coeff[2][0];
u1 = d1[0]*coeff[2][2]-d1[2]*coeff[2][0];
if ((u0 > rsum && u1 > rsum) || (u0 < -rsum && u1 < -rsum) )
return itA1B2;
/////////////////////////////////////////////////////////////////////////
// L = A2xB0
/////////////////////////////////////////////////////////////////////////
ra = FABS(box0.Extent[0]*coeff[0][1])+FABS(box0.Extent[1]*coeff[0][0]);
rb = FABS(box1.Extent[1]*coeff[2][2])+FABS(box1.Extent[2]*coeff[1][2]);
rsum = ra+rb;
u0 = d0[1]*coeff[0][0]-d0[0]*coeff[0][1];
u1 = d1[1]*coeff[0][0]-d1[0]*coeff[0][1];
if ((u0 > rsum && u1 > rsum) || (u0 < -rsum && u1 < -rsum) )
return itA2B0;
/////////////////////////////////////////////////////////////////////////
// L = A2xB1
/////////////////////////////////////////////////////////////////////////
ra = FABS(box0.Extent[0]*coeff[1][1])+FABS(box0.Extent[1]*coeff[1][0]);
rb = FABS(box1.Extent[0]*coeff[2][2])+FABS(box1.Extent[2]*coeff[0][2]);
rsum = ra+rb;
u0 = d0[1]*coeff[1][0]-d0[0]*coeff[1][1];
u1 = d1[1]*coeff[1][0]-d1[0]*coeff[1][1];
if ((u0 > rsum && u1 > rsum) || (u0 < -rsum && u1 < -rsum) )
return itA2B1;
/////////////////////////////////////////////////////////////////////////
// L = A2xB2
/////////////////////////////////////////////////////////////////////////
ra = FABS(box0.Extent[0]*coeff[2][1])+FABS(box0.Extent[1]*coeff[2][0]);
rb = FABS(box1.Extent[0]*coeff[1][2])+FABS(box1.Extent[1]*coeff[0][2]);
rsum = ra+rb;
u0 = d0[1]*coeff[2][0]-d0[0]*coeff[2][1];
u1 = d1[1]*coeff[2][0]-d1[0]*coeff[2][1];
if ((u0 > rsum && u1 > rsum) || (u0 < -rsum && u1 < -rsum) )
return itA2B2;
return itIntersects;
}
//---------------------------------------------------------------------------
IntersectType Boxes_Intersect(const BoxClass & box0, const BoxClass & box1)
{
// memoized values for Dot_Product(box0.Basis[i],box1.Basis[j]),
Matrix3 AB;
// calculate difference of centers
Vector3 C = box1.Center - box0.Center;
float ra, rb, rsum, u0;
/////////////////////////////////////////////////////////////////////////
// L = A0
//
// Projecting the two boxes onto Box0's X axis. If their intervals
// on this line do not intersect, the boxes are not intersecting!
// Each of the tests in this function work in a similar way.
/////////////////////////////////////////////////////////////////////////
AB[0][0] = Dot_Product(box0.Basis[0],box1.Basis[0]);
AB[0][1] = Dot_Product(box0.Basis[0],box1.Basis[1]);
AB[0][2] = Dot_Product(box0.Basis[0],box1.Basis[2]);
ra = FABS(box0.Extent[0]);
rb = FABS(box1.Extent[0]*AB[0][0])+FABS(box1.Extent[1]*AB[0][1])+FABS(box1.Extent[2]*AB[0][2]);
rsum = ra+rb;
// u0 = projected distance between the box centers at t0
// u1 = projected distance between the box centers at t1
u0 = Dot_Product(C,box0.Basis[0]);
if ((u0 > rsum) || (u0 < -rsum))
return itA0;
/////////////////////////////////////////////////////////////////////////
// L = A1
// Separating Axis is Box0's Y axis
/////////////////////////////////////////////////////////////////////////
AB[1][0] = Dot_Product(box0.Basis[1],box1.Basis[0]);
AB[1][1] = Dot_Product(box0.Basis[1],box1.Basis[1]);
AB[1][2] = Dot_Product(box0.Basis[1],box1.Basis[2]);
ra = FABS(box0.Extent[1]);
rb = FABS(box1.Extent[0]*AB[1][0])+FABS(box1.Extent[1]*AB[1][1])+FABS(box1.Extent[2]*AB[1][2]);
rsum = ra+rb;
u0 = Dot_Product(C,box0.Basis[1]);
if ((u0 > rsum) || (u0 < -rsum))
return itA1;
/////////////////////////////////////////////////////////////////////////
// L = A2
// Separating Axis is Box0's Y axis
/////////////////////////////////////////////////////////////////////////
AB[2][0] = Dot_Product(box0.Basis[2],box1.Basis[0]);
AB[2][1] = Dot_Product(box0.Basis[2],box1.Basis[1]);
AB[2][2] = Dot_Product(box0.Basis[2],box1.Basis[2]);
ra = FABS(box0.Extent[2]);
rb = FABS(box1.Extent[0]*AB[2][0])+FABS(box1.Extent[1]*AB[2][1])+FABS(box1.Extent[2]*AB[2][2]);
rsum = ra+rb;
u0 = Dot_Product(C,box0.Basis[2]);
if ((u0 > rsum) || (u0 < -rsum))
return itA2;
/////////////////////////////////////////////////////////////////////////
// L = B0
// Separating Axis is Box1's X axis
/////////////////////////////////////////////////////////////////////////
ra = FABS(box0.Extent[0]*AB[0][0])+FABS(box0.Extent[1]*AB[1][0])+FABS(box0.Extent[2]*AB[2][0]);
rb = FABS(box1.Extent[0]);
rsum = ra+rb;
u0 = Dot_Product(C,box1.Basis[0]);
if ((u0 > rsum) || (u0 < -rsum))
return itB0;
/////////////////////////////////////////////////////////////////////////
// L = B1
// Separating Axis is Box1's Y axis
/////////////////////////////////////////////////////////////////////////
ra = FABS(box0.Extent[0]*AB[0][1])+FABS(box0.Extent[1]*AB[1][1])+FABS(box0.Extent[2]*AB[2][1]);
rb = FABS(box1.Extent[1]);
rsum = ra+rb;
u0 = Dot_Product(C,box1.Basis[1]);
if ((u0 > rsum) || (u0 < -rsum))
return itB1;
/////////////////////////////////////////////////////////////////////////
// L = B2
// Separating Axis is Box1's Z axis
/////////////////////////////////////////////////////////////////////////
ra = FABS(box0.Extent[0]*AB[0][2])+FABS(box0.Extent[1]*AB[1][2])+FABS(box0.Extent[2]*AB[2][2]);
rb = FABS(box1.Extent[2]);
rsum = ra+rb;
u0 = Dot_Product(C,box1.Basis[2]);
if ((u0 > rsum) || (u0 < -rsum))
return itB2;
/////////////////////////////////////////////////////////////////////////
// None of the aligned axes turned out to be separating axes. Now
// we check all combinations of cross products of the two boxes axes.
/////////////////////////////////////////////////////////////////////////
Matrix3 Ainv = box0.Basis.Transpose();
Matrix3 coeff = AB.Transpose();
// difference of centers in box0's-basis
Vector3 d0, d1, product;
d0 = Ainv * C;
/////////////////////////////////////////////////////////////////////////
// L = A0xB0
/////////////////////////////////////////////////////////////////////////
ra = FABS(box0.Extent[1]*coeff[0][2])+FABS(box0.Extent[2]*coeff[0][1]);
rb = FABS(box1.Extent[1]*coeff[2][0])+FABS(box1.Extent[2]*coeff[1][0]);
rsum = ra+rb;
u0 = d0[2]*coeff[1][0]-d0[1]*coeff[2][0];
if ((u0 > rsum) || (u0 < -rsum))
return itA0B0;
/////////////////////////////////////////////////////////////////////////
// L = A0xB1
/////////////////////////////////////////////////////////////////////////
ra = FABS(box0.Extent[1]*coeff[1][2])+FABS(box0.Extent[2]*coeff[1][1]);
rb = FABS(box1.Extent[0]*coeff[2][0])+FABS(box1.Extent[2]*coeff[0][0]);
rsum = ra+rb;
u0 = d0[2]*coeff[1][1]-d0[1]*coeff[1][2];
if ((u0 > rsum) || (u0 < -rsum))
return itA0B1;
/////////////////////////////////////////////////////////////////////////
// L = A0xB2
/////////////////////////////////////////////////////////////////////////
ra = FABS(box0.Extent[1]*coeff[2][2])+FABS(box0.Extent[2]*coeff[2][1]);
rb = FABS(box1.Extent[0]*coeff[1][0])+FABS(box1.Extent[1]*coeff[0][0]);
rsum = ra+rb;
u0 = d0[2]*coeff[2][1]-d0[1]*coeff[2][2];
if ((u0 > rsum) || (u0 < -rsum))
return itA0B2;
/////////////////////////////////////////////////////////////////////////
// L = A1xB0
/////////////////////////////////////////////////////////////////////////
ra = FABS(box0.Extent[0]*coeff[0][2])+FABS(box0.Extent[2]*coeff[0][0]);
rb = FABS(box1.Extent[1]*coeff[2][1])+FABS(box1.Extent[2]*coeff[1][1]);
rsum = ra+rb;
u0 = d0[0]*coeff[0][2]-d0[2]*coeff[0][0];
if ((u0 > rsum) || (u0 < -rsum))
return itA1B0;
/////////////////////////////////////////////////////////////////////////
// L = A1xB1
/////////////////////////////////////////////////////////////////////////
ra = FABS(box0.Extent[0]*coeff[1][2])+FABS(box0.Extent[2]*coeff[1][0]);
rb = FABS(box1.Extent[0]*coeff[2][1])+FABS(box1.Extent[2]*coeff[0][1]);
rsum = ra+rb;
u0 = d0[0]*coeff[1][2]-d0[2]*coeff[1][0];
if ((u0 > rsum) || (u0 < -rsum))
return itA1B1;
/////////////////////////////////////////////////////////////////////////
// L = A1xB2
/////////////////////////////////////////////////////////////////////////
ra = FABS(box0.Extent[0]*coeff[2][2])+FABS(box0.Extent[2]*coeff[2][0]);
rb = FABS(box1.Extent[0]*coeff[1][1])+FABS(box1.Extent[1]*coeff[0][1]);
rsum = ra+rb;
u0 = d0[0]*coeff[2][2]-d0[2]*coeff[2][0];
if ((u0 > rsum) || (u0 < -rsum))
return itA1B2;
/////////////////////////////////////////////////////////////////////////
// L = A2xB0
/////////////////////////////////////////////////////////////////////////
ra = FABS(box0.Extent[0]*coeff[0][1])+FABS(box0.Extent[1]*coeff[0][0]);
rb = FABS(box1.Extent[1]*coeff[2][2])+FABS(box1.Extent[2]*coeff[1][2]);
rsum = ra+rb;
u0 = d0[1]*coeff[0][0]-d0[0]*coeff[0][1];
if ((u0 > rsum) || (u0 < -rsum))
return itA2B0;
/////////////////////////////////////////////////////////////////////////
// L = A2xB1
/////////////////////////////////////////////////////////////////////////
ra = FABS(box0.Extent[0]*coeff[1][1])+FABS(box0.Extent[1]*coeff[1][0]);
rb = FABS(box1.Extent[0]*coeff[2][2])+FABS(box1.Extent[2]*coeff[0][2]);
rsum = ra+rb;
u0 = d0[1]*coeff[1][0]-d0[0]*coeff[1][1];
if ((u0 > rsum) || (u0 < -rsum))
return itA2B1;
/////////////////////////////////////////////////////////////////////////
// L = A2xB2
/////////////////////////////////////////////////////////////////////////
ra = FABS(box0.Extent[0]*coeff[2][1])+FABS(box0.Extent[1]*coeff[2][0]);
rb = FABS(box1.Extent[0]*coeff[1][2])+FABS(box1.Extent[1]*coeff[0][2]);
rsum = ra+rb;
u0 = d0[1]*coeff[2][0]-d0[0]*coeff[2][1];
if ((u0 > rsum) || (u0 < -rsum))
return itA2B2;
return itIntersects;
}

59
Code/Tests/collide/col.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/>.
*/
#include "matrix3.h"
#include "vector3.h"
#include "cvec.h"
typedef enum
{
itIntersects,
itA0, itA1, itA2,
itB0, itB1, itB2,
itA0B0, itA0B1, itA0B2,
itA1B0, itA1B1, itA1B2,
itA2B0, itA2B1, itA2B2
}
IntersectType;
typedef struct
{
Vector center;
Vector basis[3];
Vector extent;
Vector velocity;
}
Box;
class BoxClass
{
public:
BoxClass(Box box);
Vector3 Center;
Vector3 Extent;
Vector3 Velocity;
Matrix3 Basis;
};
IntersectType Boxes_Intersect(const BoxClass & box0, const BoxClass & box1);
IntersectType Boxes_Intersect(const BoxClass & box0, const BoxClass & box1,float dt);
IntersectType BoxesIntersect(float dt, const Box & box0, const Box & box1);

View File

@@ -0,0 +1,113 @@
# Microsoft Developer Studio Project File - Name="collide" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 5.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=collide - 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 "collide.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 "collide.mak" CFG="collide - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "collide - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "collide - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP Scc_ProjName ""$/Commando/Code/Tests/collide", NWHAAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "collide - 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 Ignore_Export_Lib 0
# 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 /I "..\..\wwmath" /I "..\..\Library" /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 /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 library.lib wwmath.lib /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "collide - 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 Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\wwmath" /I "..\..\Library" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /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 /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 libraryd.lib wwmathd.lib /nologo /subsystem:console /debug /machine:I386
!ENDIF
# Begin Target
# Name "collide - Win32 Release"
# Name "collide - Win32 Debug"
# Begin Group "source files"
# PROP Default_Filter "cpp;c"
# Begin Source File
SOURCE=.\col.cpp
# End Source File
# Begin Source File
SOURCE=.\Collide.cpp
# End Source File
# Begin Source File
SOURCE=.\oldcol.cpp
# End Source File
# End Group
# Begin Group "Header files"
# PROP Default_Filter "h"
# Begin Source File
SOURCE=.\col.h
# End Source File
# Begin Source File
SOURCE=.\cvec.h
# End Source File
# End Group
# End Target
# End Project

102
Code/Tests/collide/cvec.h Normal file
View File

@@ -0,0 +1,102 @@
/*
** 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/>.
*/
#ifndef CVEC_H
#define CVEC_H
typedef float Vector[3];
#define FABS(f) (float(fabs(f)))
//---------------------------------------------------------------------------
inline void Add (const Vector u, const Vector v, Vector sum)
{
sum[0] = u[0] + v[0];
sum[1] = u[1] + v[1];
sum[2] = u[2] + v[2];
}
//---------------------------------------------------------------------------
inline void Sub (const Vector u, const Vector v, Vector diff)
{
diff[0] = u[0] - v[0];
diff[1] = u[1] - v[1];
diff[2] = u[2] - v[2];
}
//---------------------------------------------------------------------------
inline float Dot (const Vector u, const Vector v)
{
return u[0]*v[0] + u[1]*v[1] + u[2]*v[2];
}
//---------------------------------------------------------------------------
inline void ScalarMult (const float scalar, const Vector u, Vector product)
{
product[0] = scalar*u[0];
product[1] = scalar*u[1];
product[2] = scalar*u[2];
}
//---------------------------------------------------------------------------
inline int Invert3x3 (const float a[3][3], float ainv[3][3])
{
// Invert a 3x3 using cofactors. This is about 8 times faster than
// the Numerical Recipes code which uses Gaussian elimination.
ainv[0][0] = a[1][1]*a[2][2]-a[1][2]*a[2][1];
ainv[0][1] = a[0][2]*a[2][1]-a[0][1]*a[2][2];
ainv[0][2] = a[0][1]*a[1][2]-a[0][2]*a[1][1];
ainv[1][0] = a[1][2]*a[2][0]-a[1][0]*a[2][2];
ainv[1][1] = a[0][0]*a[2][2]-a[0][2]*a[2][0];
ainv[1][2] = a[0][2]*a[1][0]-a[0][0]*a[1][2];
ainv[2][0] = a[1][0]*a[2][1]-a[1][1]*a[2][0];
ainv[2][1] = a[0][1]*a[2][0]-a[0][0]*a[2][1];
ainv[2][2] = a[0][0]*a[1][1]-a[0][1]*a[1][0];
float det = a[0][0]*ainv[0][0]+a[0][1]*ainv[1][0]+a[0][2]*ainv[2][0];
if (FABS(det) <= 1e-06f )
return 0;
float invdet = 1.0f/det;
for (int row = 0; row < 3; row++)
for (int col = 0; col < 3; col++)
ainv[row][col] *= invdet;
return 1;
}
//---------------------------------------------------------------------------
inline void MultiplyVM (Vector input, float m[3][3], Vector output)
{
output[0] = input[0]*m[0][0] + input[1]*m[1][0] + input[2]*m[2][0];
output[1] = input[0]*m[0][1] + input[1]*m[1][1] + input[2]*m[2][1];
output[2] = input[0]*m[0][2] + input[1]*m[1][2] + input[2]*m[2][2];
}
//---------------------------------------------------------------------------
inline void MultiplyMM (const float A[3][3], const float B[3][3], float AB[3][3])
{
for (int row = 0; row < 3; row++)
{
for (int col = 0; col < 3; col++)
{
AB[row][col] = 0.0f;
for (int mid = 0; mid < 3; mid++)
AB[row][col] += A[row][mid]*B[mid][col];
}
}
}
#endif

View File

@@ -0,0 +1,261 @@
/*
** 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/>.
*/
#include "col.h"
// The eight box vertices of the box at time zero are
// center+extent[i]*basis[i]
// center-extent[i]*basis[i]
// for i = 0,1,2,3. The vertices after a time step of dt are
// center+dt*velocity+extent[i]*basis[i]
// center+dt*velocity-extent[i]*basis[i]
// for i = 0,1,2,3.
//---------------------------------------------------------------------------
IntersectType BoxesIntersect (float dt, const Box& box0, const Box& box1)
{
// Comments indicate where additional speed is gained for orthonormal bases
// for both boxes. If a box is known to be flat (a[i] = 0 for some i OR
// b[j] = 0 for some j), then more terms can be eliminated.
const Vector* A = box0.basis;
const Vector* B = box1.basis;
const float* a = box0.extent;
const float* b = box1.extent;
// memoized values for Dot(A[i],A[j]), Dot(A[i],B[j]), Dot(B[i],B[j])
float AA[3][3], AB[3][3], BB[3][3];
// calculate difference of centers
Vector C, V;
Sub(box1.center,box0.center,C);
Sub(box1.velocity,box0.velocity,V);
float ra, rb, rsum, u0, u1;
// L = A0
AA[0][0] = Dot(A[0],A[0]); // = 1 for orthonormal basis
AA[0][1] = Dot(A[0],A[1]); // = 0 for orthonormal basis
AA[0][2] = Dot(A[0],A[2]); // = 0 for orthonormal basis
AB[0][0] = Dot(A[0],B[0]);
AB[0][1] = Dot(A[0],B[1]);
AB[0][2] = Dot(A[0],B[2]);
ra = FABS(a[0]*AA[0][0])+FABS(a[1]*AA[0][1])+FABS(a[2]*AA[0][2]);
// = FABS(a[0]) for orthonormal basis
rb = FABS(b[0]*AB[0][0])+FABS(b[1]*AB[0][1])+FABS(b[2]*AB[0][2]);
rsum = ra+rb;
u0 = Dot(C,A[0]);
u1 = u0+dt*Dot(V,A[0]);
if ((u0 > rsum && u1 > rsum) || (u0 < -rsum && u1 < -rsum) )
return itA0;
// L = A1
AA[1][1] = Dot(A[1],A[1]); // = 1 for orthonormal basis
AA[1][2] = Dot(A[1],A[2]); // = 0 for orthonormal basis
AB[1][0] = Dot(A[1],B[0]);
AB[1][1] = Dot(A[1],B[1]);
AB[1][2] = Dot(A[1],B[2]);
ra = FABS(a[0]*AA[0][1])+FABS(a[1]*AA[1][1])+FABS(a[2]*AA[1][2]);
// = FABS(a[1]) for orthonormal basis
rb = FABS(b[0]*AB[1][0])+FABS(b[1]*AB[1][1])+FABS(b[2]*AB[1][2]);
rsum = ra+rb;
u0 = Dot(C,A[1]);
u1 = u0+dt*Dot(V,A[1]);
if ((u0 > rsum && u1 > rsum) || (u0 < -rsum && u1 < -rsum) )
return itA1;
// L = A2
AA[2][2] = Dot(A[2],A[2]); // = 1 for orthonormal basis
AB[2][0] = Dot(A[2],B[0]);
AB[2][1] = Dot(A[2],B[1]);
AB[2][2] = Dot(A[2],B[2]);
ra = FABS(a[0]*AA[0][2])+FABS(a[1]*AA[1][2])+FABS(a[2]*AA[2][2]);
// = FABS(a[2]) for orthonormal basis
rb = FABS(b[0]*AB[2][0])+FABS(b[1]*AB[2][1])+FABS(b[2]*AB[2][2]);
rsum = ra+rb;
u0 = Dot(C,A[2]);
u1 = u0+dt*Dot(V,A[2]);
if ((u0 > rsum && u1 > rsum) || (u0 < -rsum && u1 < -rsum) )
return itA2;
// L = B0
BB[0][0] = Dot(B[0],B[0]); // = 1 for orthonormal basis
BB[0][1] = Dot(B[0],B[1]); // = 0 for orthonormal basis
BB[0][2] = Dot(B[0],B[2]); // = 0 for orthonormal basis
ra = FABS(a[0]*AB[0][0])+FABS(a[1]*AB[1][0])+FABS(a[2]*AB[2][0]);
rb = FABS(b[0]*BB[0][0])+FABS(b[1]*BB[0][1])+FABS(b[2]*BB[0][2]);
// = FABS(b[0]) for orthonormal basis
rsum = ra+rb;
u0 = Dot(C,B[0]);
u1 = u0+dt*Dot(V,B[0]);
if ((u0 > rsum && u1 > rsum) || (u0 < -rsum && u1 < -rsum) )
return itB0;
// L = B1
BB[1][1] = Dot(B[1],B[1]); // = 1 for orthonormal basis
BB[1][2] = Dot(B[1],B[2]); // = 0 for orthonormal basis
ra = FABS(a[0]*AB[0][1])+FABS(a[1]*AB[1][1])+FABS(a[2]*AB[2][1]);
rb = FABS(b[0]*BB[0][1])+FABS(b[1]*BB[1][1])+FABS(b[2]*BB[1][2]);
// = FABS(b[1]) for orthonormal basis
rsum = ra+rb;
u0 = Dot(C,B[1]);
u1 = u0+dt*Dot(V,B[1]);
if ((u0 > rsum && u1 > rsum) || (u0 < -rsum && u1 < -rsum) )
return itB1;
// L = B2
BB[2][2] = Dot(B[2],B[2]); // = 1 for orthonormal basis
ra = FABS(a[0]*AB[0][2])+FABS(a[1]*AB[1][2])+FABS(a[2]*AB[2][2]);
rb = FABS(b[0]*BB[0][2])+FABS(b[1]*BB[1][2])+FABS(b[2]*BB[2][2]);
// = FABS(b[2]) for orthonormal basis
rsum = ra+rb;
u0 = Dot(C,B[2]);
u1 = u0+dt*Dot(V,B[2]);
if ((u0 > rsum && u1 > rsum) || (u0 < -rsum && u1 < -rsum) )
return itB2;
// check separating axes which are cross products of box edges
float Ainv[3][3], coeff[3][3];
Invert3x3(A,Ainv);
// Ainv = Transpose(A) for orthonormal basis, no need to invert
MultiplyMM(B,Ainv,coeff);
// coeff[i][j] = AB[j][i] for orthonormal basis, no need to multiply
// memoize minors of coefficient matrix
float minor[3][3];
// difference of centers in A-basis
Vector d0, d1, product;
MultiplyVM(C,Ainv,d0); // Ainv = Transpose(A) for orthonormal basis
MultiplyVM(V,Ainv,d1); // Ainv = Transpose(A) for orthonormal basis
ScalarMult(dt,d1,product);
Add(d0,product,d1);
// L = A0xB0
minor[0][1] = coeff[0][1]*coeff[2][2]-coeff[2][1]*coeff[0][2];
// = -coeff[1][0] for orthonormal bases
minor[0][2] = coeff[0][1]*coeff[1][2]-coeff[1][1]*coeff[0][2];
// = +coeff[2][0] for orthonormal bases
ra = FABS(a[1]*coeff[0][2])+FABS(a[2]*coeff[0][1]);
rb = FABS(b[1]*minor[0][2])+FABS(b[2]*minor[0][1]);
// = FABS(b[1]*coeff[2][0])+FABS(b[2]*coeff[1][0]) for orthonormal bases
rsum = ra+rb;
u0 = d0[2]*coeff[1][0]-d0[1]*coeff[2][0];
u1 = d1[2]*coeff[1][0]-d1[1]*coeff[2][0];
if ((u0 > rsum && u1 > rsum) || (u0 < -rsum && u1 < -rsum) )
return itA0B0;
// L = A0xB1
minor[0][0] = coeff[1][1]*coeff[2][2]-coeff[2][1]*coeff[1][2];
// = +coeff[0][0] for orthonormal bases
ra = FABS(a[1]*coeff[1][2])+FABS(a[2]*coeff[1][1]);
rb = FABS(b[0]*minor[0][2])+FABS(b[2]*minor[0][0]);
// = FABS(b[0]*coeff[2][0])+FABS(b[2]*coeff[0][0]) for orthonormal bases
rsum = ra+rb;
u0 = d0[2]*coeff[1][1]-d0[1]*coeff[1][2];
u1 = d1[2]*coeff[1][1]-d1[1]*coeff[1][2];
if ((u0 > rsum && u1 > rsum) || (u0 < -rsum && u1 < -rsum) )
return itA0B1;
// L = A0xB2
ra = FABS(a[1]*coeff[2][2])+FABS(a[2]*coeff[2][1]);
rb = FABS(b[0]*minor[0][1])+FABS(b[1]*minor[0][0]);
// = FABS(b[0]*coeff[1][0])+FABS(b[1]*coeff[0][0]) for orthonormal bases
rsum = ra+rb;
u0 = d0[2]*coeff[2][1]-d0[1]*coeff[2][2];
u1 = d1[2]*coeff[2][1]-d1[1]*coeff[2][2];
if ((u0 > rsum && u1 > rsum) || (u0 < -rsum && u1 < -rsum) )
return itA0B2;
// L = A1xB0
minor[1][1] = coeff[0][0]*coeff[2][2]-coeff[2][0]*coeff[0][2];
// = +coeff[1][1] for orthonormal bases
minor[1][2] = coeff[0][0]*coeff[1][2]-coeff[1][0]*coeff[0][2];
// = -coeff[2][1] for orthonormal bases
ra = FABS(a[0]*coeff[0][2])+FABS(a[2]*coeff[0][0]);
rb = FABS(b[1]*minor[1][2])+FABS(b[2]*minor[1][1]);
// = FABS(b[1]*coeff[2][1])+FABS(b[2]*coeff[1][1]) for orthonormal bases
rsum = ra+rb;
u0 = d0[0]*coeff[0][2]-d0[2]*coeff[0][0];
u1 = d1[0]*coeff[0][2]-d1[2]*coeff[0][0];
if ((u0 > rsum && u1 > rsum) || (u0 < -rsum && u1 < -rsum) )
return itA1B0;
// L = A1xB1
minor[1][0] = coeff[1][0]*coeff[2][2]-coeff[2][0]*coeff[1][2];
// = -coeff[0][1] for orthonormal bases
ra = FABS(a[0]*coeff[1][2])+FABS(a[2]*coeff[1][0]);
rb = FABS(b[0]*minor[1][2])+FABS(b[2]*minor[1][0]);
// = FABS(b[0]*coeff[2][1])+FABS(b[2]*coeff[0][1]) for orthonormal bases
rsum = ra+rb;
u0 = d0[0]*coeff[1][2]-d0[2]*coeff[1][0];
u1 = d1[0]*coeff[1][2]-d1[2]*coeff[1][0];
if ((u0 > rsum && u1 > rsum) || (u0 < -rsum && u1 < -rsum) )
return itA1B1;
// L = A1xB2
ra = FABS(a[0]*coeff[2][2])+FABS(a[2]*coeff[2][0]);
rb = FABS(b[0]*minor[1][1])+FABS(b[1]*minor[1][0]);
// = FABS(b[0]*coeff[1][1])+FABS(b[1]*coeff[0][1]) for orthonormal bases
rsum = ra+rb;
u0 = d0[0]*coeff[2][2]-d0[2]*coeff[2][0];
u1 = d1[0]*coeff[2][2]-d1[2]*coeff[2][0];
if ((u0 > rsum && u1 > rsum) || (u0 < -rsum && u1 < -rsum) )
return itA1B2;
// L = A2xB0
minor[2][1] = coeff[0][0]*coeff[2][1]-coeff[2][0]*coeff[0][1];
// = -coeff[2][1] for orthonormal bases
minor[2][2] = coeff[0][0]*coeff[1][1]-coeff[1][0]*coeff[0][1];
// = +coeff[2][2] for orthonormal bases
ra = FABS(a[0]*coeff[0][1])+FABS(a[1]*coeff[0][0]);
rb = FABS(b[1]*minor[2][2])+FABS(b[2]*minor[2][1]);
// = FABS(b[1]*coeff[2][2])+FABS(b[2]*coeff[1][2]) for orthonormal bases
rsum = ra+rb;
u0 = d0[1]*coeff[0][0]-d0[0]*coeff[0][1];
u1 = d1[1]*coeff[0][0]-d1[0]*coeff[0][1];
if ((u0 > rsum && u1 > rsum) || (u0 < -rsum && u1 < -rsum) )
return itA2B0;
// L = A2xB1
minor[2][0] = coeff[1][0]*coeff[2][1]-coeff[2][0]*coeff[1][1];
// = +coeff[0][2] for orthonormal bases
ra = FABS(a[0]*coeff[1][1])+FABS(a[1]*coeff[1][0]);
rb = FABS(b[0]*minor[2][2])+FABS(b[2]*minor[2][0]);
// = FABS(b[0]*coeff[2][2])+FABS(b[2]*coeff[0][2]) for orthonormal bases
rsum = ra+rb;
u0 = d0[1]*coeff[1][0]-d0[0]*coeff[1][1];
u1 = d1[1]*coeff[1][0]-d1[0]*coeff[1][1];
if ((u0 > rsum && u1 > rsum) || (u0 < -rsum && u1 < -rsum) )
return itA2B1;
// L = A2xB2
ra = FABS(a[0]*coeff[2][1])+FABS(a[1]*coeff[2][0]);
rb = FABS(b[0]*minor[2][1])+FABS(b[1]*minor[2][0]);
// = FABS(b[0]*coeff[1][2])+FABS(b[1]*coeff[0][2]) for orthonormal bases
rsum = ra+rb;
u0 = d0[1]*coeff[2][0]-d0[0]*coeff[2][1];
u1 = d1[1]*coeff[2][0]-d1[0]*coeff[2][1];
if ((u0 > rsum && u1 > rsum) || (u0 < -rsum && u1 < -rsum) )
return itA2B2;
return itIntersects;
}

View File

@@ -0,0 +1,48 @@
/*
** 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/>.
*/
/* $Header: /Commando/Code/Tests/mathtest/P_timer.cpp 2 7/22/97 1:14p Greg_h $ */
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Voxel Technology *
* *
* File Name : P_TIMER.CPP *
* *
* Programmer : Greg Hjelstrom *
* *
* Start Date : 02/24/97 *
* *
* Last Update : February 24, 1997 [GH] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "p_timer.h"
#ifndef __WATCOMC__
unsigned Get_CPU_Clock ( void )
{
__asm {
_emit 0x0f
_emit 0x31
}
}
#endif

Some files were not shown because too many files have changed in this diff Show More