Initial commit of Command & Conquer Renegade source code.

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

View File

@@ -0,0 +1,228 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// DataView.cpp : implementation file
//
#include "stdafx.h"
#include "phystest.h"
#include "DataView.h"
#include "PhysTestDoc.h"
#include "assetmgr.h"
#include "rendobj.h"
#include "pscene.h"
#include "phys.h"
#include "physlist.h"
#include "mainfrm.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDataView
IMPLEMENT_DYNCREATE(CDataView, CTreeView)
CDataView::CDataView() :
ModelsRoot(NULL),
InstancesRoot(NULL)
{
}
CDataView::~CDataView()
{
}
void CDataView::Rebuild_Tree(void)
{
// Turn off repainting
GetTreeCtrl ().SetRedraw (FALSE);
// wipe clean
GetTreeCtrl().DeleteItem(ModelsRoot);
GetTreeCtrl().DeleteItem(InstancesRoot);
ModelsRoot = GetTreeCtrl().InsertItem("Models", NULL, NULL);
InstancesRoot = GetTreeCtrl().InsertItem ("Physics Object Instances", NULL, NULL);
// MODELS
// Get an iterator from the asset manager that we can
// use to enumerate the currently loaded assets
RenderObjIterator * obj_iterator = WW3DAssetManager::Get_Instance()->Create_Render_Obj_Iterator();
ASSERT(obj_iterator);
if (obj_iterator) {
// Loop through all the assets in the manager
for (obj_iterator->First (); !obj_iterator->Is_Done(); obj_iterator->Next()) {
// If the asset is an HLOD, add it to our possible model list
if (obj_iterator->Current_Item_Class_ID() == RenderObjClass::CLASSID_HLOD) {
const char * model_name = obj_iterator->Current_Item_Name();
// Add this entry to the tree
HTREEITEM hItem = GetTreeCtrl().InsertItem(model_name,NULL,0,ModelsRoot,TVI_SORT);
ASSERT (hItem != NULL);
ItemInfoClass * item_info = new ItemInfoClass(model_name,ItemInfoClass::MODEL);
GetTreeCtrl().SetItemData(hItem, (ULONG)item_info);
}
}
// Free the enumerator object we created earlier
WW3DAssetManager::Get_Instance()->Release_Render_Obj_Iterator(obj_iterator);
}
// PHYSICS OBJECT INSTANCES
CPhysTestDoc * doc = (CPhysTestDoc *)GetDocument();
RefPhysListIterator phys_iterator = PhysicsSceneClass::Get_Instance()->Get_Dynamic_Object_Iterator();
for (phys_iterator.First();!phys_iterator.Is_Done();phys_iterator.Next()) {
const char * instance_name = phys_iterator.Peek_Obj()->Get_Name();
if (instance_name != NULL) {
// Add this entry to the tree
HTREEITEM hItem = GetTreeCtrl().InsertItem(instance_name,NULL,0,InstancesRoot,TVI_SORT);
ASSERT (hItem != NULL);
ItemInfoClass * item_info = new ItemInfoClass(instance_name,ItemInfoClass::INSTANCE);
item_info->Instance = phys_iterator.Peek_Obj();
GetTreeCtrl().SetItemData(hItem, (ULONG)item_info);
}
}
// Turn;repainting back on and force a redraw
GetTreeCtrl().SetRedraw (TRUE);
Invalidate(FALSE);
UpdateWindow();
}
ItemInfoClass * CDataView::Get_Selected_Item(void)
{
ItemInfoClass * item_info = NULL;
// Get the currently selected node from the tree control
HTREEITEM htree_item = GetTreeCtrl ().GetSelectedItem ();
if (htree_item != NULL) {
// Get the data associated with this item
item_info = (ItemInfoClass *)GetTreeCtrl().GetItemData(htree_item);
}
// Return the asset information associated with the current item
return item_info;
}
void CDataView::Save(ChunkSaveClass & csave)
{
}
void CDataView::Load(ChunkLoadClass & cload)
{
}
BEGIN_MESSAGE_MAP(CDataView, CTreeView)
//{{AFX_MSG_MAP(CDataView)
ON_WM_CREATE()
ON_NOTIFY_REFLECT(TVN_DELETEITEM, OnDeleteitem)
ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelchanged)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDataView drawing
void CDataView::OnDraw(CDC* pDC)
{
CDocument* pDoc = GetDocument();
// TODO: add draw code here
}
/////////////////////////////////////////////////////////////////////////////
// CDataView diagnostics
#ifdef _DEBUG
void CDataView::AssertValid() const
{
CTreeView::AssertValid();
}
void CDataView::Dump(CDumpContext& dc) const
{
CTreeView::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CDataView message handlers
BOOL CDataView::PreCreateWindow(CREATESTRUCT& cs)
{
// Modify the style bits for the window so it will
// have buttons and lines between nodes.
cs.style |= TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_SHOWSELALWAYS;
return CTreeView::PreCreateWindow(cs);
}
int CDataView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CTreeView::OnCreate(lpCreateStruct) == -1)
return -1;
ModelsRoot = GetTreeCtrl().InsertItem("Models", NULL, NULL);
InstancesRoot = GetTreeCtrl().InsertItem ("Physics Object Instances", NULL, NULL);
return 0;
}
void CDataView::OnDeleteitem(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
ItemInfoClass * item_info = (ItemInfoClass *)pNMTreeView->itemOld.lParam;
// Free the asset information object
if (item_info != NULL) {
delete item_info;
}
// Reset the data associated with this entry
GetTreeCtrl().SetItemData(pNMTreeView->itemOld.hItem, NULL);
*pResult = 0;
}
void CDataView::OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult)
{
// just tell the main window that the selection changed so it
// can link/unlink the virtual joystick.
((CMainFrame *)::AfxGetMainWnd())->Notify_Selection_Changed();
*pResult = 0;
}

View File

@@ -0,0 +1,113 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined(AFX_DATAVIEW_H__A9B6C2E1_E61E_11D2_802E_0040056350C8__INCLUDED_)
#define AFX_DATAVIEW_H__A9B6C2E1_E61E_11D2_802E_0040056350C8__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// DataView.h : header file
//
#include "AfxCView.H"
class PhysClass;
class ChunkSaveClass;
class ChunkLoadClass;
/////////////////////////////////////////////////////////////////////////////
//
// ItemInfoClass - stores info about all of the items in the CDataView
//
class ItemInfoClass
{
public:
enum { MODEL = 0, INSTANCE };
ItemInfoClass(const char * name,int type) : Instance(NULL) { Name = strdup(name); Type = type; }
~ItemInfoClass(void) { if (Name) free(Name); }
char * Name;
int Type;
PhysClass * Instance;
};
/////////////////////////////////////////////////////////////////////////////
//
// CDataView view
//
class CDataView : public CTreeView
{
protected:
CDataView(); // protected constructor used by dynamic creation
DECLARE_DYNCREATE(CDataView)
// Attributes
public:
// Operations
public:
void Rebuild_Tree(void);
ItemInfoClass * Get_Selected_Item(void);
void Save(ChunkSaveClass & csave);
void Load(ChunkLoadClass & cload);
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CDataView)
protected:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
//}}AFX_VIRTUAL
// Implementation
protected:
virtual ~CDataView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
///////////////////////////////////////////////////////
//
// Private member data
//
HTREEITEM ModelsRoot;
HTREEITEM InstancesRoot;
// Generated message map functions
protected:
//{{AFX_MSG(CDataView)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnDeleteitem(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_DATAVIEW_H__A9B6C2E1_E61E_11D2_802E_0040056350C8__INCLUDED_)

View File

@@ -0,0 +1,23 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "stdafx.h"
#include "assetmgr.h"
WW3DAssetManager _TheAssetManager;

View File

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

View File

