mirror of
https://github.com/electronicarts/CnC_Renegade.git
synced 2025-12-16 15:41:39 -05:00
Initial commit of Command & Conquer Renegade source code.
This commit is contained in:
888
Code/Tools/LevelEdit/LevelEditView.cpp
Normal file
888
Code/Tools/LevelEdit/LevelEditView.cpp
Normal file
@@ -0,0 +1,888 @@
|
||||
/*
|
||||
** 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/>.
|
||||
*/
|
||||
|
||||
// LevelEditView.cpp : implementation of the CLevelEditView class
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "leveledit.h"
|
||||
#include "leveleditdoc.h"
|
||||
#include "leveleditview.h"
|
||||
#include "camera.h"
|
||||
#include "cameramgr.h"
|
||||
#include "mainfrm.h"
|
||||
#include "ww3d.h"
|
||||
#include "mousemgr.h"
|
||||
#include "sceneeditor.h"
|
||||
#include <process.h>
|
||||
#include "nodemgr.h"
|
||||
#include "mmsystem.h"
|
||||
#include "dynamesh.h"
|
||||
#include "vertmaterial.h"
|
||||
#include "win.h"
|
||||
#include "wwaudio.h"
|
||||
#include "combat.h"
|
||||
#include "timemgr.h"
|
||||
#include "gameobjmanager.h"
|
||||
#include "gameobjobserver.h"
|
||||
#include "scripts.h"
|
||||
#include "backgroundmgr.h"
|
||||
#include "dazzle.h"
|
||||
#include "phys.h"
|
||||
#include "weathermgr.h"
|
||||
#include "soundenvironment.h"
|
||||
#include "heightfieldeditor.h"
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Local Prototypes
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
void CALLBACK fnTimerCallback (UINT, UINT, DWORD, DWORD, DWORD);
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Static member initialization
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
int CLevelEditView::_iPaintingLock = 0;
|
||||
bool CLevelEditView::_bNeedsRepaint = false;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Globals
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
CRITICAL_SECTION _CriticalSection;
|
||||
|
||||
|
||||
IMPLEMENT_DYNCREATE(CLevelEditView, CView)
|
||||
|
||||
BEGIN_MESSAGE_MAP(CLevelEditView, CView)
|
||||
//{{AFX_MSG_MAP(CLevelEditView)
|
||||
ON_WM_SIZE()
|
||||
ON_WM_CREATE()
|
||||
ON_WM_LBUTTONDOWN()
|
||||
ON_WM_LBUTTONUP()
|
||||
ON_WM_RBUTTONDOWN()
|
||||
ON_WM_RBUTTONUP()
|
||||
ON_WM_MOUSEMOVE()
|
||||
ON_WM_DESTROY()
|
||||
ON_WM_LBUTTONDBLCLK()
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CLevelEditView
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
CLevelEditView::CLevelEditView (void)
|
||||
: m_iDeviceIndex (-1),
|
||||
m_iBitsPerPixel (16),
|
||||
m_iWindowed (1),
|
||||
m_bRenderDeviceInitialized (FALSE),
|
||||
m_pCameraMgr (NULL),
|
||||
m_pMouseMgr (NULL),
|
||||
m_bActive (false),
|
||||
m_p2DScene (NULL),
|
||||
m_p2DCamera (NULL),
|
||||
m_TimerID (0),
|
||||
m_HorzFOV (0),
|
||||
m_VertFOV (0),
|
||||
m_CursorXRatio (1),
|
||||
m_CursorYRatio (1),
|
||||
m_hMouseHook (NULL)
|
||||
{
|
||||
// Get the windowed mode from the registry
|
||||
CString string_windowed = theApp.GetProfileString ("Config", "Windowed", "1");
|
||||
m_iWindowed = ::atoi ((LPCTSTR)string_windowed) || Is_Silent_Mode ();
|
||||
|
||||
|
||||
::InitializeCriticalSection (&_CriticalSection);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ~CLevelEditView
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
CLevelEditView::~CLevelEditView (void)
|
||||
{
|
||||
// If the camera manager exists, free it.
|
||||
SAFE_DELETE (m_pCameraMgr);
|
||||
SAFE_DELETE (m_pMouseMgr);
|
||||
|
||||
m_pCursorMesh->Remove ();
|
||||
MEMBER_RELEASE (m_pCursorMesh);
|
||||
MEMBER_RELEASE (m_p2DScene);
|
||||
MEMBER_RELEASE (m_p2DCamera);
|
||||
|
||||
// Cache this information in the registry
|
||||
TCHAR temp_string[10];
|
||||
::itoa (m_iWindowed, temp_string, 10);
|
||||
theApp.WriteProfileString ("Config", "Windowed", temp_string);
|
||||
|
||||
::DeleteCriticalSection (&_CriticalSection);
|
||||
return ;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PreCreateWindow
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
BOOL
|
||||
CLevelEditView::PreCreateWindow (CREATESTRUCT& cs)
|
||||
{
|
||||
// Allow the base class to process this message
|
||||
return CView::PreCreateWindow (cs);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnDraw
|
||||
//
|
||||
void
|
||||
CLevelEditView::OnDraw (CDC* pDC)
|
||||
{
|
||||
CLevelEditDoc* doc = GetDocument();
|
||||
ASSERT_VALID(doc);
|
||||
|
||||
// If we are in fullscreen mode, then erase the window background
|
||||
if (m_iWindowed == 0) {
|
||||
|
||||
// Get the client rectangle of the window
|
||||
RECT rect;
|
||||
GetClientRect (&rect);
|
||||
|
||||
// Erase the background
|
||||
::FillRect (*pDC, &rect, (HBRUSH)(COLOR_WINDOW + 1));
|
||||
}
|
||||
|
||||
// Ask the view to repaint itself.
|
||||
Repaint_View ();
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// MFC Junk
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
#ifdef _DEBUG
|
||||
void CLevelEditView::AssertValid() const
|
||||
{
|
||||
CView::AssertValid();
|
||||
}
|
||||
|
||||
void CLevelEditView::Dump(CDumpContext& dc) const
|
||||
{
|
||||
CView::Dump(dc);
|
||||
}
|
||||
|
||||
CLevelEditDoc* CLevelEditView::GetDocument() // non-debug version is inline
|
||||
{
|
||||
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CLevelEditDoc)));
|
||||
return (CLevelEditDoc*)m_pDocument;
|
||||
}
|
||||
#endif //_DEBUG
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Initialize_Render_Device
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
bool
|
||||
CLevelEditView::Initialize_Render_Device (void)
|
||||
{
|
||||
::EnterCriticalSection (&_CriticalSection);
|
||||
|
||||
// Assume failure
|
||||
m_bRenderDeviceInitialized = FALSE;
|
||||
|
||||
// Initialize the rendering engine with the information from
|
||||
// this window.
|
||||
RECT rect;
|
||||
GetClientRect (&rect);
|
||||
|
||||
int cx = rect.right-rect.left;
|
||||
int cy = rect.bottom-rect.top;
|
||||
int bpp = m_iBitsPerPixel;
|
||||
if (m_iWindowed == 0) {
|
||||
cx = 640;
|
||||
cy = 480;
|
||||
bpp = 16;
|
||||
|
||||
// Determine what our aspect ratio should be to
|
||||
// constrain the mouse to the 'window' while in full screen mode.
|
||||
m_CursorXRatio = cx / ((float)rect.right);
|
||||
m_CursorYRatio = cy / ((float)rect.bottom);
|
||||
} else {
|
||||
m_CursorXRatio = 1.0F;
|
||||
m_CursorYRatio = 1.0F;
|
||||
}
|
||||
|
||||
// Ask W3D to use this rendering device
|
||||
m_bRenderDeviceInitialized = (WW3D::Set_Render_Device (m_iDeviceIndex,
|
||||
cx,
|
||||
cy,
|
||||
bpp,
|
||||
m_iWindowed) == WW3D_ERROR_OK);
|
||||
|
||||
ASSERT (m_bRenderDeviceInitialized);
|
||||
|
||||
// Create a new camera manager object
|
||||
if (m_pCameraMgr == NULL) {
|
||||
m_pCameraMgr = new CameraMgr;
|
||||
}
|
||||
|
||||
// Create a new mouse manager object
|
||||
if (m_pMouseMgr == NULL) {
|
||||
m_pMouseMgr = new MouseMgrClass;
|
||||
}
|
||||
|
||||
// Reset the camera's FOV
|
||||
m_pCameraMgr->Get_Camera ()->Set_View_Plane (m_HorzFOV, m_VertFOV);
|
||||
|
||||
if (m_p2DCamera == NULL) {
|
||||
|
||||
// Create a new instance of the camera class to use
|
||||
// when rendering the background BMP
|
||||
m_p2DCamera = new CameraClass ();
|
||||
|
||||
// Were we successful in creating the new instance?
|
||||
ASSERT (m_p2DCamera != NULL);
|
||||
if (m_p2DCamera != NULL) {
|
||||
|
||||
// Set the default values for the new camera
|
||||
m_p2DCamera->Set_View_Plane (Vector2 (-1.00F, -1.00F), Vector2 (1.00F, 1.00F));
|
||||
m_p2DCamera->Set_Position (Vector3 (0.00F, 0.00F, 1.00F));
|
||||
m_p2DCamera->Set_Clip_Planes (0.1F, 10.0F);
|
||||
//m_p2DCamera->Set_Position (Vector3 (0.00F, 0.00F, 1.00F));
|
||||
//m_p2DCamera->Set_Transform (Matrix3D (1));
|
||||
}
|
||||
}
|
||||
|
||||
if (m_p2DScene == NULL) {
|
||||
|
||||
// Instantiate a new scene
|
||||
m_p2DScene = new SimpleSceneClass;
|
||||
|
||||
// Allocate a new mesh we can use to represent the mouse
|
||||
//.cursor while in full screen mode
|
||||
m_pCursorMesh = new DynamicScreenMeshClass (2, 6);
|
||||
//m_pCursorMesh->Set_Force_Visible (true);
|
||||
|
||||
VertexMaterialClass *vmat = new VertexMaterialClass;
|
||||
|
||||
vmat->Set_Emissive (1,1,1);
|
||||
vmat->Set_Diffuse (0,0,0);
|
||||
|
||||
m_pCursorMesh->Set_Vertex_Material (vmat);
|
||||
MEMBER_RELEASE (vmat);
|
||||
|
||||
m_pCursorMesh->Begin_Tri_Strip();
|
||||
|
||||
m_pCursorMesh->Set_Vertex_Color (Vector3 (0, 0.384F, 0.5F));
|
||||
m_pCursorMesh->Vertex (0.0F, 0.0F, 0, 0, 0);
|
||||
m_pCursorMesh->Set_Vertex_Color (Vector3 (0, 0, 0.5F));
|
||||
m_pCursorMesh->Vertex (0.026F,0.028F, 0, 0, 0);
|
||||
m_pCursorMesh->Set_Vertex_Color (Vector3 (0, 0.5F, 1));
|
||||
m_pCursorMesh->Vertex (0.010F,0.024F, 0, 0, 0);
|
||||
|
||||
m_pCursorMesh->End_Tri_Strip();
|
||||
|
||||
|
||||
m_pCursorMesh->Begin_Tri_Strip();
|
||||
|
||||
m_pCursorMesh->Set_Vertex_Color (Vector3 (0, 0.5F, 1));
|
||||
m_pCursorMesh->Vertex (0.010F,0.024F, 0, 0, 0);
|
||||
m_pCursorMesh->Set_Vertex_Color (Vector3 (0.53F, 0.76F, 1));
|
||||
m_pCursorMesh->Vertex (0.0F, 0.041F, 0, 0, 0);
|
||||
m_pCursorMesh->Set_Vertex_Color (Vector3 (0, 0.5F, 1));
|
||||
m_pCursorMesh->Vertex (0.0F, 0.0F, 0, 0, 0);
|
||||
|
||||
m_pCursorMesh->End_Tri_Strip();
|
||||
|
||||
// Add the cursor to the 2D scene
|
||||
m_pCursorMesh->Add (m_p2DScene);
|
||||
}
|
||||
|
||||
LeaveCriticalSection (&_CriticalSection);
|
||||
|
||||
// Return the TRUE/FALSE result code
|
||||
return m_bRenderDeviceInitialized;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnSize
|
||||
//
|
||||
void
|
||||
CLevelEditView::OnSize
|
||||
(
|
||||
UINT nType,
|
||||
int cx,
|
||||
int cy
|
||||
)
|
||||
{
|
||||
// Allow the base class to process this message
|
||||
CView::OnSize (nType, cx, cy);
|
||||
|
||||
int bpp = m_iBitsPerPixel;
|
||||
if (m_iWindowed == 0) {
|
||||
|
||||
// Determine what our aspect ratio should be to
|
||||
// constrain the mouse to the 'window' while in full screen mode.
|
||||
m_CursorXRatio = 640 / ((float)cx);
|
||||
m_CursorYRatio = 480 / ((float)cy);
|
||||
|
||||
cx = 640;
|
||||
cy = 480;
|
||||
bpp = 16;
|
||||
}
|
||||
|
||||
// update the camera FOV settings
|
||||
// take the larger of the two dimensions, give it the
|
||||
// full desired FOV, then give the other dimension an
|
||||
// FOV proportional to its relative size
|
||||
m_HorzFOV = 0.0F;
|
||||
m_VertFOV = 0.0F;
|
||||
if (cy > cx) {
|
||||
m_VertFOV = (float)DEG_TO_RAD(45.0f);
|
||||
m_HorzFOV = (double)cx / (double)cy * m_VertFOV;
|
||||
}
|
||||
else {
|
||||
m_HorzFOV = (float)DEG_TO_RAD(45.0f);
|
||||
m_VertFOV = (double)cy / (double)cx * m_HorzFOV;
|
||||
}
|
||||
|
||||
if (m_bRenderDeviceInitialized) {
|
||||
|
||||
if (m_iWindowed == 1) {
|
||||
// Change the resolution of the rendering device to
|
||||
// match that of the view's current dimensions
|
||||
WW3D::Set_Device_Resolution (cx, cy, bpp, m_iWindowed);
|
||||
}
|
||||
|
||||
// Reset the field of view
|
||||
m_pCameraMgr->Get_Camera ()->Set_View_Plane (m_HorzFOV, m_VertFOV);
|
||||
|
||||
// Force a repaint of the screen
|
||||
Repaint_View ();
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Allow_Repaint
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
CLevelEditView::Allow_Repaint (bool active)
|
||||
{
|
||||
// Either increment or decrement the lock
|
||||
_iPaintingLock += (active ? -1 : 1);
|
||||
|
||||
//
|
||||
// Refresh the view if necessary
|
||||
//
|
||||
if ((_iPaintingLock == 0) && _bNeedsRepaint) {
|
||||
::Refresh_Main_View ();
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Repaint_View
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
CLevelEditView::Repaint_View (void)
|
||||
{
|
||||
CLevelEditDoc *doc = (CLevelEditDoc *)GetDocument ();
|
||||
|
||||
//
|
||||
// Make sure separate threads don't try to render at the same time
|
||||
//
|
||||
::EnterCriticalSection (&_CriticalSection);
|
||||
_bNeedsRepaint = false;
|
||||
|
||||
//
|
||||
// Are we in a valid state?
|
||||
//
|
||||
WWASSERT (_iPaintingLock >= 0);
|
||||
if (m_bRenderDeviceInitialized &&
|
||||
(_iPaintingLock == 0) &&
|
||||
(doc != NULL) &&
|
||||
(doc->Get_Scene () != NULL) &&
|
||||
(::Is_Silent_Mode () == false))
|
||||
{
|
||||
_iPaintingLock ++;
|
||||
|
||||
//
|
||||
// Get access to the scene and current render camera
|
||||
//
|
||||
SceneEditorClass *scene = ::Get_Scene_Editor ();
|
||||
CameraClass *camera = scene->Get_Render_Camera ();
|
||||
|
||||
//
|
||||
// Let the game free up anything it needs
|
||||
//
|
||||
NetworkObjectMgrClass::Delete_Pending ();
|
||||
GameObjObserverManager::Delete_Pending ();
|
||||
ScriptManager::Destroy_Pending ();
|
||||
|
||||
//
|
||||
// Call updates on some of the subsystems
|
||||
//
|
||||
WWAudioClass::Get_Instance ()->On_Frame_Update ();
|
||||
|
||||
TimeManager::Update ();
|
||||
((CMainFrame *)::AfxGetMainWnd ())->Update_Poly_Count ();
|
||||
((CMainFrame *)::AfxGetMainWnd ())->Update_Texture_Mem ();
|
||||
|
||||
//
|
||||
// Let the camera know to update its animation (if any)
|
||||
//
|
||||
::Get_Camera_Mgr ()->On_Frame ();
|
||||
::Get_Scene_Editor ()->On_Frame ();
|
||||
::Get_Scene_Editor ()->Update_Selection_Boxes ();
|
||||
|
||||
// Update some sub-systems.
|
||||
BackgroundMgrClass::Update (scene, camera);
|
||||
SoundEnvironmentClass *sound_environment = CombatManager::Get_Sound_Environment ();
|
||||
if (sound_environment != NULL) sound_environment->Update (scene, camera);
|
||||
WeatherMgrClass::Update (scene, camera);
|
||||
|
||||
//
|
||||
// Collect visible objects and such...
|
||||
//
|
||||
PhysicsSceneClass::Get_Instance ()->Pre_Render_Processing (*camera);
|
||||
|
||||
//
|
||||
// Set-up the rendering process
|
||||
//
|
||||
WW3D::Begin_Render (true, true, BackgroundMgrClass::Get_Clear_Color());
|
||||
|
||||
//
|
||||
// Render the background scene from the game (this will give
|
||||
// us the sky and stuff).
|
||||
//
|
||||
WW3D::Render (CombatManager::Get_Background_Scene(), camera);
|
||||
|
||||
//
|
||||
// Now render the main scene
|
||||
//
|
||||
WW3D::Render (scene, camera);
|
||||
|
||||
//
|
||||
// Render any heightfield editing gizmos
|
||||
//
|
||||
HeightfieldEditorClass::Render ();
|
||||
|
||||
//
|
||||
// Render the dazzle layer (if necessary)
|
||||
//
|
||||
DazzleLayerClass *dazzle_layer = CombatManager::Get_Dazzle_Layer ();
|
||||
if (dazzle_layer != NULL) {
|
||||
dazzle_layer->Render (camera);
|
||||
}
|
||||
|
||||
//
|
||||
// Finish out the rendering process
|
||||
//
|
||||
WW3D::End_Render ();
|
||||
|
||||
//
|
||||
// Cleanup the rendering processing
|
||||
//
|
||||
PhysicsSceneClass::Get_Instance ()->Post_Render_Processing ();
|
||||
|
||||
_iPaintingLock --;
|
||||
} else {
|
||||
_bNeedsRepaint = true;
|
||||
}
|
||||
|
||||
::LeaveCriticalSection (&_CriticalSection);
|
||||
return ;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnFinalRelease
|
||||
//
|
||||
void
|
||||
CLevelEditView::OnFinalRelease (void)
|
||||
{
|
||||
// Allow the base class to process this message
|
||||
CView::OnFinalRelease ();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnInitialUpdate
|
||||
//
|
||||
void
|
||||
CLevelEditView::OnInitialUpdate (void)
|
||||
{
|
||||
// Allow the base class to process this message
|
||||
CView::OnInitialUpdate();
|
||||
|
||||
// Initialize the render device before we can update the view
|
||||
if (m_bRenderDeviceInitialized == false) {
|
||||
Initialize_Render_Device ();
|
||||
}
|
||||
|
||||
if (m_bRenderDeviceInitialized)
|
||||
{
|
||||
Start_Update ();
|
||||
}
|
||||
|
||||
//MainWindow = m_hWnd;
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Start_Update
|
||||
//
|
||||
void
|
||||
CLevelEditView::Start_Update (bool bstart)
|
||||
{
|
||||
if (bstart && (m_TimerID == 0)) {
|
||||
|
||||
// Kick off a timer that we can use to update
|
||||
// the display (kinda like a game loop iterator)
|
||||
m_TimerID = (UINT)::timeSetEvent (50,
|
||||
50,
|
||||
fnTimerCallback,
|
||||
(DWORD)m_hWnd,
|
||||
TIME_PERIODIC);
|
||||
|
||||
} else if ((bstart == false) && (m_TimerID != 0)) {
|
||||
|
||||
// Stop the timer
|
||||
::timeKillEvent ((UINT)m_TimerID);
|
||||
|
||||
// We don't need this anymore
|
||||
m_TimerID = 0;
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// fnMouseHookProc
|
||||
//
|
||||
LRESULT CALLBACK
|
||||
fnMouseHookProc
|
||||
(
|
||||
int nCode,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam
|
||||
)
|
||||
{
|
||||
LRESULT result = 0L;
|
||||
|
||||
CLevelEditView *pview = ::Get_Main_View ();
|
||||
if (pview != NULL) {
|
||||
MOUSEHOOKSTRUCT *pinfo = (MOUSEHOOKSTRUCT *)lParam;
|
||||
if (pinfo != NULL) {
|
||||
|
||||
bool allow_update = pinfo->hwnd == pview->m_hWnd;
|
||||
if (!allow_update) {
|
||||
allow_update = (::GetProp (pinfo->hwnd, "ALLOW_UPDATE") != NULL);
|
||||
if (!allow_update && ::GetParent (pinfo->hwnd)) {
|
||||
allow_update = (::GetProp (::GetParent (pinfo->hwnd), "ALLOW_UPDATE") != NULL);
|
||||
}
|
||||
|
||||
if ( ::Get_Mouse_Mgr () &&
|
||||
::Get_Mouse_Mgr ()->Get_Mouse_Mode () == MouseMgrClass::MODE_CAMERA_WALK) {
|
||||
allow_update = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Start or stop updating the view
|
||||
pview->Start_Update (allow_update);
|
||||
}
|
||||
|
||||
// Call the next hook in our chain
|
||||
result = ::CallNextHookEx (::Get_Main_View ()->Get_Hook (), nCode, wParam, lParam);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnCreate
|
||||
//
|
||||
int
|
||||
CLevelEditView::OnCreate (LPCREATESTRUCT lpCreateStruct)
|
||||
{
|
||||
if (CView::OnCreate(lpCreateStruct) == -1)
|
||||
return -1;
|
||||
|
||||
// Let the main window know we want to be the active view
|
||||
CMainFrame *pwnd = (CMainFrame *)::AfxGetMainWnd ();
|
||||
if (pwnd) {
|
||||
pwnd->SetActiveView (this, FALSE);
|
||||
}
|
||||
|
||||
m_hMouseHook = ::SetWindowsHookEx (WH_MOUSE,
|
||||
fnMouseHookProc,
|
||||
::AfxGetInstanceHandle (),
|
||||
::GetCurrentThreadId ());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnLButtonDown
|
||||
//
|
||||
void
|
||||
CLevelEditView::OnLButtonDown
|
||||
(
|
||||
UINT nFlags,
|
||||
CPoint point
|
||||
)
|
||||
{
|
||||
// Pass this onto the mouse manager
|
||||
m_pMouseMgr->Handle_LButton_Down (nFlags, point);
|
||||
|
||||
// Allow the base class to process this message
|
||||
CView::OnLButtonDown(nFlags, point);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnLButtonDown
|
||||
//
|
||||
void
|
||||
CLevelEditView::OnLButtonUp
|
||||
(
|
||||
UINT nFlags,
|
||||
CPoint point
|
||||
)
|
||||
{
|
||||
// Pass this onto the mouse manager
|
||||
m_pMouseMgr->Handle_LButton_Up (nFlags, point);
|
||||
|
||||
// Allow the base class to process this message
|
||||
CView::OnLButtonUp(nFlags, point);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnLButtonDown
|
||||
//
|
||||
void
|
||||
CLevelEditView::OnRButtonDown
|
||||
(
|
||||
UINT nFlags,
|
||||
CPoint point
|
||||
)
|
||||
{
|
||||
// Pass this onto the mouse manager
|
||||
m_pMouseMgr->Handle_RButton_Down (nFlags, point);
|
||||
|
||||
// Allow the base class to process this message
|
||||
CView::OnRButtonDown (nFlags, point);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnRButtonUp
|
||||
//
|
||||
void
|
||||
CLevelEditView::OnRButtonUp
|
||||
(
|
||||
UINT nFlags,
|
||||
CPoint point
|
||||
)
|
||||
{
|
||||
// Pass this onto the mouse manager
|
||||
m_pMouseMgr->Handle_RButton_Up (nFlags, point);
|
||||
|
||||
// Allow the base class to process this message
|
||||
CView::OnRButtonUp (nFlags, point);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnMouseMove
|
||||
//
|
||||
void
|
||||
CLevelEditView::OnMouseMove
|
||||
(
|
||||
UINT nFlags,
|
||||
CPoint point
|
||||
)
|
||||
{
|
||||
// Pass this onto the mouse manager
|
||||
m_pMouseMgr->Handle_Mouse_Move (nFlags, point);
|
||||
SetFocus ();
|
||||
|
||||
// Allow the base class to process this message
|
||||
CView::OnMouseMove (nFlags, point);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// WindowProc
|
||||
//
|
||||
LRESULT
|
||||
CLevelEditView::WindowProc
|
||||
(
|
||||
UINT message,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam
|
||||
)
|
||||
{
|
||||
// Is this the repaint message we are expecting?
|
||||
if (message == WM_USER+101)
|
||||
{
|
||||
Repaint_View ();
|
||||
::RemoveProp (m_hWnd, "WaitingToProcess");
|
||||
}
|
||||
|
||||
// Allow the base class to process this message
|
||||
return CView::WindowProc(message, wParam, lParam);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnDestroy
|
||||
//
|
||||
void
|
||||
CLevelEditView::OnDestroy (void)
|
||||
{
|
||||
// Kill the timer
|
||||
Start_Update (false);
|
||||
|
||||
if (m_hMouseHook != NULL) {
|
||||
::UnhookWindowsHookEx (m_hMouseHook);
|
||||
m_hMouseHook = NULL;
|
||||
}
|
||||
|
||||
::RemoveProp (m_hWnd, "WaitingToProcess");
|
||||
|
||||
// Allow the base class to process this message
|
||||
CView::OnDestroy ();
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Reset_View
|
||||
//
|
||||
void
|
||||
CLevelEditView::Reset_View (void)
|
||||
{
|
||||
ASSERT (m_pCameraMgr != NULL);
|
||||
|
||||
// Re-initialize the camera
|
||||
m_pCameraMgr->Init_Camera ();
|
||||
|
||||
// Reset the mouse mode
|
||||
m_pMouseMgr->Set_Mouse_Mode (MouseMgrClass::MODE_OBJECT_MANIPULATE);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// fnTimerCallback
|
||||
//
|
||||
void CALLBACK
|
||||
fnTimerCallback
|
||||
(
|
||||
UINT uID,
|
||||
UINT uMsg,
|
||||
DWORD dwUser,
|
||||
DWORD dw1,
|
||||
DWORD dw2
|
||||
)
|
||||
{
|
||||
HWND hwnd = (HWND)dwUser;
|
||||
if (hwnd != NULL) {
|
||||
|
||||
// Send this event off to the view to process (hackish, but fine for now)
|
||||
if ((GetProp (hwnd, "WaitingToProcess") == NULL) &&
|
||||
(CLevelEditView::_iPaintingLock == 0))
|
||||
{
|
||||
SetProp (hwnd, "WaitingToProcess", (HANDLE)1);
|
||||
|
||||
// Send the message to the view so it will be in the
|
||||
// same thread (Surrender doesn't seem to be thread-safe)
|
||||
::PostMessage (hwnd, WM_USER+101, 0, 0L);
|
||||
}
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnLButtonDblClk
|
||||
//
|
||||
void
|
||||
CLevelEditView::OnLButtonDblClk
|
||||
(
|
||||
UINT nFlags,
|
||||
CPoint point
|
||||
)
|
||||
{
|
||||
// Pass this onto the mouse manager
|
||||
m_pMouseMgr->Handle_LButton_Dblclk (nFlags, point);
|
||||
|
||||
// Allow the base class to process this message
|
||||
CView::OnLButtonDown(nFlags, point);
|
||||
return ;
|
||||
}
|
||||
Reference in New Issue
Block a user