Complete disaster-recovery snapshot: engine/game source, game data assets, VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive. Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false, no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
1542 lines
41 KiB
C++
1542 lines
41 KiB
C++
// MFC Gos.cpp : Defines the class behaviors for the application.
|
|
//
|
|
|
|
// Note:
|
|
// Unresolved Problems:
|
|
// Imagehlp.dll Not Found on Load from Double Click
|
|
// Wire only works on Scenes
|
|
|
|
|
|
#include "stdafx.h"
|
|
#include "MFC Gos.h"
|
|
|
|
#include "MainFrm.h"
|
|
#include "MFC GosDoc.h"
|
|
#include "MFC GosView.h"
|
|
#include <Gameos\Toolos.hpp>
|
|
|
|
HGOSHEAP client;
|
|
|
|
extern DWORD _stdcall RunGameOSLogic();
|
|
|
|
#define DEBUGPOINT(x) MessageBox(NULL,x,"Test Point",MB_OK)
|
|
|
|
#include <ElementRenderer\ElementRenderer.hpp>
|
|
#include <ElementRenderer\GroupElement.hpp>
|
|
#include <ElementRenderer\StateChange.hpp>
|
|
#include <ElementRenderer\CameraElement.hpp>
|
|
#include <ElementRenderer\PointCloudElement.hpp>
|
|
#include <ElementRenderer\LineCloudElement.hpp>
|
|
#include <ElementRenderer\ElementRenderer.hpp>
|
|
#include <ElementRenderer\GroupElement.hpp>
|
|
#include <ElementRenderer\StateChange.hpp>
|
|
#include <ElementRenderer\CameraElement.hpp>
|
|
#include <ElementRenderer\ShapeElement.hpp>
|
|
#include <ElementRenderer\ListElement.hpp>
|
|
#include <ElementRenderer\GridElement.hpp>
|
|
#include <ElementRenderer\SwitchElement.hpp>
|
|
#include <ElementRenderer\LODElement.hpp>
|
|
|
|
#include <gosFX\gosFX.hpp>
|
|
#include <gosFX\EffectLibrary.hpp>
|
|
#include <MLR\MLR.hpp>
|
|
#include <MFCPlatform\MFCPlatform.hpp>
|
|
#include <MLR\MLRPointCloud.hpp>
|
|
#include <MLR\MLRLineCloud.hpp>
|
|
#include <MLR\MLRPointLight.hpp>
|
|
#include <MLR\MLRLightMap.hpp>
|
|
#include "LightListDlg.h"
|
|
|
|
extern DWORD gCurrentHeapStackLevel;
|
|
|
|
BumpAnime bumpAnime;
|
|
int animeCounter = 0;
|
|
|
|
//
|
|
// Global variables
|
|
//
|
|
const char* Command_Line=NULL;
|
|
|
|
int UpdateLevel=0;
|
|
ElementRenderer::GroupElement *Scene=NULL;
|
|
ElementRenderer::Element *ErfElement=NULL;
|
|
ElementRenderer::CameraElement *Camera=NULL;
|
|
ElementRenderer::StateChange *LightState=NULL;
|
|
CLightListDlg *LightDlg;
|
|
|
|
Stuff::Point3D Camera_Pivot(Stuff::Point3D::Identity);
|
|
Stuff::YawPitchRange Camera_Direction(0.0f, 0.0f, -10.0f);
|
|
Stuff::Vector2DOf<Stuff::Scalar> Camera_Shift(0.0f, 0.0f);
|
|
//Stuff::Point3D Camera_Loc(0.0f,100.0f,-100.0f),
|
|
Stuff::Point3D Camera_LookAt(0.0f,0.0f,0.0f);
|
|
|
|
|
|
//Bump Map Test
|
|
|
|
|
|
ElementRenderer::StateChange *Camera_State=NULL;
|
|
Stuff::RGBAColor fogColor(0.3f, 0.3f, 0.3f, 1.0f);
|
|
bool Window3DOpen=false;
|
|
|
|
bool drawPointsYes = false;
|
|
bool drawNormalsYes = false;
|
|
MidLevelRenderer::DrawEffectInformation *drawEffectInfo[2];
|
|
unsigned Point_Count=MidLevelRenderer::Limits::Max_Number_Vertices_Per_Mesh;
|
|
Stuff::RGBAColor Color_Data[2][2*MidLevelRenderer::Limits::Max_Number_Vertices_Per_Mesh];
|
|
|
|
Stuff::MString *erf_texture_path,*erf_effects_path;
|
|
CList<Stuff::MString*, Stuff::MString*> m_pErf_Name_List;
|
|
|
|
|
|
#undef SHADOW_TEST
|
|
|
|
#ifdef SHADOW_TEST
|
|
MidLevelRenderer::MLRTexture *shadowTexture;
|
|
MidLevelRenderer::MLRShape *shadowShape;
|
|
MidLevelRenderer::DrawShapeInformation drawShapeInfo;
|
|
Stuff::LinearMatrix4D shadowMatrix;
|
|
|
|
extern void _stdcall End3DScene();
|
|
#endif
|
|
|
|
#define APPNAME "3dViewTest"
|
|
|
|
extern DWORD _stdcall RunGameOSLogic();
|
|
extern bool DebuggerActive;
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CMFCGosApp
|
|
|
|
BEGIN_MESSAGE_MAP(CMFCGosApp, CWinApp)
|
|
//{{AFX_MSG_MAP(CMFCGosApp)
|
|
ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
|
|
ON_COMMAND(ID_OPTIONS_TEXTUREPATH, OnOptionsTexturepath)
|
|
ON_COMMAND(ID_VIEW_3DVIEWWINDOW, OnView3dviewwindow)
|
|
ON_UPDATE_COMMAND_UI(ID_VIEW_3DVIEWWINDOW, OnUpdateView3dviewwindow)
|
|
ON_COMMAND(ID_VIEW_UPDATEONIDLE, OnViewUpdateonidle)
|
|
ON_UPDATE_COMMAND_UI(ID_VIEW_UPDATEONIDLE, OnUpdateViewUpdateonidle)
|
|
ON_COMMAND(ID_WINDOWS_LIGHTLIST, OnWindowsLightlist)
|
|
ON_UPDATE_COMMAND_UI(ID_WINDOWS_LIGHTLIST, OnUpdateWindowsLightlist)
|
|
//}}AFX_MSG_MAP
|
|
// Standard file based document commands
|
|
ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
|
|
ON_COMMAND(ID_FILE_OPEN,OnFileOpen)
|
|
ON_COMMAND(ID_VIEW_EXPANDALL, OnExpandAll)
|
|
ON_COMMAND(ID_VIEW_COLLAPSEALL, OnCollapseAll)
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CMFCGosApp construction
|
|
|
|
CMFCGosApp::CMFCGosApp()
|
|
{
|
|
GOSActive=false;
|
|
DrawOnIdle=true;
|
|
m_pFileSet_List.RemoveAll();
|
|
m_phashErfNameMapping = NULL;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// The one and only CMFCGosApp object
|
|
|
|
CMFCGosApp theApp;
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CMFCGosApp initialization
|
|
|
|
BOOL CMFCGosApp::InitInstance()
|
|
{
|
|
AfxEnableControlContainer();
|
|
// Standard initialization
|
|
|
|
#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.
|
|
// jcem - SetRegistryKey(_T("Local AppWizard-Generated Applications"));
|
|
|
|
LoadStdProfileSettings(); // Load standard INI file options (including MRU)
|
|
|
|
// Register document templates
|
|
|
|
CString mutexstr;
|
|
mutexstr.LoadString(AFX_IDS_APP_TITLE);
|
|
CreateMutex(NULL,TRUE,mutexstr);
|
|
if(ERROR_ALREADY_EXISTS==GetLastError())
|
|
{
|
|
MessageBox(NULL,"Another Instance of this Application is Currently Running","Error...",MB_OK);
|
|
exit(1);
|
|
}
|
|
|
|
CSingleDocTemplate* pDocTemplate;
|
|
pDocTemplate = new CSingleDocTemplate(
|
|
IDR_MAINFRAME,
|
|
RUNTIME_CLASS(CMFCGosDoc),
|
|
RUNTIME_CLASS(CMainFrame), // main SDI frame window
|
|
RUNTIME_CLASS(CMFCGosView));
|
|
AddDocTemplate(pDocTemplate);
|
|
|
|
|
|
// Parse command line for standard shell commands, DDE, file open
|
|
CCommandLineInfo cmdInfo;
|
|
ParseCommandLine(cmdInfo);
|
|
|
|
// Dispatch commands specified on the command line
|
|
if (!ProcessShellCommandNoLoad(cmdInfo))
|
|
return FALSE;
|
|
|
|
|
|
m_pMainWnd->ShowWindow(SW_SHOW);
|
|
m_pMainWnd->UpdateWindow();
|
|
|
|
|
|
|
|
|
|
Window3D = new ViewWnd3D;
|
|
|
|
|
|
Window3D->Create(NULL,
|
|
"3D View Window",
|
|
WS_OVERLAPPED|WS_CAPTION,
|
|
//|WS_MINIMIZEBOX|WS_SYSMENU,
|
|
Window3D->rectDefault,
|
|
// m_pMainWnd, //This Will make The render Window Stay ontop of the main window
|
|
NULL,
|
|
MAKEINTRESOURCE(IDR_RENDERMENU),
|
|
NULL);
|
|
|
|
CRect rct;
|
|
rct.top=rct.left=0;
|
|
rct.right=640;
|
|
rct.bottom=480+18;
|
|
|
|
|
|
Window3D->ShowWindow(SW_SHOW);
|
|
Window3D->CalcWindowRect(&rct,CWnd::adjustOutside);
|
|
Window3D->SetWindowPos(NULL,rct.left,rct.top,rct.Width(),rct.Height(),SWP_SHOWWINDOW|SWP_NOOWNERZORDER|SWP_NOMOVE);
|
|
Window3D->SetIcon(LoadIcon(IDI_ICON3D),TRUE);
|
|
|
|
|
|
Command_Line = m_lpCmdLine;
|
|
InitGameOS( m_hInstance , Window3D->m_hWnd, m_lpCmdLine );
|
|
// client=gos_CreateMemoryHeap("PixelProHeap");
|
|
// gos_PushCurrentHeap(client);
|
|
theApp.Window3D->GOSActive=true;
|
|
theApp.Window3D->GOSInit=true;
|
|
theApp.Window3D->Fix3DView();
|
|
DrawScreen();
|
|
GOSActive=true;
|
|
|
|
|
|
LightDlg=new CLightListDlg;
|
|
LightDlg->Create( CLightListDlg::IDD,m_pMainWnd);
|
|
LightDlg->ShowWindow(SW_HIDE);
|
|
|
|
// has to be initialized in InitializeGameEngine()
|
|
// m_pstrErfNameMapping = new CMap<DWORD, DWORD, Stuff::MString*, Stuff::MString*>;
|
|
|
|
//
|
|
//-----------------------
|
|
// Parse the command line
|
|
//-----------------------
|
|
//
|
|
const char* space = strchr(Command_Line, ' ');
|
|
if (!space || space == Command_Line)
|
|
{
|
|
// Abort_Program("Need both ERF file and texture path");
|
|
// GetTexturePath();
|
|
}
|
|
else
|
|
{
|
|
MString * tmp = new MString(Command_Line);
|
|
m_pErf_Name_List.AddHead(tmp);
|
|
// ((LPCSTR)(erf_name))[space - Command_Line] = '\0';
|
|
// erf_name.SetAt(space - Command_Line],'\0');
|
|
|
|
static_cast<char*>(*(m_pErf_Name_List.GetHead()))[space - Command_Line] = '\0';
|
|
(*(theApp.m_phashErfNameMapping)).DeletePlugs();
|
|
(*(theApp.m_phashErfNameMapping)).AddValue(new Stuff::PlugOf<MString *> (tmp), 0); // this is only a copy...
|
|
while (*space == ' ')
|
|
++space;
|
|
if (!*space)
|
|
{
|
|
STOP(( "Need both ERF file and texture path" ));
|
|
}
|
|
else
|
|
{
|
|
*erf_texture_path = space;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// CG: The following block was inserted by the 'Document Registration' component.
|
|
{
|
|
// Enable DDE Execute open
|
|
EnableShellOpen();
|
|
RegisterShellFileTypes(TRUE);
|
|
|
|
m_pMainWnd->DragAcceptFiles();
|
|
}
|
|
|
|
if (!ProcessShellCommandOnlyLoad(cmdInfo))
|
|
return FALSE;
|
|
|
|
|
|
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 CMFCGosApp::OnAppAbout()
|
|
{
|
|
CAboutDlg aboutDlg;
|
|
aboutDlg.DoModal();
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CMFCGosApp message handlers
|
|
|
|
|
|
|
|
|
|
BOOL CMFCGosApp::OnIdle(LONG lCount)
|
|
{
|
|
DWORD level = gCurrentHeapStackLevel;
|
|
|
|
if(DrawOnIdle || DebuggerActive)
|
|
{
|
|
DrawScreen();
|
|
Verify(level == gCurrentHeapStackLevel);
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
Verify(level == gCurrentHeapStackLevel);
|
|
return CWinApp::OnIdle(lCount);
|
|
}
|
|
}
|
|
|
|
int CMFCGosApp::ExitInstance()
|
|
{
|
|
ExitGameOS();
|
|
if(Window3D)
|
|
{
|
|
//delete Window3D;
|
|
Window3D=NULL;
|
|
}
|
|
return CWinApp::ExitInstance();
|
|
}
|
|
|
|
|
|
void _stdcall InitializeGameEngine()
|
|
{
|
|
//
|
|
//---------------------
|
|
// Initialize libraries
|
|
//---------------------
|
|
//
|
|
Stuff::InitializeClasses();
|
|
MidLevelRenderer::InitializeClasses(NULL, 8192, 1024*64);
|
|
|
|
gosFX::InitializeClasses();
|
|
ElementRenderer::InitializeClasses();
|
|
if (!theApp.m_phashErfNameMapping)
|
|
{
|
|
// BYTE * memory = new BYTE[sizeof(CMap<DWORD, DWORD, Stuff::MString*, Stuff::MString*>)];
|
|
//theApp.m_pstrErfNameMapping = new(memory) (CMap<DWORD, DWORD, Stuff::MString*, Stuff::MString*>);
|
|
theApp.m_phashErfNameMapping = new Stuff::HashOf<Stuff::PlugOf<Stuff::MString *>*,DWORD>(67, NULL, true);
|
|
}
|
|
while (m_pErf_Name_List.GetCount() && m_pErf_Name_List.GetHead())
|
|
{Unregister_Object(m_pErf_Name_List.GetHead()); delete m_pErf_Name_List.GetHead(); m_pErf_Name_List.RemoveHead();}
|
|
(*(theApp.m_phashErfNameMapping)).DeletePlugs();
|
|
m_pErf_Name_List.AddHead(new Stuff::MString);
|
|
Register_Object(m_pErf_Name_List.GetHead());
|
|
(*(theApp.m_phashErfNameMapping)).AddValue(new Stuff::PlugOf<MString *> (m_pErf_Name_List.GetHead()), 0);
|
|
erf_texture_path = new Stuff::MString;
|
|
Register_Object(erf_texture_path);
|
|
erf_effects_path = new Stuff::MString;
|
|
Register_Object(erf_effects_path);
|
|
|
|
//
|
|
//---------------------
|
|
// Build the scene root
|
|
//---------------------
|
|
//
|
|
theApp.GetTexturePath();
|
|
theApp.GetEffectsPath();
|
|
|
|
|
|
Scene = new ElementRenderer::GroupElement;
|
|
Register_Object(Scene);
|
|
Scene->SetRootMode();
|
|
Scene->LockBounds();
|
|
|
|
LightState = new ElementRenderer::StateChange;
|
|
Register_Object(LightState);
|
|
for(int li=0;li<MidLevelRenderer::Limits::Max_Number_Of_Lights_Per_Primitive;li++)
|
|
LightState->m_lights[li]=NULL;
|
|
Scene->AdoptStateChange(LightState);
|
|
|
|
//
|
|
//------------------------
|
|
// Set up the texture pool
|
|
//------------------------
|
|
//
|
|
if(erf_texture_path->GetLength())
|
|
{
|
|
gos_PushCurrentHeap(MidLevelRenderer::TexturePoolHeap);
|
|
MidLevelRenderer::TGAFilePool *pool =
|
|
new MidLevelRenderer::TGAFilePool(*erf_texture_path, "textures.hint");
|
|
Register_Object(pool);
|
|
MidLevelRenderer::MLRTexturePool::Instance = new MidLevelRenderer::MLRTexturePool(pool);
|
|
Check_Object(MidLevelRenderer::MLRTexturePool::Instance);
|
|
Register_Object(MidLevelRenderer::MLRTexturePool::Instance);
|
|
gos_PopCurrentHeap();
|
|
|
|
#if 0
|
|
Stuff::MString effects_name = *erf_texture_path;
|
|
int content_root_length = effects_name.GetLength() - 9;
|
|
Verify(!_stricmp(&((char*)effects_name)[content_root_length], "Textures\\"));
|
|
((char*)effects_name)[content_root_length] = '\0';
|
|
effects_name.SetLength(content_root_length);
|
|
effects_name += "Effects\\mw.effects";
|
|
|
|
Stuff::FileStream *stream = Stuff::FileStream::MakeFileStream(effects_name);
|
|
Register_Object(stream);
|
|
gosFX::EffectLibrary::Instance = new gosFX::EffectLibrary;
|
|
Register_Object(gosFX::EffectLibrary::Instance);
|
|
gosFX::EffectLibrary::Instance->Load(stream);
|
|
Unregister_Object(stream);
|
|
delete stream;
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
// fatal warning
|
|
}
|
|
|
|
//
|
|
//----------------------------------------------
|
|
// Load the .ERF file and attach it to the scene
|
|
//----------------------------------------------
|
|
//
|
|
//if(erf_name->GetLength())
|
|
/* if (erf_name)
|
|
{
|
|
theApp.m_perf_file = new Stuff::FileStream(*erf_name);
|
|
|
|
ErfElement =
|
|
ElementRenderer::Element::Create(
|
|
theApp.m_perf_file,
|
|
ElementRenderer::ReadERFVersion(theApp.m_perf_file)
|
|
);
|
|
Scene->AttachChild(ErfElement);
|
|
}*/
|
|
|
|
//---------------
|
|
// Build a camera
|
|
//---------------
|
|
//
|
|
gos_PushCurrentHeap(ElementRenderer::g_Heap);
|
|
Camera_State = new ElementRenderer::StateChange();
|
|
Register_Object(Camera_State);
|
|
Camera_State->EnableBackfaceCulling();
|
|
Camera_State->EnableDithering();
|
|
Camera_State->EnablePerspectiveCorrection();
|
|
Camera_State->EnableZBufferWrite();
|
|
Camera_State->EnableZBufferCompare();
|
|
Camera_State->SetFogColor(fogColor);
|
|
Camera_State->SetFogMode(ElementRenderer::StateChange::DisableFogMode);
|
|
Camera = new ElementRenderer::CameraElement(Camera_State);
|
|
Register_Object(Camera);
|
|
Scene->AttachChild(Camera);
|
|
Camera->SetPerspective(1.0f, 1000.0f, Stuff::Pi_Over_3);
|
|
Camera->SetViewport(1.0f, 1.0f, 0.0f, 0.0f);
|
|
Camera->SetScene(Scene);
|
|
Stuff::LinearMatrix4D origin;
|
|
origin.BuildRotation(
|
|
Stuff::EulerAngles(Camera_Direction.pitch, Camera_Direction.yaw, 0.0f)
|
|
);
|
|
origin.BuildTranslation(Stuff::Point3D(Camera_Direction));
|
|
Camera->SetLocalToParent(origin);
|
|
|
|
|
|
CString strWindowTitle;
|
|
strWindowTitle.Format("%s = %f", "Camera Distance", Camera_Direction.range);
|
|
theApp.Window3D->SetWindowText((LPCSTR)strWindowTitle);
|
|
|
|
gos_PopCurrentHeap();
|
|
// Camera->SetFogColor(fogColor);
|
|
|
|
#if 0
|
|
//Make a Point Cloud
|
|
drawEffectInfo = new MidLevelRenderer::DrawEffectInformation;
|
|
Register_Pointer(drawEffectInfo);
|
|
drawEffectInfo->effect = new MidLevelRenderer::MLRPointCloud(Point_Count, 4);
|
|
Register_Object(drawEffectInfo->effect);
|
|
|
|
drawEffectInfo->clippingFlags.SetClippingState(0x3f);
|
|
drawEffectInfo->effectToWorld = NULL;
|
|
drawEffectInfo->effect->TurnAllOn();
|
|
drawEffectInfo->state.SetFogMode(MidLevelRenderer::MLRState::DisableFogMode);
|
|
drawEffectInfo->state.SetZBufferWriteOff();
|
|
drawEffectInfo->state.SetZBufferCompareOff();
|
|
|
|
unsigned i;
|
|
for (i=0; i<MidLevelRenderer::Limits::Max_Number_Vertices_Per_Mesh; ++i)
|
|
{
|
|
Color_Data[i] = Stuff::RGBAColor(
|
|
0.95f + Stuff::Random::GetFraction()*0.05f,
|
|
0.0f,
|
|
0.0f,
|
|
1.0f
|
|
);
|
|
}
|
|
#endif
|
|
|
|
//Make a Point Cloud
|
|
gos_PushCurrentHeap(MidLevelRenderer::EffectHeap);
|
|
drawEffectInfo[0] = new MidLevelRenderer::DrawEffectInformation;
|
|
Register_Pointer(drawEffectInfo[0]);
|
|
drawEffectInfo[0]->effect = new MidLevelRenderer::MLRPointCloud(Point_Count, 4);
|
|
Register_Object(drawEffectInfo[0]->effect);
|
|
gos_PopCurrentHeap();
|
|
|
|
drawEffectInfo[0]->clippingFlags.SetClippingState(0x3f);
|
|
drawEffectInfo[0]->effectToWorld = NULL;
|
|
drawEffectInfo[0]->effect->TurnAllOn();
|
|
|
|
// drawEffectInfo[0]->state.SetFogMode(MidLevelRenderer::MLRState::DisableFogMode);
|
|
drawEffectInfo[0]->state.SetFogMode(0);
|
|
drawEffectInfo[0]->state.SetZBufferWriteOff();
|
|
drawEffectInfo[0]->state.SetZBufferCompareOff();
|
|
|
|
drawEffectInfo[0]->state.SetPriority(15);
|
|
|
|
unsigned i;
|
|
for (i=0; i<MidLevelRenderer::Limits::Max_Number_Vertices_Per_Mesh; ++i)
|
|
{
|
|
Color_Data[0][i] = Stuff::RGBAColor(
|
|
0.95f + Stuff::Random::GetFraction()*0.05f,
|
|
0.0f,
|
|
0.0f,
|
|
1.0f
|
|
);
|
|
}
|
|
|
|
//Make a Line Cloud
|
|
gos_PushCurrentHeap(MidLevelRenderer::EffectHeap);
|
|
drawEffectInfo[1] = new MidLevelRenderer::DrawEffectInformation;
|
|
Register_Pointer(drawEffectInfo[1]);
|
|
drawEffectInfo[1]->effect = new MidLevelRenderer::MLRLineCloud(Point_Count, 4);
|
|
Register_Object(drawEffectInfo[1]->effect);
|
|
gos_PopCurrentHeap();
|
|
|
|
drawEffectInfo[1]->clippingFlags.SetClippingState(0x3f);
|
|
drawEffectInfo[1]->effectToWorld = NULL;
|
|
drawEffectInfo[1]->effect->TurnAllOn();
|
|
|
|
// drawEffectInfo[1]->state.SetFogMode(MidLevelRenderer::MLRState::DisableFogMode);
|
|
drawEffectInfo[1]->state.SetFogMode(0);
|
|
drawEffectInfo[1]->state.SetZBufferWriteOff();
|
|
drawEffectInfo[1]->state.SetZBufferCompareOn();
|
|
drawEffectInfo[1]->state.SetFilterMode(MidLevelRenderer::MLRState::BiLinearFilterMode);
|
|
|
|
drawEffectInfo[1]->state.SetPriority(15);
|
|
|
|
for (i=0; i<MidLevelRenderer::Limits::Max_Number_Vertices_Per_Mesh; ++i)
|
|
{
|
|
Color_Data[1][2*i] = Stuff::RGBAColor(
|
|
0.0f,
|
|
0.9f,
|
|
0.0f,
|
|
1.0f
|
|
);
|
|
}
|
|
//
|
|
//-----------------------------------------------------
|
|
// Sync the matrices of the scene and load the textures
|
|
//-----------------------------------------------------
|
|
//
|
|
Scene->Sync();
|
|
|
|
#ifdef SHADOW_TEST
|
|
gos_PushCurrentHeap(MidLevelRenderer::LightsHeap);
|
|
DWORD hints = gosHint_DisableMipmap | gosHint_DontShrink;
|
|
shadowTexture = MLRTexturePool::Instance->Add("Shadow Test", gos_Texture_Keyed, 256, (gos_TextureHints)hints);
|
|
|
|
MidLevelRenderer::MLR_I_TMesh *shadowMesh = new MidLevelRenderer::MLR_I_TMesh;
|
|
Register_Object(shadowMesh);
|
|
shadowMesh->AttachReference();
|
|
|
|
shadowMesh->dataStore->coords.SetLength(4);
|
|
shadowMesh->dataStore->coords[0] = Point3D(-5.0f, 0.0f, 0.0f);
|
|
shadowMesh->dataStore->coords[1] = Point3D(-5.0f, 0.0f, 10.0f);
|
|
shadowMesh->dataStore->coords[2] = Point3D(5.0f, 0.0f, 10.0f);
|
|
shadowMesh->dataStore->coords[3] = Point3D(5.0f, 0.0f, 0.0f);
|
|
shadowMesh->SetCoordData(shadowMesh->dataStore->coords.GetData(), 4);
|
|
|
|
shadowMesh->dataStore->texCoords.SetLength(4);
|
|
shadowMesh->dataStore->texCoords[0] = Vector2DScalar(0.0f, 0.0f);
|
|
shadowMesh->dataStore->texCoords[1] = Vector2DScalar(0.0f, 1.0f);
|
|
shadowMesh->dataStore->texCoords[2] = Vector2DScalar(1.0f, 1.0f);
|
|
shadowMesh->dataStore->texCoords[3] = Vector2DScalar(1.0f, 0.0f);
|
|
shadowMesh->SetTexCoordData(shadowMesh->dataStore->texCoords.GetData(), 4);
|
|
|
|
shadowMesh->dataStore->index.SetLength(6);
|
|
shadowMesh->dataStore->index[0] = 0;
|
|
shadowMesh->dataStore->index[1] = 1;
|
|
shadowMesh->dataStore->index[2] = 2;
|
|
shadowMesh->dataStore->index[3] = 0;
|
|
shadowMesh->dataStore->index[4] = 2;
|
|
shadowMesh->dataStore->index[5] = 3;
|
|
shadowMesh->SetIndexData(shadowMesh->dataStore->index.GetData(), 6);
|
|
|
|
shadowMesh->SetSubprimitiveLengths(NULL, 2);
|
|
|
|
MLRState state;
|
|
state.SetTextureHandle(shadowTexture->GetTextureHandle());
|
|
state.SetZBufferCompareOn();
|
|
|
|
shadowMesh->SetReferenceState(state);
|
|
gos_PopCurrentHeap();
|
|
|
|
gos_PushCurrentHeap(MidLevelRenderer::ShapesHeap);
|
|
shadowShape = new MidLevelRenderer::MLRShape(1);
|
|
Register_Object(shadowShape);
|
|
|
|
shadowShape->Add(shadowMesh);
|
|
|
|
shadowMatrix = Stuff::LinearMatrix4D::Identity;
|
|
shadowMatrix.BuildTranslation(Point3D(0.0f, -10.0f, 5.0));
|
|
|
|
drawShapeInfo.shape = shadowShape;
|
|
drawShapeInfo.nrOfActiveLights = 0;
|
|
drawShapeInfo.clippingFlags.SetClippingState(0x3f);
|
|
drawShapeInfo.shapeToWorld = &shadowMatrix;
|
|
drawShapeInfo.worldToShape = &shadowMatrix;
|
|
drawShapeInfo.paintMeColor = &RGBAColor::White;
|
|
|
|
gos_PopCurrentHeap();
|
|
#endif
|
|
|
|
MidLevelRenderer::MLRTexturePool::Instance->LoadImages();
|
|
}
|
|
|
|
#ifdef SHADOW_TEST
|
|
void
|
|
TraversErfBranch(ElementRenderer::Element *elmt)
|
|
{
|
|
if(elmt->GetClassID() == ElementRenderer::CameraElementClassID)
|
|
{
|
|
return;
|
|
}
|
|
|
|
switch(elmt->GetClassID())
|
|
{
|
|
case ElementRenderer::GroupElementClassID:
|
|
{
|
|
ElementRenderer::GroupElement *group = Cast_Pointer(ElementRenderer::GroupElement *, elmt);
|
|
|
|
Stuff::ChainIteratorOf<ElementRenderer::Element*> *children = group->MakeIterator();
|
|
Register_Object(children);
|
|
|
|
ElementRenderer::Element *child = NULL;
|
|
while ((child = children->ReadAndNext()) != NULL)
|
|
{
|
|
TraversErfBranch( child);
|
|
}
|
|
Unregister_Object(children);
|
|
delete children;
|
|
}
|
|
break;
|
|
|
|
case ElementRenderer::ListElementClassID:
|
|
{
|
|
ElementRenderer::ListElement *group = Cast_Pointer(ElementRenderer::ListElement *, elmt);
|
|
|
|
for(int i=0;i<group->GetActiveCount();i++)
|
|
{
|
|
TraversErfBranch(group->GetIndexedElement(i));
|
|
}
|
|
}
|
|
break;
|
|
case ElementRenderer::GridElementClassID:
|
|
{
|
|
ElementRenderer::GridElement *group = Cast_Pointer(ElementRenderer::GridElement *, elmt);
|
|
|
|
unsigned xSize, zSize;
|
|
group->GetSize(&xSize, &zSize);
|
|
for(int i=0;i<zSize;i++)
|
|
for(int j=0;j<xSize;j++)
|
|
{
|
|
TraversErfBranch( group->GetIndexedElement(i, j));
|
|
}
|
|
}
|
|
break;
|
|
case ElementRenderer::LODElementClassID:
|
|
{
|
|
ElementRenderer::ListElement *group = Cast_Pointer(ElementRenderer::ListElement *, elmt);
|
|
|
|
for(int i=0;i<group->GetActiveCount();i++)
|
|
{
|
|
TraversErfBranch(group->GetIndexedElement(i));
|
|
}
|
|
}
|
|
break;
|
|
case ElementRenderer::PointCloudElementClassID:
|
|
{
|
|
}
|
|
break;
|
|
case ElementRenderer::ScalableShapeElementClassID:
|
|
{
|
|
ElementRenderer::ShapeElement *group = Cast_Pointer(ElementRenderer::ShapeElement *, elmt);
|
|
MidLevelRenderer::MLRShape *shape=group->GetMLRShape();
|
|
|
|
UnitVector3D uvec;
|
|
uvec.Normalize(UnitVector3D(0.0f, -1.0f, 1.0f));
|
|
shape->DrawMyShadow(shadowMatrix, uvec);
|
|
}
|
|
break;
|
|
case ElementRenderer::ScreenQuadsElementClassID:
|
|
{
|
|
}
|
|
break;
|
|
|
|
case ElementRenderer::ShapeElementClassID:
|
|
{
|
|
ElementRenderer::ShapeElement *group = Cast_Pointer(ElementRenderer::ShapeElement *, elmt);
|
|
MidLevelRenderer::MLRShape *shape = group->GetMLRShape();
|
|
|
|
UnitVector3D uvec;
|
|
uvec.Normalize(UnitVector3D(0.0f, -1.0f, 1.0f));
|
|
shape->DrawMyShadow(shadowMatrix, uvec);
|
|
}
|
|
break;
|
|
case ElementRenderer::SwitchElementClassID:
|
|
{
|
|
ElementRenderer::ListElement *group = Cast_Pointer(ElementRenderer::ListElement *, elmt);
|
|
|
|
for(int i=0;i<group->GetActiveCount();i++)
|
|
{
|
|
TraversErfBranch(group->GetIndexedElement(i));
|
|
}
|
|
}
|
|
break;
|
|
case ElementRenderer::TriangleCloudElementClassID:
|
|
{
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void _stdcall DoGameLogic()
|
|
{
|
|
DWORD level = gCurrentHeapStackLevel;
|
|
|
|
//
|
|
//-----------------------------------------------
|
|
// Read the keyboard to see how to set the switch
|
|
//-----------------------------------------------
|
|
//
|
|
if(!Camera_State)
|
|
{
|
|
Verify(gCurrentHeapStackLevel == level);
|
|
return;
|
|
}
|
|
|
|
Check_Object(Camera_State);
|
|
MidLevelRenderer::MLRState mlr_state = Camera_State->GetMLRState();
|
|
|
|
//
|
|
//---------------
|
|
// Read the mouse
|
|
//---------------
|
|
//
|
|
int
|
|
x_delta,
|
|
y_delta;
|
|
Stuff::Scalar
|
|
n_xdelta,
|
|
n_ydelta;
|
|
|
|
DWORD
|
|
buttons;
|
|
gos_GetMouseInfo(NULL, NULL, &x_delta, &y_delta, NULL, &buttons);
|
|
Stuff::Scalar
|
|
x_speed = x_delta * 0.01f,
|
|
y_speed = y_delta * 0.01f;
|
|
|
|
n_xdelta=(Stuff::Scalar)x_delta/Environment.screenWidth;
|
|
n_ydelta=(Stuff::Scalar)y_delta/Environment.screenHeight;
|
|
|
|
//
|
|
//------------------------------------------------------
|
|
// If the left Ctrl button is held down, move the camera
|
|
//------------------------------------------------------
|
|
//
|
|
gosEnum_KeyStatus status = gos_GetKeyStatus(KEY_LCONTROL);
|
|
if (status != KEY_FREE && status != KEY_RELEASED)
|
|
{
|
|
Camera_Direction.pitch += y_speed;
|
|
Camera_Direction.yaw -= x_speed;
|
|
if(theApp.Window3D)
|
|
theApp.Window3D->SetCapture();
|
|
|
|
}
|
|
|
|
//
|
|
//------------------------------------------------------
|
|
// If the left Shift button is held down, pan the camera
|
|
//------------------------------------------------------
|
|
//
|
|
status = gos_GetKeyStatus(KEY_LSHIFT);
|
|
if (status != KEY_FREE && status != KEY_RELEASED)
|
|
{
|
|
Camera_Shift.x += n_xdelta*Camera_Direction.range;
|
|
Camera_Shift.y += n_ydelta*Camera_Direction.range;
|
|
if(theApp.Window3D)
|
|
theApp.Window3D->SetCapture();
|
|
|
|
}
|
|
|
|
//
|
|
//-----------------------------------------------------
|
|
// If the left Alt button is held down, zoom the camera
|
|
//-----------------------------------------------------
|
|
//
|
|
status = gos_GetKeyStatus(KEY_LMENU);
|
|
if (status != KEY_FREE && status != KEY_RELEASED)
|
|
{
|
|
Camera_Direction.range *=(Stuff::Scalar)pow(2, n_ydelta);
|
|
if(theApp.Window3D)
|
|
theApp.Window3D->SetCapture();
|
|
|
|
}
|
|
|
|
|
|
Stuff::LinearMatrix4D ZTrans(true);
|
|
Stuff::LinearMatrix4D LookAtTrans(true);
|
|
Stuff::LinearMatrix4D RotMat(true);
|
|
Stuff::LinearMatrix4D PanMat(true);
|
|
Stuff::LinearMatrix4D TempMat1(true),TempMat2(true),CameraMatrix(true);
|
|
|
|
ZTrans.BuildTranslation(Stuff::Point3D(0.0f,0.0f,-Camera_Direction.range));
|
|
RotMat.BuildRotation(Stuff::EulerAngles(Camera_Direction.pitch,Camera_Direction.yaw , 0.0f));
|
|
LookAtTrans.BuildTranslation(Camera_LookAt);
|
|
PanMat.BuildTranslation(Stuff::Point3D(Camera_Shift.x,Camera_Shift.y,0.0f));
|
|
|
|
TempMat1.Multiply(PanMat,ZTrans);
|
|
TempMat2.Multiply(TempMat1,RotMat);
|
|
CameraMatrix.Multiply(TempMat2,LookAtTrans);
|
|
|
|
Camera->SetLocalToParent(CameraMatrix);
|
|
CString strWindowTitle;
|
|
static Stuff::Scalar old_camera_range = 0.0f;
|
|
if (old_camera_range != Camera_Direction.range)
|
|
{
|
|
strWindowTitle.Format("%s = %f", "Camera Distance", Camera_Direction.range);
|
|
theApp.Window3D->SetWindowText((LPCSTR)strWindowTitle);
|
|
old_camera_range = Camera_Direction.range;
|
|
}
|
|
|
|
|
|
//
|
|
//-------------------------------------------------------
|
|
// Now that we have moved everything, update the matrices
|
|
//-------------------------------------------------------
|
|
//
|
|
Camera->Sync();
|
|
|
|
MidLevelRenderer::MLRTexturePool::Instance->LoadImages();
|
|
Verify(gCurrentHeapStackLevel == level);
|
|
|
|
#ifdef SHADOW_TEST
|
|
MidLevelRenderer::MLRState dState;
|
|
|
|
Camera->GetClipper()->StartDraw(
|
|
Stuff::LinearMatrix4D::Identity,
|
|
Stuff::LinearMatrix4D::Identity,
|
|
Stuff::RGBAColor::White,
|
|
&Stuff::RGBAColor::White,
|
|
dState,
|
|
NULL
|
|
);
|
|
|
|
gos_StartRenderToTexture( shadowTexture->GetImage()->GetHandle() );
|
|
TraversErfBranch(Scene);
|
|
gos_EndRenderToTexture();
|
|
|
|
End3DScene();
|
|
#endif
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void _stdcall UpdateDisplay()
|
|
{
|
|
DWORD level = gCurrentHeapStackLevel;
|
|
|
|
Camera->SetViewport(1.0f, 1.0f, 0.0f, 0.0f);
|
|
Camera->DrawScene();
|
|
|
|
MidLevelRenderer::MLRState dState;
|
|
Camera->GetClipper()->ResetSorter(dState);
|
|
|
|
if(drawPointsYes == true)
|
|
{
|
|
Camera->GetClipper()->DrawEffect(drawEffectInfo[0]);
|
|
}
|
|
if(drawNormalsYes == true)
|
|
{
|
|
Camera->GetClipper()->DrawEffect(drawEffectInfo[1]);
|
|
}
|
|
|
|
#ifdef SHADOW_TEST
|
|
Camera->GetClipper()->DrawShape(&drawShapeInfo);
|
|
#endif
|
|
|
|
if(drawPointsYes == true || drawNormalsYes == true)
|
|
{
|
|
Camera->GetClipper()->RenderNow();
|
|
}
|
|
|
|
MLRTexture *tex = NULL;
|
|
if(bumpAnime.water>0 && (tex = (*MidLevelRenderer::MLRTexturePool::Instance)[bumpAnime.water])!=NULL)
|
|
{
|
|
Stuff::AffineMatrix4D *texture_matrix = tex->GetTextureMatrix();
|
|
texture_matrix->entries[3] = bumpAnime.wu*animeCounter;
|
|
texture_matrix->entries[7] = bumpAnime.wv*animeCounter;
|
|
}
|
|
tex = NULL;
|
|
if(bumpAnime.bump>0 && (tex = (*MidLevelRenderer::MLRTexturePool::Instance)[bumpAnime.bump])!=NULL)
|
|
{
|
|
Stuff::AffineMatrix4D *texture_matrix = tex->GetTextureMatrix();
|
|
texture_matrix->entries[3] = bumpAnime.bu*animeCounter;
|
|
texture_matrix->entries[7] = bumpAnime.bv*animeCounter;
|
|
}
|
|
tex = NULL;
|
|
if(bumpAnime.normal>0 && (tex = (*MidLevelRenderer::MLRTexturePool::Instance)[bumpAnime.normal])!=NULL)
|
|
{
|
|
Stuff::AffineMatrix4D *texture_matrix = tex->GetTextureMatrix();
|
|
texture_matrix->entries[3] = bumpAnime.nu*animeCounter;
|
|
texture_matrix->entries[7] = bumpAnime.nv*animeCounter;
|
|
}
|
|
|
|
animeCounter++;
|
|
|
|
static float lasttime=(float)gos_GetElapsedTime();
|
|
float thistime=(float)gos_GetElapsedTime();
|
|
float timepast=(thistime-lasttime);
|
|
YawPitchRoll ypr(thistime*Stuff::Pi_Over_2/5.0f,Stuff::Pi_Over_4,0.0f);
|
|
LinearMatrix4D mat(ypr);
|
|
Vector3D vect(0,0,1),v2;
|
|
v2.Multiply(vect,mat);
|
|
v2.Normalize(v2);
|
|
MLR_BumpyWater::SetSunLight(UnitVector3D(v2));
|
|
//MLR_Water::SetSunLight(UnitVector3D(v2));
|
|
|
|
lasttime=thistime;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void _stdcall TerminateGameEngine()
|
|
{
|
|
while (m_pErf_Name_List.GetCount() && m_pErf_Name_List.GetHead())
|
|
{Unregister_Object(m_pErf_Name_List.GetHead()); delete m_pErf_Name_List.GetHead(); m_pErf_Name_List.RemoveHead();}
|
|
(*(theApp.m_phashErfNameMapping)).DeletePlugs();
|
|
delete theApp.m_phashErfNameMapping;
|
|
Unregister_Object(erf_texture_path);
|
|
delete erf_texture_path;
|
|
|
|
Unregister_Object(drawEffectInfo[0]->effect);
|
|
delete drawEffectInfo[0]->effect;
|
|
Unregister_Pointer(drawEffectInfo[0]);
|
|
delete drawEffectInfo[0];
|
|
|
|
Unregister_Object(drawEffectInfo[1]->effect);
|
|
delete drawEffectInfo[1]->effect;
|
|
Unregister_Pointer(drawEffectInfo[1]);
|
|
delete drawEffectInfo[1];
|
|
|
|
//
|
|
//-------------------
|
|
// Turn off libraries
|
|
//-------------------
|
|
//
|
|
ElementRenderer::TerminateClasses();
|
|
gosFX::TerminateClasses();
|
|
MidLevelRenderer::TerminateClasses();
|
|
Stuff::TerminateClasses();
|
|
|
|
Camera_State=NULL;
|
|
}
|
|
|
|
|
|
//
|
|
// Setup the GameOS structure
|
|
//
|
|
void __stdcall GetGameOSEnvironment( char* CommandLine )
|
|
{
|
|
// Command_Line=CommandLine;
|
|
Environment.applicationName = "ERFViewer";
|
|
Environment.screenWidth = 640;
|
|
Environment.screenHeight = 480;
|
|
Environment.fullScreen = FALSE;
|
|
Environment.bitDepth = 16;
|
|
Environment.debugLog = "ErfViewer.txt";
|
|
Environment.spew = ""; //"GameOS*";
|
|
|
|
Environment.UpdateRenderers = UpdateDisplay;
|
|
Environment.DoGameLogic = DoGameLogic;
|
|
Environment.InitializeGameEngine = InitializeGameEngine;
|
|
Environment.TerminateGameEngine = TerminateGameEngine;
|
|
|
|
Environment.Renderer = 0;
|
|
Environment.FullScreenDevice = 0;
|
|
|
|
Environment.AntiAlias = 0; // true/false - Enable full screen antialiasing
|
|
|
|
//
|
|
// Texture infomation
|
|
//
|
|
Environment.Texture_S_256 = 13;
|
|
Environment.Texture_S_128 = 12;
|
|
Environment.Texture_S_64 = 1;
|
|
Environment.Texture_S_32 = 1;
|
|
Environment.Texture_S_16 = 1;
|
|
|
|
Environment.Texture_K_256 = 1;
|
|
Environment.Texture_K_128 = 1;
|
|
Environment.Texture_K_64 = 1;
|
|
Environment.Texture_K_32 = 1;
|
|
Environment.Texture_K_16 = 1;
|
|
|
|
Environment.Texture_A_256 = 1;
|
|
Environment.Texture_A_128 = 1;
|
|
Environment.Texture_A_64 = 1;
|
|
Environment.Texture_A_32 = 1;
|
|
Environment.Texture_A_16 = 1;
|
|
|
|
Environment.dontClearRegistry = true;
|
|
}
|
|
|
|
|
|
void __stdcall ILFree(LPITEMIDLIST pidl);
|
|
|
|
|
|
void CMFCGosApp::OnOptionsTexturepath()
|
|
{
|
|
NewTexturePath();
|
|
MessageBox(NULL,"These changes will not take effect until the program is restarted","Warning!!!",MB_OK|MB_ICONEXCLAMATION);
|
|
}
|
|
|
|
|
|
void __stdcall ILFree(LPITEMIDLIST pidl)
|
|
{
|
|
LPMALLOC pMalloc;
|
|
|
|
if (pidl)
|
|
{
|
|
#ifdef DEBUG
|
|
UINT cbSize = ILGetSize(pidl);
|
|
VALIDATE_PIDL(pidl);
|
|
|
|
// Fill the memory with some bad value...
|
|
_fmemset(pidl, 0xE5, cbSize);
|
|
|
|
// If large enough try to save the call return address of who
|
|
// freed us in the 3-6 byte of the structure.
|
|
if (cbSize >= 6)
|
|
*((UINT*)((LPSTR)pidl + 2)) = *(((UINT*)&pidl) - 1);
|
|
|
|
#endif
|
|
SHGetMalloc(&pMalloc);
|
|
pMalloc->Free( pidl);
|
|
pMalloc->Release();
|
|
|
|
}
|
|
}
|
|
|
|
void CMFCGosApp::GetTexturePath()
|
|
{
|
|
|
|
TexturePath=GetProfileString("ERF Viewer MFC","TexturePath");
|
|
if(TexturePath.GetLength()==0)
|
|
{
|
|
NewTexturePath();
|
|
} // end if string in Registry
|
|
|
|
|
|
*erf_texture_path = Stuff::MString((LPCSTR)TexturePath);
|
|
if(erf_texture_path->GetLength())
|
|
{
|
|
if(MidLevelRenderer::MLRTexturePool::Instance)
|
|
{
|
|
MidLevelRenderer::TGAFilePool *pool =
|
|
new MidLevelRenderer::TGAFilePool(*erf_texture_path, "textures.hint");
|
|
Register_Object(pool);
|
|
MidLevelRenderer::MLRTexturePool::Instance = new MidLevelRenderer::MLRTexturePool(pool);
|
|
Check_Object(MidLevelRenderer::MLRTexturePool::Instance);
|
|
Register_Object(MidLevelRenderer::MLRTexturePool::Instance);
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
void CMFCGosApp::NewTexturePath()
|
|
{
|
|
char pname[MAX_PATH];
|
|
BROWSEINFO bi;
|
|
if(m_pMainWnd==NULL)
|
|
bi.hwndOwner =NULL;
|
|
else
|
|
bi.hwndOwner = m_pMainWnd->m_hWnd;
|
|
|
|
bi.pidlRoot = NULL;
|
|
bi.pszDisplayName = NULL;
|
|
bi.lpszTitle = "Choose Texture Path...";
|
|
bi.ulFlags = BIF_RETURNONLYFSDIRS;
|
|
bi.lpfn = NULL;
|
|
bi.lParam = (LPARAM)this;
|
|
|
|
LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
|
|
|
|
if (SHGetPathFromIDList(pidl,pname))
|
|
{
|
|
TexturePath=pname;
|
|
TexturePath+="\\";
|
|
|
|
|
|
WriteProfileString("ERF Viewer MFC","TexturePath",TexturePath);
|
|
}
|
|
|
|
if (bi.pidlRoot)
|
|
{
|
|
ILFree( const_cast< ITEMIDLIST* >( bi.pidlRoot ) );
|
|
}
|
|
|
|
}
|
|
|
|
void CMFCGosApp::GetEffectsPath()
|
|
{
|
|
|
|
EffectsPath=GetProfileString("ERF Viewer MFC","EffectsPath");
|
|
if(EffectsPath.GetLength()==0)
|
|
{
|
|
NewEffectsPath();
|
|
} // end if string in Registry
|
|
|
|
|
|
*erf_effects_path = Stuff::MString((LPCSTR)EffectsPath);
|
|
if(erf_effects_path->GetLength())
|
|
{
|
|
}
|
|
|
|
|
|
}
|
|
|
|
void CMFCGosApp::NewEffectsPath()
|
|
{
|
|
char pname[MAX_PATH];
|
|
BROWSEINFO bi;
|
|
if(m_pMainWnd==NULL)
|
|
bi.hwndOwner =NULL;
|
|
else
|
|
bi.hwndOwner = m_pMainWnd->m_hWnd;
|
|
|
|
bi.pidlRoot = NULL;
|
|
bi.pszDisplayName = NULL;
|
|
bi.lpszTitle = "Choose effects Path...";
|
|
bi.ulFlags = BIF_RETURNONLYFSDIRS;
|
|
bi.lpfn = NULL;
|
|
bi.lParam = (LPARAM)this;
|
|
|
|
LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
|
|
|
|
if (SHGetPathFromIDList(pidl,pname))
|
|
{
|
|
EffectsPath=pname;
|
|
EffectsPath+="\\";
|
|
|
|
|
|
WriteProfileString("ERF Viewer MFC","EffectsPath",EffectsPath);
|
|
}
|
|
|
|
if (bi.pidlRoot)
|
|
{
|
|
ILFree( const_cast< ITEMIDLIST* >( bi.pidlRoot ) );
|
|
}
|
|
|
|
}
|
|
|
|
BOOL CMFCGosApp::ProcessShellCommandNoLoad(CCommandLineInfo &rCmdInfo)
|
|
{
|
|
BOOL bResult = TRUE;
|
|
switch (rCmdInfo.m_nShellCommand)
|
|
{
|
|
case CCommandLineInfo::FileNew:
|
|
case CCommandLineInfo::FileOpen:
|
|
if (!AfxGetApp()->OnCmdMsg(ID_FILE_NEW, 0, NULL, NULL))
|
|
OnFileNew();
|
|
if (m_pMainWnd == NULL)
|
|
bResult = FALSE;
|
|
break;
|
|
|
|
case CCommandLineInfo::FilePrintTo:
|
|
case CCommandLineInfo::FilePrint:
|
|
m_nCmdShow = SW_HIDE;
|
|
ASSERT(m_pCmdInfo == NULL);
|
|
OpenDocumentFile(rCmdInfo.m_strFileName);
|
|
m_pCmdInfo = &rCmdInfo;
|
|
m_pMainWnd->SendMessage(WM_COMMAND, ID_FILE_PRINT_DIRECT);
|
|
m_pCmdInfo = NULL;
|
|
bResult = FALSE;
|
|
break;
|
|
|
|
// If we're doing DDE, hide ourselves
|
|
|
|
case CCommandLineInfo::FileDDE:
|
|
m_pCmdInfo = (CCommandLineInfo*)m_nCmdShow;
|
|
m_nCmdShow = SW_HIDE;
|
|
break;
|
|
|
|
// If we've been asked to unregister, unregister and then terminate
|
|
case CCommandLineInfo::AppUnregister:
|
|
{
|
|
UnregisterShellFileTypes();
|
|
BOOL bUnregistered = Unregister();
|
|
|
|
// if you specify /EMBEDDED, we won't make an success/failure box
|
|
// this use of /EMBEDDED is not related to OLE
|
|
|
|
if (!rCmdInfo.m_bRunEmbedded)
|
|
{
|
|
if (bUnregistered)
|
|
AfxMessageBox(AFX_IDP_UNREG_DONE);
|
|
else
|
|
AfxMessageBox(AFX_IDP_UNREG_FAILURE);
|
|
}
|
|
bResult = FALSE; // that's all we do
|
|
|
|
// If nobody is using it already, we can use it.
|
|
// We'll flag that we're unregistering and not save our state
|
|
// on the way out. This new object gets deleted by the
|
|
// app object destructor.
|
|
|
|
if (m_pCmdInfo == NULL)
|
|
{
|
|
m_pCmdInfo = new CCommandLineInfo;
|
|
m_pCmdInfo->m_nShellCommand = CCommandLineInfo::AppUnregister;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
return bResult;
|
|
}
|
|
|
|
BOOL CMFCGosApp::ProcessShellCommandOnlyLoad(CCommandLineInfo &rCmdInfo)
|
|
{
|
|
BOOL bResult = TRUE;
|
|
switch (rCmdInfo.m_nShellCommand)
|
|
{
|
|
// If we've been asked to open a file, call OpenDocumentFile()
|
|
|
|
case CCommandLineInfo::FileOpen:
|
|
if (!OpenDocumentFile(rCmdInfo.m_strFileName))
|
|
bResult = FALSE;
|
|
break;
|
|
|
|
}
|
|
return bResult;
|
|
}
|
|
|
|
void CMFCGosApp::OnView3dviewwindow()
|
|
{
|
|
// TODO: Add your command handler code here
|
|
if(Window3D)
|
|
Window3D->ShowWindow(Window3D->IsWindowVisible( )?SW_HIDE:SW_SHOW);
|
|
}
|
|
|
|
void CMFCGosApp::OnUpdateView3dviewwindow(CCmdUI* pCmdUI)
|
|
{
|
|
// TODO: Add your command update UI handler code here
|
|
if(Window3D)
|
|
pCmdUI->SetCheck( Window3D->IsWindowVisible( ));
|
|
}
|
|
|
|
void CMFCGosApp::GosShutDown()
|
|
{
|
|
|
|
theApp.Window3D->PreGosCleanUp();
|
|
|
|
if(Scene)
|
|
{
|
|
Unregister_Object(Scene);
|
|
delete Scene;
|
|
}
|
|
Stuff::FileStream * pFile;
|
|
while (theApp.m_pFileSet_List.GetCount() && ((pFile = theApp.m_pFileSet_List.GetHead()) != NULL))
|
|
{
|
|
delete pFile;
|
|
theApp.m_pFileSet_List.RemoveHead();
|
|
}
|
|
|
|
|
|
|
|
TerminateGameEngine();
|
|
// gos_PopCurrentHeap();
|
|
// gos_DestroyMemoryHeap(client);
|
|
ExitGameOS();
|
|
theApp.Window3D->GOSActive=false;
|
|
GOSActive=false;
|
|
}
|
|
|
|
void CMFCGosApp::DrawScreen()
|
|
{
|
|
DWORD level = gCurrentHeapStackLevel;
|
|
Verify(UpdateLevel>=0);
|
|
if(UpdateLevel==0)
|
|
{
|
|
UpdateLevel++;
|
|
if(RunGameOSLogic()) PostQuitMessage(0);
|
|
if(Window3DOpen==true) Window3D->UpdateMenu();
|
|
UpdateLevel--;
|
|
}
|
|
Verify(gCurrentHeapStackLevel == level);
|
|
}
|
|
|
|
void CMFCGosApp::OnViewUpdateonidle()
|
|
{
|
|
DrawOnIdle=!DrawOnIdle;
|
|
}
|
|
|
|
void CMFCGosApp::OnUpdateViewUpdateonidle(CCmdUI* pCmdUI)
|
|
{
|
|
pCmdUI->SetCheck(DrawOnIdle?1:0);
|
|
}
|
|
|
|
void CMFCGosApp::UpdateLightList()
|
|
{
|
|
int i,idx;
|
|
|
|
LightDlg->m_LightList.ResetContent();
|
|
for(i=0;i<MidLevelRenderer::Limits::Max_Number_Of_Lights_Per_Primitive && LightState->m_lights[i];i++)
|
|
{
|
|
switch(LightState->m_lights[i]->GetLightType())
|
|
{
|
|
case MidLevelRenderer::MLRLight::AmbientLight:
|
|
idx=LightDlg->m_LightList.AddString("Ambient Light");
|
|
break;
|
|
|
|
case MidLevelRenderer::MLRLight::InfiniteLight:
|
|
idx=LightDlg->m_LightList.AddString("Infinite Light");
|
|
break;
|
|
|
|
case MidLevelRenderer::MLRLight::PointLight:
|
|
idx=LightDlg->m_LightList.AddString("Point Light");
|
|
break;
|
|
|
|
case MidLevelRenderer::MLRLight::SpotLight:
|
|
idx=LightDlg->m_LightList.AddString("Spot Light");
|
|
break;
|
|
case MidLevelRenderer::MLRLight::ProjectLight:
|
|
idx=LightDlg->m_LightList.AddString("Project Light");
|
|
break;
|
|
}
|
|
LightDlg->m_LightList.SetItemDataPtr(idx,LightState->m_lights[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void CMFCGosApp::OnWindowsLightlist()
|
|
{
|
|
if(LightDlg)
|
|
LightDlg->ShowWindow(LightDlg->IsWindowVisible()?SW_HIDE:SW_SHOW);
|
|
}
|
|
|
|
void CMFCGosApp::OnUpdateWindowsLightlist(CCmdUI* pCmdUI)
|
|
{
|
|
if(LightDlg)
|
|
pCmdUI->SetCheck(LightDlg->IsWindowVisible()?1:0);
|
|
}
|
|
|
|
|
|
|
|
void CMFCGosApp::OnFileOpen()
|
|
{
|
|
CFileDialog dlg(true,"*.erf",NULL,OFN_ALLOWMULTISELECT | OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_SHAREAWARE,"MLR Files (*.erf;*.mlr)|*.erf;*.mlr||");
|
|
|
|
char szFileListOriginal[64*1024 +1] = "";
|
|
char szFileList[64*1024 +1] = "";
|
|
char *tmp= szFileList;
|
|
|
|
dlg.m_ofn.lpstrFile = szFileListOriginal;
|
|
dlg.m_ofn.nMaxFile = 64 * 1024 - 1;
|
|
|
|
|
|
if (IDOK==dlg.DoModal())
|
|
{
|
|
int count = 00;
|
|
|
|
|
|
|
|
|
|
|
|
POSITION pos = dlg.GetStartPosition();
|
|
CString strFileName;
|
|
while (pos)
|
|
{
|
|
count++;
|
|
if (count >= 64)
|
|
{
|
|
MessageBox(NULL, "Too many files. Files > 64.", "Error", MB_OK);
|
|
return;
|
|
}
|
|
strFileName = dlg.GetNextPathName(pos);
|
|
strcpy(tmp, (LPCSTR) strFileName);
|
|
if (pos) // there are more
|
|
{
|
|
tmp += strFileName.GetLength();
|
|
*tmp = '/';
|
|
tmp++;
|
|
}
|
|
}
|
|
CMFCGosDoc * pDoc = GetActiveErfDocument();
|
|
if (!pDoc)
|
|
return;
|
|
CWinApp::OnFileNew();
|
|
pDoc->OnOpenDocument(szFileList);
|
|
}
|
|
else
|
|
{
|
|
DWORD dwTemp = CommDlgExtendedError();
|
|
|
|
}
|
|
}
|
|
|
|
|
|
void CMFCGosApp::OnExpandAll()
|
|
{
|
|
CFrameWnd * pWnd = (CFrameWnd *)this->GetMainWnd();
|
|
CMFCGosView * pView = (CMFCGosView *)pWnd->GetActiveView();
|
|
pView->OnExpandAll();
|
|
|
|
}
|
|
|
|
void CMFCGosApp::OnCollapseAll()
|
|
{
|
|
CFrameWnd * pWnd = (CFrameWnd *)this->GetMainWnd();
|
|
CMFCGosView * pView = (CMFCGosView *)pWnd->GetActiveView();
|
|
pView->OnCollapseAll();
|
|
|
|
}
|
|
|
|
|
|
#define CAMERA_KEY_SPEED (1.0f)
|
|
void CMFCGosApp::UpdateCameraFromKeyMessage(UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
#define HIGHBITON(M_X) ((M_X & (1<<((sizeof(SHORT)*8)-1))) != 0)
|
|
BOOL controlDown = HIGHBITON(GetKeyState(VK_CONTROL));
|
|
BOOL shiftDown = HIGHBITON(GetKeyState(VK_SHIFT));
|
|
BOOL altDown = controlDown && shiftDown;//HIGHBITON(GetKeyState(VK_MENU));
|
|
if (altDown)
|
|
{
|
|
controlDown = shiftDown = false;
|
|
}
|
|
|
|
switch (wParam)
|
|
{
|
|
case VK_UP:
|
|
if (controlDown)
|
|
Camera_Direction.pitch -= CAMERA_KEY_SPEED * .05f;
|
|
if (shiftDown)
|
|
Camera_Shift.y += CAMERA_KEY_SPEED;
|
|
if (altDown)
|
|
Camera_Direction.range -= CAMERA_KEY_SPEED;
|
|
break;
|
|
case VK_DOWN:
|
|
if (controlDown)
|
|
Camera_Direction.pitch += CAMERA_KEY_SPEED * .05f;
|
|
if (shiftDown)
|
|
Camera_Shift.y -= CAMERA_KEY_SPEED;
|
|
if (altDown)
|
|
Camera_Direction.range += CAMERA_KEY_SPEED;
|
|
break;
|
|
case VK_LEFT:
|
|
if (controlDown)
|
|
Camera_Direction.yaw -= CAMERA_KEY_SPEED * .05f;
|
|
if (shiftDown)
|
|
Camera_Shift.x += CAMERA_KEY_SPEED;
|
|
break;
|
|
case VK_RIGHT:
|
|
if (controlDown)
|
|
Camera_Direction.yaw += CAMERA_KEY_SPEED * .05f;
|
|
if (shiftDown)
|
|
Camera_Shift.x -= CAMERA_KEY_SPEED;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
|