@@ -0,0 +1,139 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// GraphicView.h : interface of the CGraphicView class
//
/////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_PHYSTESTVIEW_H__616293EC_E4F0_11D2_802E_0040056350C8__INCLUDED_)
#define AFX_PHYSTESTVIEW_H__616293EC_E4F0_11D2_802E_0040056350C8__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CPhysTestDoc;
class RenderObjClass;
class CameraClass;
class SceneClass;
class ChunkSaveClass;
class ChunkLoadClass;
class CGraphicView : public CView
{
protected: // create from serialization only
CGraphicView();
DECLARE_DYNCREATE(CGraphicView)
// Attributes
public:
CPhysTestDoc* GetDocument();
void Save(ChunkSaveClass & csave);
void Load(ChunkLoadClass & cload);
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CGraphicView)
public:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
virtual void OnInitialUpdate();
protected:
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
//}}AFX_VIRTUAL
// Implementation
public:
enum {
CAMERA_FLY = 0,
CAMERA_FOLLOW,
CAMERA_TETHER,
CAMERA_RIGID_TETHER,
};
virtual ~CGraphicView();
BOOL Initialize_WW3D(int device,int bits);
bool Is_WW3D_Initialized(void) { return Initialized; }
void Repaint_View(void);
void Set_Active(bool onoff);
bool Is_Simulation_Enabled(void) { return RunSimulation; }
void Enable_Simulation(bool onoff) { RunSimulation = onoff; }
bool Is_Collision_Box_Display_Enabled(void);
void Enable_Collision_Box_Display(bool onoff);
void Set_Camera_Mode(int mode) { CameraMode = mode; }
int Get_Camera_Mode(void) { return CameraMode; }
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
bool Initialized;
bool Active;
bool RunSimulation;
bool DisplayBoxes;
int CameraMode;
CameraClass * Camera;
int TimerID;
bool LMouseDown;
bool RMouseDown;
CPoint LastPoint;
CameraClass * PipCamera;
SceneClass * PipScene;
RenderObjClass * Axes;
void Timestep(void);
void Update_Pip_Camera(void);
// Generated message map functions
protected:
//{{AFX_MSG(CGraphicView)
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnDestroy();
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
#ifndef _DEBUG // debug version in PhysTestView.cpp
inline CPhysTestDoc* CGraphicView::GetDocument()
{ return (CPhysTestDoc*)m_pDocument; }
#endif
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_PHYSTESTVIEW_H__616293EC_E4F0_11D2_802E_0040056350C8__INCLUDED_)

View File

@@ -0,0 +1,140 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// InertiaDialog.cpp : implementation file
//
#include "stdafx.h"
#include "phystest.h"
#include "InertiaDialog.h"
#include "rbody.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
const int MIN_IBODY = 0;
const int MAX_IBODY = 255;
/////////////////////////////////////////////////////////////////////////////
// CInertiaDialog dialog
CInertiaDialog::CInertiaDialog(CWnd* pParent,RigidBodyClass * obj) :
CDialog(CInertiaDialog::IDD, pParent),
Object(obj)
{
//{{AFX_DATA_INIT(CInertiaDialog)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
ASSERT(Object != NULL);
}
void CInertiaDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CInertiaDialog)
DDX_Control(pDX, IDC_IBODYZ_SPIN, m_IBodyZSpin);
DDX_Control(pDX, IDC_IBODYY_SPIN, m_IBodyYSpin);
DDX_Control(pDX, IDC_IBODYX_SPIN, m_IBodyXSpin);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CInertiaDialog, CDialog)
//{{AFX_MSG_MAP(CInertiaDialog)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CInertiaDialog message handlers
BOOL CInertiaDialog::OnInitDialog()
{
CDialog::OnInitDialog();
m_IBodyXSpin.SetRange(MIN_IBODY * 100,MAX_IBODY * 100);
m_IBodyYSpin.SetRange(MIN_IBODY * 100,MAX_IBODY * 100);
m_IBodyZSpin.SetRange(MIN_IBODY * 100,MAX_IBODY * 100);
Matrix3 ibody;
Object->Get_Inertia(&ibody);
m_IBodyXSpin.SetPos(ibody[0][0] * 100);
m_IBodyYSpin.SetPos(ibody[1][1] * 100);
m_IBodyZSpin.SetPos(ibody[2][2] * 100);
SetDlgItemFloat(IDC_IBODYX_EDIT,ibody[0][0]);
SetDlgItemFloat(IDC_IBODYY_EDIT,ibody[1][1]);
SetDlgItemFloat(IDC_IBODYZ_EDIT,ibody[2][2]);
return TRUE;
}
BOOL CInertiaDialog::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
// make the spin controls work...
switch(wParam)
{
case IDC_IBODYX_SPIN:
case IDC_IBODYY_SPIN:
case IDC_IBODYZ_SPIN:
LPNMUPDOWN lpnmud = (LPNMUPDOWN) lParam;
if (lpnmud->hdr.code == UDN_DELTAPOS) {
HWND hwnd = (HWND)SendDlgItemMessage(LOWORD(wParam),UDM_GETBUDDY);
float curval = GetDlgItemFloat(GetWindowLong(hwnd,GWL_ID));
curval += (float)lpnmud->iDelta / 100.0f;
SetDlgItemFloat(GetWindowLong(hwnd,GWL_ID), curval);
}
break;
}
return CDialog::OnNotify(wParam, lParam, pResult);
}
void CInertiaDialog::OnOK()
{
Matrix3 ibody(1);
ibody[0][0] = GetDlgItemFloat(IDC_IBODYX_EDIT);
ibody[1][1] = GetDlgItemFloat(IDC_IBODYY_EDIT);
ibody[2][2] = GetDlgItemFloat(IDC_IBODYZ_EDIT);
Object->Set_Inertia(ibody);
CDialog::OnOK();
}
float CInertiaDialog::GetDlgItemFloat(int controlid)
{
CString string;
GetDlgItemText(controlid,string);
return atof(string);
}
void CInertiaDialog::SetDlgItemFloat(int controlid,float val)
{
CString string;
string.Format("%.2f",val);
SetDlgItemText(controlid,string);
}

View File

