Initial commit of Command & Conquer Renegade source code.
341
Code/Tests/Bandy/bandy.cpp
Normal 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
@@ -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
|
||||
29
Code/Tests/Bandy/bandy.dsw
Normal 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>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
109
Code/Tests/BitPackTest/BitPackTest.dsp
Normal 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
|
||||
373
Code/Tests/BitPackTest/Code/BitPacker.cpp
Normal 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;
|
||||
}
|
||||
80
Code/Tests/BitPackTest/Code/BitPacker.h
Normal 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_
|
||||
85
Code/Tests/BitPackTest/Code/Main.cpp
Normal 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;
|
||||
}
|
||||
455
Code/Tests/BitPackTest/Code/TypeEncoder.cpp
Normal 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;
|
||||
}
|
||||
106
Code/Tests/BitPackTest/Code/TypeEncoder.h
Normal 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_
|
||||
95
Code/Tests/BitPackTest/Code/UTypes.h
Normal 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_
|
||||
58
Code/Tests/LocalHost/LocalHost.dsp
Normal 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
|
||||
29
Code/Tests/LocalHost/LocalHost.dsw
Normal 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>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
117
Code/Tests/LocalHost/main.cpp
Normal 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);
|
||||
}
|
||||
388
Code/Tests/MeshTest/WINMAIN.CPP
Normal 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);
|
||||
}
|
||||
|
||||
46
Code/Tests/MeshTest/WINMAIN.H
Normal 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
|
||||
50
Code/Tests/MeshTest/_GLOBALS.CPP
Normal 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];
|
||||
|
||||
|
||||
|
||||
75
Code/Tests/MeshTest/_GLOBALS.H
Normal 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
|
||||
40
Code/Tests/MeshTest/_scenes.cpp
Normal 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;
|
||||
47
Code/Tests/MeshTest/_scenes.h
Normal 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
|
||||
67
Code/Tests/MeshTest/_viewpt.cpp
Normal 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;
|
||||
|
||||
72
Code/Tests/MeshTest/_viewpt.h
Normal 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
|
||||
56
Code/Tests/MeshTest/init.cpp
Normal 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;
|
||||
}
|
||||
|
||||
43
Code/Tests/MeshTest/init.h
Normal 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
|
||||
503
Code/Tests/MeshTest/mainloop.cpp
Normal 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
|
||||
}
|
||||
43
Code/Tests/MeshTest/mainloop.h
Normal 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
|
||||
203
Code/Tests/MeshTest/meshtest.dsp
Normal 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
|
||||
47
Code/Tests/MeshTest/shutdown.cpp
Normal 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();
|
||||
}
|
||||
|
||||
46
Code/Tests/MeshTest/shutdown.h
Normal 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
|
||||
228
Code/Tests/PhysTest/DataView.cpp
Normal 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;
|
||||
}
|
||||
|
||||
113
Code/Tests/PhysTest/DataView.h
Normal 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_)
|
||||
23
Code/Tests/PhysTest/Globals.cpp
Normal 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;
|
||||
707
Code/Tests/PhysTest/GraphicView.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
139
Code/Tests/PhysTest/GraphicView.h
Normal 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_)
|
||||
140
Code/Tests/PhysTest/InertiaDialog.cpp
Normal 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);
|
||||
}
|
||||
74
Code/Tests/PhysTest/InertiaDialog.h
Normal 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_)
|
||||
1001
Code/Tests/PhysTest/MainFrm.cpp
Normal file
176
Code/Tests/PhysTest/MainFrm.h
Normal 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_)
|
||||
119
Code/Tests/PhysTest/MotorVehicleDialog.cpp
Normal 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();
|
||||
}
|
||||
73
Code/Tests/PhysTest/MotorVehicleDialog.h
Normal 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_)
|
||||
132
Code/Tests/PhysTest/MotorcycleDialog.cpp
Normal 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();
|
||||
}
|
||||
75
Code/Tests/PhysTest/MotorcycleDialog.h
Normal 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_)
|
||||
423
Code/Tests/PhysTest/PhysTest.cpp
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
264
Code/Tests/PhysTest/PhysTest.dsp
Normal 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
|
||||
66
Code/Tests/PhysTest/PhysTest.h
Normal 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_)
|
||||
754
Code/Tests/PhysTest/PhysTest.rc
Normal 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
|
||||
|
||||
405
Code/Tests/PhysTest/PhysTestDoc.cpp
Normal 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;
|
||||
}
|
||||
|
||||
101
Code/Tests/PhysTest/PhysTestDoc.h
Normal 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_)
|
||||
75
Code/Tests/PhysTest/PhysTestSaveSystem.cpp
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
90
Code/Tests/PhysTest/PhysTestSaveSystem.h
Normal 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
|
||||
135
Code/Tests/PhysTest/PhysicsConstantsDialog.cpp
Normal 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);
|
||||
}
|
||||
71
Code/Tests/PhysTest/PhysicsConstantsDialog.h
Normal 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_)
|
||||
192
Code/Tests/PhysTest/RbodyPropertiesDialog.cpp
Normal 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);
|
||||
}
|
||||
80
Code/Tests/PhysTest/RbodyPropertiesDialog.h
Normal 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_)
|
||||
98
Code/Tests/PhysTest/RenderDeviceDialog.cpp
Normal 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();
|
||||
}
|
||||
|
||||
65
Code/Tests/PhysTest/RenderDeviceDialog.h
Normal 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_)
|
||||
26
Code/Tests/PhysTest/StdAfx.cpp
Normal 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"
|
||||
|
||||
|
||||
|
||||
45
Code/Tests/PhysTest/StdAfx.h
Normal 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_)
|
||||
234
Code/Tests/PhysTest/VJoyDialog.cpp
Normal 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();
|
||||
}
|
||||
72
Code/Tests/PhysTest/VJoyDialog.h
Normal 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_)
|
||||
146
Code/Tests/PhysTest/WheeledVehicleDialog.cpp
Normal 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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
75
Code/Tests/PhysTest/WheeledVehicleDialog.h
Normal 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_)
|
||||
81
Code/Tests/PhysTest/lev_file.h
Normal 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
|
||||
|
||||
BIN
Code/Tests/PhysTest/res/Axes.w3d
Normal file
BIN
Code/Tests/PhysTest/res/PhysTest.ico
Normal file
|
After Width: | Height: | Size: 766 B |
13
Code/Tests/PhysTest/res/PhysTest.rc2
Normal 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...
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
BIN
Code/Tests/PhysTest/res/PhysTestDoc.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Code/Tests/PhysTest/res/Point.w3d
Normal file
BIN
Code/Tests/PhysTest/res/Toolbar.bmp
Normal file
|
After Width: | Height: | Size: 4.6 KiB |
BIN
Code/Tests/PhysTest/res/toolbar1.bmp
Normal file
|
After Width: | Height: | Size: 5.5 KiB |
125
Code/Tests/PhysTest/resource.h
Normal 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
|
||||
97
Code/Tests/SplineTest/CardinalDialog.cpp
Normal 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);
|
||||
}
|
||||
73
Code/Tests/SplineTest/CardinalDialog.h
Normal 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_)
|
||||
39
Code/Tests/SplineTest/CurvePoints.cpp
Normal 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 },
|
||||
};
|
||||
25
Code/Tests/SplineTest/CurvePoints.h
Normal 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
|
||||
272
Code/Tests/SplineTest/MainFrm.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
89
Code/Tests/SplineTest/MainFrm.h
Normal 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_)
|
||||
170
Code/Tests/SplineTest/SplineTest.cpp
Normal 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
|
||||
|
||||
196
Code/Tests/SplineTest/SplineTest.dsp
Normal 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
|
||||
67
Code/Tests/SplineTest/SplineTest.h
Normal 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_)
|
||||
408
Code/Tests/SplineTest/SplineTest.rc
Normal 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
|
||||
|
||||
279
Code/Tests/SplineTest/SplineTestDoc.cpp
Normal 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 ;
|
||||
}
|
||||
103
Code/Tests/SplineTest/SplineTestDoc.h
Normal 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_)
|
||||
317
Code/Tests/SplineTest/SplineTestView.cpp
Normal 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;
|
||||
}
|
||||
93
Code/Tests/SplineTest/SplineTestView.h
Normal 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_)
|
||||
26
Code/Tests/SplineTest/StdAfx.cpp
Normal 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"
|
||||
|
||||
|
||||
|
||||
45
Code/Tests/SplineTest/StdAfx.h
Normal 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_)
|
||||
105
Code/Tests/SplineTest/TCBDialog.cpp
Normal 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);
|
||||
}
|
||||
74
Code/Tests/SplineTest/TCBDialog.h
Normal 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_)
|
||||
BIN
Code/Tests/SplineTest/res/SplineTest.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
13
Code/Tests/SplineTest/res/SplineTest.rc2
Normal 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...
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
BIN
Code/Tests/SplineTest/res/SplineTestDoc.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Code/Tests/SplineTest/res/Toolbar.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
33
Code/Tests/SplineTest/resource.h
Normal 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
|
||||
316
Code/Tests/collide/Collide.cpp
Normal 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
@@ -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
@@ -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);
|
||||
113
Code/Tests/collide/collide.dsp
Normal 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
@@ -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
|
||||
261
Code/Tests/collide/oldcol.cpp
Normal 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;
|
||||
}
|
||||
48
Code/Tests/mathtest/P_timer.cpp
Normal 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
|
||||