Branan Purvine-Riley
11 years ago
21 changed files with 181 additions and 2789 deletions
@ -0,0 +1,158 @@ |
|||||||
|
/*==LICENSE==*
|
||||||
|
|
||||||
|
CyanWorlds.com Engine - MMOG client, server and tools |
||||||
|
Copyright (C) 2011 Cyan Worlds, 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/>.
|
||||||
|
|
||||||
|
Additional permissions under GNU GPL version 3 section 7 |
||||||
|
|
||||||
|
If you modify this Program, or any covered work, by linking or |
||||||
|
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, |
||||||
|
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent |
||||||
|
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK |
||||||
|
(or a modified version of those libraries), |
||||||
|
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, |
||||||
|
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG |
||||||
|
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the |
||||||
|
licensors of this Program grant you additional |
||||||
|
permission to convey the resulting work. Corresponding Source for a |
||||||
|
non-source form of such a combination shall include the source code for |
||||||
|
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered |
||||||
|
work. |
||||||
|
|
||||||
|
You can contact Cyan Worlds, Inc. by email legal@cyan.com |
||||||
|
or by snail mail at: |
||||||
|
Cyan Worlds, Inc. |
||||||
|
14617 N Newport Hwy |
||||||
|
Mead, WA 99021 |
||||||
|
|
||||||
|
*==LICENSE==*/ |
||||||
|
|
||||||
|
#include "HeadSpin.h" |
||||||
|
#include "plString.h" |
||||||
|
|
||||||
|
#include <max.h> |
||||||
|
#pragma hdrstop |
||||||
|
|
||||||
|
/** \file This file contains a stub implementation for the ClassDescs left behind by
|
||||||
|
* Cyan's SceneViewer crap. This just keeps new versions of 3ds Max from crashing on |
||||||
|
* null ClassDescs returned by the GUP. It also silences that "Dll Missing" dialog that |
||||||
|
* everyone evar wants to whine about even though it means absolutely nothing. |
||||||
|
*/ |
||||||
|
|
||||||
|
#define PLASMA_FILE_DATA_CID Class_ID(0x255a700a, 0x285279dc) |
||||||
|
#define MAXFILE_DATA_CHUNK 1001 |
||||||
|
static const uint8_t kVersion = 1; |
||||||
|
|
||||||
|
class plMaxFileDataControl : public StdControl |
||||||
|
{ |
||||||
|
public: |
||||||
|
SYSTEMTIME fCodeBuildTime; |
||||||
|
char fBranch[128]; |
||||||
|
|
||||||
|
plMaxFileDataControl() |
||||||
|
{ |
||||||
|
memset(&fCodeBuildTime, 0, sizeof(SYSTEMTIME)); |
||||||
|
memset(&fBranch, 0, arrsize(fBranch)); |
||||||
|
} |
||||||
|
|
||||||
|
// Animatable
|
||||||
|
virtual void EditTrackParams(TimeValue t, ParamDimensionBase *dim, TCHAR *pname, HWND hParent, IObjParam *ip, DWORD flags) { } |
||||||
|
int TrackParamsType() { return TRACKPARAMS_WHOLE; } |
||||||
|
virtual void DeleteThis() { delete this; } |
||||||
|
|
||||||
|
// ReferenceMaker
|
||||||
|
virtual RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget, PartID& partID, RefMessage message) |
||||||
|
{ |
||||||
|
return REF_DONTCARE; |
||||||
|
} |
||||||
|
|
||||||
|
Class_ID ClassID() { return PLASMA_FILE_DATA_CID; } |
||||||
|
SClass_ID SuperClassID() { return CTRL_FLOAT_CLASS_ID; } |
||||||
|
void GetClassName(TSTR& s) { s = "DEAD - SceneViewer"; } |
||||||
|
|
||||||
|
// Control methods
|
||||||
|
RefTargetHandle Clone(RemapDir& remap) { return new plMaxFileDataControl(); } |
||||||
|
void Copy(Control* from) { } |
||||||
|
virtual BOOL IsReplaceable() { return FALSE; } |
||||||
|
|
||||||
|
// StdControl methods
|
||||||
|
void GetValueLocalTime(TimeValue t, void* val, Interval& valid, GetSetMethod method = CTRL_ABSOLUTE) { } |
||||||
|
void SetValueLocalTime(TimeValue t, void* val, int commit, GetSetMethod method) { } |
||||||
|
void Extrapolate(Interval range, TimeValue t, void* val, Interval& valid, int type) { } |
||||||
|
void *CreateTempValue() { return nullptr; } |
||||||
|
void DeleteTempValue(void *val) { } |
||||||
|
void ApplyValue(void* val, void* delta) { } |
||||||
|
void MultiplyValue(void* val, float m) { } |
||||||
|
|
||||||
|
// MyControl methods
|
||||||
|
IOResult Load(ILoad *iload); |
||||||
|
IOResult Save(ISave *isave); |
||||||
|
}; |
||||||
|
|
||||||
|
IOResult plMaxFileDataControl::Load(ILoad *iload) |
||||||
|
{ |
||||||
|
ULONG nb; |
||||||
|
IOResult res; |
||||||
|
while (IO_OK==(res=iload->OpenChunk())) |
||||||
|
{ |
||||||
|
if (iload->CurChunkID() == MAXFILE_DATA_CHUNK) |
||||||
|
{ |
||||||
|
uint8_t version = 0; |
||||||
|
res = iload->Read(&version, sizeof(uint8_t), &nb); |
||||||
|
res = iload->Read(&fCodeBuildTime, sizeof(SYSTEMTIME), &nb); |
||||||
|
|
||||||
|
int branchLen = 0; |
||||||
|
iload->Read(&branchLen, sizeof(int), &nb); |
||||||
|
iload->Read(&fBranch, branchLen, &nb); |
||||||
|
} |
||||||
|
|
||||||
|
iload->CloseChunk(); |
||||||
|
if (res != IO_OK) |
||||||
|
return res; |
||||||
|
} |
||||||
|
|
||||||
|
return IO_OK; |
||||||
|
} |
||||||
|
|
||||||
|
IOResult plMaxFileDataControl::Save(ISave *isave) |
||||||
|
{ |
||||||
|
ULONG nb; |
||||||
|
isave->BeginChunk(MAXFILE_DATA_CHUNK); |
||||||
|
|
||||||
|
isave->Write(&kVersion, sizeof(kVersion), &nb); |
||||||
|
isave->Write(&fCodeBuildTime, sizeof(SYSTEMTIME), &nb); |
||||||
|
|
||||||
|
int branchLen = strlen(fBranch)+1; |
||||||
|
isave->Write(&branchLen, sizeof(int), &nb); |
||||||
|
isave->Write(&fBranch, branchLen, &nb); |
||||||
|
|
||||||
|
isave->EndChunk(); |
||||||
|
return IO_OK; |
||||||
|
} |
||||||
|
|
||||||
|
class MaxFileDataClassDesc : public ClassDesc |
||||||
|
{ |
||||||
|
public: |
||||||
|
int IsPublic() { return FALSE; } |
||||||
|
void* Create(BOOL loading) { return new plMaxFileDataControl; } |
||||||
|
const TCHAR* ClassName() { return _T("MaxFileData"); } |
||||||
|
SClass_ID SuperClassID() { return CTRL_FLOAT_CLASS_ID; } |
||||||
|
Class_ID ClassID() { return PLASMA_FILE_DATA_CID; } |
||||||
|
const TCHAR* Category() { return _T(""); } |
||||||
|
}; |
||||||
|
|
||||||
|
MaxFileDataClassDesc gMaxFileDataClassDesc; |
||||||
|
ClassDesc* GetMaxFileDataDesc() { return &gMaxFileDataClassDesc; } |
@ -1,35 +0,0 @@ |
|||||||
include_directories("../") |
|
||||||
include_directories("../../Plasma/Apps") |
|
||||||
include_directories("../../Plasma/CoreLib") |
|
||||||
include_directories("../../Plasma/FeatureLib") |
|
||||||
include_directories("../../Plasma/FeatureLib/inc") |
|
||||||
include_directories("../../Plasma/NucleusLib") |
|
||||||
include_directories("../../Plasma/NucleusLib/inc") |
|
||||||
include_directories("../../Plasma/PubUtilLib") |
|
||||||
include_directories("../../Plasma/PubUtilLib/inc") |
|
||||||
include_directories(${3dsm_INCLUDE_DIR}) |
|
||||||
|
|
||||||
set(MaxSceneViewer_HEADERS |
|
||||||
plKeyRefSort.h |
|
||||||
plMaxFileData.h |
|
||||||
plPluginApp.h |
|
||||||
plPluginClient.h |
|
||||||
SceneSync.h |
|
||||||
SceneViewer.h |
|
||||||
SceneWatcher.h |
|
||||||
) |
|
||||||
|
|
||||||
set(MaxSceneViewer_SOURCES |
|
||||||
plKeyRefSort.cpp |
|
||||||
plMaxFileData.cpp |
|
||||||
plPluginApp.cpp |
|
||||||
plPluginClient.cpp |
|
||||||
SceneSync.cpp |
|
||||||
SceneViewer.cpp |
|
||||||
SceneWatcher.cpp |
|
||||||
) |
|
||||||
|
|
||||||
add_library(MaxSceneViewer STATIC ${MaxSceneViewer_HEADERS} ${MaxSceneViewer_SOURCES}) |
|
||||||
|
|
||||||
source_group("Header Files" FILES ${MaxSceneViewer_HEADERS}) |
|
||||||
source_group("Source Files" FILES ${MaxSceneViewer_SOURCES}) |
|
@ -1,678 +0,0 @@ |
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools |
|
||||||
Copyright (C) 2011 Cyan Worlds, 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/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7 |
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or |
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, |
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent |
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK |
|
||||||
(or a modified version of those libraries), |
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, |
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG |
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the |
|
||||||
licensors of this Program grant you additional |
|
||||||
permission to convey the resulting work. Corresponding Source for a |
|
||||||
non-source form of such a combination shall include the source code for |
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered |
|
||||||
work. |
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com |
|
||||||
or by snail mail at: |
|
||||||
Cyan Worlds, Inc. |
|
||||||
14617 N Newport Hwy |
|
||||||
Mead, WA 99021 |
|
||||||
|
|
||||||
*==LICENSE==*/ |
|
||||||
#include "HeadSpin.h" |
|
||||||
|
|
||||||
#include "SceneSync.h" |
|
||||||
#include "SceneWatcher.h" |
|
||||||
|
|
||||||
#define MAXPLUGINCODE |
|
||||||
|
|
||||||
#include "pnSceneObject/plSceneObject.h" |
|
||||||
#include "MaxMain/plMaxNode.h" |
|
||||||
#include "MaxMain/plPluginResManager.h" |
|
||||||
#include "MaxConvert/plConvert.h" |
|
||||||
#include "MaxConvert/hsMaterialConverter.h" |
|
||||||
#include "MaxComponent/plComponent.h" |
|
||||||
#include "hsThread.h" |
|
||||||
#include "hsSTLStream.h" |
|
||||||
#include "plClient/plClientUpdateFormat.h" |
|
||||||
|
|
||||||
#include "plMaxFileData.h" |
|
||||||
|
|
||||||
SceneSync& SceneSync::Instance() |
|
||||||
{ |
|
||||||
static SceneSync theInstance; |
|
||||||
return theInstance; |
|
||||||
} |
|
||||||
|
|
||||||
SceneSync::SceneSync() : fUpdateSignal(nil), fSceneWatcher(nil), fTimerID(0), fUpdateFreq(-1) |
|
||||||
{ |
|
||||||
// Need to save the current state
|
|
||||||
RegisterNotification(INotify, 0, NOTIFY_SYSTEM_PRE_RESET); |
|
||||||
RegisterNotification(INotify, 0, NOTIFY_SYSTEM_PRE_NEW); |
|
||||||
RegisterNotification(INotify, 0, NOTIFY_FILE_PRE_OPEN); |
|
||||||
RegisterNotification(INotify, 0, NOTIFY_PRE_EXPORT); |
|
||||||
|
|
||||||
// Need to load the saved state
|
|
||||||
RegisterNotification(INotify, 0, NOTIFY_FILE_POST_OPEN); |
|
||||||
RegisterNotification(INotify, 0, NOTIFY_POST_EXPORT); |
|
||||||
RegisterNotification(INotify, 0, NOTIFY_EXPORT_FAILED); |
|
||||||
|
|
||||||
// Need to save the current state and cleanup
|
|
||||||
RegisterNotification(INotify, 0, NOTIFY_SYSTEM_SHUTDOWN); |
|
||||||
} |
|
||||||
|
|
||||||
void SceneSync::IShutdown() |
|
||||||
{ |
|
||||||
UnRegisterNotification(INotify, 0, NOTIFY_SYSTEM_PRE_RESET); |
|
||||||
UnRegisterNotification(INotify, 0, NOTIFY_SYSTEM_PRE_NEW); |
|
||||||
UnRegisterNotification(INotify, 0, NOTIFY_FILE_PRE_OPEN); |
|
||||||
UnRegisterNotification(INotify, 0, NOTIFY_PRE_EXPORT); |
|
||||||
|
|
||||||
UnRegisterNotification(INotify, 0, NOTIFY_FILE_POST_OPEN); |
|
||||||
UnRegisterNotification(INotify, 0, NOTIFY_POST_EXPORT); |
|
||||||
UnRegisterNotification(INotify, 0, NOTIFY_EXPORT_FAILED); |
|
||||||
|
|
||||||
UnRegisterNotification(INotify, 0, NOTIFY_SYSTEM_SHUTDOWN); |
|
||||||
|
|
||||||
delete fUpdateSignal; |
|
||||||
fUpdateSignal = nil; |
|
||||||
} |
|
||||||
|
|
||||||
#include <shellapi.h> |
|
||||||
#include "../MaxMain/plMaxCFGFile.h" |
|
||||||
#include "../MaxExport/plExportErrorMsg.h" |
|
||||||
|
|
||||||
// TEMP
|
|
||||||
#include <direct.h> |
|
||||||
|
|
||||||
bool SceneSync::CreateClientData() |
|
||||||
{ |
|
||||||
char path[MAX_PATH]; |
|
||||||
if (!GetOutputDir(path)) |
|
||||||
return false; |
|
||||||
|
|
||||||
char datPath[MAX_PATH]; |
|
||||||
sprintf(datPath, "%sdat", path); |
|
||||||
|
|
||||||
// Setup for the convert
|
|
||||||
plExportErrorMsg msg; |
|
||||||
plConvertSettings settings; |
|
||||||
settings.fSceneViewer = true; |
|
||||||
plConvert::Instance().Init(GetCOREInterface(), &msg, &settings); |
|
||||||
|
|
||||||
// Do the convert
|
|
||||||
plConvert::Instance().Convert(); |
|
||||||
|
|
||||||
// If convert failed, fail too
|
|
||||||
if (msg.IsBogus()) |
|
||||||
return false; |
|
||||||
|
|
||||||
// Clear the dirty flags since everything is fresh
|
|
||||||
IClearDirtyRecur((plMaxNode*)GetCOREInterface()->GetRootNode()); |
|
||||||
|
|
||||||
//
|
|
||||||
// Write the converted data out and page out the objects
|
|
||||||
//
|
|
||||||
IDeletePath(path); |
|
||||||
CreateDirectory(path, NULL); |
|
||||||
CreateDirectory(datPath, NULL); |
|
||||||
|
|
||||||
// TEMP
|
|
||||||
char oldCWD[MAX_PATH]; |
|
||||||
getcwd(oldCWD, MAX_PATH); |
|
||||||
chdir(path); |
|
||||||
|
|
||||||
hsAssert( false, "YOU NEED TO FIX ME" ); |
|
||||||
// hsgResMgr::ResMgr()->Write();
|
|
||||||
|
|
||||||
// TEMP
|
|
||||||
chdir(oldCWD); |
|
||||||
|
|
||||||
IWriteNodeMap(path); |
|
||||||
|
|
||||||
// TEMP
|
|
||||||
hsMaterialConverter::Instance().FreeMaterialCache(path); |
|
||||||
|
|
||||||
hsAssert( false, "YOU NEED TO FIX ME" ); |
|
||||||
// hsgResMgr::ResMgr()->PageOutConverted();
|
|
||||||
hsgResMgr::Reset(); |
|
||||||
|
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
bool SceneSync::IsClientRunning() |
|
||||||
{ |
|
||||||
return (fUpdateSignal != nil); |
|
||||||
} |
|
||||||
|
|
||||||
void SceneSync::IShutdownClient() |
|
||||||
{ |
|
||||||
hsNamedPipeStream outStream(hsNamedPipeStream::kThrowOnError, 500); |
|
||||||
try |
|
||||||
{ |
|
||||||
if (outStream.Open(fPipeName, "w")) |
|
||||||
{ |
|
||||||
// Signal the Client
|
|
||||||
fUpdateSignal->Signal(); |
|
||||||
|
|
||||||
if (outStream.WaitForClientConnect()) |
|
||||||
outStream.WriteByte(ClientUpdate::kShutdown); |
|
||||||
|
|
||||||
outStream.Close(); |
|
||||||
} |
|
||||||
} |
|
||||||
catch (hsNamedPipeStream*) |
|
||||||
{ |
|
||||||
hsAssert(0, "Error writing to pipe"); |
|
||||||
outStream.Close(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void SceneSync::SetUpdateFreq(int freq) |
|
||||||
{ |
|
||||||
fUpdateFreq = freq; |
|
||||||
|
|
||||||
// If the client is running, change it's update freq
|
|
||||||
if (IsClientRunning()) |
|
||||||
{ |
|
||||||
// Kill the old timer
|
|
||||||
if (fTimerID != 0) |
|
||||||
{ |
|
||||||
KillTimer(NULL, fTimerID); |
|
||||||
fTimerID = 0; |
|
||||||
} |
|
||||||
|
|
||||||
// Create a new timer
|
|
||||||
if (fUpdateFreq != -1) |
|
||||||
fTimerID = SetTimer(NULL, 0, fUpdateFreq, ITimerProc); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
bool SceneSync::BeginClientSync(const char *semaphoreName, const char *pipeName) |
|
||||||
{ |
|
||||||
char path[MAX_PATH]; |
|
||||||
if (!GetOutputDir(path)) |
|
||||||
return false; |
|
||||||
|
|
||||||
char datPath[MAX_PATH]; |
|
||||||
sprintf(datPath, "%sdat", path); |
|
||||||
|
|
||||||
// Load the saved rooms and their keys (but not objects)
|
|
||||||
hsAssert( false, "YOU NEED TO FIX ME" ); |
|
||||||
// hsgResMgr::ResMgr()->ForceLoadDirectory(datPath, true/*false*/); // TEMP
|
|
||||||
|
|
||||||
// Set the keys in the plMaxNodes. Also, delete Plasma objects for any
|
|
||||||
// plMaxNodes that can't be found (must have been deleted).
|
|
||||||
IReadNodeMap(path); |
|
||||||
|
|
||||||
if (!fSceneWatcher) |
|
||||||
IStartWatching(true); |
|
||||||
|
|
||||||
if (fUpdateFreq != -1) |
|
||||||
fTimerID = SetTimer(NULL, 0, fUpdateFreq, ITimerProc); |
|
||||||
|
|
||||||
// Update();
|
|
||||||
|
|
||||||
fUpdateSignal = new hsSemaphore(0, semaphoreName); |
|
||||||
|
|
||||||
fPipeName = pipeName; |
|
||||||
|
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
void SceneSync::EndClientSync(bool abort) |
|
||||||
{ |
|
||||||
if (fTimerID != 0 || fUpdateSignal) |
|
||||||
{ |
|
||||||
KillTimer(NULL, fTimerID); |
|
||||||
fTimerID = 0; |
|
||||||
|
|
||||||
if (!abort) |
|
||||||
{ |
|
||||||
SaveResMgr(); |
|
||||||
IShutdownClient(); |
|
||||||
} |
|
||||||
else |
|
||||||
{ |
|
||||||
// Delete files so we won't try to run with this possibly corrupted data
|
|
||||||
char path[MAX_PATH]; |
|
||||||
if (GetOutputDir(path)) |
|
||||||
IDeletePath(path); |
|
||||||
} |
|
||||||
|
|
||||||
delete fUpdateSignal; |
|
||||||
fUpdateSignal = nil; |
|
||||||
|
|
||||||
hsAssert( false, "YOU NEED TO FIX ME" ); |
|
||||||
// hsgResMgr::ResMgr()->PageOutConverted();
|
|
||||||
// hsgResMgr::Reset();
|
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#include "../pnKeyedObject/plKey.h" |
|
||||||
|
|
||||||
void SceneSync::IClearDirtyRecur(plMaxNode *node) |
|
||||||
{ |
|
||||||
node->SetDirty(plMaxNode::kAllDirty, false); |
|
||||||
|
|
||||||
for (int i = 0; i < node->NumberOfChildren(); i++) |
|
||||||
IClearDirtyRecur((plMaxNode*)node->GetChildNode(i)); |
|
||||||
} |
|
||||||
|
|
||||||
void SceneSync::IDeletePath(const char *path) |
|
||||||
{ |
|
||||||
// Remove any files in the dat directory
|
|
||||||
char datPath[MAX_PATH]; |
|
||||||
sprintf(datPath, "%sdat\\", path); |
|
||||||
hsFolderIterator folder(datPath); |
|
||||||
while (folder.NextFile()) |
|
||||||
{ |
|
||||||
char file[MAX_PATH]; |
|
||||||
folder.GetPathAndName(file); |
|
||||||
DeleteFile(file); |
|
||||||
} |
|
||||||
|
|
||||||
// Remove the dat directory
|
|
||||||
// RemoveDirectory(datPath);
|
|
||||||
|
|
||||||
// Remove any files in the root dir
|
|
||||||
folder.SetPath(path); |
|
||||||
while (folder.NextFile()) |
|
||||||
{ |
|
||||||
char file[MAX_PATH]; |
|
||||||
folder.GetPathAndName(file); |
|
||||||
DeleteFile(file); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
bool SceneSync::SaveResMgr() |
|
||||||
{ |
|
||||||
// Get the output directory for the current file
|
|
||||||
char path[MAX_PATH]; |
|
||||||
if (!GetOutputDir(path)) |
|
||||||
return false; |
|
||||||
|
|
||||||
IWriteNodeMap(path); |
|
||||||
|
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
bool SceneSync::GetOutputDir(char *buf) |
|
||||||
{ |
|
||||||
const char *path = plMaxConfig::GetClientPath(); |
|
||||||
if (!path) |
|
||||||
return false; |
|
||||||
|
|
||||||
const char *file = GetCOREInterface()->GetCurFileName(); |
|
||||||
if (!file || *file == '\0') |
|
||||||
return false; |
|
||||||
|
|
||||||
char filecpy[_MAX_FNAME]; |
|
||||||
_splitpath(file, nil, nil, filecpy, nil); |
|
||||||
|
|
||||||
strcpy(buf, path); |
|
||||||
strcat(buf, "SceneViewer\\"); |
|
||||||
|
|
||||||
// Make sure the SceneViewer directory is created (CreateDirectory sucks)
|
|
||||||
// CreateDirectory(buf, nil);
|
|
||||||
|
|
||||||
strcat(buf, filecpy); |
|
||||||
strcat(buf, "\\"); |
|
||||||
|
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
bool SceneSync::IStartWatching(bool forceWatch) |
|
||||||
{ |
|
||||||
IStopWatching(); |
|
||||||
|
|
||||||
// Ref all the nodes in the scene if:
|
|
||||||
// a) we are being forced to watch (starting SceneViewer)
|
|
||||||
// b) there is previously saved data for this scene (we need to keep up to date)
|
|
||||||
if (forceWatch || CanLoadOldResMgr()) |
|
||||||
{ |
|
||||||
fSceneWatcher = new SceneWatcher; |
|
||||||
} |
|
||||||
|
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
bool SceneSync::IStopWatching() |
|
||||||
{ |
|
||||||
if (!fSceneWatcher) |
|
||||||
return true; |
|
||||||
|
|
||||||
delete fSceneWatcher; |
|
||||||
fSceneWatcher = nil; |
|
||||||
|
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
static const char *kKeysFile = "NodeMap.dat"; |
|
||||||
|
|
||||||
bool SceneSync::CanLoadOldResMgr() |
|
||||||
{ |
|
||||||
char path[MAX_PATH]; |
|
||||||
if (!GetOutputDir(path)) |
|
||||||
return false; |
|
||||||
strcat(path, kKeysFile); |
|
||||||
|
|
||||||
hsUNIXStream s; |
|
||||||
if (s.Open(path)) |
|
||||||
{ |
|
||||||
s.Close(); |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
static void IGetNodes(std::vector<plMaxNode*>& nodes, plMaxNode *curNode=nil) |
|
||||||
{ |
|
||||||
if (!curNode) |
|
||||||
curNode = (plMaxNode*)GetCOREInterface()->GetRootNode(); |
|
||||||
else |
|
||||||
nodes.push_back(curNode); |
|
||||||
|
|
||||||
for (int i = 0; i < curNode->NumberOfChildren(); i++) |
|
||||||
{ |
|
||||||
plMaxNode *childNode = (plMaxNode*)curNode->GetChildNode(i); |
|
||||||
if (childNode) |
|
||||||
IGetNodes(nodes, childNode); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// The NodeMap is a mapping from unique node id's to Uoid's.
|
|
||||||
// It is used to figure out the plKey associated with a particular node, which
|
|
||||||
// will be needed if the node's data needs to be deleted out of the Plasma scene.
|
|
||||||
//
|
|
||||||
bool SceneSync::IWriteNodeMap(const char *dir) |
|
||||||
{ |
|
||||||
char path[MAX_PATH]; |
|
||||||
strcpy(path, dir); |
|
||||||
strcat(path, kKeysFile); |
|
||||||
|
|
||||||
hsUNIXStream s; |
|
||||||
if (!s.Open(path, "wb")) |
|
||||||
return false; |
|
||||||
|
|
||||||
int numWritten = 0; |
|
||||||
s.WriteSwap32(numWritten); |
|
||||||
|
|
||||||
std::vector<plMaxNode*> nodes; |
|
||||||
IGetNodes(nodes); |
|
||||||
|
|
||||||
int numNodes = nodes.size(); |
|
||||||
for (int i = 0; i < numNodes; i++) |
|
||||||
{ |
|
||||||
plMaxNode *node = nodes[i]; |
|
||||||
|
|
||||||
if (node->GetKey()) |
|
||||||
{ |
|
||||||
s.WriteSwap32(node->GetHandle()); |
|
||||||
node->GetKey()->GetUoid().Write(&s); |
|
||||||
|
|
||||||
numWritten++; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
s.Rewind(); |
|
||||||
s.WriteSwap32(numWritten); |
|
||||||
|
|
||||||
s.Close(); |
|
||||||
|
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
#include "../MaxMain/plMaxNodeData.h" |
|
||||||
|
|
||||||
bool SceneSync::IReadNodeMap(const char *dir) |
|
||||||
{ |
|
||||||
char path[MAX_PATH]; |
|
||||||
strcpy(path, dir); |
|
||||||
strcat(path, kKeysFile); |
|
||||||
|
|
||||||
hsUNIXStream s; |
|
||||||
if (!s.Open(path, "rb")) |
|
||||||
return false; |
|
||||||
|
|
||||||
int numWritten = s.ReadSwap32(); |
|
||||||
|
|
||||||
for (int i = 0; i < numWritten; i++) |
|
||||||
{ |
|
||||||
// Read in the node handle and get the actual node
|
|
||||||
ULONG handle = s.ReadSwap32(); |
|
||||||
plMaxNode *node = (plMaxNode*)GetCOREInterface()->GetINodeByHandle(handle); |
|
||||||
|
|
||||||
// Read in the Uoid and get the key
|
|
||||||
plUoid uoid; |
|
||||||
uoid.Read(&s); |
|
||||||
plKey key = hsgResMgr::ResMgr()->FindKey(uoid); |
|
||||||
|
|
||||||
// A node with that handle wasn't found, it must have been deleted.
|
|
||||||
// Delete it from the Plasma scene.
|
|
||||||
if (!node) |
|
||||||
{ |
|
||||||
hsAssert( false, "YOU NEED TO FIX ME" ); |
|
||||||
// hsgResMgr::ResMgr()->RemoveObject(key);
|
|
||||||
} |
|
||||||
else |
|
||||||
{ |
|
||||||
// Save the node's key in the node data
|
|
||||||
plMaxNodeData *dat = node->GetMaxNodeData(); |
|
||||||
// Allocate the node data if it doesn't have any
|
|
||||||
if (!dat) |
|
||||||
{ |
|
||||||
plMaxNodeData data; |
|
||||||
node->SetMaxNodeData(&data); |
|
||||||
dat = node->GetMaxNodeData(); |
|
||||||
} |
|
||||||
dat->SetKey(key); |
|
||||||
dat->SetSceneObject(plSceneObject::ConvertNoRef(key->GetObjectPtr())); |
|
||||||
node->CanConvert(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
s.Close(); |
|
||||||
|
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
#include "plKeyRefSort.h" |
|
||||||
|
|
||||||
bool SceneSync::Update() |
|
||||||
{ |
|
||||||
// If there are no dirty nodes, and nothing was deleted, return now
|
|
||||||
if (!fSceneWatcher || (!fSceneWatcher->AnyDirty() && !fSceneWatcher->AnyDeleted())) |
|
||||||
return false; |
|
||||||
|
|
||||||
std::vector<plUoid> delUoids; |
|
||||||
|
|
||||||
// If any nodes were deleted, remove them from the ResManager
|
|
||||||
if (fSceneWatcher->AnyDeleted()) |
|
||||||
{ |
|
||||||
SceneWatcher::KeyList& deleted = fSceneWatcher->GetDeleted(); |
|
||||||
|
|
||||||
for (int i = 0; i < deleted.size(); i++) |
|
||||||
{ |
|
||||||
delUoids.push_back(deleted[i]->GetUoid()); |
|
||||||
hsAssert( false, "YOU NEED TO FIX ME" ); |
|
||||||
// hsgResMgr::ResMgr()->RemoveObject(deleted[i]);
|
|
||||||
} |
|
||||||
|
|
||||||
deleted.clear(); |
|
||||||
} |
|
||||||
|
|
||||||
hsAssert( false, "YOU NEED TO FIX ME" ); |
|
||||||
// hsgResMgr::ResMgr()->SaveNewKeys(true);
|
|
||||||
|
|
||||||
// If any nodes are dirty, reconvert them
|
|
||||||
if (fSceneWatcher->AnyDirty()) |
|
||||||
{ |
|
||||||
// Go through all the referenced nodes and put all the ones that need to be
|
|
||||||
// reconverted in a list
|
|
||||||
SceneWatcher::NodeSet dirtyNodes; |
|
||||||
fSceneWatcher->GetDirty(dirtyNodes); |
|
||||||
|
|
||||||
// Delete the SceneObjects for all the dirty nodes, and put them in a list
|
|
||||||
// that we can send to the converter
|
|
||||||
hsTArray<plMaxNode*> nodes; |
|
||||||
for (SceneWatcher::NodeSet::iterator it = dirtyNodes.begin(); it != dirtyNodes.end(); it++) |
|
||||||
{ |
|
||||||
// If the material is dirty, tell the material converter to release
|
|
||||||
// it's ref, so it will be recreated.
|
|
||||||
if ((*it)->GetDirty(plMaxNode::kMatDirty)) |
|
||||||
hsMaterialConverter::Instance().ClearDoneMaterials(*it); |
|
||||||
|
|
||||||
plKey key = (*it)->GetKey(); |
|
||||||
if (key) |
|
||||||
{ |
|
||||||
delUoids.push_back(key->GetUoid()); |
|
||||||
hsAssert( false, "YOU NEED TO FIX ME" ); |
|
||||||
// hsgResMgr::ResMgr()->RemoveObject(key);
|
|
||||||
} |
|
||||||
|
|
||||||
nodes.Append(*it); |
|
||||||
} |
|
||||||
|
|
||||||
// Convert
|
|
||||||
plExportErrorMsg msg; |
|
||||||
plConvertSettings settings; |
|
||||||
settings.fSceneViewer = true; |
|
||||||
plConvert::Instance().Init(GetCOREInterface(), &msg, &settings); |
|
||||||
bool ret = plConvert::Instance().Convert(nodes); |
|
||||||
|
|
||||||
// REMOVE/FIX (COLIN)
|
|
||||||
hsMaterialConverter::Instance().FreeMaterialCache(nil); |
|
||||||
} |
|
||||||
|
|
||||||
//
|
|
||||||
// Sort the new keys
|
|
||||||
//
|
|
||||||
hsAssert( false, "YOU NEED TO FIX ME" ); |
|
||||||
// const plUpdatableResManager::KeyList& keys = hsgResMgr::ResMgr()->GetNewKeys();
|
|
||||||
std::vector<plKey> newKeys;// = keys;
|
|
||||||
plKeyRefSort::Sort(&newKeys); |
|
||||||
|
|
||||||
#if 0 |
|
||||||
hsStatusMessage("New Keys (Sorted):\n"); |
|
||||||
for (int x = 0; x < newKeys.size(); x++) |
|
||||||
{ |
|
||||||
hsStatusMessage(" "); |
|
||||||
hsStatusMessage(newKeys[x]->GetName()); |
|
||||||
hsStatusMessage("\n"); |
|
||||||
} |
|
||||||
#endif |
|
||||||
|
|
||||||
//
|
|
||||||
// Write out the data to the client
|
|
||||||
//
|
|
||||||
hsNamedPipeStream outStream(hsNamedPipeStream::kThrowOnError); |
|
||||||
try |
|
||||||
{ |
|
||||||
if (outStream.Open(fPipeName, "w")) |
|
||||||
{ |
|
||||||
// Signal the Client
|
|
||||||
fUpdateSignal->Signal(); |
|
||||||
|
|
||||||
if (outStream.WaitForClientConnect()) |
|
||||||
{ |
|
||||||
outStream.WriteByte(ClientUpdate::kUpdate); |
|
||||||
|
|
||||||
int i; |
|
||||||
|
|
||||||
// Write out the deleted Uoids
|
|
||||||
int numUoids = delUoids.size(); |
|
||||||
outStream.WriteSwap32(numUoids); |
|
||||||
for (i = 0; i < numUoids; i++) |
|
||||||
{ |
|
||||||
delUoids[i].Write(&outStream); |
|
||||||
} |
|
||||||
|
|
||||||
hsAssert( false, "NEED TO FIX ME!" ); |
|
||||||
// hsgResMgr::ResMgr()->WriteChangedSpans(&outStream);
|
|
||||||
|
|
||||||
// Write out the new keys (and objects)
|
|
||||||
int numKeys = newKeys.size(); |
|
||||||
outStream.WriteSwap32(numKeys); |
|
||||||
for (i = 0; i < numKeys; i++) |
|
||||||
{ |
|
||||||
plKey key = newKeys[i]; |
|
||||||
if (key && key->GetObjectPtr()) |
|
||||||
hsgResMgr::ResMgr()->WriteCreatable(&outStream, key->GetObjectPtr()); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
outStream.Close(); |
|
||||||
} |
|
||||||
} |
|
||||||
catch (...) |
|
||||||
{ |
|
||||||
hsAssert(0, "Error writing to pipe"); |
|
||||||
outStream.Close(); |
|
||||||
|
|
||||||
EndClientSync(true); |
|
||||||
} |
|
||||||
|
|
||||||
hsAssert( false, "NEED TO FIX ME!" ); |
|
||||||
// hsgResMgr::ResMgr()->SaveNewKeys(false);
|
|
||||||
|
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
void SceneSync::INotify(void *param, NotifyInfo *info) |
|
||||||
{ |
|
||||||
SceneSync &inst = SceneSync::Instance(); |
|
||||||
|
|
||||||
int code = info->intcode; |
|
||||||
|
|
||||||
// Need to save the current state
|
|
||||||
if (code == NOTIFY_SYSTEM_PRE_RESET || |
|
||||||
code == NOTIFY_SYSTEM_PRE_NEW || |
|
||||||
code == NOTIFY_FILE_PRE_OPEN || |
|
||||||
code == NOTIFY_PRE_EXPORT) |
|
||||||
{ |
|
||||||
inst.IStopWatching(); |
|
||||||
} |
|
||||||
// Need to load the saved state
|
|
||||||
else if (code == NOTIFY_FILE_POST_OPEN || |
|
||||||
code == NOTIFY_POST_EXPORT || |
|
||||||
code == NOTIFY_EXPORT_FAILED) |
|
||||||
{ |
|
||||||
inst.IStartWatching(); |
|
||||||
} |
|
||||||
// Need to save the current state and cleanup
|
|
||||||
else if (code == NOTIFY_SYSTEM_SHUTDOWN) |
|
||||||
{ |
|
||||||
inst.SaveResMgr(); |
|
||||||
inst.IStopWatching(); |
|
||||||
inst.IShutdown(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void CALLBACK SceneSync::ITimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) |
|
||||||
{ |
|
||||||
Instance().Update(); |
|
||||||
} |
|
@ -1,118 +0,0 @@ |
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools |
|
||||||
Copyright (C) 2011 Cyan Worlds, 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/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7 |
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or |
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, |
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent |
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK |
|
||||||
(or a modified version of those libraries), |
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, |
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG |
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the |
|
||||||
licensors of this Program grant you additional |
|
||||||
permission to convey the resulting work. Corresponding Source for a |
|
||||||
non-source form of such a combination shall include the source code for |
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered |
|
||||||
work. |
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com |
|
||||||
or by snail mail at: |
|
||||||
Cyan Worlds, Inc. |
|
||||||
14617 N Newport Hwy |
|
||||||
Mead, WA 99021 |
|
||||||
|
|
||||||
*==LICENSE==*/ |
|
||||||
#ifndef SCENE_SYNC_H |
|
||||||
#define SCENE_SYNC_H |
|
||||||
|
|
||||||
#include "Max.h" |
|
||||||
#include "notify.h" |
|
||||||
|
|
||||||
#include <vector> |
|
||||||
#include <set> |
|
||||||
|
|
||||||
class plMaxNode; |
|
||||||
class hsSemaphore; |
|
||||||
class SceneWatcher; |
|
||||||
class plSceneNode; |
|
||||||
|
|
||||||
#include "pnKeyedObject/plUoid.h" |
|
||||||
#include "pnKeyedObject/plKey.h" |
|
||||||
|
|
||||||
class SceneSync |
|
||||||
{ |
|
||||||
protected: |
|
||||||
SceneWatcher *fSceneWatcher; |
|
||||||
hsSemaphore *fUpdateSignal; |
|
||||||
const char *fPipeName; |
|
||||||
int fTimerID; |
|
||||||
int fUpdateFreq; |
|
||||||
|
|
||||||
SceneSync(); |
|
||||||
|
|
||||||
public: |
|
||||||
static SceneSync& Instance(); |
|
||||||
|
|
||||||
// Get the path where the current Max file will be exported to (not including "dat")
|
|
||||||
bool GetOutputDir(char *buf); |
|
||||||
|
|
||||||
bool IsClientRunning(); |
|
||||||
|
|
||||||
// Is there valid data on disk that we can load into the ResMgr or do we need to reconvert?
|
|
||||||
bool CanLoadOldResMgr(); |
|
||||||
|
|
||||||
// Create client data
|
|
||||||
bool CreateClientData(); |
|
||||||
|
|
||||||
void SetUpdateFreq(int freq); // In milliseconds
|
|
||||||
|
|
||||||
// Start updating the client
|
|
||||||
bool BeginClientSync(const char *semaphoreName, const char *pipeName); |
|
||||||
// Stop updating the client. If abort is true, don't try saving, something went wrong
|
|
||||||
void EndClientSync(bool abort); |
|
||||||
|
|
||||||
protected: |
|
||||||
bool SaveResMgr(); |
|
||||||
|
|
||||||
void IShutdownClient(); |
|
||||||
|
|
||||||
// Reconvert any dirty nodes to sync the Plasma database and the Max one
|
|
||||||
bool Update(); |
|
||||||
|
|
||||||
void AddSceneNodes(std::set<plSceneNode*>& sceneNodes, std::vector<plUoid>& delUoids, std::vector<plKey>& newKeys); |
|
||||||
|
|
||||||
bool IStartWatching(bool forceWatch=false); |
|
||||||
bool IStopWatching(); |
|
||||||
|
|
||||||
// Called by open and close scene.
|
|
||||||
bool IReadNodeMap(const char *dir); |
|
||||||
bool IWriteNodeMap(const char *dir); |
|
||||||
|
|
||||||
void IShutdown(); |
|
||||||
|
|
||||||
void IDeletePath(const char *path); |
|
||||||
void IClearDirtyRecur(plMaxNode *node); |
|
||||||
|
|
||||||
static void INotify(void *param, NotifyInfo *info); |
|
||||||
|
|
||||||
static void CALLBACK ITimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime); |
|
||||||
}; |
|
||||||
|
|
||||||
#endif //SCENE_SYNC_H
|
|
@ -1,296 +0,0 @@ |
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools |
|
||||||
Copyright (C) 2011 Cyan Worlds, 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/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7 |
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or |
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, |
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent |
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK |
|
||||||
(or a modified version of those libraries), |
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, |
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG |
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the |
|
||||||
licensors of this Program grant you additional |
|
||||||
permission to convey the resulting work. Corresponding Source for a |
|
||||||
non-source form of such a combination shall include the source code for |
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered |
|
||||||
work. |
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com |
|
||||||
or by snail mail at: |
|
||||||
Cyan Worlds, Inc. |
|
||||||
14617 N Newport Hwy |
|
||||||
Mead, WA 99021 |
|
||||||
|
|
||||||
*==LICENSE==*/ |
|
||||||
#include "HeadSpin.h" |
|
||||||
#include "SceneViewer.h" |
|
||||||
#include "SceneSync.h" |
|
||||||
|
|
||||||
#include "MaxMain/plMaxCFGFile.h" |
|
||||||
|
|
||||||
#include "MaxMain/resource.h" |
|
||||||
|
|
||||||
// For ShellExecute
|
|
||||||
#include <shellapi.h> |
|
||||||
|
|
||||||
static const char *kDebugClientExe = "plClient_dbg.exe"; |
|
||||||
static const char *kReleaseClientExe = "plClient.exe"; |
|
||||||
|
|
||||||
static const char *kSemaphoreName = "PlasmaSceneViewer"; |
|
||||||
static const char *kPipeName = "\\\\.\\pipe\\PlasmaSceneViewer"; |
|
||||||
|
|
||||||
SceneViewer::SceneViewer() : fhDlg(NULL) |
|
||||||
{ |
|
||||||
// Get the plugin CFG dir
|
|
||||||
const char *plugFile = plMaxConfig::GetPluginIni(); |
|
||||||
|
|
||||||
fUpdate = (GetPrivateProfileInt("SceneViewer", "Update", 1, plugFile) != 0); |
|
||||||
fUpdateFreq = GetPrivateProfileInt("SceneViewer", "UpdateFreq", 500, plugFile); |
|
||||||
fLoadOld = (GetPrivateProfileInt("SceneViewer", "LoadOld", 0, plugFile) != 0); |
|
||||||
fReleaseExe = (GetPrivateProfileInt("SceneViewer", "ReleaseExe", 1, plugFile) != 0); |
|
||||||
} |
|
||||||
|
|
||||||
SceneViewer::~SceneViewer() |
|
||||||
{ |
|
||||||
// Make sure the client is shut down
|
|
||||||
ISetRunning(false); |
|
||||||
|
|
||||||
// Get the plugin CFG dir
|
|
||||||
const char *plugFile = plMaxConfig::GetPluginIni(); |
|
||||||
|
|
||||||
char buf[20]; |
|
||||||
WritePrivateProfileString("SceneViewer", "Update", fUpdate ? "1" : "0", plugFile); |
|
||||||
WritePrivateProfileString("SceneViewer", "UpdateFreq", itoa(fUpdateFreq, buf, 10), plugFile); |
|
||||||
WritePrivateProfileString("SceneViewer", "LoadOld", fLoadOld ? "1" : "0", plugFile); |
|
||||||
WritePrivateProfileString("SceneViewer", "ReleaseExe", fReleaseExe ? "1" : "0", plugFile); |
|
||||||
} |
|
||||||
|
|
||||||
SceneViewer &SceneViewer::Instance() |
|
||||||
{ |
|
||||||
static SceneViewer theInstance; |
|
||||||
return theInstance; |
|
||||||
} |
|
||||||
|
|
||||||
void SceneViewer::Show() |
|
||||||
{ |
|
||||||
// If the dialog is already created, make sure it is visible
|
|
||||||
if (fhDlg) |
|
||||||
{ |
|
||||||
if (IsIconic(fhDlg)) |
|
||||||
ShowWindow(fhDlg, SW_RESTORE); |
|
||||||
} |
|
||||||
else |
|
||||||
{ |
|
||||||
fhDlg = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_SCENEVIEWER), GetCOREInterface()->GetMAXHWnd(), ForwardDlgProc); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// Toggles the client and SceneSync
|
|
||||||
bool SceneViewer::IToggleRunning() |
|
||||||
{ |
|
||||||
fRunning = !fRunning; |
|
||||||
return ISetRunning(fRunning); |
|
||||||
} |
|
||||||
|
|
||||||
// Starts/Stops the client and SceneSync
|
|
||||||
bool SceneViewer::ISetRunning(bool running) |
|
||||||
{ |
|
||||||
if (running) |
|
||||||
{ |
|
||||||
// The client actually is running, hmmm
|
|
||||||
if (SceneSync::Instance().IsClientRunning()) |
|
||||||
return true; |
|
||||||
|
|
||||||
// If we're not loading old data, or we are but it's not there, try to create some.
|
|
||||||
if (!fLoadOld || !SceneSync::Instance().CanLoadOldResMgr()) |
|
||||||
{ |
|
||||||
// If creation fails, fail
|
|
||||||
if (!SceneSync::Instance().CreateClientData()) |
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
char path[MAX_PATH]; |
|
||||||
SceneSync::Instance().GetOutputDir(path); |
|
||||||
strcat(path, "dat\\"); |
|
||||||
|
|
||||||
// Start the client
|
|
||||||
char *options = new char[strlen(path)+2+strlen(kSemaphoreName)+strlen(kPipeName)+6]; |
|
||||||
sprintf(options, "-s %s %s \"%s\"", kSemaphoreName, kPipeName, path); |
|
||||||
|
|
||||||
int ret = (int)ShellExecute(NULL, |
|
||||||
"open", |
|
||||||
fReleaseExe ? kReleaseClientExe : kDebugClientExe, |
|
||||||
options, |
|
||||||
plMaxConfig::GetClientPath(), |
|
||||||
SW_SHOWNORMAL); |
|
||||||
delete [] options; |
|
||||||
|
|
||||||
// Client start failed
|
|
||||||
if (ret < 32) |
|
||||||
return false; |
|
||||||
|
|
||||||
// Start client sync
|
|
||||||
SceneSync::Instance().SetUpdateFreq(fUpdateFreq); |
|
||||||
SceneSync::Instance().BeginClientSync(kSemaphoreName, kPipeName); |
|
||||||
|
|
||||||
return true; |
|
||||||
} |
|
||||||
else |
|
||||||
{ |
|
||||||
if (SceneSync::Instance().IsClientRunning()) |
|
||||||
SceneSync::Instance().EndClientSync(false); |
|
||||||
return true; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
BOOL SceneViewer::ForwardDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) |
|
||||||
{ |
|
||||||
return Instance().DlgProc(hDlg, msg, wParam, lParam); |
|
||||||
} |
|
||||||
|
|
||||||
BOOL SceneViewer::DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) |
|
||||||
{ |
|
||||||
switch (msg) |
|
||||||
{ |
|
||||||
case WM_INITDIALOG: |
|
||||||
{ |
|
||||||
fhDlg = hDlg; |
|
||||||
|
|
||||||
// Set the exe to use
|
|
||||||
HWND hExeCombo = GetDlgItem(hDlg, IDC_EXE); |
|
||||||
ComboBox_AddString(hExeCombo, "Release"); |
|
||||||
ComboBox_AddString(hExeCombo, "Debug"); |
|
||||||
ComboBox_SetCurSel(hExeCombo, fReleaseExe ? 0 : 1); |
|
||||||
|
|
||||||
// Set the client path
|
|
||||||
const char *path = plMaxConfig::GetClientPath(false, true); |
|
||||||
ICustEdit *edit = GetICustEdit(GetDlgItem(hDlg, IDC_CLIENT_PATH)); |
|
||||||
edit->SetText((char*)path); |
|
||||||
|
|
||||||
// Set the "Load old data" checkbox
|
|
||||||
HWND hLoadOld = GetDlgItem(hDlg, IDC_REUSE_DATA); |
|
||||||
Button_SetCheck(hLoadOld, fLoadOld ? BST_CHECKED : BST_UNCHECKED); |
|
||||||
Button_Enable(hLoadOld, SceneSync::Instance().CanLoadOldResMgr()); |
|
||||||
|
|
||||||
// Set the update controls
|
|
||||||
float val = float(fUpdateFreq) / 1000.f; |
|
||||||
ISpinnerControl *spin = SetupFloatSpinner(hDlg, IDC_SPINNER, IDC_EDIT, 0.1, 1.f, val); |
|
||||||
spin->Enable(fUpdate); |
|
||||||
CheckDlgButton(hDlg, IDC_UPDATE, fUpdate ? BST_CHECKED : BST_UNCHECKED); |
|
||||||
|
|
||||||
IEnableSetupControls(!SceneSync::Instance().IsClientRunning()); |
|
||||||
} |
|
||||||
return TRUE; |
|
||||||
|
|
||||||
case WM_COMMAND: |
|
||||||
// Start/Stop SceneViewer
|
|
||||||
if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_START) |
|
||||||
{ |
|
||||||
IToggleRunning(); |
|
||||||
IEnableSetupControls(!SceneSync::Instance().IsClientRunning()); |
|
||||||
return TRUE; |
|
||||||
} |
|
||||||
// Close dialog
|
|
||||||
else if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDCANCEL) |
|
||||||
{ |
|
||||||
DestroyWindow(hDlg); |
|
||||||
fhDlg = NULL; |
|
||||||
return TRUE; |
|
||||||
} |
|
||||||
// Browse for directory
|
|
||||||
else if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_DIR) |
|
||||||
{ |
|
||||||
const char *path = plMaxConfig::GetClientPath(true); |
|
||||||
if (path) |
|
||||||
{ |
|
||||||
ICustEdit *edit = GetICustEdit(GetDlgItem(hDlg, IDC_CLIENT_PATH)); |
|
||||||
edit->SetText((char*)path); |
|
||||||
} |
|
||||||
|
|
||||||
return TRUE; |
|
||||||
} |
|
||||||
// "Load old data" selection changed
|
|
||||||
else if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_REUSE_DATA) |
|
||||||
{ |
|
||||||
fLoadOld = (Button_GetCheck((HWND)lParam) == BST_CHECKED); |
|
||||||
return TRUE; |
|
||||||
} |
|
||||||
// Release/Debug exe selection changed
|
|
||||||
else if (HIWORD(wParam) == CBN_SELCHANGE && LOWORD(wParam) == IDC_EXE) |
|
||||||
{ |
|
||||||
int sel = ComboBox_GetCurSel((HWND)lParam); |
|
||||||
fReleaseExe = (sel == 0); |
|
||||||
return TRUE; |
|
||||||
} |
|
||||||
else if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_UPDATE) |
|
||||||
{ |
|
||||||
fUpdate = (SendMessage((HWND)lParam, BM_GETCHECK, 0, 0) == BST_CHECKED); |
|
||||||
|
|
||||||
ISpinnerControl *spin = GetISpinner(GetDlgItem(hDlg, IDC_SPINNER)); |
|
||||||
spin->Enable(fUpdate); |
|
||||||
ReleaseISpinner(spin); |
|
||||||
|
|
||||||
// If update was turned on, send out an update message so any dirty objects
|
|
||||||
// will be reconverted right away
|
|
||||||
if (fUpdate) |
|
||||||
SceneSync::Instance().SetUpdateFreq(fUpdateFreq); |
|
||||||
|
|
||||||
return TRUE; |
|
||||||
} |
|
||||||
break; |
|
||||||
|
|
||||||
// Update frequency changed
|
|
||||||
case CC_SPINNER_CHANGE: |
|
||||||
if (LOWORD(wParam) == IDC_SPINNER) |
|
||||||
{ |
|
||||||
ISpinnerControl *spin = (ISpinnerControl*)lParam; |
|
||||||
float val = spin->GetFVal(); |
|
||||||
fUpdateFreq = int(val*1000.f); |
|
||||||
SceneSync::Instance().SetUpdateFreq(fUpdateFreq); |
|
||||||
} |
|
||||||
return TRUE; |
|
||||||
|
|
||||||
// Type in directory
|
|
||||||
case WM_CUSTEDIT_ENTER: |
|
||||||
if (wParam == IDC_CLIENT_PATH) |
|
||||||
{ |
|
||||||
ICustEdit *edit = GetICustEdit((HWND)lParam); |
|
||||||
|
|
||||||
char path[MAX_PATH]; |
|
||||||
edit->GetText(path, sizeof(path)); |
|
||||||
plMaxConfig::SetClientPath(path); |
|
||||||
} |
|
||||||
return TRUE; |
|
||||||
} |
|
||||||
|
|
||||||
return FALSE; |
|
||||||
} |
|
||||||
|
|
||||||
void SceneViewer::IEnableSetupControls(bool enable) |
|
||||||
{ |
|
||||||
ICustEdit *edit = GetICustEdit(GetDlgItem(fhDlg, IDC_CLIENT_PATH)); |
|
||||||
edit->Enable(enable); |
|
||||||
|
|
||||||
EnableWindow(GetDlgItem(fhDlg, IDC_DIR), enable); |
|
||||||
EnableWindow(GetDlgItem(fhDlg, IDC_EXE), enable); |
|
||||||
EnableWindow(GetDlgItem(fhDlg, IDC_REUSE_DATA), enable); |
|
||||||
|
|
||||||
SetWindowText(GetDlgItem(fhDlg, IDC_START), enable ? "Start" : "Stop"); |
|
||||||
} |
|
@ -1,77 +0,0 @@ |
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools |
|
||||||
Copyright (C) 2011 Cyan Worlds, 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/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7 |
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or |
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, |
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent |
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK |
|
||||||
(or a modified version of those libraries), |
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, |
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG |
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the |
|
||||||
licensors of this Program grant you additional |
|
||||||
permission to convey the resulting work. Corresponding Source for a |
|
||||||
non-source form of such a combination shall include the source code for |
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered |
|
||||||
work. |
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com |
|
||||||
or by snail mail at: |
|
||||||
Cyan Worlds, Inc. |
|
||||||
14617 N Newport Hwy |
|
||||||
Mead, WA 99021 |
|
||||||
|
|
||||||
*==LICENSE==*/ |
|
||||||
#ifndef SceneViewer_h_inc |
|
||||||
#define SceneViewer_h_inc |
|
||||||
|
|
||||||
#include "HeadSpin.h" |
|
||||||
|
|
||||||
// The dialog for setting up and starting the SceneViewer. Controls starting the client
|
|
||||||
// and SceneSync; SceneSync controls the updates though.
|
|
||||||
class SceneViewer |
|
||||||
{ |
|
||||||
protected: |
|
||||||
bool fUpdate; |
|
||||||
int fUpdateFreq; // Update rate (ms), -1 for no update
|
|
||||||
bool fLoadOld; // Load old data if possible
|
|
||||||
bool fReleaseExe; // True for release exe, false for debug
|
|
||||||
bool fRunning; // Do we think the client is currently running (not sure since the
|
|
||||||
// client can terminate without us knowing).
|
|
||||||
HWND fhDlg; // Handle to the setup dialog
|
|
||||||
|
|
||||||
SceneViewer(); |
|
||||||
|
|
||||||
static BOOL CALLBACK ForwardDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); |
|
||||||
BOOL DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); |
|
||||||
|
|
||||||
void IEnableSetupControls(bool enable); |
|
||||||
|
|
||||||
bool IToggleRunning(); |
|
||||||
bool ISetRunning(bool running); |
|
||||||
|
|
||||||
public: |
|
||||||
~SceneViewer(); |
|
||||||
static SceneViewer &Instance(); |
|
||||||
|
|
||||||
void Show(); |
|
||||||
}; |
|
||||||
|
|
||||||
#endif // SceneViewer_h_inc
|
|
@ -1,368 +0,0 @@ |
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools |
|
||||||
Copyright (C) 2011 Cyan Worlds, 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/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7 |
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or |
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, |
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent |
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK |
|
||||||
(or a modified version of those libraries), |
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, |
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG |
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the |
|
||||||
licensors of this Program grant you additional |
|
||||||
permission to convey the resulting work. Corresponding Source for a |
|
||||||
non-source form of such a combination shall include the source code for |
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered |
|
||||||
work. |
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com |
|
||||||
or by snail mail at: |
|
||||||
Cyan Worlds, Inc. |
|
||||||
14617 N Newport Hwy |
|
||||||
Mead, WA 99021 |
|
||||||
|
|
||||||
*==LICENSE==*/ |
|
||||||
#include "HeadSpin.h" |
|
||||||
|
|
||||||
#include "SceneWatcher.h" |
|
||||||
|
|
||||||
#include "MaxMain/plMaxNode.h" |
|
||||||
#include "MaxComponent/plComponent.h" |
|
||||||
#include "MaxMain/plPlasmaRefMsgs.h" |
|
||||||
|
|
||||||
#include "pnKeyedObject/plKey.h" |
|
||||||
|
|
||||||
SceneWatcher::SceneWatcher() : fDirty(false) |
|
||||||
{ |
|
||||||
RegisterNotification(INotify, this, NOTIFY_NODE_CREATED); |
|
||||||
IAddNodeRecur((plMaxNode*)GetCOREInterface()->GetRootNode()); |
|
||||||
} |
|
||||||
|
|
||||||
SceneWatcher::~SceneWatcher() |
|
||||||
{ |
|
||||||
DeleteAllRefsFromMe(); |
|
||||||
UnRegisterNotification(INotify, this, NOTIFY_NODE_CREATED); |
|
||||||
} |
|
||||||
|
|
||||||
int SceneWatcher::NumRefs() |
|
||||||
{ |
|
||||||
return fNodes.size(); |
|
||||||
} |
|
||||||
|
|
||||||
RefTargetHandle SceneWatcher::GetReference(int i) |
|
||||||
{ |
|
||||||
if (i < fNodes.size()) |
|
||||||
return fNodes[i]; |
|
||||||
|
|
||||||
hsAssert(0, "Index out of range"); |
|
||||||
return nil; |
|
||||||
} |
|
||||||
|
|
||||||
void SceneWatcher::SetReference(int i, RefTargetHandle rtarg) |
|
||||||
{ |
|
||||||
if (i < fNodes.size()) |
|
||||||
fNodes[i] = (plMaxNode*)rtarg; |
|
||||||
else |
|
||||||
hsAssert(0, "Index out of range"); |
|
||||||
} |
|
||||||
|
|
||||||
//
|
|
||||||
// Something in the scene has changed.
|
|
||||||
//
|
|
||||||
RefResult SceneWatcher::NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget,
|
|
||||||
PartID& partID, RefMessage message) |
|
||||||
{ |
|
||||||
plMaxNode *node = (plMaxNode *)hTarget; |
|
||||||
|
|
||||||
#ifdef HS_DEBUGGING |
|
||||||
char *tmp = node->GetName(); |
|
||||||
#endif |
|
||||||
|
|
||||||
if (message == REFMSG_CHANGE) |
|
||||||
{ |
|
||||||
// If the message is from a component, and was not generated locally (ie.
|
|
||||||
// it came from a ref parameter), ignore it. There is no way to tell if
|
|
||||||
// one of these messages is an actual change to the component or just a
|
|
||||||
// change to the referenced object. We'll catch the real changes with
|
|
||||||
// REFMSG_USER_COMP_REF_CHANGED below.
|
|
||||||
if (node->IsComponent()) |
|
||||||
{ |
|
||||||
plComponentBase *comp = node->ConvertToComponent(); |
|
||||||
if (!comp->IsCurMsgLocal()) |
|
||||||
return REF_SUCCEED; |
|
||||||
} |
|
||||||
|
|
||||||
// If this is a static light, ignore it
|
|
||||||
Object *obj = node->GetObjectRef(); |
|
||||||
if (obj && obj->SuperClassID() == LIGHT_CLASS_ID && !node->GetRunTimeLight()) |
|
||||||
return REF_SUCCEED; |
|
||||||
|
|
||||||
node->SetDirty(plMaxNode::kGeomDirty, true); |
|
||||||
ISetDirty(); |
|
||||||
} |
|
||||||
else if (message == REFMSG_TARGET_DELETED) |
|
||||||
{ |
|
||||||
// If the deleted node was a component, dirty everyone it was attached to
|
|
||||||
if (node->IsComponent()) |
|
||||||
{ |
|
||||||
plComponentBase *comp = node->ConvertToComponent(); |
|
||||||
for (uint32_t i = 0; i < comp->NumTargets(); i++) |
|
||||||
{ |
|
||||||
if (comp->GetTarget(i)) |
|
||||||
comp->GetTarget(i)->SetDirty(plMaxNode::kGeomDirty, true); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fDeleted.push_back(node->GetKey()); |
|
||||||
|
|
||||||
IRemoveRef(node); |
|
||||||
ISetDirty(); |
|
||||||
} |
|
||||||
else if (message == REFMSG_NODE_MATERIAL_CHANGED || |
|
||||||
message == REFMSG_USER_MAT) |
|
||||||
{ |
|
||||||
if (!node->IsComponent()) |
|
||||||
{ |
|
||||||
node->SetDirty(plMaxNode::kMatDirty, true); |
|
||||||
ISetDirty(); |
|
||||||
} |
|
||||||
} |
|
||||||
// A node was added to the components target list
|
|
||||||
else if (message == REFMSG_USER_TARGET_ADD) |
|
||||||
{ |
|
||||||
plMaxNode *target = (plMaxNode*)partID; |
|
||||||
target->SetDirty(plMaxNode::kGeomDirty, true); |
|
||||||
ISetDirty(); |
|
||||||
} |
|
||||||
// A node was deleted from the components target list
|
|
||||||
else if (message == REFMSG_USER_TARGET_DELETE) |
|
||||||
{ |
|
||||||
plMaxNode *target = (plMaxNode*)partID; |
|
||||||
target->SetDirty(plMaxNode::kGeomDirty, true); |
|
||||||
ISetDirty(); |
|
||||||
} |
|
||||||
// A ref maintained by a component PB changed (not just a propagated message
|
|
||||||
// from the ref)
|
|
||||||
else if (message == REFMSG_USER_COMP_REF_CHANGED) |
|
||||||
{ |
|
||||||
node->SetDirty(plMaxNode::kGeomDirty, true); |
|
||||||
ISetDirty(); |
|
||||||
} |
|
||||||
|
|
||||||
return REF_SUCCEED; |
|
||||||
} |
|
||||||
|
|
||||||
bool SceneWatcher::AnyDeleted() |
|
||||||
{ |
|
||||||
return !fDeleted.empty(); |
|
||||||
} |
|
||||||
|
|
||||||
SceneWatcher::KeyList& SceneWatcher::GetDeleted() |
|
||||||
{ |
|
||||||
return fDeleted; |
|
||||||
} |
|
||||||
|
|
||||||
const SceneWatcher::NodeList& SceneWatcher::GetWatchNodes() |
|
||||||
{ |
|
||||||
return fNodes; |
|
||||||
} |
|
||||||
|
|
||||||
bool SceneWatcher::AnyDirty() |
|
||||||
{ |
|
||||||
return fDirty; |
|
||||||
} |
|
||||||
|
|
||||||
void SceneWatcher::GetDirty(NodeSet& dirtyNodes) |
|
||||||
{ |
|
||||||
int size = fNodes.size(); |
|
||||||
for (int i = 0; i < size; i++) |
|
||||||
{ |
|
||||||
plMaxNode *node = fNodes[i]; |
|
||||||
|
|
||||||
#ifdef HS_DEBUGGING |
|
||||||
const char *tmp = node ? node->GetName() : nil; |
|
||||||
#endif |
|
||||||
// If any dirty flags are set, add to dirty list
|
|
||||||
if (node && node->GetDirty(plMaxNode::kAllDirty)) |
|
||||||
IGetDependents(node, dirtyNodes); |
|
||||||
} |
|
||||||
|
|
||||||
fDirty = false; |
|
||||||
} |
|
||||||
|
|
||||||
void SceneWatcher::IAddRef(plMaxNode *node) |
|
||||||
{ |
|
||||||
// Ensure that we don't already ref this node
|
|
||||||
if (FindRef(node) != -1) |
|
||||||
return; |
|
||||||
|
|
||||||
// Make a ref
|
|
||||||
int size = fNodes.size(); |
|
||||||
fNodes.resize(size+1); |
|
||||||
MakeRefByID(FOREVER, size, node); |
|
||||||
} |
|
||||||
|
|
||||||
void SceneWatcher::IRemoveRef(plMaxNode *node) |
|
||||||
{ |
|
||||||
// Delete the reference if it's in our list
|
|
||||||
int i = FindRef(node); |
|
||||||
|
|
||||||
if (i != -1) |
|
||||||
{ |
|
||||||
// Clear the node data, in case it is undeleted later
|
|
||||||
// (when it will be invalid)
|
|
||||||
node->ClearData(nil, nil); |
|
||||||
node->SetDirty(plMaxNode::kAllDirty, true); |
|
||||||
|
|
||||||
// We can never really delete this reference because the user may "undo"
|
|
||||||
// and cause it to come back, which just sets the reference again.
|
|
||||||
fNodes[i] = nil; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void SceneWatcher::IAddNodeRecur(plMaxNode *node) |
|
||||||
{ |
|
||||||
IAddRef(node); |
|
||||||
|
|
||||||
// If a node is dirty, make sure to set the dirty flag (since nodes may have
|
|
||||||
// been dirtied in a previous run but not reconverted yet).
|
|
||||||
if (node->GetDirty(plMaxNode::kAllDirty)) |
|
||||||
fDirty = true; |
|
||||||
|
|
||||||
for (int i = 0; i < node->NumberOfChildren(); ++i) |
|
||||||
{ |
|
||||||
plMaxNode *childNode = (plMaxNode*)node->GetChildNode(i); |
|
||||||
IAddNodeRecur(childNode); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void SceneWatcher::INotify(void *param, NotifyInfo *info) |
|
||||||
{ |
|
||||||
SceneWatcher *inst = (SceneWatcher*)param; |
|
||||||
|
|
||||||
int code = info->intcode; |
|
||||||
|
|
||||||
// New node was added to the scene, add it to our refs
|
|
||||||
if (code == NOTIFY_NODE_CREATED) |
|
||||||
{ |
|
||||||
plMaxNode *node = (plMaxNode*)info->callParam; |
|
||||||
|
|
||||||
// Add a ref to the node and set it to dirty
|
|
||||||
inst->IAddRef(node); |
|
||||||
node->SetDirty(plMaxNodeBase::kAllDirty, true); |
|
||||||
inst->ISetDirty(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void SceneWatcher::ISetDirty() |
|
||||||
{ |
|
||||||
fDirty = true; |
|
||||||
} |
|
||||||
|
|
||||||
#include "../MaxComponent/plMiscComponents.h" |
|
||||||
|
|
||||||
#include "../MaxExport/plExportErrorMsg.h" |
|
||||||
#include "../MaxExport/plExportProgressBar.h" |
|
||||||
#include "../MaxComponent/plResponderComponent.h" // Just need the CID |
|
||||||
|
|
||||||
void SceneWatcher::IGetLogicDependents(plMaxNode *node, NodeSet& nodes) |
|
||||||
{ |
|
||||||
int attached = node->NumAttachedComponents(); |
|
||||||
for (int i = 0; i < attached; i++) |
|
||||||
{ |
|
||||||
plComponentBase *comp = node->GetAttachedComponent(i); |
|
||||||
/*
|
|
||||||
if (comp->ClassID() == ACTIVATOR_CID) |
|
||||||
{ |
|
||||||
plMaxNodeBase *activatorNode = comp->GetINode(); |
|
||||||
int numResponders = activatorNode->NumAttachedComponents(true); |
|
||||||
for (int i = 0; i < numResponders; i++) |
|
||||||
{ |
|
||||||
plComponentBase *responderComp = activatorNode->GetAttachedComponent(i, true); |
|
||||||
if (responderComp->ClassID() == RESPONDER_CID) |
|
||||||
{ |
|
||||||
for (int j = 0; j < responderComp->NumTargets(); j++) |
|
||||||
{ |
|
||||||
plMaxNode *targ = (plMaxNode*)responderComp->GetTarget(j); |
|
||||||
if (targ && nodes.find(targ) == nodes.end()) |
|
||||||
{ |
|
||||||
nodes.insert(targ); |
|
||||||
IGetLogicDependents(targ, nodes); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
else |
|
||||||
*/ |
|
||||||
if (comp->ClassID() == RESPONDER_CID) |
|
||||||
{ |
|
||||||
int activatorCnt = ResponderGetActivatorCount(comp); |
|
||||||
for (int i = 0; i < activatorCnt; i++) |
|
||||||
{ |
|
||||||
plComponentBase *activator = ResponderGetActivator(comp, i); |
|
||||||
|
|
||||||
for (int j = 0; j < activator->NumTargets(); j++) |
|
||||||
{ |
|
||||||
plMaxNode *targ = (plMaxNode*)activator->GetTarget(j); |
|
||||||
if (targ && nodes.find(targ) == nodes.end()) |
|
||||||
{ |
|
||||||
nodes.insert(targ); |
|
||||||
IGetLogicDependents(targ, nodes); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void SceneWatcher::IGetDependents(plMaxNode *node, NodeSet& nodes) |
|
||||||
{ |
|
||||||
NodeSet dependents; |
|
||||||
|
|
||||||
if (node->IsComponent()) |
|
||||||
{ |
|
||||||
plComponentBase *comp = node->ConvertToComponent(); |
|
||||||
|
|
||||||
if (comp->ClassID() == ROOM_CID || comp->ClassID() == PAGEINFO_CID) |
|
||||||
return; |
|
||||||
|
|
||||||
for (int i = 0; i < comp->NumTargets(); i++) |
|
||||||
{ |
|
||||||
plMaxNode *targ = (plMaxNode*)comp->GetTarget(i); |
|
||||||
if (targ) |
|
||||||
{ |
|
||||||
dependents.insert(targ); |
|
||||||
IGetLogicDependents(targ, dependents); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
else |
|
||||||
{ |
|
||||||
dependents.insert(node); |
|
||||||
|
|
||||||
IGetLogicDependents(node, dependents); |
|
||||||
} |
|
||||||
|
|
||||||
// Bug in VC++?
|
|
||||||
// nodes.insert(dependents.begin(), dependents.end());
|
|
||||||
for (NodeSet::iterator i = dependents.begin(); i != dependents.end(); i++) |
|
||||||
nodes.insert(*i); |
|
||||||
} |
|
@ -1,109 +0,0 @@ |
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools |
|
||||||
Copyright (C) 2011 Cyan Worlds, 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/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7 |
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or |
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, |
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent |
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK |
|
||||||
(or a modified version of those libraries), |
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, |
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG |
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the |
|
||||||
licensors of this Program grant you additional |
|
||||||
permission to convey the resulting work. Corresponding Source for a |
|
||||||
non-source form of such a combination shall include the source code for |
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered |
|
||||||
work. |
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com |
|
||||||
or by snail mail at: |
|
||||||
Cyan Worlds, Inc. |
|
||||||
14617 N Newport Hwy |
|
||||||
Mead, WA 99021 |
|
||||||
|
|
||||||
*==LICENSE==*/ |
|
||||||
#ifndef SCENE_WATCHER_H |
|
||||||
#define SCENE_WATCHER_H |
|
||||||
|
|
||||||
#include "Max.h" |
|
||||||
#include "notify.h" |
|
||||||
|
|
||||||
#include <vector> |
|
||||||
#include <set> |
|
||||||
|
|
||||||
#include "pnKeyedObject/plKey.h" |
|
||||||
|
|
||||||
class plMaxNode; |
|
||||||
|
|
||||||
class SceneWatcher : public ReferenceMaker |
|
||||||
{ |
|
||||||
public: |
|
||||||
typedef std::vector<plMaxNode*> NodeList; |
|
||||||
typedef std::set<plMaxNode*> NodeSet; |
|
||||||
typedef std::vector<plKey> KeyList; |
|
||||||
|
|
||||||
protected: |
|
||||||
NodeList fNodes; |
|
||||||
KeyList fDeleted; |
|
||||||
|
|
||||||
bool fDirty; |
|
||||||
|
|
||||||
public: |
|
||||||
SceneWatcher(); |
|
||||||
~SceneWatcher(); |
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
// ReferenceMaker functions
|
|
||||||
//
|
|
||||||
RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget,
|
|
||||||
PartID& partID, RefMessage message); |
|
||||||
|
|
||||||
int NumRefs(); |
|
||||||
RefTargetHandle GetReference(int i); |
|
||||||
void SetReference(int i, RefTargetHandle rtarg); |
|
||||||
|
|
||||||
BOOL IsRealDependency(ReferenceTarget *rtarg) { return FALSE; } |
|
||||||
|
|
||||||
// Get all the nodes we're watching
|
|
||||||
const NodeList& GetWatchNodes(); |
|
||||||
|
|
||||||
// Get all the nodes that need to be reconverted
|
|
||||||
bool AnyDirty(); |
|
||||||
void GetDirty(NodeSet& dirtyNodes); |
|
||||||
|
|
||||||
bool AnyDeleted(); |
|
||||||
KeyList& GetDeleted(); |
|
||||||
|
|
||||||
protected: |
|
||||||
void IAddRef(plMaxNode *node); |
|
||||||
void IRemoveRef(plMaxNode *node); |
|
||||||
|
|
||||||
void IAddNodeRecur(plMaxNode *node); |
|
||||||
|
|
||||||
// Helpers for GetDirtyNodes
|
|
||||||
void IGetDependents(plMaxNode *node, NodeSet& nodes); |
|
||||||
void IGetLogicDependents(plMaxNode *node, NodeSet& nodes); |
|
||||||
|
|
||||||
void ISetDirty(); |
|
||||||
|
|
||||||
static void INotify(void *param, NotifyInfo *info); |
|
||||||
}; |
|
||||||
|
|
||||||
#endif //SCENE_WATCHER_H
|
|
@ -1,103 +0,0 @@ |
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools |
|
||||||
Copyright (C) 2011 Cyan Worlds, 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/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7 |
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or |
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, |
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent |
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK |
|
||||||
(or a modified version of those libraries), |
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, |
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG |
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the |
|
||||||
licensors of this Program grant you additional |
|
||||||
permission to convey the resulting work. Corresponding Source for a |
|
||||||
non-source form of such a combination shall include the source code for |
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered |
|
||||||
work. |
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com |
|
||||||
or by snail mail at: |
|
||||||
Cyan Worlds, Inc. |
|
||||||
14617 N Newport Hwy |
|
||||||
Mead, WA 99021 |
|
||||||
|
|
||||||
*==LICENSE==*/ |
|
||||||
#include "plKeyRefSort.h" |
|
||||||
#include "pnKeyedObject/plKeyImp.h" |
|
||||||
|
|
||||||
#include <algorithm> |
|
||||||
|
|
||||||
std::vector<plKey>* plKeyRefSort::fKeys = nil; |
|
||||||
std::vector<plKeyRefSort::KeyRefs> plKeyRefSort::fNumRefs; |
|
||||||
|
|
||||||
int plKeyRefSort::CountRefsRecur(plKey key, std::vector<plKey>& traversedKeys) |
|
||||||
{ |
|
||||||
int numRefs = 0; |
|
||||||
|
|
||||||
if (std::find(traversedKeys.begin(), traversedKeys.end(), key) == traversedKeys.end()) |
|
||||||
{ |
|
||||||
traversedKeys.push_back(key); |
|
||||||
|
|
||||||
plKeyImp* iKey = (plKeyImp*)key; |
|
||||||
for (int i = 0; i < iKey->GetNumRefs(); i++) |
|
||||||
{ |
|
||||||
plKey refKey = iKey->GetRef(i); |
|
||||||
if (std::find(fKeys->begin(), fKeys->end(), refKey) != fKeys->end()) |
|
||||||
numRefs++; |
|
||||||
|
|
||||||
numRefs += CountRefsRecur(refKey, traversedKeys); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
return numRefs; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
class RefComp |
|
||||||
{ |
|
||||||
public: |
|
||||||
bool operator() (plKey key1, plKey key2) const |
|
||||||
{ |
|
||||||
std::vector<plKeyRefSort::KeyRefs>::iterator it1 = std::find(plKeyRefSort::fNumRefs.begin(), plKeyRefSort::fNumRefs.end(), key1); |
|
||||||
std::vector<plKeyRefSort::KeyRefs>::iterator it2 = std::find(plKeyRefSort::fNumRefs.begin(), plKeyRefSort::fNumRefs.end(), key2); |
|
||||||
|
|
||||||
return ((*it1).fNumRefs < (*it2).fNumRefs); |
|
||||||
} |
|
||||||
}; |
|
||||||
|
|
||||||
void plKeyRefSort::Sort(std::vector<plKey>* keys) |
|
||||||
{ |
|
||||||
fKeys = keys; |
|
||||||
int numKeys = keys->size(); |
|
||||||
fNumRefs.resize(numKeys); |
|
||||||
|
|
||||||
int i; |
|
||||||
for (i = 0; i < numKeys; i++) |
|
||||||
{ |
|
||||||
plKey curKey = (*keys)[i]; |
|
||||||
|
|
||||||
std::vector<plKey> traversedKeys; |
|
||||||
int numRefs = CountRefsRecur(curKey, traversedKeys); |
|
||||||
|
|
||||||
fNumRefs[i] = KeyRefs(curKey, numRefs); |
|
||||||
} |
|
||||||
|
|
||||||
std::sort(fKeys->begin(), fKeys->end(), RefComp()); |
|
||||||
} |
|
@ -1,75 +0,0 @@ |
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools |
|
||||||
Copyright (C) 2011 Cyan Worlds, 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/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7 |
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or |
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, |
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent |
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK |
|
||||||
(or a modified version of those libraries), |
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, |
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG |
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the |
|
||||||
licensors of this Program grant you additional |
|
||||||
permission to convey the resulting work. Corresponding Source for a |
|
||||||
non-source form of such a combination shall include the source code for |
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered |
|
||||||
work. |
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com |
|
||||||
or by snail mail at: |
|
||||||
Cyan Worlds, Inc. |
|
||||||
14617 N Newport Hwy |
|
||||||
Mead, WA 99021 |
|
||||||
|
|
||||||
*==LICENSE==*/ |
|
||||||
#include "HeadSpin.h" |
|
||||||
#include <vector> |
|
||||||
#include "pnKeyedObject/plKey.h" |
|
||||||
|
|
||||||
|
|
||||||
// A really crappy sort of a list of keys from the most referenced key to the least.
|
|
||||||
// This allows you to write out and read in the keys without having to worry about
|
|
||||||
// one referencing another that isn't loaded yet (ie, in the SceneViewer)
|
|
||||||
class plKeyRefSort |
|
||||||
{ |
|
||||||
protected: |
|
||||||
class KeyRefs |
|
||||||
{ |
|
||||||
public: |
|
||||||
plKey fKey; |
|
||||||
int fNumRefs; |
|
||||||
KeyRefs() : fKey(nil), fNumRefs(-1) {} |
|
||||||
KeyRefs(plKey key, int numRefs) : fKey(key), fNumRefs(numRefs) {} |
|
||||||
bool operator== (const plKey key) |
|
||||||
{ |
|
||||||
return (fKey == key); |
|
||||||
} |
|
||||||
}; |
|
||||||
|
|
||||||
static std::vector<plKey>* fKeys; |
|
||||||
static std::vector<KeyRefs> fNumRefs; |
|
||||||
|
|
||||||
friend class RefComp; |
|
||||||
|
|
||||||
static int CountRefsRecur(plKey key, std::vector<plKey>& traversedKeys); |
|
||||||
|
|
||||||
public: |
|
||||||
static void Sort(std::vector<plKey>* keys); |
|
||||||
}; |
|
@ -1,293 +0,0 @@ |
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools |
|
||||||
Copyright (C) 2011 Cyan Worlds, 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/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7 |
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or |
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, |
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent |
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK |
|
||||||
(or a modified version of those libraries), |
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, |
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG |
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the |
|
||||||
licensors of this Program grant you additional |
|
||||||
permission to convey the resulting work. Corresponding Source for a |
|
||||||
non-source form of such a combination shall include the source code for |
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered |
|
||||||
work. |
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com |
|
||||||
or by snail mail at: |
|
||||||
Cyan Worlds, Inc. |
|
||||||
14617 N Newport Hwy |
|
||||||
Mead, WA 99021 |
|
||||||
|
|
||||||
*==LICENSE==*/ |
|
||||||
#include "HeadSpin.h" |
|
||||||
#include "plMaxFileData.h" |
|
||||||
#include "hsUtils.h" |
|
||||||
|
|
||||||
#include "max.h" |
|
||||||
#include "notify.h" |
|
||||||
#include "tvnode.h" |
|
||||||
|
|
||||||
#define PLASMA_FILE_DATA_CID Class_ID(0x255a700a, 0x285279dc) |
|
||||||
|
|
||||||
// MyControl is derived from StdControl, but has no controller functionality. It simply has some
|
|
||||||
// membervariables and saves these by Load and Save.
|
|
||||||
// EditTrackParams and TrackParamsType are responsible for displaying a user interface (RightClick->Properties)
|
|
||||||
// on the controler. With these functions you can avoid it, having an interface !
|
|
||||||
// As you can see, most of these methods are stubbed. Only Load and Save are implemented
|
|
||||||
// and of course the methods, to access the membervariables.
|
|
||||||
class plMaxFileDataControl : public StdControl |
|
||||||
{ |
|
||||||
public: |
|
||||||
SYSTEMTIME fCodeBuildTime; |
|
||||||
char fBranch[128]; |
|
||||||
|
|
||||||
plMaxFileDataControl() |
|
||||||
{ |
|
||||||
memset(&fCodeBuildTime, 0, sizeof(SYSTEMTIME)); |
|
||||||
memset(&fBranch, 0, sizeof(fBranch)); |
|
||||||
} |
|
||||||
|
|
||||||
// Animatable
|
|
||||||
virtual void EditTrackParams(TimeValue t, ParamDimensionBase *dim,TCHAR *pname,HWND hParent, IObjParam *ip, DWORD flags){}; |
|
||||||
int TrackParamsType() { return TRACKPARAMS_WHOLE; } |
|
||||||
virtual void DeleteThis() { delete this; } |
|
||||||
|
|
||||||
// ReferenceMaker
|
|
||||||
virtual RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget, PartID& partID,RefMessage message) |
|
||||||
{return REF_DONTCARE;} |
|
||||||
|
|
||||||
Class_ID ClassID() { return PLASMA_FILE_DATA_CID; } |
|
||||||
SClass_ID SuperClassID() { return CTRL_FLOAT_CLASS_ID; } |
|
||||||
void GetClassName(TSTR& s) {s = "blah";} |
|
||||||
|
|
||||||
// Control methods
|
|
||||||
RefTargetHandle Clone(RemapDir& remap) { return new plMaxFileDataControl(); } |
|
||||||
void Copy(Control *from) {} |
|
||||||
virtual BOOL IsReplaceable() { return FALSE; } |
|
||||||
|
|
||||||
// StdControl methods
|
|
||||||
void GetValueLocalTime(TimeValue t, void *val, Interval &valid, GetSetMethod method=CTRL_ABSOLUTE){} |
|
||||||
void SetValueLocalTime(TimeValue t, void *val, int commit, GetSetMethod method) {} |
|
||||||
void Extrapolate(Interval range,TimeValue t,void *val,Interval &valid,int type){} |
|
||||||
void *CreateTempValue() {return NULL;} |
|
||||||
void DeleteTempValue(void *val) {} |
|
||||||
void ApplyValue(void *val, void *delta) {} |
|
||||||
void MultiplyValue(void *val, float m) {} |
|
||||||
|
|
||||||
// MyControl methods
|
|
||||||
IOResult Load(ILoad *iload); |
|
||||||
IOResult Save(ISave *isave); |
|
||||||
}; |
|
||||||
|
|
||||||
#define MAXFILE_DATA_CHUNK 1001 |
|
||||||
static const uint8_t kVersion = 1; |
|
||||||
|
|
||||||
IOResult plMaxFileDataControl::Load(ILoad *iload) |
|
||||||
{ |
|
||||||
ULONG nb; |
|
||||||
IOResult res; |
|
||||||
while (IO_OK==(res=iload->OpenChunk())) |
|
||||||
{ |
|
||||||
if (iload->CurChunkID() == MAXFILE_DATA_CHUNK) |
|
||||||
{ |
|
||||||
uint8_t version = 0; |
|
||||||
res = iload->Read(&version, sizeof(uint8_t), &nb); |
|
||||||
res = iload->Read(&fCodeBuildTime, sizeof(SYSTEMTIME), &nb); |
|
||||||
|
|
||||||
int branchLen = 0; |
|
||||||
iload->Read(&branchLen, sizeof(int), &nb); |
|
||||||
iload->Read(&fBranch, branchLen, &nb); |
|
||||||
} |
|
||||||
|
|
||||||
iload->CloseChunk(); |
|
||||||
if (res != IO_OK) |
|
||||||
return res; |
|
||||||
} |
|
||||||
|
|
||||||
return IO_OK; |
|
||||||
} |
|
||||||
|
|
||||||
IOResult plMaxFileDataControl::Save(ISave *isave) |
|
||||||
{ |
|
||||||
ULONG nb; |
|
||||||
isave->BeginChunk(MAXFILE_DATA_CHUNK); |
|
||||||
|
|
||||||
isave->Write(&kVersion, sizeof(kVersion), &nb); |
|
||||||
isave->Write(&fCodeBuildTime, sizeof(SYSTEMTIME), &nb); |
|
||||||
|
|
||||||
int branchLen = strlen(fBranch)+1; |
|
||||||
isave->Write(&branchLen, sizeof(int), &nb); |
|
||||||
isave->Write(&fBranch, branchLen, &nb); |
|
||||||
|
|
||||||
isave->EndChunk(); |
|
||||||
return IO_OK; |
|
||||||
} |
|
||||||
|
|
||||||
class MaxFileDataClassDesc : public ClassDesc |
|
||||||
{ |
|
||||||
public: |
|
||||||
int IsPublic() { return FALSE; } |
|
||||||
void* Create(BOOL loading) { return new plMaxFileDataControl; } |
|
||||||
const TCHAR* ClassName() { return _T("MaxFileData"); } |
|
||||||
SClass_ID SuperClassID() { return CTRL_FLOAT_CLASS_ID; } |
|
||||||
Class_ID ClassID() { return PLASMA_FILE_DATA_CID; } |
|
||||||
const TCHAR* Category() { return _T(""); } |
|
||||||
}; |
|
||||||
MaxFileDataClassDesc gMaxFileDataClassDesc; |
|
||||||
ClassDesc* GetMaxFileDataDesc() { return &gMaxFileDataClassDesc; } |
|
||||||
|
|
||||||
// This functions searches for Trackviewnode and the Controller and creates one, if none is present.
|
|
||||||
plMaxFileDataControl *GetMaxFileData(bool& created) |
|
||||||
{ |
|
||||||
plMaxFileDataControl *pCtrl = NULL; |
|
||||||
ITrackViewNode *tvNode = NULL; |
|
||||||
ITrackViewNode *tvRoot = GetCOREInterface()->GetTrackViewRootNode(); |
|
||||||
|
|
||||||
int i = tvRoot->FindItem(PLASMA_FILE_DATA_CID); |
|
||||||
if (i < 0) |
|
||||||
{ |
|
||||||
created = true; |
|
||||||
|
|
||||||
tvNode = CreateITrackViewNode(); |
|
||||||
|
|
||||||
// This method adds the Node with the specific Title (e.g. "My Settings")
|
|
||||||
tvRoot->AddNode(tvNode, "Plasma Globals", PLASMA_FILE_DATA_CID); |
|
||||||
pCtrl = (plMaxFileDataControl*)CreateInstance(CTRL_FLOAT_CLASS_ID, PLASMA_FILE_DATA_CID); |
|
||||||
|
|
||||||
TSTR s; |
|
||||||
pCtrl->GetClassName(s); |
|
||||||
|
|
||||||
|
|
||||||
// This adds the controller
|
|
||||||
tvNode->AddController(pCtrl, s, PLASMA_FILE_DATA_CID); |
|
||||||
tvNode->HideChildren(TRUE); |
|
||||||
} |
|
||||||
else |
|
||||||
{ |
|
||||||
created = false; |
|
||||||
|
|
||||||
tvNode = tvRoot->GetNode(i); |
|
||||||
pCtrl = (plMaxFileDataControl*)tvNode->GetController(PLASMA_FILE_DATA_CID); |
|
||||||
} |
|
||||||
|
|
||||||
return pCtrl; |
|
||||||
} |
|
||||||
|
|
||||||
static SYSTEMTIME gThisCodeBuildTime; |
|
||||||
static char gThisBranch[128]; |
|
||||||
|
|
||||||
static void PrintTime(SYSTEMTIME& time, char* buf) |
|
||||||
{ |
|
||||||
sprintf(buf, "%d/%d/%d %d:%02d %s", time.wMonth, time.wDay, time.wYear, |
|
||||||
(time.wHour <= 12) ? time.wHour : time.wHour-12, |
|
||||||
time.wMinute, |
|
||||||
(time.wHour < 12 || time.wHour == 24) ? "AM" : "PM"); |
|
||||||
} |
|
||||||
|
|
||||||
static void NotifyProc(void *param, NotifyInfo *info) |
|
||||||
{ |
|
||||||
if (info->intcode == NOTIFY_FILE_POST_OPEN) |
|
||||||
{ |
|
||||||
bool created; |
|
||||||
plMaxFileDataControl* data = GetMaxFileData(created); |
|
||||||
|
|
||||||
if (!created) |
|
||||||
{ |
|
||||||
FILETIME fileTime, pluginTime; |
|
||||||
SystemTimeToFileTime(&gThisCodeBuildTime, &pluginTime); |
|
||||||
SystemTimeToFileTime(&data->fCodeBuildTime, &fileTime); |
|
||||||
|
|
||||||
if (CompareFileTime(&fileTime, &pluginTime) > 0) |
|
||||||
{ |
|
||||||
if (hsMessageBox_SuppressPrompts) |
|
||||||
return; |
|
||||||
|
|
||||||
char buf[1024]; |
|
||||||
|
|
||||||
strcpy(buf, "This file was last saved with plugins stamped:\n\n"); |
|
||||||
|
|
||||||
char timeBuf[128]; |
|
||||||
PrintTime(data->fCodeBuildTime, timeBuf); |
|
||||||
strcat(buf, timeBuf); |
|
||||||
strcat(buf, "\n"); |
|
||||||
strcat(buf, data->fBranch); |
|
||||||
|
|
||||||
strcat(buf, "\n\nThese plugins are stamped:\n\n"); |
|
||||||
|
|
||||||
PrintTime(gThisCodeBuildTime, timeBuf); |
|
||||||
strcat(buf, timeBuf); |
|
||||||
strcat(buf, "\n"); |
|
||||||
strcat(buf, gThisBranch); |
|
||||||
|
|
||||||
strcat(buf, |
|
||||||
"\n\nNew features may have been added to the newer plugins,\n" |
|
||||||
"so saving this file could cause data to be lost."); |
|
||||||
|
|
||||||
MessageBox(GetCOREInterface()->GetMAXHWnd(), buf, "Plugin Warning", MB_OK | MB_ICONEXCLAMATION); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
strcpy(data->fBranch, gThisBranch); |
|
||||||
memcpy(&data->fCodeBuildTime, &gThisCodeBuildTime, sizeof(SYSTEMTIME)); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void IGetString(int resID, char *destBuffer, int size) |
|
||||||
{ |
|
||||||
HRSRC rsrc = ::FindResource(hInstance, MAKEINTRESOURCE(resID), RT_RCDATA); |
|
||||||
|
|
||||||
if (rsrc != NULL) |
|
||||||
{ |
|
||||||
HGLOBAL handle = ::LoadResource(hInstance, rsrc); |
|
||||||
|
|
||||||
if (handle != NULL) |
|
||||||
{ |
|
||||||
char* str = (char*)::LockResource(handle); |
|
||||||
strncpy(destBuffer, str, size); |
|
||||||
UnlockResource(handle); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void InitMaxFileData() |
|
||||||
{ |
|
||||||
memset(&gThisCodeBuildTime, 0, sizeof(SYSTEMTIME)); |
|
||||||
|
|
||||||
// Date
|
|
||||||
char buf[128]; |
|
||||||
IGetString(1000, buf, sizeof(buf) - 1); |
|
||||||
sscanf(buf, "%hu/%hu/%hu", &gThisCodeBuildTime.wMonth, &gThisCodeBuildTime.wDay, &gThisCodeBuildTime.wYear); |
|
||||||
|
|
||||||
// Time
|
|
||||||
IGetString(1001, buf, sizeof(buf) - 1); |
|
||||||
sscanf(buf, "%hu:%hu", &gThisCodeBuildTime.wHour, &gThisCodeBuildTime.wMinute); |
|
||||||
|
|
||||||
if (strstr(buf, "PM") != nil) |
|
||||||
{ |
|
||||||
gThisCodeBuildTime.wHour += 12; |
|
||||||
} |
|
||||||
|
|
||||||
IGetString(1002, gThisBranch, sizeof(gThisBranch) - 1); |
|
||||||
|
|
||||||
RegisterNotification(NotifyProc, 0, NOTIFY_FILE_POST_OPEN); |
|
||||||
} |
|
@ -1,44 +0,0 @@ |
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools |
|
||||||
Copyright (C) 2011 Cyan Worlds, 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/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7 |
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or |
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, |
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent |
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK |
|
||||||
(or a modified version of those libraries), |
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, |
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG |
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the |
|
||||||
licensors of this Program grant you additional |
|
||||||
permission to convey the resulting work. Corresponding Source for a |
|
||||||
non-source form of such a combination shall include the source code for |
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered |
|
||||||
work. |
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com |
|
||||||
or by snail mail at: |
|
||||||
Cyan Worlds, Inc. |
|
||||||
14617 N Newport Hwy |
|
||||||
Mead, WA 99021 |
|
||||||
|
|
||||||
*==LICENSE==*/ |
|
||||||
|
|
||||||
void InitMaxFileData(); |
|
||||||
ClassDesc* GetMaxFileDataDesc(); |
|
@ -1,67 +0,0 @@ |
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools |
|
||||||
Copyright (C) 2011 Cyan Worlds, 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/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7 |
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or |
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, |
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent |
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK |
|
||||||
(or a modified version of those libraries), |
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, |
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG |
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the |
|
||||||
licensors of this Program grant you additional |
|
||||||
permission to convey the resulting work. Corresponding Source for a |
|
||||||
non-source form of such a combination shall include the source code for |
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered |
|
||||||
work. |
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com |
|
||||||
or by snail mail at: |
|
||||||
Cyan Worlds, Inc. |
|
||||||
14617 N Newport Hwy |
|
||||||
Mead, WA 99021 |
|
||||||
|
|
||||||
*==LICENSE==*/ |
|
||||||
#include "plPluginClient.h" |
|
||||||
#include "plPluginApp.h" |
|
||||||
#include "pnNetCommon/plNetApp.h" |
|
||||||
|
|
||||||
plClient *plPluginApp::Startup(char *pCmdLine) |
|
||||||
{ |
|
||||||
// Create the client
|
|
||||||
fClient = new plPluginClient; |
|
||||||
|
|
||||||
// disable networking always
|
|
||||||
plNetClientApp::GetInstance()->SetFlagsBit(plNetClientApp::kDisabled); |
|
||||||
// and set local triggers
|
|
||||||
plNetClientApp::GetInstance()->SetFlagsBit(plNetClientApp::kLocalTriggers);
|
|
||||||
|
|
||||||
return fClient;
|
|
||||||
} |
|
||||||
|
|
||||||
void plPluginApp::Shutdown() |
|
||||||
{ |
|
||||||
// Destroy the client
|
|
||||||
if (fClient) |
|
||||||
{ |
|
||||||
fClient->Shutdown(); |
|
||||||
fClient = nil; |
|
||||||
} |
|
||||||
} |
|
@ -1,59 +0,0 @@ |
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools |
|
||||||
Copyright (C) 2011 Cyan Worlds, 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/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7 |
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or |
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, |
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent |
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK |
|
||||||
(or a modified version of those libraries), |
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, |
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG |
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the |
|
||||||
licensors of this Program grant you additional |
|
||||||
permission to convey the resulting work. Corresponding Source for a |
|
||||||
non-source form of such a combination shall include the source code for |
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered |
|
||||||
work. |
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com |
|
||||||
or by snail mail at: |
|
||||||
Cyan Worlds, Inc. |
|
||||||
14617 N Newport Hwy |
|
||||||
Mead, WA 99021 |
|
||||||
|
|
||||||
*==LICENSE==*/ |
|
||||||
#include "plClient/plApp.h" |
|
||||||
|
|
||||||
class plPluginClient; |
|
||||||
|
|
||||||
//
|
|
||||||
// Plugin app class. Creates and destroys the client, leaves the resmanager
|
|
||||||
//
|
|
||||||
class plPluginApp : public plApp |
|
||||||
{ |
|
||||||
protected: |
|
||||||
plPluginClient *fClient; |
|
||||||
|
|
||||||
public: |
|
||||||
plPluginApp() : fClient(NULL) {} |
|
||||||
|
|
||||||
virtual plClient *Startup(char *CmdLine); |
|
||||||
virtual void Shutdown(); |
|
||||||
}; |
|
@ -1,307 +0,0 @@ |
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools |
|
||||||
Copyright (C) 2011 Cyan Worlds, 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/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7 |
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or |
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, |
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent |
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK |
|
||||||
(or a modified version of those libraries), |
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, |
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG |
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the |
|
||||||
licensors of this Program grant you additional |
|
||||||
permission to convey the resulting work. Corresponding Source for a |
|
||||||
non-source form of such a combination shall include the source code for |
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered |
|
||||||
work. |
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com |
|
||||||
or by snail mail at: |
|
||||||
Cyan Worlds, Inc. |
|
||||||
14617 N Newport Hwy |
|
||||||
Mead, WA 99021 |
|
||||||
|
|
||||||
*==LICENSE==*/ |
|
||||||
#include "plPluginClient.h" |
|
||||||
|
|
||||||
#include "plPipeline/hsG3DDeviceSelector.h" |
|
||||||
|
|
||||||
#include "hsThread.h" |
|
||||||
#include "hsSTLStream.h" |
|
||||||
|
|
||||||
#include "pnKeyedObject/plUoid.h" |
|
||||||
#include "plResMgr/plUpdatableResManager.h" |
|
||||||
#include "plStatusLog/plStatusLog.h" |
|
||||||
|
|
||||||
// Needed for IEnableProxies
|
|
||||||
#include "plPipeline.h" |
|
||||||
#include "plDrawable/plDrawableSpans.h" |
|
||||||
#include "pnMessage/plProxyDrawMsg.h" |
|
||||||
#include "plgDispatch.h" |
|
||||||
|
|
||||||
#define LOG_SCENEVIWER |
|
||||||
|
|
||||||
static plUpdatableResManager *GetResMgr() |
|
||||||
{ |
|
||||||
return (plUpdatableResManager*)hsgResMgr::ResMgr(); |
|
||||||
} |
|
||||||
|
|
||||||
plUpdatableClient::plUpdatableClient() : fPipeName(nil), fUpdateSignal(nil), fDataPath(nil), fActive(true), fDirty(false) |
|
||||||
{ |
|
||||||
#ifdef LOG_SCENEVIWER |
|
||||||
fLog = plStatusLogMgr::GetInstance().CreateStatusLog(25, "SceneViewer", |
|
||||||
plStatusLog::kDontWriteFile | plStatusLog::kFilledBackground | plStatusLog::kAlignToTop); |
|
||||||
#endif // LOG_SCENEVIWER
|
|
||||||
} |
|
||||||
|
|
||||||
plUpdatableClient::~plUpdatableClient() |
|
||||||
{ |
|
||||||
if (fUpdateSignal) |
|
||||||
{ |
|
||||||
delete fUpdateSignal; |
|
||||||
fUpdateSignal = nil; |
|
||||||
} |
|
||||||
|
|
||||||
if (fLog) |
|
||||||
{ |
|
||||||
delete fLog; |
|
||||||
fLog = nil; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void plUpdatableClient::InitUpdate(const char *semaphoreName, const char *pipeName, const char *dir) |
|
||||||
{ |
|
||||||
fUpdateSignal = new hsSemaphore(0, semaphoreName); |
|
||||||
fPipeName = pipeName; |
|
||||||
fDataPath = dir; |
|
||||||
} |
|
||||||
|
|
||||||
hsG3DDeviceModeRecord plUpdatableClient::ILoadDevMode(const char* devModeFile) |
|
||||||
{ |
|
||||||
// Get the usual devmode
|
|
||||||
hsG3DDeviceModeRecord dmr = plClient::ILoadDevMode(devModeFile); |
|
||||||
|
|
||||||
// Override the mode with a windowed one
|
|
||||||
hsG3DDeviceMode *mode = (hsG3DDeviceMode*)dmr.GetMode(); |
|
||||||
mode->SetColorDepth(0); |
|
||||||
|
|
||||||
return hsG3DDeviceModeRecord(*dmr.GetDevice(), *mode); |
|
||||||
} |
|
||||||
|
|
||||||
#include "../../../Plasma/Apps/plClient/plClientUpdateFormat.h" |
|
||||||
#include "../pnKeyedObject/plKey.h" |
|
||||||
|
|
||||||
void plUpdatableClient::IGetUpdate() |
|
||||||
{ |
|
||||||
// If the semaphore is signaled an update is ready
|
|
||||||
if (fUpdateSignal && fUpdateSignal->Wait(0)) |
|
||||||
{ |
|
||||||
hsNamedPipeStream s; |
|
||||||
s.Open(fPipeName, "r"); |
|
||||||
|
|
||||||
#ifdef LOG_SCENEVIWER |
|
||||||
fLog->Clear(); |
|
||||||
static int numUpdates = 0; |
|
||||||
numUpdates++; |
|
||||||
fLog->AddLineF(plStatusLog::kBlue, "SceneViewer Update #%d", numUpdates); |
|
||||||
#endif // LOG_SCENEVIWER
|
|
||||||
|
|
||||||
uint8_t type = s.ReadByte(); |
|
||||||
|
|
||||||
if (type == ClientUpdate::kShutdown) |
|
||||||
{ |
|
||||||
#ifdef LOG_SCENEVIWER |
|
||||||
fLog->AddLine("Client shutdown"); |
|
||||||
#endif // LOG_SCENEVIWER
|
|
||||||
|
|
||||||
PostMessage(GetWindowHandle(), WM_SYSCOMMAND, SC_CLOSE, 0); |
|
||||||
} |
|
||||||
else if (type == ClientUpdate::kUpdate) |
|
||||||
{ |
|
||||||
fDirty = true; |
|
||||||
|
|
||||||
IEnableProxies(false); |
|
||||||
|
|
||||||
int i; |
|
||||||
|
|
||||||
//
|
|
||||||
// Delete the deleted keys
|
|
||||||
//
|
|
||||||
int numDeleted = s.ReadSwap32(); |
|
||||||
std::vector<plKey*> delKeys; |
|
||||||
delKeys.reserve(numDeleted); |
|
||||||
|
|
||||||
for (i = 0; i < numDeleted; i++) |
|
||||||
{ |
|
||||||
plUoid uoid; |
|
||||||
uoid.Read(&s); |
|
||||||
plKey *key = hsgResMgr::ResMgr()->FindKey(uoid); |
|
||||||
hsAssert(key, "Key to delete not found"); |
|
||||||
if (key) |
|
||||||
{ |
|
||||||
#ifdef LOG_SCENEVIWER |
|
||||||
fLog->AddLineF("Remove: %s", key->GetName()); |
|
||||||
#endif // LOG_SCENEVIWER
|
|
||||||
|
|
||||||
GetResMgr()->RemoveObject(key, false); |
|
||||||
delKeys.push_back(key); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
GetResMgr()->DelayLoad(true); |
|
||||||
|
|
||||||
//
|
|
||||||
// Read in the changed spans
|
|
||||||
//
|
|
||||||
hsStatusMessage("ReadChangedSpans\n"); |
|
||||||
GetResMgr()->ReadChangedSpans(&s); |
|
||||||
|
|
||||||
//
|
|
||||||
// Read in the new keys and objects
|
|
||||||
//
|
|
||||||
int numNew = s.ReadSwap32(); |
|
||||||
for (i = 0; i < numNew; i++) |
|
||||||
{ |
|
||||||
plCreatable *cre = GetResMgr()->ReadCreatable(&s); |
|
||||||
|
|
||||||
hsKeyedObject *ko = hsKeyedObject::ConvertNoRef(cre); |
|
||||||
|
|
||||||
#ifdef LOG_SCENEVIWER |
|
||||||
if (ko) |
|
||||||
fLog->AddLineF("Read: %s", ko->GetKey()->GetName()); |
|
||||||
else |
|
||||||
fLog->AddLine("Read: (null)"); |
|
||||||
#endif // LOG_SCENEVIWER
|
|
||||||
} |
|
||||||
|
|
||||||
GetResMgr()->DelayLoad(false); |
|
||||||
|
|
||||||
// Clear out any objects that were never reloaded (really deleted)
|
|
||||||
for (i = 0; i < delKeys.size(); i++) |
|
||||||
{ |
|
||||||
plKey *key = delKeys[i]; |
|
||||||
if (!key->ObjectIsLoaded()) |
|
||||||
{ |
|
||||||
#ifdef LOG_SCENEVIWER |
|
||||||
fLog->AddLineF("Key deleted: %s", key->GetName()); |
|
||||||
#endif // LOG_SCENEVIWER
|
|
||||||
|
|
||||||
GetResMgr()->RemoveObject(key); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
IEnableProxies(true); |
|
||||||
} |
|
||||||
|
|
||||||
s.Close(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
bool plUpdatableClient::Init() |
|
||||||
{ |
|
||||||
if (plClient::Init()) |
|
||||||
{ |
|
||||||
GetResMgr()->ForceLoadDirectory(fDataPath, true); |
|
||||||
// Page in the SceneViewer now that our key is ready
|
|
||||||
GetResMgr()->PageInSceneViewer(); |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
bool plUpdatableClient::MainLoop() |
|
||||||
{ |
|
||||||
IGetUpdate(); |
|
||||||
|
|
||||||
if (fActive) |
|
||||||
return plClient::MainLoop(); |
|
||||||
else |
|
||||||
{ |
|
||||||
Sleep(100); |
|
||||||
return true; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#include <direct.h> |
|
||||||
|
|
||||||
bool plUpdatableClient::Shutdown() |
|
||||||
{ |
|
||||||
if (fDirty && fDataPath) |
|
||||||
{ |
|
||||||
char oldCwd[MAX_PATH]; |
|
||||||
getcwd(oldCwd, sizeof(oldCwd)); |
|
||||||
|
|
||||||
// Even bigger hack
|
|
||||||
char tempCrap[MAX_PATH]; |
|
||||||
strcpy(tempCrap, fDataPath); |
|
||||||
tempCrap[strlen(tempCrap)-strlen("dat\\")] = '\0'; |
|
||||||
chdir(tempCrap); |
|
||||||
|
|
||||||
GetResMgr()->WriteSceneViewer(); |
|
||||||
|
|
||||||
chdir(oldCwd); |
|
||||||
} |
|
||||||
|
|
||||||
return plClient::Shutdown(); |
|
||||||
} |
|
||||||
|
|
||||||
void plUpdatableClient::IEnableProxies(bool enable) |
|
||||||
{ |
|
||||||
if (enable) |
|
||||||
{ |
|
||||||
// switch back on any drawable proxies
|
|
||||||
if (fPipeline->GetDrawableTypeMask() & plDrawableSpans::kAudibleProxy) |
|
||||||
{
|
|
||||||
plProxyDrawMsg* msg = new plProxyDrawMsg(plProxyDrawMsg::kAudible | plProxyDrawMsg::kCreate); |
|
||||||
plgDispatch::MsgSend(msg); |
|
||||||
} |
|
||||||
if (fPipeline->GetDrawableTypeMask() & plDrawableSpans::kOccluderProxy) |
|
||||||
{
|
|
||||||
plProxyDrawMsg* msg = new plProxyDrawMsg(plProxyDrawMsg::kOccluder | plProxyDrawMsg::kCreate); |
|
||||||
plgDispatch::MsgSend(msg); |
|
||||||
} |
|
||||||
if (fPipeline->GetDrawableTypeMask() & plDrawableSpans::kPhysicalProxy) |
|
||||||
{
|
|
||||||
plProxyDrawMsg* msg = new plProxyDrawMsg(plProxyDrawMsg::kPhysical | plProxyDrawMsg::kCreate); |
|
||||||
plgDispatch::MsgSend(msg); |
|
||||||
} |
|
||||||
if (fPipeline->GetDrawableTypeMask() & plDrawableSpans::kLightProxy) |
|
||||||
{
|
|
||||||
plProxyDrawMsg* msg = new plProxyDrawMsg(plProxyDrawMsg::kLight | plProxyDrawMsg::kCreate); |
|
||||||
plgDispatch::MsgSend(msg); |
|
||||||
} |
|
||||||
} |
|
||||||
else |
|
||||||
{ |
|
||||||
// notify any and all drawable proxies to stop drawing...
|
|
||||||
plProxyDrawMsg* nuke = new plProxyDrawMsg(plProxyDrawMsg::kAudible |
|
||||||
| plProxyDrawMsg::kOccluder |
|
||||||
| plProxyDrawMsg::kPhysical |
|
||||||
| plProxyDrawMsg::kLight |
|
||||||
| plProxyDrawMsg::kDestroy); |
|
||||||
plgDispatch::MsgSend(nuke); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void plUpdatableClient::WindowActivate(bool active) |
|
||||||
{ |
|
||||||
fActive = active; |
|
||||||
} |
|
@ -1,81 +0,0 @@ |
|||||||
/*==LICENSE==*
|
|
||||||
|
|
||||||
CyanWorlds.com Engine - MMOG client, server and tools |
|
||||||
Copyright (C) 2011 Cyan Worlds, 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/>.
|
|
||||||
|
|
||||||
Additional permissions under GNU GPL version 3 section 7 |
|
||||||
|
|
||||||
If you modify this Program, or any covered work, by linking or |
|
||||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, |
|
||||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent |
|
||||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK |
|
||||||
(or a modified version of those libraries), |
|
||||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, |
|
||||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG |
|
||||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the |
|
||||||
licensors of this Program grant you additional |
|
||||||
permission to convey the resulting work. Corresponding Source for a |
|
||||||
non-source form of such a combination shall include the source code for |
|
||||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered |
|
||||||
work. |
|
||||||
|
|
||||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com |
|
||||||
or by snail mail at: |
|
||||||
Cyan Worlds, Inc. |
|
||||||
14617 N Newport Hwy |
|
||||||
Mead, WA 99021 |
|
||||||
|
|
||||||
*==LICENSE==*/ |
|
||||||
#ifndef plUpdatableClient_h_inc |
|
||||||
#define plUpdatableClient_h_inc |
|
||||||
|
|
||||||
#include "HeadSpin.h" |
|
||||||
#include "plClient/plClient.h" |
|
||||||
|
|
||||||
class hsSemaphore; |
|
||||||
class plStatusLog; |
|
||||||
|
|
||||||
class plUpdatableClient : public plClient |
|
||||||
{ |
|
||||||
protected: |
|
||||||
hsSemaphore *fUpdateSignal; |
|
||||||
const char *fPipeName; |
|
||||||
const char *fDataPath; |
|
||||||
|
|
||||||
bool fActive; |
|
||||||
bool fDirty; |
|
||||||
|
|
||||||
plStatusLog *fLog; |
|
||||||
|
|
||||||
void IEnableProxies(bool enable); |
|
||||||
void IGetUpdate(); |
|
||||||
|
|
||||||
public: |
|
||||||
plUpdatableClient(); |
|
||||||
virtual ~plUpdatableClient(); |
|
||||||
|
|
||||||
virtual hsG3DDeviceModeRecord ILoadDevMode(const char* devModeFile); |
|
||||||
|
|
||||||
virtual bool Init(); |
|
||||||
virtual bool MainLoop(); |
|
||||||
virtual bool Shutdown(); |
|
||||||
|
|
||||||
void InitUpdate(const char *semaphoreName, const char *pipeName, const char *dir); |
|
||||||
|
|
||||||
virtual void WindowActivate(bool active); |
|
||||||
}; |
|
||||||
|
|
||||||
#endif // plUpdatableClient_h_inc
|
|
Loading…
Reference in new issue