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,134 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// MainFrm.cpp : implementation of the CMainFrame class
//
#include "stdafx.h"
#include "SimpleGraph.h"
#include "MainFrm.h"
#include "RangeDialog.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CMainFrame
IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
ON_WM_CREATE()
ON_COMMAND(IDM_SET_RANGES, OnSetRanges)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
static UINT indicators[] =
{
ID_SEPARATOR, // status line indicator
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
};
/////////////////////////////////////////////////////////////////////////////
// CMainFrame construction/destruction
CMainFrame::CMainFrame()
{
// TODO: add member initialization code here
}
CMainFrame::~CMainFrame()
{
}
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("Failed to create status bar\n");
return -1; // fail to create
}
// TODO: Delete these three lines if you don't want the toolbar to
// be dockable
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
return 0;
}
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CMainFrame diagnostics
#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
CFrameWnd::AssertValid();
}
void CMainFrame::Dump(CDumpContext& dc) const
{
CFrameWnd::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
//
// OnSetRanges
//
/////////////////////////////////////////////////////////////////////////////
void
CMainFrame::OnSetRanges (void)
{
CRangeDialog dialog (this);
dialog.DoModal ();
return ;
}

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/>.
*/
// MainFrm.h : interface of the CMainFrame class
//
/////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_MAINFRM_H__C44E4EB9_F133_11D3_A08F_00104B791122__INCLUDED_)
#define AFX_MAINFRM_H__C44E4EB9_F133_11D3_A08F_00104B791122__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CMainFrame : public CFrameWnd
{
protected: // create from serialization only
CMainFrame();
DECLARE_DYNCREATE(CMainFrame)
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMainFrame)
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CMainFrame();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected: // control bar embedded members
CStatusBar m_wndStatusBar;
CToolBar m_wndToolBar;
// Generated message map functions
protected:
//{{AFX_MSG(CMainFrame)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnSetRanges();
//}}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__C44E4EB9_F133_11D3_A08F_00104B791122__INCLUDED_)

View File

@@ -0,0 +1,254 @@
/*
** 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/>.
*/
// RangeDialog.cpp : implementation file
//
#include "stdafx.h"
#include "SimpleGraph.h"
#include "RangeDialog.h"
#include "SimpleGraphView.h"
#include "mainfrm.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
//
// fnEditToFloatProc
//
/////////////////////////////////////////////////////////////////////////////
LRESULT CALLBACK
fnEditToFloatProc
(
HWND hwnd,
UINT message,
WPARAM wparam,
LPARAM lparam
)
{
WNDPROC old_proc = (WNDPROC)::GetProp (hwnd, "OLD_WND_PROC");
LRESULT result = 0L;
if (message == WM_SETTEXT) {
//
// Convert the textual value to a long, convert
// the long to a float, and conver the float to
// a string.
//
LPCTSTR string = (LPCTSTR)lparam;
if (::strchr (string, '.') != 0) {
result = ::CallWindowProc (old_proc, hwnd, message, wparam, lparam);
} else {
long value = ::atol ((LPCTSTR)lparam);
float float_value = value / 100.0F;
CString new_text;
new_text.Format ("%.2f", float_value);
result = ::CallWindowProc (old_proc, hwnd, message, wparam, (LPARAM)(LPCTSTR)new_text);
}
} else if (message == WM_GETTEXT) {
//
// Get the value (as text) from the control,
// convert it to a float, convert the float
// to a long, then convert the long back to
// a string.
//
result = ::CallWindowProc (old_proc, hwnd, message, wparam, lparam);
LPCTSTR string = (LPCTSTR)lparam;
if (::strchr (string, '.') != 0) {
float float_value = ::atof (string);
long int_value = long(float_value * 100);
::itoa (int_value, (LPTSTR)lparam, 10);
} else {
long int_value = ::atol (string) * 100;
::itoa (int_value, (LPTSTR)lparam, 10);
}
result = ::lstrlen ((LPTSTR)lparam);
} else if (message == WM_CHAR) {
//
// Check to see if this is one of the characters we allow
// the user to type
//
if ( (wparam >= '0' && wparam <= '9') ||
wparam == '.' ||
wparam == VK_BACK ||
wparam == '-')
{
result = ::CallWindowProc (old_proc, hwnd, message, wparam, lparam);
}
} else if (old_proc != NULL) {
result = ::CallWindowProc (old_proc, hwnd, message, wparam, lparam);
}
return result;
}
/////////////////////////////////////////////////////////////////////////////
//
// Make_Edit_Float_Ctrl
//
/////////////////////////////////////////////////////////////////////////////
void
Make_Edit_Float_Ctrl (HWND edit_wnd)
{
LONG old_proc = ::SetWindowLong (edit_wnd, GWL_WNDPROC, (LONG)fnEditToFloatProc);
SetProp (edit_wnd, "OLD_WND_PROC", (HANDLE)old_proc);
return ;
}
////////////////////////////////////////////////////////////////////////////
//
// SetDlgItemFloat
//
////////////////////////////////////////////////////////////////////////////
void
SetDlgItemFloat
(
HWND hdlg,
UINT child_id,
float value
)
{
// Convert the float to a string
CString text;
text.Format ("%.2f", value);
// Pass the string onto the dialog control
::SetDlgItemText (hdlg, child_id, text);
return ;
}
////////////////////////////////////////////////////////////////////////////
//
// GetDlgItemFloat
//
////////////////////////////////////////////////////////////////////////////
float
GetDlgItemFloat
(
HWND hdlg,
UINT child_id
)
{
// Get the string from the window
TCHAR string_value[20];
::GetDlgItemText (hdlg, child_id, string_value, sizeof (string_value));
// Convert the string to a float and return the value
return ::atof (string_value);
}
/////////////////////////////////////////////////////////////////////////////
//
// CRangeDialog
//
/////////////////////////////////////////////////////////////////////////////
CRangeDialog::CRangeDialog(CWnd* pParent /*=NULL*/)
: CDialog(CRangeDialog::IDD, pParent)
{
//{{AFX_DATA_INIT(CRangeDialog)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
return ;
}
void CRangeDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CRangeDialog)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CRangeDialog, CDialog)
//{{AFX_MSG_MAP(CRangeDialog)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
//
// CRangeDialog
//
/////////////////////////////////////////////////////////////////////////////
BOOL
CRangeDialog::OnInitDialog (void)
{
CDialog::OnInitDialog ();
CSimpleGraphView *view = (CSimpleGraphView *)((CMainFrame *)::AfxGetMainWnd ())->GetActiveView ();
Vector2 range_min;
Vector2 range_max;
view->Get_Ranges (range_min, range_max);
/*::Make_Edit_Float_Ctrl (::GetDlgItem (m_hWnd, IDC_MIN_X));
::Make_Edit_Float_Ctrl (::GetDlgItem (m_hWnd, IDC_MIN_Y));
::Make_Edit_Float_Ctrl (::GetDlgItem (m_hWnd, IDC_MAX_X));
::Make_Edit_Float_Ctrl (::GetDlgItem (m_hWnd, IDC_MAX_Y));*/
SetDlgItemFloat (m_hWnd, IDC_MIN_X, range_min.X);
SetDlgItemFloat (m_hWnd, IDC_MIN_Y, range_min.Y);
SetDlgItemFloat (m_hWnd, IDC_MAX_X, range_max.X);
SetDlgItemFloat (m_hWnd, IDC_MAX_Y, range_max.Y);
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
//
// OnOK
//
/////////////////////////////////////////////////////////////////////////////
void
CRangeDialog::OnOK (void)
{
Vector2 range_min;
Vector2 range_max;
range_min.X = ::GetDlgItemFloat (m_hWnd, IDC_MIN_X);
range_min.Y = ::GetDlgItemFloat (m_hWnd, IDC_MIN_Y);
range_max.X = ::GetDlgItemFloat (m_hWnd, IDC_MAX_X);
range_max.Y = ::GetDlgItemFloat (m_hWnd, IDC_MAX_Y);
CSimpleGraphView *view = (CSimpleGraphView *)((CMainFrame *)::AfxGetMainWnd ())->GetActiveView ();
view->Set_Ranges (range_min, range_max);
view->InvalidateRect (NULL, TRUE);
view->UpdateWindow ();
CDialog::OnOK ();
return ;
}

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_RANGEDIALOG_H__C44E4EC7_F133_11D3_A08F_00104B791122__INCLUDED_)
#define AFX_RANGEDIALOG_H__C44E4EC7_F133_11D3_A08F_00104B791122__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// RangeDialog.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CRangeDialog dialog
class CRangeDialog : public CDialog
{
// Construction
public:
CRangeDialog(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CRangeDialog)
enum { IDD = IDD_RANGES };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CRangeDialog)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CRangeDialog)
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_RANGEDIALOG_H__C44E4EC7_F133_11D3_A08F_00104B791122__INCLUDED_)