@@ -0,0 +1,74 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined(AFX_INERTIADIALOG_H__33DD6AC4_E78D_11D2_9BD2_00A0C9988171__INCLUDED_)
#define AFX_INERTIADIALOG_H__33DD6AC4_E78D_11D2_9BD2_00A0C9988171__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// InertiaDialog.h : header file
//
class RigidBodyClass;
/////////////////////////////////////////////////////////////////////////////
// CInertiaDialog dialog
class CInertiaDialog : public CDialog
{
// Construction
public:
CInertiaDialog(CWnd* pParent,RigidBodyClass * obj);
// Dialog Data
//{{AFX_DATA(CInertiaDialog)
enum { IDD = IDD_INERTIA_DIALOG };
CSpinButtonCtrl m_IBodyZSpin;
CSpinButtonCtrl m_IBodyYSpin;
CSpinButtonCtrl m_IBodyXSpin;
//}}AFX_DATA
RigidBodyClass * Object;
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CInertiaDialog)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
//}}AFX_VIRTUAL
// Implementation
protected:
float GetDlgItemFloat(int controlid);
void SetDlgItemFloat(int controlid,float val);
// Generated message map functions
//{{AFX_MSG(CInertiaDialog)
virtual void OnOK();
virtual BOOL OnInitDialog();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_INERTIADIALOG_H__33DD6AC4_E78D_11D2_9BD2_00A0C9988171__INCLUDED_)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,176 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// MainFrm.h : interface of the CMainFrame class
//
/////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_MAINFRM_H__616293E8_E4F0_11D2_802E_0040056350C8__INCLUDED_)
#define AFX_MAINFRM_H__616293E8_E4F0_11D2_802E_0040056350C8__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class Vector3;
class CVJoyDialog;
class PhysClass;
class MoveablePhysClass;
class RigidBodyClass;
class MotorVehicleClass;
class WheeledVehicleClass;
class MotorcycleClass;
class CPhysTestDoc;
class ChunkLoadClass;
class ChunkSaveClass;
class CMainFrame : public CFrameWnd
{
protected: // create from serialization only
CMainFrame();
DECLARE_DYNCREATE(CMainFrame)
// Attributes
protected:
CSplitterWnd Splitter;
CVJoyDialog * VirtualJoystick;
MoveablePhysClass * ControlledObject;
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMainFrame)
public:
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CMainFrame();
CView * Get_Pane(int iRow, int iCol) const { return (CView *)Splitter.GetPane(iRow, iCol); }
void Apply_Impulse(const Vector3 & imp);
void Apply_Couple(const Vector3 & p0,const Vector3 & i0,const Vector3 & p1,const Vector3 & i1);
void Set_Status_Bar_Text(const char * text);
void Notify_Selection_Changed(void);
const char * Peek_Selected_Model(void);
PhysClass * Peek_Selected_Object(void);
MoveablePhysClass * Peek_Selected_MoveablePhysClass(void);
RigidBodyClass * Peek_Selected_RigidBodyClass(void);
MotorVehicleClass * Peek_Selected_MotorVehicleClass(void);
WheeledVehicleClass * Peek_Selected_WheeledVehicleClass(void);
MotorcycleClass * Peek_Selected_MotorcycleClass(void);
void Add_Object(PhysClass * new_obj);
CPhysTestDoc * Get_Document(void);
void Save(ChunkSaveClass & csave);
void Load(ChunkLoadClass & cload);
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
CStatusBar m_wndStatusBar;
CToolBar m_wndToolBar;
CToolBar m_wndImpulseToolBar;
// Generated message map functions
protected:
//{{AFX_MSG(CMainFrame)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnActivateApp(BOOL bActive, HTASK hTask);
afx_msg void OnOptionsRunSimulation();
afx_msg void OnUpdateOptionsRunSimulation(CCmdUI* pCmdUI);
afx_msg void OnOptionsDisplayBoxes();
afx_msg void OnUpdateOptionsDisplayBoxes(CCmdUI* pCmdUI);
afx_msg void OnCreateRigidBody();
afx_msg void OnUpdateImpulseButton(CCmdUI* pCmdUI);
afx_msg void OnCoupleNegx();
afx_msg void OnCoupleNegy();
afx_msg void OnCoupleNegz();
afx_msg void OnCouplePosx();
afx_msg void OnCouplePosy();
afx_msg void OnCouplePosz();
afx_msg void OnImpulseNegx();
afx_msg void OnImpulseNegy();
afx_msg void OnImpulseNegz();
afx_msg void OnImpulsePosx();
afx_msg void OnImpulsePosy();
afx_msg void OnImpulsePosz();
afx_msg void OnViewImpulsetoolbar();
afx_msg void OnUpdateViewImpulsetoolbar(CCmdUI* pCmdUI);
afx_msg void OnProperties();
afx_msg void OnInertia();
afx_msg void OnOptionsPhysicsConstants();
afx_msg void OnFreezeObject();
afx_msg void OnDebugObject();
afx_msg void OnUpdateDebugObject(CCmdUI* pCmdUI);
afx_msg void OnViewVirtualjoystick();
afx_msg void OnUpdateViewVirtualjoystick(CCmdUI* pCmdUI);
afx_msg void OnDestroy();
afx_msg void OnOptionsFilled();
afx_msg void OnUpdateOptionsFilled(CCmdUI* pCmdUI);
afx_msg void OnOptionsPoints();
afx_msg void OnUpdateOptionsPoints(CCmdUI* pCmdUI);
afx_msg void OnOptionsWireframe();
afx_msg void OnUpdateOptionsWireframe(CCmdUI* pCmdUI);
afx_msg void OnMotorProperties();
afx_msg void OnWheelProperties();
afx_msg void OnUpdateWheelProperties(CCmdUI* pCmdUI);
afx_msg void OnUpdateMotorProperties(CCmdUI* pCmdUI);
afx_msg void OnCameraFollow();
afx_msg void OnUpdateCameraFollow(CCmdUI* pCmdUI);
afx_msg void OnCameraFly();
afx_msg void OnUpdateCameraFly(CCmdUI* pCmdUI);
afx_msg void OnCameraTether();
afx_msg void OnUpdateCameraTether(CCmdUI* pCmdUI);
afx_msg void OnCameraRigidTether();
afx_msg void OnUpdateCameraRigidTether(CCmdUI* pCmdUI);
afx_msg void OnCreateWheeledVehicle();
afx_msg void OnUpdateCreateRigidBody(CCmdUI* pCmdUI);
afx_msg void OnUpdateCreateWheeledVehicle(CCmdUI* pCmdUI);
afx_msg void OnUpdateProperties(CCmdUI* pCmdUI);
afx_msg void OnCreateMotorcycle();
afx_msg void OnUpdateCreateMotorcycle(CCmdUI* pCmdUI);
afx_msg void OnMotorcycleProperties();
afx_msg void OnUpdateMotorcycleProperties(CCmdUI* pCmdUI);
afx_msg void OnOptionsRenderDevice();
afx_msg void OnUpdateOptionsRenderDevice(CCmdUI* pCmdUI);
afx_msg void OnFileImportModel();
afx_msg void OnFileImportLev();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_MAINFRM_H__616293E8_E4F0_11D2_802E_0040056350C8__INCLUDED_)

View File

@@ -0,0 +1,119 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// MotorVehicleDialog.cpp : implementation file
//
#include "stdafx.h"
#include "phystest.h"
#include "MotorVehicleDialog.h"
#include "motorvehicle.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
const float MIN_TORQUE = 1.0f;
const float MAX_TORQUE = 10000.0f;
/////////////////////////////////////////////////////////////////////////////
// CMotorVehicleDialog dialog
CMotorVehicleDialog::CMotorVehicleDialog(CWnd* pParent,MotorVehicleClass * obj)
: CDialog(CMotorVehicleDialog::IDD, pParent),
EditedObject(obj)
{
//{{AFX_DATA_INIT(CMotorVehicleDialog)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
void CMotorVehicleDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CMotorVehicleDialog)
DDX_Control(pDX, IDC_MVEHICLE_TORQUE_SPIN, m_TorqueSpin);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CMotorVehicleDialog, CDialog)
//{{AFX_MSG_MAP(CMotorVehicleDialog)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMotorVehicleDialog message handlers
float CMotorVehicleDialog::GetDlgItemFloat(int controlid)
{
CString string;
GetDlgItemText(controlid,string);
return atof(string);
}
void CMotorVehicleDialog::SetDlgItemFloat(int controlid,float val)
{
CString string;
string.Format("%.2f",val);
SetDlgItemText(controlid,string);
}
BOOL CMotorVehicleDialog::OnInitDialog()
{
CDialog::OnInitDialog();
m_TorqueSpin.SetRange(MIN_TORQUE * 100,MAX_TORQUE * 100);
float mt = EditedObject->Get_Max_Engine_Torque();
m_TorqueSpin.SetPos(mt * 100);
SetDlgItemFloat(IDC_MVEHICLE_TORQUE_EDIT,mt);
return TRUE;
}
BOOL CMotorVehicleDialog::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
// make the spin controls work...
switch(wParam)
{
case IDC_MVEHICLE_TORQUE_SPIN:
LPNMUPDOWN lpnmud = (LPNMUPDOWN) lParam;
if (lpnmud->hdr.code == UDN_DELTAPOS) {
HWND hwnd = (HWND)SendDlgItemMessage(LOWORD(wParam),UDM_GETBUDDY);
float curval = GetDlgItemFloat(GetWindowLong(hwnd,GWL_ID));
curval += (float)lpnmud->iDelta / 100.0f;
SetDlgItemFloat(GetWindowLong(hwnd,GWL_ID), curval);
}
break;
}
return CDialog::OnNotify(wParam, lParam, pResult);
}
void CMotorVehicleDialog::OnOK()
{
float mt = GetDlgItemFloat(IDC_MVEHICLE_TORQUE_EDIT);
EditedObject->Set_Max_Engine_Torque(mt);
CDialog::OnOK();
}

View File

@@ -0,0 +1,73 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined(AFX_MOTORVEHICLEDIALOG_H__14B8CCA1_F28E_11D2_9BD8_00A0C9988171__INCLUDED_)
#define AFX_MOTORVEHICLEDIALOG_H__14B8CCA1_F28E_11D2_9BD8_00A0C9988171__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// MotorVehicleDialog.h : header file
//
class MotorVehicleClass;
/////////////////////////////////////////////////////////////////////////////
// CMotorVehicleDialog dialog
class CMotorVehicleDialog : public CDialog
{
// Construction
public:
CMotorVehicleDialog(CWnd* pParent,MotorVehicleClass * obj);
// Dialog Data
//{{AFX_DATA(CMotorVehicleDialog)
enum { IDD = IDD_MOTORVEHICLE_DIALOG };
CSpinButtonCtrl m_TorqueSpin;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMotorVehicleDialog)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
//}}AFX_VIRTUAL
// Implementation
protected:
MotorVehicleClass * EditedObject;
float GetDlgItemFloat(int controlid);
void SetDlgItemFloat(int controlid,float val);
// Generated message map functions
//{{AFX_MSG(CMotorVehicleDialog)
virtual BOOL OnInitDialog();
virtual void OnOK();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_MOTORVEHICLEDIALOG_H__14B8CCA1_F28E_11D2_9BD8_00A0C9988171__INCLUDED_)

View File