View File

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

View File

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

View File

@@ -0,0 +1,67 @@
/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// SimpleGraph.h : main header file for the SIMPLEGRAPH application
//
#if !defined(AFX_SIMPLEGRAPH_H__C44E4EB5_F133_11D3_A08F_00104B791122__INCLUDED_)
#define AFX_SIMPLEGRAPH_H__C44E4EB5_F133_11D3_A08F_00104B791122__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
/////////////////////////////////////////////////////////////////////////////
// CSimpleGraphApp:
// See SimpleGraph.cpp for the implementation of this class
//
class CSimpleGraphApp : public CWinApp
{
public:
CSimpleGraphApp();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CSimpleGraphApp)
public:
virtual BOOL InitInstance();
//}}AFX_VIRTUAL
// Implementation
//{{AFX_MSG(CSimpleGraphApp)
afx_msg void OnAppAbout();
// NOTE - the ClassWizard will add and remove member functions here.
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_SIMPLEGRAPH_H__C44E4EB5_F133_11D3_A08F_00104B791122__INCLUDED_)

View File

@@ -0,0 +1,407 @@
//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\\SimpleGraph.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\\SimpleGraph.ico"
IDR_SIMPLETYPE ICON DISCARDABLE "res\\SimpleGraphDoc.ico"
/////////////////////////////////////////////////////////////////////////////
//
// Bitmap
//
IDR_MAINFRAME BITMAP MOVEABLE PURE "res\\Toolbar.bmp"
/////////////////////////////////////////////////////////////////////////////
//
// Toolbar
//
IDR_MAINFRAME TOOLBAR DISCARDABLE 16, 15
BEGIN
BUTTON ID_FILE_NEW
BUTTON ID_FILE_OPEN
BUTTON ID_FILE_SAVE
SEPARATOR
BUTTON ID_EDIT_CUT
BUTTON ID_EDIT_COPY
BUTTON ID_EDIT_PASTE
SEPARATOR
BUTTON ID_FILE_PRINT
SEPARATOR
BUTTON ID_APP_ABOUT
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
MENUITEM "Save &As...", ID_FILE_SAVE_AS
MENUITEM SEPARATOR
MENUITEM "Recent File", ID_FILE_MRU_FILE1, GRAYED
MENUITEM SEPARATOR
MENUITEM "E&xit", ID_APP_EXIT
END
POPUP "&Edit"
BEGIN
MENUITEM "&Delete Key", IDM_DELETE
MENUITEM SEPARATOR
MENUITEM "&Set Ranges...", IDM_SET_RANGES
END
POPUP "&View"
BEGIN
MENUITEM "&Toolbar", ID_VIEW_TOOLBAR
MENUITEM "&Status Bar", ID_VIEW_STATUS_BAR
MENUITEM SEPARATOR
MENUITEM "&Zoom Extents", IDM_ZOOM_EXTENTS
END
POPUP "&Help"
BEGIN
MENUITEM "&About SimpleGraph...", ID_APP_ABOUT
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Accelerator
//
IDR_MAINFRAME ACCELERATORS PRELOAD MOVEABLE PURE
BEGIN
"C", ID_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT
"N", ID_FILE_NEW, VIRTKEY, CONTROL, NOINVERT
"O", ID_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT
"S", ID_FILE_SAVE, VIRTKEY, CONTROL, NOINVERT
"V", ID_EDIT_PASTE, VIRTKEY, CONTROL, NOINVERT
VK_BACK, ID_EDIT_UNDO, VIRTKEY, ALT, NOINVERT
VK_DELETE, IDM_DELETE, VIRTKEY, NOINVERT
VK_DELETE, ID_EDIT_CUT, VIRTKEY, SHIFT, NOINVERT
VK_F6, ID_NEXT_PANE, VIRTKEY, NOINVERT
VK_F6, ID_PREV_PANE, VIRTKEY, SHIFT, NOINVERT
VK_INSERT, ID_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT
VK_INSERT, ID_EDIT_PASTE, VIRTKEY, SHIFT, NOINVERT
"X", ID_EDIT_CUT, VIRTKEY, CONTROL, NOINVERT
"Z", ID_EDIT_UNDO, VIRTKEY, CONTROL, NOINVERT
END
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_ABOUTBOX DIALOG DISCARDABLE 0, 0, 235, 55
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "About SimpleGraph"
FONT 8, "MS Sans Serif"
BEGIN
ICON IDR_MAINFRAME,IDC_STATIC,11,17,20,20
LTEXT "SimpleGraph Version 1.0",IDC_STATIC,40,10,119,8,
SS_NOPREFIX
LTEXT "Copyright (C) 2000",IDC_STATIC,40,25,119,8
DEFPUSHBUTTON "OK",IDOK,178,7,50,14,WS_GROUP
END
IDD_RANGES DIALOG DISCARDABLE 0, 0, 200, 126
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Graph Ranges"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "Use the controls below to specify the min and max values for the current view.",
IDC_STATIC,7,7,186,24
GROUPBOX "&X - Axis",IDC_STATIC,7,33,79,63
EDITTEXT IDC_MIN_X,16,49,40,14,ES_AUTOHSCROLL
LTEXT "min",IDC_STATIC,64,54,20,8
EDITTEXT IDC_MAX_X,16,71,40,14,ES_AUTOHSCROLL
LTEXT "max",IDC_STATIC,64,73,17,8
GROUPBOX "&Y - Axis",IDC_STATIC,111,33,79,63
EDITTEXT IDC_MIN_Y,120,49,40,14,ES_AUTOHSCROLL
LTEXT "min",IDC_STATIC,168,54,20,8
EDITTEXT IDC_MAX_Y,120,71,40,14,ES_AUTOHSCROLL
LTEXT "max",IDC_STATIC,168,73,17,8
DEFPUSHBUTTON "OK",IDOK,40,104,50,14
PUSHBUTTON "Cancel",IDCANCEL,110,104,50,14
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", "SimpleGraph MFC Application\0"
VALUE "FileVersion", "1, 0, 0, 1\0"
VALUE "InternalName", "SimpleGraph\0"
VALUE "LegalCopyright", "Copyright (C) 2000\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "SimpleGraph.EXE\0"
VALUE "ProductName", "SimpleGraph 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_RANGES, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 193
TOPMARGIN, 7
BOTTOMMARGIN, 119
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE PRELOAD DISCARDABLE
BEGIN
IDR_MAINFRAME "SimpleGraph\n\nSimple\nData Table (*.tbl)\n.tbl\nSimpleGraph.Document\nSimple Document"
END
STRINGTABLE PRELOAD DISCARDABLE
BEGIN
AFX_IDS_APP_TITLE "SimpleGraph"
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
#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\SimpleGraph.rc2" // non-Microsoft Visual C++ edited resources
#include "afxres.rc" // Standard components
#endif
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@@ -0,0 +1,148 @@
/*
** 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/>.
*/
// SimpleGraphDoc.cpp : implementation of the CSimpleGraphDoc class
//
#include "stdafx.h"
#include "SimpleGraph.h"
#include "SimpleGraphDoc.h"
#include "SimpleGraphView.h"
#include "lookuptable.h"
#include "rawfile.h"
#include "chunkio.h"
#include "catmullromspline.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CSimpleGraphDoc
IMPLEMENT_DYNCREATE(CSimpleGraphDoc, CDocument)
BEGIN_MESSAGE_MAP(CSimpleGraphDoc, CDocument)
//{{AFX_MSG_MAP(CSimpleGraphDoc)
// 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()
/////////////////////////////////////////////////////////////////////////////
// CSimpleGraphDoc construction/destruction
CSimpleGraphDoc::CSimpleGraphDoc() :
m_Spline(NULL)
{
// TODO: add one-time construction code here
m_Spline = new CatmullRomSpline1DClass;
}
CSimpleGraphDoc::~CSimpleGraphDoc()
{
delete m_Spline;
}
BOOL CSimpleGraphDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
// TODO: add reinitialization code here
// (SDI documents will reuse this document)
int count = m_Spline->Key_Count ();
while (count --) {
m_Spline->Remove_Key (0);
}
POSITION pos = GetFirstViewPosition ();
CSimpleGraphView *view = (CSimpleGraphView *)GetNextView (pos);
view->Set_Ranges (Vector2 (0, 0), Vector2 (100, 100));
view->InvalidateRect (NULL, TRUE);
view->UpdateWindow ();
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CSimpleGraphDoc serialization
void CSimpleGraphDoc::Serialize(CArchive& ar)
{
POSITION pos = GetFirstViewPosition ();
CSimpleGraphView *view = (CSimpleGraphView *)GetNextView (pos);
if (ar.IsStoring())
{
RawFileClass file;
file.Attach ((void *)ar.GetFile ()->m_hFile);
ChunkSaveClass csave (&file);
Vector2 range_min,range_max;
view->Get_Ranges(range_min,range_max);
_TheLookupTableManager.Save_Table_Desc(csave, m_Spline, range_min, range_max);
file.Detach ();
}
else
{
RawFileClass file;
file.Attach ((void *)ar.GetFile ()->m_hFile);
ChunkLoadClass cload (&file);
// Load the curve from the file
Vector2 range_min,range_max;
Curve1DClass * curve = NULL;
_TheLookupTableManager.Load_Table_Desc (cload, &curve, &range_min, &range_max);
view->Set_Ranges(range_min,range_max);
// If we successfully loaded a new curve, delete the old one
// and install this one.
WWASSERT(m_Spline != NULL);
delete m_Spline;
m_Spline = curve;
file.Detach ();
}
}
/////////////////////////////////////////////////////////////////////////////
// CSimpleGraphDoc diagnostics
#ifdef _DEBUG
void CSimpleGraphDoc::AssertValid() const
{
CDocument::AssertValid();
}
void CSimpleGraphDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CSimpleGraphDoc commands

View File

@@ -0,0 +1,91 @@
/*
** 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/>.
*/
// SimpleGraphDoc.h : interface of the CSimpleGraphDoc class
//
/////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_SIMPLEGRAPHDOC_H__C44E4EBB_F133_11D3_A08F_00104B791122__INCLUDED_)
#define AFX_SIMPLEGRAPHDOC_H__C44E4EBB_F133_11D3_A08F_00104B791122__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "cardinalspline.h"
class CSimpleGraphDoc : public CDocument
{
protected: // create from serialization only
CSimpleGraphDoc();
DECLARE_DYNCREATE(CSimpleGraphDoc)
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CSimpleGraphDoc)
public:
virtual BOOL OnNewDocument();
virtual void Serialize(CArchive& ar);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CSimpleGraphDoc();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
// Generated message map functions
protected:
//{{AFX_MSG(CSimpleGraphDoc)
// 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()
public:
//////////////////////////////////////////////////////////
// Public methods
//////////////////////////////////////////////////////////
Curve1DClass & Get_Spline (void) { return *m_Spline; }
protected:
//////////////////////////////////////////////////////////
// Protected member data
//////////////////////////////////////////////////////////
Curve1DClass * m_Spline;
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_SIMPLEGRAPHDOC_H__C44E4EBB_F133_11D3_A08F_00104B791122__INCLUDED_)