@@ -0,0 +1,132 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// MotorcycleDialog.cpp : implementation file
//
#include "stdafx.h"
#include "phystest.h"
#include "MotorcycleDialog.h"
#include "motorcycle.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
const float MIN_K = 0.01f;
const float MAX_K = 100.0f;
/////////////////////////////////////////////////////////////////////////////
// CMotorcycleDialog dialog
CMotorcycleDialog::CMotorcycleDialog(CWnd* pParent,MotorcycleClass * obj)
: CDialog(CMotorcycleDialog::IDD, pParent),
EditedObject(obj)
{
//{{AFX_DATA_INIT(CMotorcycleDialog)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
void CMotorcycleDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CMotorcycleDialog)
DDX_Control(pDX, IDC_LEAN_K1_SPIN, m_LeanK1Spin);
DDX_Control(pDX, IDC_LEAN_K0_SPIN, m_LeanK0Spin);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CMotorcycleDialog, CDialog)
//{{AFX_MSG_MAP(CMotorcycleDialog)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMotorcycleDialog message handlers
float CMotorcycleDialog::GetDlgItemFloat(int controlid)
{
CString string;
GetDlgItemText(controlid,string);
return atof(string);
}
void CMotorcycleDialog::SetDlgItemFloat(int controlid,float val)
{
CString string;
string.Format("%.2f",val);
SetDlgItemText(controlid,string);
}
BOOL CMotorcycleDialog::OnInitDialog()
{
CDialog::OnInitDialog();
m_LeanK0Spin.SetRange(MIN_K * 100,MAX_K * 100);
m_LeanK1Spin.SetRange(MIN_K * 100,MAX_K * 100);
float k;
k = EditedObject->LeanK0;
m_LeanK0Spin.SetPos(k * 100);
SetDlgItemFloat(IDC_LEAN_K0_EDIT,k);
k = EditedObject->LeanK1;
m_LeanK1Spin.SetPos(k * 100);
SetDlgItemFloat(IDC_LEAN_K1_EDIT,k);
return TRUE;
}
BOOL CMotorcycleDialog::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
// make the spin controls work...
switch(wParam)
{
case IDC_LEAN_K0_SPIN:
case IDC_LEAN_K1_SPIN:
LPNMUPDOWN lpnmud = (LPNMUPDOWN) lParam;
if (lpnmud->hdr.code == UDN_DELTAPOS) {
HWND hwnd = (HWND)SendDlgItemMessage(LOWORD(wParam),UDM_GETBUDDY);
float curval = GetDlgItemFloat(GetWindowLong(hwnd,GWL_ID));
curval += (float)lpnmud->iDelta / 100.0f;
SetDlgItemFloat(GetWindowLong(hwnd,GWL_ID), curval);
}
break;
}
return CDialog::OnNotify(wParam, lParam, pResult);
}
void CMotorcycleDialog::OnOK()
{
float k;
k = GetDlgItemFloat(IDC_LEAN_K0_EDIT);
EditedObject->LeanK0 = k;
k = GetDlgItemFloat(IDC_LEAN_K1_EDIT);
EditedObject->LeanK1 = k;
CDialog::OnOK();
}

View File

@@ -0,0 +1,75 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined(AFX_MOTORCYCLEDIALOG_H__AD117871_03C8_11D3_9BDD_00A0C9988171__INCLUDED_)
#define AFX_MOTORCYCLEDIALOG_H__AD117871_03C8_11D3_9BDD_00A0C9988171__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// MotorcycleDialog.h : header file
//
class MotorcycleClass;
/////////////////////////////////////////////////////////////////////////////
// CMotorcycleDialog dialog
class CMotorcycleDialog : public CDialog
{
// Construction
public:
CMotorcycleDialog(CWnd* pParent,MotorcycleClass * obj);
// Dialog Data
//{{AFX_DATA(CMotorcycleDialog)
enum { IDD = IDD_MOTORCYCLE_DIALOG };
CSpinButtonCtrl m_LeanK1Spin;
CSpinButtonCtrl m_LeanK0Spin;
CSpinButtonCtrl m_BalanceK0Spin;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMotorcycleDialog)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
//}}AFX_VIRTUAL
// Implementation
protected:
MotorcycleClass * EditedObject;
float GetDlgItemFloat(int controlid);
void SetDlgItemFloat(int controlid,float val);
// Generated message map functions
//{{AFX_MSG(CMotorcycleDialog)
virtual BOOL OnInitDialog();
virtual void OnOK();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_MOTORCYCLEDIALOG_H__AD117871_03C8_11D3_9BDD_00A0C9988171__INCLUDED_)

View File

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

View File

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

View File

@@ -0,0 +1,66 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// PhysTest.h : main header file for the PHYSTEST application
//
#if !defined(AFX_PHYSTEST_H__616293E4_E4F0_11D2_802E_0040056350C8__INCLUDED_)
#define AFX_PHYSTEST_H__616293E4_E4F0_11D2_802E_0040056350C8__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#ifndef __AFXWIN_H__
#error include 'stdafx.h' before including this file for PCH
#endif
#include "resource.h" // main symbols
/////////////////////////////////////////////////////////////////////////////
// CPhysTestApp:
// See PhysTest.cpp for the implementation of this class
//
class CPhysTestApp : public CWinApp
{
public:
CPhysTestApp();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CPhysTestApp)
public:
virtual BOOL InitInstance();
virtual int ExitInstance();
//}}AFX_VIRTUAL
// Implementation
//{{AFX_MSG(CPhysTestApp)
afx_msg void OnAppAbout();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_PHYSTEST_H__616293E4_E4F0_11D2_802E_0040056350C8__INCLUDED_)

View File

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

View File

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

View File

@@ -0,0 +1,101 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// PhysTestDoc.h : interface of the CPhysTestDoc class
//
/////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_PHYSTESTDOC_H__616293EA_E4F0_11D2_802E_0040056350C8__INCLUDED_)
#define AFX_PHYSTESTDOC_H__616293EA_E4F0_11D2_802E_0040056350C8__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CGraphicView;
class CDataView;
class PhysicsSceneClass;
class LightClass;
class RenderObjClass;
class PhysClass;
class CPhysTestDoc : public CDocument
{
protected: // create from serialization only
CPhysTestDoc();
DECLARE_DYNCREATE(CPhysTestDoc)
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CPhysTestDoc)
public:
virtual BOOL OnNewDocument();
virtual void Serialize(CArchive& ar);
virtual BOOL OnOpenDocument(LPCTSTR lpszPathName);
virtual BOOL OnSaveDocument(LPCTSTR lpszPathName);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CPhysTestDoc(void);
void Init_Scene(void);
void Load_LEV_File(LPCTSTR lpszPathName);
void Load_W3D_File(LPCTSTR lpszPathName);
void Load_PHY_File(LPCTSTR lpszPathName);
void Save_PHY_File(LPCTSTR lpszPathName);
CGraphicView * Get_Graphic_View(void);
CDataView * Get_Data_View(void);
void Add_Physics_Object(PhysClass * obj);
int Get_Physics_Object_Count(void);
#ifdef _DEBUG
virtual void AssertValid(void) const;
virtual void Dump(CDumpContext& dc) const;
#endif
PhysicsSceneClass * Scene;
LightClass * Light;
RenderObjClass * Origin;
DWORD LastTime;
protected:
// Generated message map functions
protected:
//{{AFX_MSG(CPhysTestDoc)
// NOTE - the ClassWizard will add and remove member functions here.
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_PHYSTESTDOC_H__616293EA_E4F0_11D2_802E_0040056350C8__INCLUDED_)

View File

@@ -0,0 +1,75 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : PhysTest *
* *
* $Archive:: /Commando/Code/Tests/PhysTest/PhysTestSaveSystem.cpp $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 11/02/00 6:20p $*
* *
* $Revision:: 3 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "StdAfx.h"
#include "PhysTestSaveSystem.h"
#include "MainFrm.h"
#include "chunkio.h"
/*
** Instantiate the Save-System
*/
PhysTestSaveSystemClass _PhysTestSaveSystem;
uint32 PhysTestSaveSystemClass::Chunk_ID(void) const
{
return PHYSTEST_CHUNKID_SUBSYSTEM;
}
bool PhysTestSaveSystemClass::Save(ChunkSaveClass &csave)
{
csave.Begin_Chunk(CHUNKID_MAINFRAME);
((CMainFrame *)(::AfxGetMainWnd()))->Save(csave);
csave.End_Chunk();
return true;
}
bool PhysTestSaveSystemClass::Load(ChunkLoadClass &cload)
{
while (cload.Open_Chunk()) {
switch (cload.Cur_Chunk_ID()) {
case CHUNKID_MAINFRAME:
((CMainFrame *)(::AfxGetMainWnd()))->Load(cload);
break;
}
cload.Close_Chunk();
}
return true;
}

View File

@@ -0,0 +1,90 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : PhysTest *
* *
* $Archive:: /Commando/Code/Tests/PhysTest/PhysTestSaveSystem.h $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 11/02/00 6:14p $*
* *
* $Revision:: 3 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef PHYSTESTSAVESYSTEM_H
#define PHYSTESTSAVESYSTEM_H
#include "always.h"
#include "saveloadsubsystem.h"
#include "saveloadids.h"
/******************************************************************************************
**
** PhysTestSaveSystem
** Saves all data for the PhysTest app
**
******************************************************************************************/
class PhysTestSaveSystemClass : public SaveLoadSubSystemClass
{
public:
virtual uint32 Chunk_ID (void) const;
protected:
virtual bool Save (ChunkSaveClass &csave);
virtual bool Load (ChunkLoadClass &cload);
/*
** internal chunk id's
*/
enum
{
CHUNKID_MAINFRAME = 0x00667001,
};
};
/*
** _PhysTestSaveSystem - global instance of the sub-system for PhysTest
*/
extern PhysTestSaveSystemClass _PhysTestSaveSystem;
/******************************************************************************************
**
** Chunk ID's used by PhysTest objects
**
******************************************************************************************/
enum
{
PHYSTEST_CHUNKID_SUBSYSTEM = CHUNKID_PHYSTEST_BEGIN,
};
#endif

View File

@@ -0,0 +1,135 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// PhysicsConstantsDialog.cpp : implementation file
//
#include "stdafx.h"
#include "phystest.h"
#include "PhysicsConstantsDialog.h"
#include "physcon.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
const int MIN_DAMPING = 0;
const int MAX_DAMPING = 255;
const int MIN_GRAVITY = -100;
const int MAX_GRAVITY = 0;
/////////////////////////////////////////////////////////////////////////////
// CPhysicsConstantsDialog dialog
CPhysicsConstantsDialog::CPhysicsConstantsDialog(CWnd* pParent /*=NULL*/)
: CDialog(CPhysicsConstantsDialog::IDD, pParent)
{
//{{AFX_DATA_INIT(CPhysicsConstantsDialog)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
void CPhysicsConstantsDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CPhysicsConstantsDialog)
DDX_Control(pDX, IDC_LDAMPING_SPIN, m_LDampingSpin);
DDX_Control(pDX, IDC_GRAVITYACCEL_SPIN, m_GravityAccelSpin);
DDX_Control(pDX, IDC_ADAMPING_SPIN, m_ADampingSpin);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CPhysicsConstantsDialog, CDialog)
//{{AFX_MSG_MAP(CPhysicsConstantsDialog)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CPhysicsConstantsDialog message handlers
BOOL CPhysicsConstantsDialog::OnInitDialog()
{
CDialog::OnInitDialog();
m_LDampingSpin.SetRange(MIN_DAMPING * 100,MAX_DAMPING * 100);
m_ADampingSpin.SetRange(MIN_DAMPING * 100,MAX_DAMPING * 100);
m_GravityAccelSpin.SetRange(MIN_GRAVITY * 100,MAX_GRAVITY * 100);
m_LDampingSpin.SetPos(PhysicsConstants::LinearDamping * 100);
m_LDampingSpin.SetPos(PhysicsConstants::LinearDamping * 100);
m_GravityAccelSpin.SetPos(PhysicsConstants::GravityAcceleration.Z * 100);
SetDlgItemFloat(IDC_LDAMPING_EDIT,PhysicsConstants::LinearDamping);
SetDlgItemFloat(IDC_ADAMPING_EDIT,PhysicsConstants::AngularDamping);
SetDlgItemFloat(IDC_GRAVITYACCEL_EDIT,PhysicsConstants::GravityAcceleration.Z);
return TRUE;
}
BOOL CPhysicsConstantsDialog::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
// make the spin controls work...
switch(wParam)
{
case IDC_LDAMPING_SPIN:
case IDC_ADAMPING_SPIN:
case IDC_GRAVITYACCEL_SPIN:
LPNMUPDOWN lpnmud = (LPNMUPDOWN) lParam;
if (lpnmud->hdr.code == UDN_DELTAPOS) {
HWND hwnd = (HWND)SendDlgItemMessage(LOWORD(wParam),UDM_GETBUDDY);
float curval = GetDlgItemFloat(GetWindowLong(hwnd,GWL_ID));
curval += (float)lpnmud->iDelta / 100.0f;
SetDlgItemFloat(GetWindowLong(hwnd,GWL_ID), curval);
}
break;
}
return CDialog::OnNotify(wParam, lParam, pResult);
}
void CPhysicsConstantsDialog::OnOK()
{
PhysicsConstants::LinearDamping = GetDlgItemFloat(IDC_LDAMPING_EDIT);
PhysicsConstants::AngularDamping = GetDlgItemFloat(IDC_ADAMPING_EDIT);
PhysicsConstants::GravityAcceleration.Z = GetDlgItemFloat(IDC_GRAVITYACCEL_EDIT);
CDialog::OnOK();
}
float CPhysicsConstantsDialog::GetDlgItemFloat(int controlid)
{
CString string;
GetDlgItemText(controlid,string);
return atof(string);
}
void CPhysicsConstantsDialog::SetDlgItemFloat(int controlid,float val)
{
CString string;
string.Format("%.2f",val);
SetDlgItemText(controlid,string);
}

View File

@@ -0,0 +1,71 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined(AFX_PHYSICSCONSTANTSDIALOG_H__33DD6AC5_E78D_11D2_9BD2_00A0C9988171__INCLUDED_)
#define AFX_PHYSICSCONSTANTSDIALOG_H__33DD6AC5_E78D_11D2_9BD2_00A0C9988171__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// PhysicsConstantsDialog.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CPhysicsConstantsDialog dialog
class CPhysicsConstantsDialog : public CDialog
{
// Construction
public:
CPhysicsConstantsDialog(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CPhysicsConstantsDialog)
enum { IDD = IDD_PHYSICS_CONSTANTS_DIALOG };
CSpinButtonCtrl m_LDampingSpin;
CSpinButtonCtrl m_GravityAccelSpin;
CSpinButtonCtrl m_ADampingSpin;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CPhysicsConstantsDialog)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
//}}AFX_VIRTUAL
// Implementation
protected:
float GetDlgItemFloat(int controlid);
void SetDlgItemFloat(int controlid,float val);
// Generated message map functions
//{{AFX_MSG(CPhysicsConstantsDialog)
virtual BOOL OnInitDialog();
virtual void OnOK();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_PHYSICSCONSTANTSDIALOG_H__33DD6AC5_E78D_11D2_9BD2_00A0C9988171__INCLUDED_)

View File

@@ -0,0 +1,192 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// RbodyPropertiesDialog.cpp : implementation file
//
#include "stdafx.h"
#include "phystest.h"
#include "RbodyPropertiesDialog.h"
#include "movephys.h"
#include "rbody.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
const int MIN_MASS = 1;
const int MAX_MASS = 255;
const int MIN_ELASTICITY = 0;
const int MAX_ELASTICITY = 1;
const int MIN_GRAVITY = 0;
const int MAX_GRAVITY = 1;
const int MIN_POS = -255;
const int MAX_POS = 255;
const int MIN_CONTACT_STIFFNESS = 0;
const int MAX_CONTACT_STIFFNESS = 255;
const int MIN_CONTACT_DAMPING = 0;
const int MAX_CONTACT_DAMPING = 255;
const int MIN_CONTACT_LENGTH = 0;
const int MAX_CONTACT_LENGTH = 2;
/////////////////////////////////////////////////////////////////////////////
// CRbodyPropertiesDialog dialog
CRbodyPropertiesDialog::CRbodyPropertiesDialog(CWnd* pParent,MoveablePhysClass * object) :
CDialog(CRbodyPropertiesDialog::IDD, pParent),
Object(object)
{
//{{AFX_DATA_INIT(CRbodyPropertiesDialog)
//}}AFX_DATA_INIT
ASSERT(Object != NULL);
}
void CRbodyPropertiesDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CRbodyPropertiesDialog)
DDX_Control(pDX, IDC_LENGTH_SPIN, m_LengthSpin);
DDX_Control(pDX, IDC_STIFFNESS_SPIN, m_StiffnessSpin);
DDX_Control(pDX, IDC_DAMPING_SPIN, m_DampingSpin);
DDX_Control(pDX, IDC_POSITIONZ_SPIN, m_PositionZSpin);
DDX_Control(pDX, IDC_POSITIONY_SPIN, m_PositionYSpin);
DDX_Control(pDX, IDC_POSITIONX_SPIN, m_PositionXSpin);
DDX_Control(pDX, IDC_MASS_SPIN, m_MassSpin);
DDX_Control(pDX, IDC_GRAVITY_SPIN, m_GravitySpin);
DDX_Control(pDX, IDC_ELASTICITY_SPIN, m_ElasticitySpin);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CRbodyPropertiesDialog, CDialog)
//{{AFX_MSG_MAP(CRbodyPropertiesDialog)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CRbodyPropertiesDialog message handlers
void CRbodyPropertiesDialog::OnOK()
{
Object->Set_Mass(GetDlgItemFloat(IDC_MASS_EDIT));
Object->Set_Gravity_Multiplier(GetDlgItemFloat(IDC_GRAVITY_EDIT));
Object->Set_Elasticity(GetDlgItemFloat(IDC_ELASTICITY_EDIT));
Vector3 pos;
pos.X = GetDlgItemFloat(IDC_POSITIONX_EDIT);
pos.Y = GetDlgItemFloat(IDC_POSITIONY_EDIT);
pos.Z = GetDlgItemFloat(IDC_POSITIONZ_EDIT);
Object->Set_Position(pos);
float length = GetDlgItemFloat(IDC_LENGTH_EDIT);
// not letting the user override stiffness and damping for now
((RigidBodyClass *)Object)->Set_Contact_Parameters(length);
CDialog::OnOK();
}
BOOL CRbodyPropertiesDialog::OnInitDialog()
{
ASSERT(Object != NULL);
CDialog::OnInitDialog();
m_MassSpin.SetRange(MIN_MASS * 100,MAX_MASS * 100);
m_GravitySpin.SetRange(MIN_GRAVITY * 100,MAX_GRAVITY * 100);
m_ElasticitySpin.SetRange(MIN_ELASTICITY * 100,MAX_ELASTICITY * 100);
m_PositionXSpin.SetRange(MIN_POS * 100,MAX_POS * 100);
m_PositionYSpin.SetRange(MIN_POS * 100,MAX_POS * 100);
m_PositionZSpin.SetRange(MIN_POS * 100,MAX_POS * 100);
m_StiffnessSpin.SetRange(MIN_CONTACT_STIFFNESS * 100,MAX_CONTACT_STIFFNESS * 100);
m_DampingSpin.SetRange(MIN_CONTACT_DAMPING * 100,MAX_CONTACT_DAMPING * 100);
m_LengthSpin.SetRange(MIN_CONTACT_LENGTH * 100,MAX_CONTACT_LENGTH * 100);
m_MassSpin.SetPos(Object->Get_Mass() * 100);
m_GravitySpin.SetPos(Object->Get_Gravity_Multiplier() * 100);
m_ElasticitySpin.SetPos(Object->Get_Elasticity() * 100);
Vector3 position = Object->Get_Transform().Get_Translation();
m_PositionXSpin.SetPos(position.X * 100);
m_PositionYSpin.SetPos(position.Y * 100);
m_PositionZSpin.SetPos(position.Z * 100);
float stiffness,damping,length;
((RigidBodyClass *)Object)->Get_Contact_Parameters(&stiffness,&damping,&length);
m_StiffnessSpin.SetPos(stiffness * 100);
m_DampingSpin.SetPos(damping * 100);
m_LengthSpin.SetPos(length * 100);
SetDlgItemFloat(IDC_MASS_EDIT,Object->Get_Mass());
SetDlgItemFloat(IDC_GRAVITY_EDIT,Object->Get_Gravity_Multiplier());
SetDlgItemFloat(IDC_ELASTICITY_EDIT,Object->Get_Elasticity());
SetDlgItemFloat(IDC_POSITIONX_EDIT,position.X);
SetDlgItemFloat(IDC_POSITIONY_EDIT,position.Y);
SetDlgItemFloat(IDC_POSITIONZ_EDIT,position.Z);
SetDlgItemFloat(IDC_STIFFNESS_EDIT,stiffness);
SetDlgItemFloat(IDC_DAMPING_EDIT,damping);
SetDlgItemFloat(IDC_LENGTH_EDIT,length);
return TRUE;
}
float CRbodyPropertiesDialog::GetDlgItemFloat(int controlid)
{
CString string;
GetDlgItemText(controlid,string);
return atof(string);
}
void CRbodyPropertiesDialog::SetDlgItemFloat(int controlid,float val)
{
CString string;
string.Format("%.2f",val);
SetDlgItemText(controlid,string);
}
BOOL CRbodyPropertiesDialog::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
// make the spin controls work...
switch(wParam)
{
case IDC_MASS_SPIN:
case IDC_GRAVITY_SPIN:
case IDC_ELASTICITY_SPIN:
case IDC_POSITIONX_SPIN:
case IDC_POSITIONY_SPIN:
case IDC_POSITIONZ_SPIN:
case IDC_STIFFNESS_SPIN:
case IDC_DAMPING_SPIN:
case IDC_LENGTH_SPIN:
LPNMUPDOWN lpnmud = (LPNMUPDOWN) lParam;
if (lpnmud->hdr.code == UDN_DELTAPOS) {
HWND hwnd = (HWND)SendDlgItemMessage(LOWORD(wParam),UDM_GETBUDDY);
float curval = GetDlgItemFloat(GetWindowLong(hwnd,GWL_ID));
curval += (float)lpnmud->iDelta / 100.0f;
SetDlgItemFloat(GetWindowLong(hwnd,GWL_ID), curval);
}
break;
}
return CDialog::OnNotify(wParam, lParam, pResult);
}

View File

@@ -0,0 +1,80 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined(AFX_RBODYPROPERTIESDIALOG_H__33DD6AC1_E78D_11D2_9BD2_00A0C9988171__INCLUDED_)
#define AFX_RBODYPROPERTIESDIALOG_H__33DD6AC1_E78D_11D2_9BD2_00A0C9988171__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// RbodyPropertiesDialog.h : header file
//
class MoveablePhysClass;
/////////////////////////////////////////////////////////////////////////////
// CRbodyPropertiesDialog dialog
class CRbodyPropertiesDialog : public CDialog
{
// Construction
public:
CRbodyPropertiesDialog(CWnd* pParent,MoveablePhysClass * obj);
// Dialog Data
//{{AFX_DATA(CRbodyPropertiesDialog)
enum { IDD = IDD_RBODY_PROPERTIES_DIALOG };
CSpinButtonCtrl m_LengthSpin;
CSpinButtonCtrl m_StiffnessSpin;
CSpinButtonCtrl m_DampingSpin;
CSpinButtonCtrl m_PositionZSpin;
CSpinButtonCtrl m_PositionYSpin;
CSpinButtonCtrl m_PositionXSpin;
CSpinButtonCtrl m_MassSpin;
CSpinButtonCtrl m_GravitySpin;
CSpinButtonCtrl m_ElasticitySpin;
//}}AFX_DATA
MoveablePhysClass * Object;
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CRbodyPropertiesDialog)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
//}}AFX_VIRTUAL
// Implementation
protected:
float GetDlgItemFloat(int controlid);
void SetDlgItemFloat(int controlid,float val);
// Generated message map functions
//{{AFX_MSG(CRbodyPropertiesDialog)
virtual void OnOK();
virtual BOOL OnInitDialog();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_RBODYPROPERTIESDIALOG_H__33DD6AC1_E78D_11D2_9BD2_00A0C9988171__INCLUDED_)

View File

@@ -0,0 +1,98 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// RenderDeviceDialog.cpp : implementation file
//
#include "stdafx.h"
#include "phystest.h"
#include "RenderDeviceDialog.h"
#include "ww3d.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CRenderDeviceDialog dialog
CRenderDeviceDialog::CRenderDeviceDialog(CWnd* pParent /*=NULL*/)
: CDialog(CRenderDeviceDialog::IDD, pParent)
{
//{{AFX_DATA_INIT(CRenderDeviceDialog)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
void CRenderDeviceDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CRenderDeviceDialog)
DDX_Control(pDX, IDC_RENDER_DEVICE_COMBO, m_RenderDeviceCombo);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CRenderDeviceDialog, CDialog)
//{{AFX_MSG_MAP(CRenderDeviceDialog)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CRenderDeviceDialog message handlers
BOOL CRenderDeviceDialog::OnInitDialog()
{
CDialog::OnInitDialog();
// plug all of the render device names into the combo box
for (int i=0; i<WW3D::Get_Render_Device_Count(); i++) {
const char * name = WW3D::Get_Render_Device_Name(i);
m_RenderDeviceCombo.AddString(name);
}
m_RenderDeviceCombo.SetCurSel(WW3D::Get_Render_Device());
return TRUE;
}
void CRenderDeviceDialog::OnOK()
{
// get the index of the currently selected render device and set ww3d to use it
int device = m_RenderDeviceCombo.GetCurSel();
if (device != CB_ERR) {
// keep trying to set a device until one works
WW3DErrorType err = WW3D_ERROR_GENERIC;
int count = 0;
while ((err != WW3D_ERROR_OK) && (count < WW3D::Get_Render_Device_Count())) {
err = WW3D::Set_Render_Device(device);
count++;
if (err != WW3D_ERROR_OK) {
device = (device + 1) % WW3D::Get_Render_Device_Count();
}
}
assert(err == WW3D_ERROR_OK);
}
CDialog::OnOK();
}

View File

@@ -0,0 +1,65 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined(AFX_RENDERDEVICEDIALOG_H__7CD32C1C_0E2E_11D3_BADB_00902742EA14__INCLUDED_)
#define AFX_RENDERDEVICEDIALOG_H__7CD32C1C_0E2E_11D3_BADB_00902742EA14__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// RenderDeviceDialog.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CRenderDeviceDialog dialog
class CRenderDeviceDialog : public CDialog
{
// Construction
public:
CRenderDeviceDialog(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CRenderDeviceDialog)
enum { IDD = IDD_RENDER_DEVICE_DIALOG };
CComboBox m_RenderDeviceCombo;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CRenderDeviceDialog)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CRenderDeviceDialog)
virtual void OnOK();
virtual BOOL OnInitDialog();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_RENDERDEVICEDIALOG_H__7CD32C1C_0E2E_11D3_BADB_00902742EA14__INCLUDED_)

View File

@@ -0,0 +1,26 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// stdafx.cpp : source file that includes just the standard includes
// PhysTest.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"

View File

@@ -0,0 +1,45 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#if !defined(AFX_STDAFX_H__616293E6_E4F0_11D2_802E_0040056350C8__INCLUDED_)
#define AFX_STDAFX_H__616293E6_E4F0_11D2_802E_0040056350C8__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
#include <afxwin.h> // MFC core and standard components
#include <afxext.h> // MFC extensions
#include <afxdisp.h> // MFC Automation classes
#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h> // MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__616293E6_E4F0_11D2_802E_0040056350C8__INCLUDED_)

View File

@@ -0,0 +1,234 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// VJoyDialog.cpp : implementation file
//
#include "stdafx.h"
#include "phystest.h"
#include "VJoyDialog.h"
#include "vector2.h"
#include "vector3.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define JOYSTICK_UPDATE_COMMAND WM_USER+101
#define SLIDER_RESOLUTION 255
/////////////////////////////////////////////////////////////////////////////
// CVJoyDialog dialog
CVJoyDialog::CVJoyDialog(CWnd* pParent /*=NULL*/)
: CDialog(CVJoyDialog::IDD, pParent)
{
//{{AFX_DATA_INIT(CVJoyDialog)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
Controller.Reset();
}
CVJoyDialog::~CVJoyDialog(void)
{
}
void CVJoyDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CVJoyDialog)
DDX_Control(pDX, IDC_TURNZ_SLIDER, m_TurnZSlider);
DDX_Control(pDX, IDC_MOVEZ_SLIDER, m_MoveZSlider);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CVJoyDialog, CDialog)
//{{AFX_MSG_MAP(CVJoyDialog)
ON_WM_VSCROLL()
ON_WM_DESTROY()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/*
** Joystick Window Proc
*/
LRESULT CALLBACK JoystickWndProc(HWND hwnd,unsigned int message,WPARAM wparam,LPARAM lparam)
{
Vector2 point;
const int RADIUS = 4;
switch (message)
{
case WM_LBUTTONDOWN:
::SetCapture(hwnd);
break;
case WM_LBUTTONUP:
::ReleaseCapture();
break;
case WM_MOUSEMOVE:
if (wparam & MK_LBUTTON) {
float ex,ey,cx,cy;
short x = LOWORD(lparam);
short y = HIWORD(lparam);
RECT rect;
GetClientRect(hwnd,&rect);
if (x > rect.right) x = rect.right;
if (x < rect.left) x = rect.left;
if (y > rect.bottom) y = rect.bottom;
if (y < rect.top) y = rect.top;
ex = (float)(rect.right - rect.left) / 2.0f;
cx = (float)(rect.right + rect.left) / 2.0f;
ey = (float)(rect.bottom - rect.top) / 2.0f;
cy = (float)(rect.bottom + rect.top) / 2.0f;
point.X = ((float)x - cx) / ex;
point.Y = ((float)y - cy) / ey;
::SendMessage(GetParent(hwnd),JOYSTICK_UPDATE_COMMAND,GetWindowLong(hwnd,GWL_ID),(long)&point);
::InvalidateRect(hwnd,NULL,FALSE);
::UpdateWindow(hwnd);
SetProp(hwnd,"XCOORD",(HANDLE)x);
SetProp(hwnd,"YCOORD",(HANDLE)y);
}
break;
case WM_PAINT:
{
RECT rect;
GetClientRect(hwnd,&rect);
HDC hdc = GetDC(hwnd);
FillRect(hdc,&rect,(HBRUSH)GetStockObject(WHITE_BRUSH));
FrameRect(hdc,&rect,(HBRUSH)GetStockObject(BLACK_BRUSH));
MoveToEx(hdc,rect.right/2,0,NULL);
LineTo(hdc,rect.right/2,rect.bottom);
MoveToEx(hdc,0,rect.bottom/2,NULL);
LineTo(hdc,rect.right,rect.bottom/2);
int x = (int)GetProp(hwnd,"XCOORD");
int y = (int)GetProp(hwnd,"YCOORD");
if (x < RADIUS) x = RADIUS;
if (x > rect.right-RADIUS) x = rect.right-RADIUS;
if (y < RADIUS) y = RADIUS;
if (y > rect.bottom-RADIUS) y = rect.bottom-RADIUS;
MoveToEx(hdc,rect.bottom/2,rect.right/2,NULL);
LineTo(hdc,x,y);
Ellipse(hdc,x-RADIUS,y-RADIUS,x+RADIUS,y+RADIUS);
ReleaseDC(hwnd,hdc);
}
break;
}
WNDPROC oldwndproc = (WNDPROC)GetProp(hwnd,"OldWndProc");
//return CallWindowProc(oldwndproc,hwnd,message,wparam,lparam);
return DefWindowProc (hwnd, message, wparam, lparam);
}
/////////////////////////////////////////////////////////////////////////////
// CVJoyDialog message handlers
BOOL CVJoyDialog::OnInitDialog()
{
CDialog::OnInitDialog();
RECT rect;
HWND movexy_wnd = ::GetDlgItem(m_hWnd,IDC_MOVEXY_STATIC);
long oldproc = SetWindowLong(movexy_wnd,GWL_WNDPROC,(long)JoystickWndProc);
SetProp(movexy_wnd,"OldWndProc",(void*)oldproc);
::GetClientRect(movexy_wnd,&rect);
SetProp(movexy_wnd,"XCOORD",(HANDLE)(rect.right/2));
SetProp(movexy_wnd,"YCOORD",(HANDLE)(rect.bottom/2));
HWND turnxy_wnd = ::GetDlgItem(m_hWnd,IDC_TURNXY_STATIC);
oldproc = SetWindowLong(turnxy_wnd,GWL_WNDPROC,(long)JoystickWndProc);
SetProp(turnxy_wnd,"OldWndProc",(void*)oldproc);
::GetClientRect(movexy_wnd,&rect);
SetProp(turnxy_wnd,"XCOORD",(HANDLE)(rect.right/2));
SetProp(turnxy_wnd,"YCOORD",(HANDLE)(rect.bottom/2));
m_MoveZSlider.SetRange(0,SLIDER_RESOLUTION);
m_TurnZSlider.SetRange(0,SLIDER_RESOLUTION);
return TRUE;
}
LRESULT CVJoyDialog::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
if (message == JOYSTICK_UPDATE_COMMAND) {
Vector2 * point = (Vector2*)lParam;
if (wParam == IDC_MOVEXY_STATIC) {
Controller.Set_Move_Forward(-point->Y);
Controller.Set_Turn_Left(-point->X);
} else if (wParam == IDC_TURNXY_STATIC) {
// Nothing to do here anymore...
}
}
return CDialog::WindowProc(message, wParam, lParam);
}
void CVJoyDialog::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
if (pScrollBar == GetDlgItem(IDC_MOVEZ_SLIDER)) {
Controller.Set_Move_Up(1.0f - 2.0f * (float)m_MoveZSlider.GetPos() / (float)SLIDER_RESOLUTION);
}
#if 0
else if (pScrollBar == GetDlgItem(IDC_TURNZ_SLIDER)) {
Controller.Set_Turn_Left(1.0f - 2.0f * (float)m_TurnZSlider.GetPos() / (float)SLIDER_RESOLUTION);
}
#endif
CDialog::OnVScroll(nSBCode, nPos, pScrollBar);
}
void CVJoyDialog::OnDestroy()
{
HWND movexy_wnd = ::GetDlgItem(m_hWnd,IDC_MOVEXY_STATIC);
RemoveProp(movexy_wnd,"OldWndProc");
RemoveProp(movexy_wnd,"XCOORD");
RemoveProp(movexy_wnd,"YCOORD");
HWND turnxy_wnd = ::GetDlgItem(m_hWnd,IDC_TURNXY_STATIC);
RemoveProp(turnxy_wnd,"OldWndProc");
RemoveProp(turnxy_wnd,"XCOORD");
RemoveProp(turnxy_wnd,"YCOORD");
CDialog::OnDestroy();
}

View File

@@ -0,0 +1,72 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined(AFX_VJOYDIALOG_H__70FBC231_F1C1_11D2_9BD8_00A0C9988171__INCLUDED_)
#define AFX_VJOYDIALOG_H__70FBC231_F1C1_11D2_9BD8_00A0C9988171__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// VJoyDialog.h : header file
//
#include "physcontrol.h"
/////////////////////////////////////////////////////////////////////////////
// CVJoyDialog dialog
class CVJoyDialog : public CDialog
{
// Construction
public:
CVJoyDialog(CWnd* pParent = NULL); // standard constructor
~CVJoyDialog(void);
// Dialog Data
//{{AFX_DATA(CVJoyDialog)
enum { IDD = IDD_VJOY_DIALOG };
CSliderCtrl m_TurnZSlider;
CSliderCtrl m_MoveZSlider;
//}}AFX_DATA
PhysControllerClass Controller;
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CVJoyDialog)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CVJoyDialog)
virtual BOOL OnInitDialog();
afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
afx_msg void OnDestroy();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_VJOYDIALOG_H__70FBC231_F1C1_11D2_9BD8_00A0C9988171__INCLUDED_)

View File

@@ -0,0 +1,146 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// WheeledVehicleDialog.cpp : implementation file
//
#include "stdafx.h"
#include "phystest.h"
#include "WheeledVehicleDialog.h"
#include "wheelvehicle.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
const float MIN_KS = 0.01f;
const float MAX_KS = 1000.0f;
const float MIN_KD = 0.01f;
const float MAX_KD = 1000.0f;
const float MIN_LENGTH = 0.1f;
const float MAX_LENGTH = 32.0f;
/////////////////////////////////////////////////////////////////////////////
// CWheeledVehicleDialog dialog
CWheeledVehicleDialog::CWheeledVehicleDialog(CWnd* pParent,WheeledVehicleClass * obj)
: CDialog(CWheeledVehicleDialog::IDD, pParent),
EditedObject(obj)
{
//{{AFX_DATA_INIT(CWheeledVehicleDialog)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
void CWheeledVehicleDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CWheeledVehicleDialog)
DDX_Control(pDX, IDC_WVEHICLE_LENGTH_SPIN, m_LengthSpin);
DDX_Control(pDX, IDC_WVEHICLE_KS_SPIN, m_KSSpin);
DDX_Control(pDX, IDC_WVEHICLE_KD_SPIN, m_KDSpin);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CWheeledVehicleDialog, CDialog)
//{{AFX_MSG_MAP(CWheeledVehicleDialog)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CWheeledVehicleDialog message handlers
BOOL CWheeledVehicleDialog::OnInitDialog()
{
CDialog::OnInitDialog();
m_KSSpin.SetRange(MIN_KS * 100,MAX_KS * 100);
m_KDSpin.SetRange(MIN_KD * 100,MAX_KD * 100);
m_LengthSpin.SetRange(MIN_LENGTH * 100,MAX_LENGTH * 100);
float ks,kd,len;
EditedObject->Get_Suspension_Parameters(&ks,&kd,&len);
m_KSSpin.SetPos(ks * 100);
m_KDSpin.SetPos(kd * 100);
m_LengthSpin.SetPos(len * 100);
SetDlgItemFloat(IDC_WVEHICLE_KS_EDIT,ks);
SetDlgItemFloat(IDC_WVEHICLE_KD_EDIT,kd);
SetDlgItemFloat(IDC_WVEHICLE_LENGTH_EDIT,len);
return TRUE;
}
BOOL CWheeledVehicleDialog::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
// make the spin controls work...
switch(wParam)
{
case IDC_WVEHICLE_KS_SPIN:
case IDC_WVEHICLE_KD_SPIN:
case IDC_WVEHICLE_LENGTH_SPIN:
LPNMUPDOWN lpnmud = (LPNMUPDOWN) lParam;
if (lpnmud->hdr.code == UDN_DELTAPOS) {
HWND hwnd = (HWND)SendDlgItemMessage(LOWORD(wParam),UDM_GETBUDDY);
float curval = GetDlgItemFloat(GetWindowLong(hwnd,GWL_ID));
curval += (float)lpnmud->iDelta / 100.0f;
SetDlgItemFloat(GetWindowLong(hwnd,GWL_ID), curval);
}
break;
}
return CDialog::OnNotify(wParam, lParam, pResult);
}
void CWheeledVehicleDialog::OnOK()
{
float ks,kd,len;
ks = GetDlgItemFloat(IDC_WVEHICLE_KS_EDIT);
kd = GetDlgItemFloat(IDC_WVEHICLE_KD_EDIT);
len = GetDlgItemFloat(IDC_WVEHICLE_LENGTH_EDIT);
EditedObject->Set_Suspension_Parameters(ks,kd,len);
CDialog::OnOK();
}
float CWheeledVehicleDialog::GetDlgItemFloat(int controlid)
{
CString string;
GetDlgItemText(controlid,string);
return atof(string);
}
void CWheeledVehicleDialog::SetDlgItemFloat(int controlid,float val)
{
CString string;
string.Format("%.2f",val);
SetDlgItemText(controlid,string);
}

View File

@@ -0,0 +1,75 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined(AFX_WHEELEDVEHICLEDIALOG_H__14B8CCA2_F28E_11D2_9BD8_00A0C9988171__INCLUDED_)
#define AFX_WHEELEDVEHICLEDIALOG_H__14B8CCA2_F28E_11D2_9BD8_00A0C9988171__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// WheeledVehicleDialog.h : header file
//
class WheeledVehicleClass;
/////////////////////////////////////////////////////////////////////////////
// CWheeledVehicleDialog dialog
class CWheeledVehicleDialog : public CDialog
{
// Construction
public:
CWheeledVehicleDialog(CWnd* pParent,WheeledVehicleClass * obj);
// Dialog Data
//{{AFX_DATA(CWheeledVehicleDialog)
enum { IDD = IDD_WHEELEDVEHICLE_DIALOG };
CSpinButtonCtrl m_LengthSpin;
CSpinButtonCtrl m_KSSpin;
CSpinButtonCtrl m_KDSpin;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CWheeledVehicleDialog)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
//}}AFX_VIRTUAL
// Implementation
protected:
WheeledVehicleClass * EditedObject;
float GetDlgItemFloat(int controlid);
void SetDlgItemFloat(int controlid,float val);
// Generated message map functions
//{{AFX_MSG(CWheeledVehicleDialog)
virtual void OnOK();
virtual BOOL OnInitDialog();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_WHEELEDVEHICLEDIALOG_H__14B8CCA2_F28E_11D2_9BD8_00A0C9988171__INCLUDED_)

View File

@@ -0,0 +1,81 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/Commando/lev_file.h $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 3/08/00 8:16p $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef LEV_FILE_H
#define LEV_FILE_H
#if 0 //OBSOLETE!!!
/*
LEV File Format.
This is another chunk-based file format which will initially describe the map for
a commando level and may eventually expand to include the description of the entire
level. Due to the structure of our code, this file format will define several
"wrapper" chunks whose contents are defined in another header file in the physics
library (physchunks.h). Game code will make calls to the physics library when it
encounters those chunks.
The chunk 'LEV_CHUNK_STATIC_SCENE' can be handled by the physics scene's Load_Static_Scene
function and the 'LEV_CHUNK_DYNAMIC_SCENE' can be handled by the physics scene's
Load_Dynamic_Scene function. The definitions for the data inside those chunks can be
found inside the header file 'physchunks.h'
*/
enum {
LEV_CHUNK_LEVEL = 0x00000000, // wraps entire level definition
LEV_CHUNK_MAP = 0x00000100, // wraps the map definition
LEV_CHUNK_STATIC_SCENE = 0x00000102, // wraps physics definition of static objs (terrain)
LEV_CHUNK_STATIC_GAMEOBJS = 0x00000103, // game object definitions which link to above phys objs
LEV_CHUNK_OBJECTS = 0x00000200, // wraps defintion of all of the dynamic objects
LEV_CHUNK_DYNAMIC_SCENE = 0x00000201, // wraps physics definition of dynamic objs
LEV_CHUNK_DYNAMIC_GAMEOBJS = 0x00000202, // game obj definitions which link to above phys objs
};
#endif 0 // OBSOLETE!!!
#endif

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

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