View File

@@ -0,0 +1,938 @@
/*
** 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/>.
*/
// SimpleGraphView.cpp : implementation of the CSimpleGraphView class
//
#include "stdafx.h"
#include "SimpleGraph.h"
#include "SimpleGraphDoc.h"
#include "SimpleGraphView.h"
#include "vector3.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CSimpleGraphView
IMPLEMENT_DYNCREATE(CSimpleGraphView, CView)
BEGIN_MESSAGE_MAP(CSimpleGraphView, CView)
//{{AFX_MSG_MAP(CSimpleGraphView)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_COMMAND(IDM_DELETE, OnDelete)
ON_UPDATE_COMMAND_UI(IDM_DELETE, OnUpdateDelete)
ON_COMMAND(IDM_ZOOM_EXTENTS, OnZoomExtents)
ON_WM_RBUTTONDOWN()
ON_WM_RBUTTONUP()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSimpleGraphView construction/destruction
CSimpleGraphView::CSimpleGraphView()
: m_Min (0, 0),
m_Max (100, 100),
m_DraggingPt (-1),
m_SelPt (-1),
m_IsZooming (false)
{
}
CSimpleGraphView::~CSimpleGraphView()
{
}
BOOL CSimpleGraphView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
m_Brush.CreateSolidBrush (RGB (0, 255, 0));
m_SelBrush.CreateSolidBrush (RGB (255, 0, 0));
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
//
// OnDraw
//
/////////////////////////////////////////////////////////////////////////////
void
CSimpleGraphView::OnDraw (CDC* dc)
{
HFONT old_font = (HFONT)::SelectObject (*dc, m_Font);
Render_Axis (dc);
Render_Graph (dc);
Render_Points (dc);
::SelectObject (*dc, old_font);
return ;
}
/////////////////////////////////////////////////////////////////////////////
// CSimpleGraphView diagnostics
#ifdef _DEBUG
void CSimpleGraphView::AssertValid() const
{
CView::AssertValid();
}
void CSimpleGraphView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CSimpleGraphDoc* CSimpleGraphView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CSimpleGraphDoc)));
return (CSimpleGraphDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CSimpleGraphView message handlers
/////////////////////////////////////////////////////////////////////////////
//
// Repaint_Graph
//
/////////////////////////////////////////////////////////////////////////////
void
CSimpleGraphView::Repaint_Graph (void)
{
CRect rect;
Get_Graph_Rect (rect);
InvalidateRect (rect, TRUE);
UpdateWindow ();
return ;
}
///////////////////////////////////////////////////////////////////////
//
// Render_Axis
//
///////////////////////////////////////////////////////////////////////
void
CSimpleGraphView::Render_Axis (CDC *dc)
{
CRect view_rect;
GetClientRect (&view_rect);
CRect graph_rect;
Get_Graph_Rect (graph_rect);
dc->MoveTo (view_rect.left + 70, view_rect.top + 25);
dc->LineTo (view_rect.left + 70, view_rect.bottom - 50);
dc->MoveTo (view_rect.left + 70, view_rect.bottom - 45);
dc->LineTo (view_rect.right - 25, view_rect.bottom - 45);
int tick_width = 35;
int tick_height = 35;
int ticks_x = (graph_rect.Width () / tick_width);
int ticks_y = (graph_rect.Height () / tick_height);
tick_width = (graph_rect.Width () / ticks_x);
tick_height = (graph_rect.Height () / ticks_y);
float x_val = m_Min.X;
float y_val = m_Max.Y;
float x_inc = (m_Max.X - m_Min.X) / ticks_x;
float y_inc = (m_Min.Y - m_Max.Y) / ticks_y;
//
// Draw the x-axis tick marks
//
int location = graph_rect.left;
for (int tick = 0; tick <= ticks_x; tick ++) {
dc->MoveTo (location, view_rect.bottom - 50);
dc->LineTo (location, view_rect.bottom - 40);
CRect label_rect;
label_rect.left = location - 15;
label_rect.right = location + 15;
label_rect.top = view_rect.bottom - 38;
label_rect.bottom = view_rect.bottom - 20;
CString label;
label.Format ("%.2f", x_val);
dc->DrawText (label, label_rect, DT_CENTER);
x_val += x_inc;
location += tick_width;
}
//
// Draw the y-axis tick marks
//
location = graph_rect.top;
for (tick = 0; tick <= ticks_y; tick ++) {
dc->MoveTo (view_rect.left + 65, location);
dc->LineTo (view_rect.left + 75, location);
CRect label_rect;
label_rect.left = view_rect.left + 38;
label_rect.right = view_rect.left + 63;
label_rect.top = location - 15;
label_rect.bottom = location + 15;
CString label;
label.Format ("%.2f", y_val);
dc->DrawText (label, label_rect, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
y_val += y_inc;
location += tick_height;
}
return ;
}
///////////////////////////////////////////////////////////////////////
//
// Render_Graph
//
///////////////////////////////////////////////////////////////////////
void
CSimpleGraphView::Render_Graph (CDC *dc)
{
Curve1DClass &spline = GetDocument ()->Get_Spline ();
if (spline.Key_Count () < 2) {
return ;
}
CRect graph_area;
Get_Graph_Rect (graph_area);
float delta_x = m_Max.X - m_Min.X;
float delta_y = m_Max.Y - m_Min.Y;
float start_time = 0;
float end_time = 0;
float foo = 0;
spline.Get_Key (0, &foo, &start_time);
spline.Get_Key (spline.Key_Count () - 1, &foo, &end_time);
start_time = max (m_Min.X, start_time);
end_time = min (m_Max.X, end_time);
float start_value = 0;
float end_value = 0;
CPoint start_pt;
CPoint end_pt;
spline.Evaluate (start_time, &start_value);
spline.Evaluate (end_time, &end_value);
Value_To_Point (Vector2 (start_time, start_value), &start_pt);
Value_To_Point (Vector2 (end_time, end_value), &end_pt);
int count = ((end_pt.x - start_pt.x) / 4);
float time_inc = (end_time - start_time) / (float)count;
//
// Draw the curve
//
dc->MoveTo (start_pt.x, start_pt.y);
for (float time = start_time; time <= end_time; time += time_inc) {
float value;
spline.Evaluate (time, &value);
float percent_x = (time - m_Min.X) / delta_x;
float percent_y = (value - m_Min.Y) / delta_y;
int client_x = graph_area.left + int(graph_area.Width () * percent_x);
int client_y = graph_area.top + int(graph_area.Height () * (1-percent_y));
if (percent_x <= 0) {
dc->MoveTo (client_x, client_y);
}
if ( percent_x >= 0 && percent_x <= 1.0F &&
percent_y >= 0 && percent_y <= 1.0F)
{
dc->LineTo (client_x, client_y);
}
}
dc->LineTo (end_pt.x, end_pt.y);
return ;
}
///////////////////////////////////////////////////////////////////////
//
// Render_Points
//
///////////////////////////////////////////////////////////////////////
void
CSimpleGraphView::Render_Points (CDC *dc)
{
Curve1DClass &spline = GetDocument ()->Get_Spline ();
if (spline.Key_Count () < 1) {
return ;
}
//
// Draw the points
//
CBrush *old_brush = dc->SelectObject (&m_Brush);
int count = spline.Key_Count ();
for (int index = 0; index < count; index ++) {
float time = 0;
float value;
spline.Get_Key (index, &value, &time);
CPoint graph_pt;
Value_To_Point (Vector2 (time,value), &graph_pt);
if (m_SelPt == index) {
dc->SelectObject (&m_SelBrush);
dc->Ellipse (graph_pt.x - 4, graph_pt.y - 4, graph_pt.x + 4, graph_pt.y + 4);
dc->SelectObject (&m_Brush);
} else {
dc->Ellipse (graph_pt.x - 4, graph_pt.y - 4, graph_pt.x + 4, graph_pt.y + 4);
}
if (m_DraggingPt == index) {
CRect label_rect;
label_rect.left = graph_pt.x - 30;
label_rect.right = graph_pt.x + 30;
label_rect.top = graph_pt.y - 30;
label_rect.bottom = graph_pt.y - 6;
CString label;
label.Format ("%.2f, %.2f", time, value);
dc->DrawText (label, label_rect, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
}
}
dc->SelectObject (old_brush);
return ;
}
///////////////////////////////////////////////////////////////////////
//
// Get_Visible_Points
//
///////////////////////////////////////////////////////////////////////
void
CSimpleGraphView::Get_Visible_Points (int *left_pt, int *right_pt)
{
Curve1DClass &spline = GetDocument ()->Get_Spline ();
(*left_pt) = -1;
(*right_pt) = -1;
CRect graph_area;
Get_Graph_Rect (graph_area);
float delta_x = m_Max.X - m_Min.X;
float delta_y = m_Max.Y - m_Min.Y;
int count = spline.Key_Count ();
for (int index = 0; index < count; index ++) {
float time = 0;
float value;
spline.Get_Key (index, &value, &time);
float percent_x = (time - m_Min.X) / delta_x;
float percent_y = 1.0F - ((value - m_Min.Y) / delta_y);
//
// Is this point in the current view?
//
if ( percent_x >= 0 && percent_x <= 1.0F &&
percent_y >= 0 && percent_y <= 1.0F)
{
if ((*left_pt) == -1) {
(*left_pt) = index;
}
(*right_pt) = index;
}
}
return ;
}
///////////////////////////////////////////////////////////////////////
//
// Hit_Test
//
///////////////////////////////////////////////////////////////////////
CSimpleGraphView::HITTYPE
CSimpleGraphView::Hit_Test (const CPoint &point, int *hit_pt)
{
Curve1DClass &spline = GetDocument ()->Get_Spline ();
HITTYPE retval = HIT_UNKNOWN;
CRect graph_area;
Get_Graph_Rect (graph_area);
//CPoint graph_pt;
//graph_pt.x = point.x - graph_area.left;
//graph_pt.y = point.y - graph_area.top;
if ( (point.x >= 0 && point.x < graph_area.left) ||
(point.y >= 0 && point.y < graph_area.top))
{
retval = HIT_AXIS;
} else if (point.x >= graph_area.left && point.y >= graph_area.top) {
retval = HIT_GRAPH_AREA;
float delta_x = m_Max.X - m_Min.X;
float delta_y = m_Max.Y - m_Min.Y;
int count = spline.Key_Count ();
for (int index = 0; index < count; index ++) {
float time = 0;
float value;
spline.Get_Key (index, &value, &time);
float percent_x = (time - m_Min.X) / delta_x;
float percent_y = 1.0F - ((value - m_Min.Y) / delta_y);
int graph_x = graph_area.left + int(graph_area.Width () * percent_x);
int graph_y = graph_area.top + int(graph_area.Height () * percent_y);
//
// Are we within 'fudge' of the graph point?
//
if ( ::abs (graph_x - point.x) < 8 &&
::abs (graph_y - point.y) < 8)
{
(*hit_pt) = index;
retval = HIT_POINT;
break;
}
}
}
return retval;
}
///////////////////////////////////////////////////////////////////////
//
// OnLButtonDown
//
///////////////////////////////////////////////////////////////////////
void
CSimpleGraphView::OnLButtonDown (UINT nFlags, CPoint point)
{
if ((nFlags & MK_RBUTTON) == 0 && m_DraggingPt == -1) {
int point_index = 0;
HITTYPE hit_type = Hit_Test (point, &point_index);
if (hit_type == HIT_GRAPH_AREA) {
m_DraggingPt = Add_New_Point (point);
} else if (hit_type == HIT_POINT) {
m_DraggingPt = point_index;
}
if (m_DraggingPt >= 0) {
m_SelPt = m_DraggingPt;
Repaint_Graph ();
SetCapture ();
}
}
CView::OnLButtonDown (nFlags, point);
return;
}
///////////////////////////////////////////////////////////////////////
//
// OnLButtonDown
//
///////////////////////////////////////////////////////////////////////
void
CSimpleGraphView::OnLButtonUp (UINT nFlags, CPoint point)
{
if (m_DraggingPt >= 0) {
::ReleaseCapture ();
m_DraggingPt = -1;
Repaint_Graph ();
}
CView::OnLButtonUp (nFlags, point);
return ;
}
///////////////////////////////////////////////////////////////////////
//
// OnMouseMove
//
///////////////////////////////////////////////////////////////////////
void
CSimpleGraphView::OnMouseMove (UINT nFlags, CPoint point)
{
if (nFlags & MK_LBUTTON && nFlags & MK_RBUTTON) {
CPoint delta = m_ZoomPt - point;
float delta_x = m_Max.X - m_Min.X;
float delta_y = m_Max.Y - m_Min.Y;
CRect graph_area;
Get_Graph_Rect (graph_area);
float units_x = (delta.x * delta_x) / (float)graph_area.Width ();
float units_y = -(delta.y * delta_y) / (float)graph_area.Height ();
m_Min.X += units_x;
m_Min.Y += units_y;
m_Max.X += units_x;
m_Max.Y += units_y;
InvalidateRect (NULL, TRUE);
UpdateWindow ();
} else if (m_IsZooming) {
CPoint delta = m_ZoomPt - point;
float delta_x = m_Max.X - m_Min.X;
float delta_y = m_Max.Y - m_Min.Y;
float factor = ((float)delta.y) / 100.0F;
/*if (delta.y < 0) {
factor = 100.0F / ((float)delta.y);
}*/
m_Min.X = m_Min.X - (factor * delta_x);
m_Min.Y = m_Min.Y - (factor * delta_y);
m_Max.X = m_Max.X + (factor * delta_x);
m_Max.Y = m_Max.Y + (factor * delta_y);
InvalidateRect (NULL, TRUE);
UpdateWindow ();
} else if (m_DraggingPt >= 0) {
//
// Determine the new value based on the the screen location
// of the mouse cursor...
//
Vector2 new_value;
Point_To_Value (point, &new_value);
new_value.X = max (new_value.X, m_Min.X);
new_value.Y = max (new_value.Y, m_Min.Y);
new_value.X = min (new_value.X, m_Max.X);
new_value.Y = min (new_value.Y, m_Max.Y);
//
// Make sure the new point is sorted correctly
//
m_DraggingPt = Move_Value (m_DraggingPt, new_value);
m_SelPt = m_DraggingPt;
}
m_ZoomPt = point;
CView::OnMouseMove (nFlags, point);
return ;
}
///////////////////////////////////////////////////////////////////////
//
// Add_New_Point
//
///////////////////////////////////////////////////////////////////////
int
CSimpleGraphView::Add_New_Point (CPoint &point)
{
Curve1DClass &spline = GetDocument ()->Get_Spline ();
Vector2 new_value;
Point_To_Value (point, &new_value);
new_value.X = max (new_value.X, m_Min.X);
new_value.Y = max (new_value.Y, m_Min.Y);
new_value.X = min (new_value.X, m_Max.X);
new_value.Y = min (new_value.Y, m_Max.Y);
float time = new_value.X;
float value = new_value.Y;
int index = spline.Add_Key (value,time);
return Move_Value (index, new_value);
}
///////////////////////////////////////////////////////////////////////
//
// Move_Value
//
///////////////////////////////////////////////////////////////////////
int
CSimpleGraphView::Move_Value (int old_index, const Vector2 &new_value)
{
Curve1DClass &spline = GetDocument ()->Get_Spline ();
int new_index = -1;
int count = spline.Key_Count ();
Vector2 *point_list = new Vector2[count];
int curr_index = 0;
for (int list_index = 0; list_index < count; list_index ++) {
//
// Skip the old value
//
if (list_index != old_index) {
//
// Get this key's value
//
float time = 0;
float value;
spline.Get_Key (list_index, &value, &time);
Vector2 curr_point;
curr_point.X = time;
curr_point.Y = value;
//
// Should the moving-value be inserted before the current value?
//
if (new_index == -1 && (new_value.X < curr_point.X)) {
new_index = curr_index++;
point_list[new_index].Set (new_value.X, new_value.Y);
}
//
// Add the current value to the list
//
point_list[curr_index++].Set (curr_point.X, curr_point.Y);
}
}
if (old_index != -1 && new_index == -1) {
new_index = curr_index;
point_list[new_index].Set (new_value.X, new_value.Y);
}
//
// Remove all the keys from the spline
//
for (int index = 0; index < count; index ++) {
spline.Remove_Key (0);
}
//
// Add the new 'sorted' keys back into the spline
//
float time;
float key;
float last_time = -9999999999.0F;
for (index = 0; index < count; index ++) {
time = point_list[index].X;
key = point_list[index].Y;
if (time == last_time) {
spline.Add_Key(key,time + WWMATH_EPSILON);
} else {
spline.Add_Key(key,time);
}
last_time = time;
}
Repaint_Graph ();
delete [] point_list;
return new_index;
}
///////////////////////////////////////////////////////////////////////
//
// Point_To_Value
//
///////////////////////////////////////////////////////////////////////
void
CSimpleGraphView::Point_To_Value (const CPoint &point, Vector2 *value)
{
CRect graph_area;
Get_Graph_Rect (graph_area);
CPoint graph_pt;
graph_pt.x = point.x - graph_area.left;
graph_pt.y = point.y - graph_area.top;
float percent_x = (float)graph_pt.x / (float)graph_area.Width ();
float percent_y = (float)graph_pt.y / (float)graph_area.Height ();
value->X = m_Min.X + ((m_Max.X - m_Min.X) * percent_x);
value->Y = m_Min.Y + ((m_Max.Y - m_Min.Y) * (1.0F - percent_y));
return ;
}
///////////////////////////////////////////////////////////////////////
//
// Value_To_Point
//
///////////////////////////////////////////////////////////////////////
void
CSimpleGraphView::Value_To_Point (const Vector2 &value, CPoint *point)
{
CRect graph_area;
Get_Graph_Rect (graph_area);
float percent_x = (value.X - m_Min.X) / (m_Max.X - m_Min.X);
float percent_y = (value.Y - m_Min.Y) / (m_Max.Y - m_Min.Y);
point->x = graph_area.left + int(graph_area.Width () * percent_x);
point->y = graph_area.top + int(graph_area.Height () * (1.0F - percent_y));
return ;
}
///////////////////////////////////////////////////////////////////////
//
// Get_Graph_Rect
//
///////////////////////////////////////////////////////////////////////
void
CSimpleGraphView::Get_Graph_Rect (CRect &rect)
{
CRect view_rect;
GetClientRect (&view_rect);
rect.left = 75;
rect.right = view_rect.Width () - 25;
rect.top = 25;
rect.bottom = view_rect.Height () - 50;
return ;
}
///////////////////////////////////////////////////////////////////////
//
// OnInitialUpdate
//
///////////////////////////////////////////////////////////////////////
void
CSimpleGraphView::OnInitialUpdate (void)
{
HDC screen_dc = ::GetDC (NULL);
m_Font = CreateFont (-::MulDiv (7, GetDeviceCaps(screen_dc, LOGPIXELSY), 72),
0,
0,
0,
FW_REGULAR,
FALSE,
FALSE,
FALSE,
ANSI_CHARSET,
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,
DEFAULT_PITCH,
"Small Fonts");
::ReleaseDC (NULL, screen_dc);
CView::OnInitialUpdate();
return ;
}
///////////////////////////////////////////////////////////////////////
//
// Delete_Point
//
///////////////////////////////////////////////////////////////////////
void
CSimpleGraphView::Delete_Point (int index)
{
Curve1DClass &spline = GetDocument ()->Get_Spline ();
if (index >= 0 && index < spline.Key_Count ()) {
spline.Remove_Key (index);
if (index == m_SelPt) {
m_SelPt = -1;
}
if (index == m_DraggingPt) {
m_DraggingPt = -1;
}
Repaint_Graph ();
}
return ;
}
///////////////////////////////////////////////////////////////////////
//
// OnDelete
//
///////////////////////////////////////////////////////////////////////
void
CSimpleGraphView::OnDelete (void)
{
if (m_SelPt != -1) {
Delete_Point (m_SelPt);
}
return ;
}
///////////////////////////////////////////////////////////////////////
//
// OnUpdateDelete
//
///////////////////////////////////////////////////////////////////////
void
CSimpleGraphView::OnUpdateDelete (CCmdUI *pCmdUI)
{
pCmdUI->Enable (m_SelPt != -1);
return ;
}
///////////////////////////////////////////////////////////////////////
//
// OnZoomExtents
//
///////////////////////////////////////////////////////////////////////
void
CSimpleGraphView::OnZoomExtents (void)
{
Curve1DClass &spline = GetDocument ()->Get_Spline ();
int count = spline.Key_Count ();
if (count > 0) {
m_Min.Set (99999.0F, 99999.0F);
m_Max.Set (-99999.0F, -99999.0F);
float start_time = spline.Get_Start_Time ();
float end_time = spline.Get_End_Time ();
float time_inc = (end_time - start_time) / 400.0F;
float time = start_time;
for (int index = 0; index < 400; index ++) {
float value;
spline.Evaluate (time, &value);
m_Min.X = min (m_Min.X, time);
m_Min.Y = min (m_Min.Y, value);
m_Max.X = max (m_Max.X, time);
m_Max.Y = max (m_Max.Y, value);
time += time_inc;
}
float delta_x = m_Max.X - m_Min.X;
float delta_y = m_Max.Y - m_Min.Y;
m_Min.X -= (delta_x / 100.0F);
m_Min.Y -= (delta_y / 100.0F);
m_Max.X += (delta_x / 100.0F);
m_Max.Y += (delta_y / 100.0F);
InvalidateRect (NULL, TRUE);
UpdateWindow ();
}
return ;
}
///////////////////////////////////////////////////////////////////////
//
// OnRButtonDown
//
///////////////////////////////////////////////////////////////////////
void
CSimpleGraphView::OnRButtonDown (UINT nFlags, CPoint point)
{
if (m_IsZooming == false) {
m_ZoomPt = point;
m_IsZooming = true;
SetCapture ();
}
CView::OnRButtonDown (nFlags, point);
return ;
}
///////////////////////////////////////////////////////////////////////
//
// OnRButtonUp
//
///////////////////////////////////////////////////////////////////////
void
CSimpleGraphView::OnRButtonUp (UINT nFlags, CPoint point)
{
if (m_IsZooming) {
m_IsZooming = false;
::ReleaseCapture ();
}
CView::OnRButtonUp(nFlags, point);
return ;
}

View File

@@ -0,0 +1,145 @@
/*
** 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/>.
*/
// SimpleGraphView.h : interface of the CSimpleGraphView class
//
/////////////////////////////////////////////////////////////////////////////
#if !defined(AFX_SIMPLEGRAPHVIEW_H__C44E4EBD_F133_11D3_A08F_00104B791122__INCLUDED_)
#define AFX_SIMPLEGRAPHVIEW_H__C44E4EBD_F133_11D3_A08F_00104B791122__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "resource.h"
#include "cardinalspline.h"
#include "vector2.h"
class CSimpleGraphDoc;
class CSimpleGraphView : public CView
{
protected: // create from serialization only
CSimpleGraphView();
DECLARE_DYNCREATE(CSimpleGraphView)
// Attributes
public:
CSimpleGraphDoc* GetDocument();
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CSimpleGraphView)
public:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
virtual void OnInitialUpdate();
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CSimpleGraphView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
// Generated message map functions
protected:
//{{AFX_MSG(CSimpleGraphView)
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnDelete();
afx_msg void OnUpdateDelete(CCmdUI* pCmdUI);
afx_msg void OnZoomExtents();
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
public:
//////////////////////////////////////////////////////////
// Protected methods
//////////////////////////////////////////////////////////
void Render_Graph (CDC *dc);
void Get_Visible_Points (int *left_pt, int *right_pt);
typedef enum
{
HIT_GRAPH_AREA = 1,
HIT_POINT,
HIT_AXIS,
HIT_UNKNOWN
} HITTYPE;
HITTYPE Hit_Test (const CPoint &point, int *hit_pt);
void Get_Graph_Rect (CRect &rect);
void Value_To_Point (const Vector2 &value, CPoint *point);
void Point_To_Value (const CPoint &point, Vector2 *value);
int Move_Value (int old_index, const Vector2 &new_value);
void Render_Axis (CDC *dc);
void Repaint_Graph (void);
void Render_Points (CDC *dc);
int Add_New_Point (CPoint &point);
void Delete_Point (int index);
int Get_Selection (void) const { return m_SelPt; }
void Get_Ranges (Vector2 &range_min, Vector2 &range_max) { range_min = m_Min; range_max = m_Max; }
void Set_Ranges (Vector2 &range_min, Vector2 &range_max) { m_Min = range_min; m_Max = range_max; Repaint_Graph (); }
protected:
//////////////////////////////////////////////////////////
// Protected member data
//////////////////////////////////////////////////////////
Vector2 m_Min;
Vector2 m_Max;
int m_DraggingPt;
int m_SelPt;
CBrush m_Brush;
CBrush m_SelBrush;
HFONT m_Font;
CPoint m_ZoomPt;
bool m_IsZooming;
};
#ifndef _DEBUG // debug version in SimpleGraphView.cpp
inline CSimpleGraphDoc* CSimpleGraphView::GetDocument()
{ return (CSimpleGraphDoc*)m_pDocument; }
#endif
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_SIMPLEGRAPHVIEW_H__C44E4EBD_F133_11D3_A08F_00104B791122__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
// SimpleGraph.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"

View File

@@ -0,0 +1,44 @@
/*
** 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__C44E4EB7_F133_11D3_A08F_00104B791122__INCLUDED_)
#define AFX_STDAFX_H__C44E4EB7_F133_11D3_A08F_00104B791122__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 <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__C44E4EB7_F133_11D3_A08F_00104B791122__INCLUDED_)

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,27 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by SimpleGraph.rc
//
#define IDD_ABOUTBOX 100
#define IDR_MAINFRAME 128
#define IDR_SIMPLETYPE 129
#define IDD_RANGES 130
#define IDC_MAX_X 1000
#define IDC_MIN_X 1001
#define IDC_MAX_Y 1004
#define IDC_MIN_Y 1005
#define IDM_DELETE 32771
#define IDM_SET_RANGES 32772
#define IDM_ZOOM_EXTENTS 32773
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_3D_CONTROLS 1
#define _APS_NEXT_RESOURCE_VALUE 131
#define _APS_NEXT_COMMAND_VALUE 32774
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif