1
0
mirror of https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git synced 2025-07-18 11:19:10 +00:00

Initial Commit of CyanWorlds.com Engine Open Source Client/Plugin

This commit is contained in:
jwplatt
2011-03-12 12:34:52 -05:00
commit b970ae4bad
3976 changed files with 1301355 additions and 0 deletions

View File

@ -0,0 +1,393 @@
/*==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/>.
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==*/
//
// 3DSMax HeadSpin exporter
//
#include "HeadSpin.h"
#include "SimpleExport.h"
#include "notify.h"
#include "plExportErrorMsg.h"
#include "plExportLogErrorMsg.h"
#include "../MaxConvert/UserPropMgr.h"
#include "hsExceptionStack.h"
#include "../MaxConvert/hsConverterUtils.h"
#include "../MaxConvert/plBitmapCreator.h"
#include "../pfPython/plPythonFileMod.h"
#include "../MaxMain/plPluginResManager.h"
#include "../plResMgr/plRegistryHelpers.h"
#include "../plResMgr/plRegistryNode.h"
#include "hsStream.h"
#include "../MaxConvert/plConvert.h"
#include "../MaxConvert/hsMaterialConverter.h"
#include "../plPhysX/plSimulationMgr.h"
#include "../plSDL/plSDL.h"
#include "../MaxMain/plMaxCFGFile.h"
// For texture export/cleanup
#include "../MaxMain/plTextureExportLog.h"
#include "../pnKeyedObject/plKey.h"
#include "../pnKeyedObject/plUoid.h"
#include "../plGImage/plCubicEnvironmap.h"
#include "../plGImage/plDynamicTextMap.h"
#include "../plGImage/plMipmap.h"
#include "../plScene/plSceneNode.h"
#include "plExportDlg.h"
#include "../plStatusLog/plStatusLog.h"
#include "../plFile/plFileUtils.h"
#include "../plAvatar/plAvatarMgr.h"
extern UserPropMgr gUserPropMgr;
#ifdef HS_DEBUGGING
#define HS_NO_TRY
#endif
//
// .MSH export module functions follow:
//
HSExport2::HSExport2()
{
}
HSExport2::~HSExport2()
{
}
int HSExport2::ExtCount()
{
return 2;
}
//
// Extensions supported for import/export modules
//
const TCHAR *HSExport2::Ext(int n)
{
static char str[64];
switch(n)
{
case 0:
return "";
case 1:
return "prd";
}
return _T("");
}
//
// Long ASCII description (i.e. "Targa 2.0 Image File")
//
const TCHAR *HSExport2::LongDesc()
{
return "Plasma 2.0";
}
//
// Short ASCII description (i.e. "Targa")
//
const TCHAR *HSExport2::ShortDesc()
{
#ifdef HS_DEBUGGING
return "Plasma 2.0 Debug";
#else
return "Plasma 2.0";
#endif
}
//
// ASCII Author name
//
const TCHAR *HSExport2::AuthorName()
{
return "Billy Bob";
}
//
// ASCII Copyright message
//
const TCHAR *HSExport2::CopyrightMessage()
{
return "Copyright 1997 HeadSpin Technology Inc.";
}
//
// Other message #1
//
const TCHAR *HSExport2::OtherMessage1()
{
return _T("");
}
//
// Other message #2
//
const TCHAR *HSExport2::OtherMessage2()
{
return _T("");
}
//
// Version number * 100 (i.e. v3.01 = 301)
//
unsigned int HSExport2::Version()
{
return 100;
}
//
// Optional
//
void HSExport2::ShowAbout(HWND hWnd)
{
}
void IGetPath(const char* name, char* path)
{
int i;
// find the last backslash in the full path
for ( i=strlen(name)-1; i>=0 ; i-- )
{
if ( name[i] == '\\' )
break;
}
if ( i >= 0 && i < 256) // if either we couldn't the backslash or the path was too big
{
strncpy(path,name,i+1);
path[i+1] = '\0'; //null terminate string (cause strncpy might not)
}
else
path[0] = '\0'; // otherwise just make it a null string
}
// Another little helper class to help write out a list of textures to a log file
class plTextureLoggerCBack : public plRegistryKeyIterator
{
protected:
plTextureExportLog* fTELog;
public:
plTextureLoggerCBack(plTextureExportLog* teLog) { fTELog = teLog; }
virtual hsBool EatKey(const plKey& key)
{
plBitmap* bmap = plBitmap::ConvertNoRef(key->ObjectIsLoaded());
if (bmap != nil)
fTELog->AddTexture(bmap);
return true; // Always continue
}
};
// Yet another key iterator, this one to call OptimizeDrawables() on each sceneNode
class plOptimizeIterator : public plRegistryKeyIterator
{
public:
virtual hsBool EatKey(const plKey& key)
{
if (key->GetUoid().GetClassType() == plSceneNode::Index())
{
plSceneNode* sn = plSceneNode::ConvertNoRef(key->ObjectIsLoaded());
if (sn != nil)
sn->OptimizeDrawables();
}
return true; // Always continue
}
};
//
//
//
int HSExport2::DoExport(const TCHAR *name,ExpInterface *ei,Interface *gi, BOOL suppressPrompts, DWORD options)
{
BOOL backupEnabled = gi->AutoBackupEnabled();
gi->EnableAutoBackup(FALSE);
BOOL bmmSilentMode = TheManager->SilentMode();
TheManager->SetSilentMode(TRUE);
bool mbSuppressPrompts = hsMessageBox_SuppressPrompts;
hsMessageBox_SuppressPrompts = (suppressPrompts)?true:false;
// Disable save so we don't crash in export or
// otherwise screw database.
SimpleExportExitCallback exitCB;
gi->RegisterExitMAXCallback(&exitCB);
gUserPropMgr.OpenQuickTable();
hsConverterUtils::Instance().CreateNodeSearchCache();
BroadcastNotification(NOTIFY_PRE_EXPORT);
// get just the path (not the file) of where we are going to export to
char out_path[256];
IGetPath(name, out_path);
// Apparently this was implied by the open dialog, but not if you call Max's ExportToFile() func
SetCurrentDirectory(out_path);
//
// Setup ErrorMsg
//
// Needs to be outside try/catch so it doesn't stack unwind...
plExportErrorMsg hituser_errorMessage; // This is the errorMessage that slaps user
TSTR filename = gi->GetCurFileName();
hsStrncpy(fName, filename, 128);
char *dot = strrchr(fName, '.');
if (dot)
*dot = 0;
char ErrorLogName[512];
sprintf(ErrorLogName, "%s%s.err", out_path, fName);
plExportLogErrorMsg logonly_errorMessage(ErrorLogName); // This errorMessage just writes it all to a file
// now decide which errorMessage object to use
plErrorMsg* errorMessage;
if (suppressPrompts)
errorMessage = &logonly_errorMessage;
else
errorMessage = &hituser_errorMessage;
// For export time stats
DWORD exportTime = timeGetTime();
_SYSTEMTIME tm;
GetSystemTime(&tm);
//
// Let's get cracking! Convert the scene...
//
plConvertSettings settings;
if (plExportDlg::Instance().IsExporting())
{
settings.fDoPreshade = plExportDlg::Instance().GetDoPreshade();
settings.fPhysicalsOnly = plExportDlg::Instance().GetPhysicalsOnly();
settings.fDoLightMap = plExportDlg::Instance().GetDoLightMap();
settings.fExportPage = plExportDlg::Instance().GetExportPage();
}
plConvert::Instance().Init(gi, errorMessage, &settings);
// We want to incorporate any SDL changes since the last export, so we DeInit()
// and re-initialize.
char buf[MAX_PATH];
strcpy(buf, plMaxConfig::GetClientPath());
strcat(buf, "sdl");
plSDLMgr::GetInstance()->SetSDLDir(buf);
plSDLMgr::GetInstance()->DeInit();
plSDLMgr::GetInstance()->Init();
// Add disk source for writing
char datPath[MAX_PATH];
strcpy(datPath, out_path);
plFileUtils::AddSlash(datPath);
strcat(datPath, "dat\\");
CreateDirectory(datPath, NULL);
plPluginResManager::ResMgr()->SetDataPath(datPath);
if (hsgResMgr::Reset())
{
plSimulationMgr::Init();
plAvatarMgr::GetInstance();
// Verify the pages here manually, since it's a separate step now
plPluginResManager::ResMgr()->VerifyPages();
plPythonFileMod::SetAtConvertTime();
// Convert!!!
hsBool convertOK = plConvert::Instance().Convert();
// Free the material cache. This will delete unused materials.
hsMaterialConverter::Instance().FreeMaterialCache(out_path);
if (convertOK)
{
// Optimize the drawables
plOptimizeIterator optIterator;
plPluginResManager::ResMgr()->IterateKeys( &optIterator );
// And save.
plPluginResManager::ResMgr()->WriteAllPages();
// Write out a texture log file
char textureLog[MAX_PATH];
sprintf(textureLog, "log\\exportedTextures_%s.log", fName);
plTextureExportLog textureExportLog( textureLog );
plTextureLoggerCBack loggerCallback( &textureExportLog );
plPluginResManager::ResMgr()->IterateKeys( &loggerCallback );
textureExportLog.Write();
// Moving this to the end of writing the files out. Yes, this means that any unused mipmaps still get
// written to disk, including ones loaded on preload, but it's the only way to get shared texture pages
// to work without loading in the entire age worth of reffing objects. - 5.30.2002 mcn
plBitmapCreator::Instance().DeInit();
}
// Have the resMgr clean up after export. This includes paging out any converted pages
plPluginResManager::ResMgr()->EndExport();
plSimulationMgr::Shutdown();
plAvatarMgr::ShutDown();
// Reset the resmgr so we free all the memory it allocated
hsgResMgr::Reset();
}
//----------------------------------------------
// Write a log entry to the Db file name for now
//----------------------------------------------
hsUNIXStream dbLog;
dbLog.Open(name,"at");
char str[256];
exportTime = (timeGetTime() - exportTime) / 1000;
sprintf(str,"Export from Max File \"%s\" on %02d/%02d/%4d took %d:%02d\n",filename,tm.wMonth,tm.wDay,tm.wYear, exportTime/60, exportTime%60);
dbLog.WriteString(str);
dbLog.Close();
// Allow plugins to clean up after export
BroadcastNotification(NOTIFY_POST_EXPORT);
hsConverterUtils::Instance().DestroyNodeSearchCache();
gUserPropMgr.CloseQuickTable();
gi->UnRegisterExitMAXCallback(&exitCB);
hsMessageBox_SuppressPrompts = mbSuppressPrompts;
TheManager->SetSilentMode(bmmSilentMode);
gi->EnableAutoBackup(backupEnabled);
MessageBeep(MB_ICONASTERISK);
return 1;
}

View File

@ -0,0 +1,108 @@
/*==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/>.
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 __SIMPLEEXPORT_H
#define __SIMPLEEXPORT_H
#include "hsWindows.h"
#include "../MaxMain/resource.h"
#include "Max.h"
#include "HeadSpin.h"
//
// Inlines
//
extern HINSTANCE hInstance;
extern TCHAR *GetString(int id);
////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
//
// Header file for headSpin 3dsMax exporter
//
class HSExport2 : public SceneExport
{
public:
HSExport2();
~HSExport2();
int ExtCount(); // Number of extensions supported
const TCHAR * Ext(int n); // Extension #n (i.e. "HS")
const TCHAR * LongDesc(); // Long ASCII description (i.e. "Autodesk 3D Studio File")
const TCHAR * ShortDesc(); // Short ASCII description (i.e. "3D Studio")
const TCHAR * AuthorName(); // ASCII Author name
const TCHAR * CopyrightMessage(); // ASCII Copyright message
const TCHAR * OtherMessage1(); // Other message #1
const TCHAR * OtherMessage2(); // Other message #2
unsigned int Version(); // Version number * 100 (i.e. v3.01 = 301)
void ShowAbout(HWND hWnd); // Show DLL's "About..." box
virtual int DoExport(const TCHAR *name,ExpInterface *ei,Interface *i, BOOL suppressPrompts=FALSE, DWORD options=0);
const char* GetName() { return fName; }
private:
static hsBool IProgressCallback(hsScalar percent);
static DWORD WINAPI IProgressDummyFunc(LPVOID arg);
char fName[128];
};
//------------------------------------------------------
class HSClassDesc2 : public ClassDesc
{
public:
int IsPublic() { return 1; }
void * Create(BOOL loading = FALSE) { return TRACKED_NEW HSExport2; }
const TCHAR * ClassName() { return "Plasma 2.0 Scene Exporter"; }
SClass_ID SuperClassID() { return SCENE_EXPORT_CLASS_ID; }
#ifdef HS_DEBUGGING
Class_ID ClassID() { return Class_ID(0x547962c7, 0x520a702d); }
#else
Class_ID ClassID() { return Class_ID(0x717f791f, 0x79412447); }
#endif
const TCHAR* Category() { return "Plasma Export..."; }
};
class SimpleExportExitCallback : public ExitMAXCallback
{
public:
BOOL Exit(HWND hWnd) { return false; }
};
//
// Externs
//
extern int controlsInit;
extern HSClassDesc2 HSDesc;
//
// Defines
//
#define no_RAM() Alert(IDS_TH_OUTOFMEMORY)
#endif // __SIMPLEEXPORT_H

View File

@ -0,0 +1,209 @@
/*==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/>.
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 "plErrorMsg.h"
#include "hsTypes.h"
#include "hsExceptions.h"
#include "hsUtils.h"
#include "plErrorMsg.h"
static plErrorMsg nullMsg;
//////////////////////////////////////////////////////////////////////////////////////////////////
// Useful null object, to assign when I don't want to worry about checking for nil everywhere...
//////////////////////////////////////////////////////////////////////////////////////////////////
plErrorMsg *plErrorMsg::GetNull()
{
return &nullMsg;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
// Non-destructive error handling
//////////////////////////////////////////////////////////////////////////////////////////////////
plErrorMsg::plErrorMsg(const char* label, const char* msg)
{
Set(label, msg);
}
plErrorMsg::plErrorMsg(hsBool bogus)
{
Set(bogus);
}
plErrorMsg::plErrorMsg(hsBool bogus, const char* label, const char* msg)
{
Set(bogus, label, msg);
}
plErrorMsg::plErrorMsg(hsBool bogus, const char* label, const char* format, const char* str)
{
Set(bogus, label, format, str);
}
plErrorMsg::plErrorMsg(hsBool bogus, const char* label, const char* format, const char* str1, const char* str2)
{
Set(bogus, label, format, str1, str2);
}
plErrorMsg::plErrorMsg(hsBool bogus, const char* label, const char* format, int n)
{
Set(bogus, label, format, n);
}
plErrorMsg::plErrorMsg(hsBool bogus, const char* label, const char* format, int n, int m)
{
Set(bogus, label, format, n, m);
}
plErrorMsg::plErrorMsg(hsBool bogus, const char* label, const char* format, float f)
{
Set(bogus, label, format, f);
}
plErrorMsg &plErrorMsg::Set(const char* label, const char* msg)
{
fBogus = true;
if( label )
hsStrncpy(fLabel, label, 256);
else
*fLabel = 0;
if( msg )
{
hsAssert(strlen(msg) < PL_ERR_MSG_MAX_MSG, "Too long of an error message for plErrorMsg.");
hsStrncpy(fMsg, msg, PL_ERR_MSG_MAX_MSG);
}
else
*fMsg = 0;
hsThrow( *this );
return *this;
}
plErrorMsg &plErrorMsg::Set(hsBool bogus)
{
fBogus = bogus;
fLabel[0] = 0;
fMsg[0] = 0;
return *this;
}
plErrorMsg &plErrorMsg::Set(hsBool bogus, const char* label, const char* msg)
{
if( fBogus = bogus )
{
if( label )
hsStrncpy(fLabel, label, 256);
else
*fLabel = 0;
if( msg )
{
hsAssert(strlen(msg) < PL_ERR_MSG_MAX_MSG, "Too long of an error message for plErrorMsg.");
hsStrncpy(fMsg, msg, PL_ERR_MSG_MAX_MSG);
}
else
*fMsg = 0;
}
return *this;
}
plErrorMsg &plErrorMsg::Set(hsBool bogus, const char* label, const char* format, const char* str)
{
if( fBogus = bogus )
{
if( label )
hsStrncpy(fLabel, label, 256);
else
*fLabel = 0;
int length = sprintf(fMsg, format, str);
hsAssert(length < PL_ERR_MSG_MAX_MSG, "Too long of an error message for plErrorMsg.");
}
return *this;
}
plErrorMsg &plErrorMsg::Set(hsBool bogus, const char* label, const char* format, const char* str1, const char* str2)
{
if( fBogus = bogus )
{
if( label )
hsStrncpy(fLabel, label, 256);
else
*fLabel = 0;
int length = sprintf(fMsg, format, str1, str2);
hsAssert(length < PL_ERR_MSG_MAX_MSG, "Too long of an error message for plErrorMsg.");
}
return *this;
}
plErrorMsg &plErrorMsg::Set(hsBool bogus, const char* label, const char* format, int n)
{
if( fBogus = bogus )
{
if( label )
hsStrncpy(fLabel, label, 256);
else
*fLabel = 0;
int length = sprintf(fMsg, format, n);
hsAssert(length < PL_ERR_MSG_MAX_MSG, "Too long of an error message for plErrorMsg.");
}
return *this;
}
plErrorMsg &plErrorMsg::Set(hsBool bogus, const char* label, const char* format, int n, int m)
{
if( fBogus = bogus )
{
if( label )
hsStrncpy(fLabel, label, 256);
else
*fLabel = 0;
int length = sprintf(fMsg, format, n, m);
hsAssert(length < PL_ERR_MSG_MAX_MSG, "Too long of an error message for plErrorMsg.");
}
return *this;
}
plErrorMsg &plErrorMsg::Set(hsBool bogus, const char* label, const char* format, float f)
{
if( fBogus = bogus )
{
if( label )
hsStrncpy(fLabel, label, 256);
else
*fLabel = 0;
int length = sprintf(fMsg, format, f);
hsAssert(length < PL_ERR_MSG_MAX_MSG, "Too long of an error message for plErrorMsg.");
}
return *this;
}

View File

@ -0,0 +1,97 @@
/*==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/>.
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 __plErrorMsg_h
#define __plErrorMsg_h
#include "hsTypes.h"
#define PL_ERR_MSG_MAX_MSG 2048
class plErrorMsg
{
public:
static plErrorMsg *GetNull();
plErrorMsg(const char* label, const char* msg);
plErrorMsg(hsBool bogus = false);
plErrorMsg(hsBool bogus, const char* label, const char* msg);
plErrorMsg(hsBool bogus, const char* label, const char* format, const char* str);
plErrorMsg(hsBool bogus, const char* label, const char* format, const char* str1, const char* str2);
plErrorMsg(hsBool bogus, const char* label, const char* format, int n);
plErrorMsg(hsBool bogus, const char* label, const char* format, int n, int m);
plErrorMsg(hsBool bogus, const char* label, const char* format, float f);
virtual ~plErrorMsg() { }
plErrorMsg &Set(const char* label, const char* msg);
plErrorMsg &Set(hsBool bogus = false);
plErrorMsg &Set(hsBool bogus, const char* label, const char* msg);
plErrorMsg &Set(hsBool bogus, const char* label, const char* format, const char* str);
plErrorMsg &Set(hsBool bogus, const char* label, const char* format, const char* str1, const char* str2);
plErrorMsg &Set(hsBool bogus, const char* label, const char* format, int n);
plErrorMsg &Set(hsBool bogus, const char* label, const char* format, int n, int m);
plErrorMsg &Set(hsBool bogus, const char* label, const char* format, float f);
hsBool IsBogus() { return GetBogus(); }
// Ask - If condition is true and user says yes to displayed query, return true, else false
virtual hsBool Ask() { return false; }
// CheckAndAsk - If condition is true and user says YES, throw self. Only asks if condition is true.
// Returns true if condition is true but user says no, else false.
virtual hsBool CheckAndAsk() { return false; }
// CheckAskOrCancel - If condition is true ( if YES, throw, else if NO return 0, else (CANCEL) return 1
virtual hsBool CheckAskOrCancel() { return false; }
// Show - If condition is true, displays message, returns true
virtual hsBool Show() { return false; }
// CheckAndShow - If condition is true, shows message box then throws self, else return false
virtual hsBool CheckAndShow() { return false; }
// Check - If condition was true, throws self, else return false
virtual hsBool Check() { return false; }
// Quit - If condition, quietly just throw with no message
virtual void Quit() { }
protected:
void SetBogus(hsBool b) { fBogus = b; }
hsBool GetBogus() { return fBogus; }
char *GetLabel() { if (!fBogus) *fLabel = 0; return fLabel; }
char *GetMsg() { if (!fBogus) *fMsg = 0; return fMsg; }
private:
hsBool fBogus;
char fLabel[256];
char fMsg[PL_ERR_MSG_MAX_MSG];
private:
// No assignment operator
plErrorMsg &operator=(const plErrorMsg &msg);
};
#endif

View File

@ -0,0 +1,518 @@
/*==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/>.
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 "hsTypes.h"
#include "plExportDlg.h"
#include "../MaxMain/resource.h"
#include "max.h"
#include "../MaxMain/plMaxCFGFile.h"
#include <vector>
#include <string>
using std::vector;
using std::string;
extern HINSTANCE hInstance;
class plExportDlgImp : public plExportDlg
{
protected:
HWND fDlg; // Handle to the setup dialog
bool fPreshade;
bool fPhysicalsOnly;
bool fLightMap;
char fExportPage[256];
char fExportSourceDir[MAX_PATH];
bool fExporting;
bool fAutoExporting;
bool fExportFile;
int fXPos, fYPos;
DWORD fLastExportTime;
static BOOL CALLBACK ForwardDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
BOOL DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
void IDestroy();
void IExportCurrentFile(const char* exportPath);
void IDoExport();
void IInitDlg(HWND hDlg);
void IGetRadio(HWND hDlg);
public:
plExportDlgImp();
~plExportDlgImp();
virtual void Show();
virtual bool IsExporting() { return fExporting; }
virtual bool IsAutoExporting() { return fAutoExporting; }
virtual bool GetDoPreshade() { return fPreshade; }
virtual bool GetPhysicalsOnly() { return fPhysicalsOnly; }
virtual bool GetDoLightMap() { return fLightMap; }
virtual const char* GetExportPage();
virtual void StartAutoExport();
};
plExportDlgImp::plExportDlgImp() : fDlg(NULL), fPreshade(true), fPhysicalsOnly(false), fLightMap(true), fLastExportTime(0), fExporting(false), fAutoExporting(false)
{
const char* path = plMaxConfig::GetPluginIni();
fXPos = GetPrivateProfileInt("Export", "X", 0, path);
fYPos = GetPrivateProfileInt("Export", "Y", 30, path);
GetPrivateProfileString("Export", "Dir", "", fExportSourceDir, sizeof(fExportSourceDir), path);
memset(fExportPage, 0, sizeof(fExportPage));
}
BOOL WritePrivateProfileInt(LPCSTR lpAppName, LPCSTR lpKeyName, int val, LPCSTR lpFileName)
{
char buf[30];
itoa(val, buf, 10);
return WritePrivateProfileString(lpAppName, lpKeyName, buf, lpFileName);
}
plExportDlgImp::~plExportDlgImp()
{
const char* path = plMaxConfig::GetPluginIni();
WritePrivateProfileInt("Export", "X", fXPos, path);
WritePrivateProfileInt("Export", "Y", fYPos, path);
WritePrivateProfileString("Export", "Dir", fExportSourceDir, path);
}
plExportDlg& plExportDlg::Instance()
{
static plExportDlgImp theInstance;
return theInstance;
}
BOOL plExportDlgImp::ForwardDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
return ((plExportDlgImp&)Instance()).DlgProc(hDlg, msg, wParam, lParam);
}
const char* plExportDlgImp::GetExportPage()
{
if (fExportPage[0] == '\0')
return nil;
else
return fExportPage;
}
#include "../MaxComponent/plComponentBase.h"
#include "../MaxComponent/plMiscComponents.h"
#include "../MaxMain/plMaxNode.h"
#include "hsStlSortUtils.h"
#include <set>
typedef std::set<plComponentBase*> CompSet;
static void GetPagesRecur(plMaxNode* node, CompSet& comps)
{
if (!node)
return;
plComponentBase* comp = node->ConvertToComponent();
if (comp && (comp->ClassID() == ROOM_CID || comp->ClassID() == PAGEINFO_CID))
{
comps.insert(comp);
}
for (int i = 0; i < node->NumberOfChildren(); i++)
GetPagesRecur((plMaxNode*)node->GetChildNode(i), comps);
}
static const char* kAllPages = "(All Pages)";
void plExportDlgImp::IGetRadio(HWND hDlg)
{
fExportFile = (IsDlgButtonChecked(hDlg, IDC_RADIO_FILE) == BST_CHECKED);
EnableWindow(GetDlgItem(hDlg, IDC_PAGE_COMBO), fExportFile);
// EnableWindow(GetDlgItem(hDlg, IDC_EXPORT_PATH), !fExportFile);
EnableWindow(GetDlgItem(hDlg, IDC_BROWSE_EXPORT), !fExportFile);
}
void plExportDlgImp::IInitDlg(HWND hDlg)
{
// Set the client path
const char* path = plMaxConfig::GetClientPath(false, true);
SetDlgItemText(hDlg, IDC_CLIENT_PATH, path);
// Set the preshade button
CheckDlgButton(hDlg, IDC_PRESHADE_CHECK, fPreshade ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hDlg, IDC_PHYSICAL_CHECK, fPhysicalsOnly ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hDlg, IDC_LIGHTMAP_CHECK, fLightMap ? BST_CHECKED : BST_UNCHECKED);
char buf[256];
sprintf(buf, "Last export took %d:%02d", fLastExportTime/60, fLastExportTime%60);
SetDlgItemText(hDlg, IDC_LAST_EXPORT, buf);
SetWindowPos(hDlg, NULL, fXPos, fYPos, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
//
// Get the names of all the pages in this scene and put them in the combo
//
HWND hPages = GetDlgItem(hDlg, IDC_PAGE_COMBO);
ComboBox_AddString(hPages, kAllPages);
bool foundPage = false;
CompSet comps;
GetPagesRecur((plMaxNode*)GetCOREInterface()->GetRootNode(), comps);
for (CompSet::iterator it = comps.begin(); it != comps.end(); it++)
{
const char* page = LocCompGetPage(*it);
if (page)
{
int idx = ComboBox_AddString(hPages, page);
if (!strcmp(page, fExportPage))
{
foundPage = true;
ComboBox_SetCurSel(hPages, idx);
}
}
}
if (!foundPage)
{
fExportPage[0] = '\0';
ComboBox_SetCurSel(hPages, 0);
}
CheckRadioButton(hDlg, IDC_RADIO_FILE, IDC_RADIO_DIR, IDC_RADIO_FILE);
IGetRadio(hDlg);
SetDlgItemText(hDlg, IDC_EXPORT_PATH, fExportSourceDir);
}
#include "../plFile/plBrowseFolder.h"
BOOL plExportDlgImp::DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_INITDIALOG:
IInitDlg(hDlg);
return TRUE;
case WM_COMMAND:
{
int cmd = HIWORD(wParam);
int resID = LOWORD(wParam);
if (cmd == BN_CLICKED)
{
if (resID == IDCANCEL)
{
IDestroy();
return TRUE;
}
else if (resID == IDC_EXPORT)
{
IDoExport();
return TRUE;
}
else if (resID == IDC_PRESHADE_CHECK)
{
fPreshade = (IsDlgButtonChecked(hDlg, IDC_PRESHADE_CHECK) == BST_CHECKED);
return TRUE;
}
else if (resID == IDC_PHYSICAL_CHECK)
{
fPhysicalsOnly = (IsDlgButtonChecked(hDlg, IDC_PHYSICAL_CHECK) == BST_CHECKED);
return TRUE;
}
else if (resID == IDC_LIGHTMAP_CHECK)
{
fLightMap = (IsDlgButtonChecked(hDlg, IDC_LIGHTMAP_CHECK) == BST_CHECKED);
return TRUE;
}
else if (resID == IDC_DIR)
{
// Get a new client path
const char* path = plMaxConfig::GetClientPath(true);
if (path)
SetDlgItemText(hDlg, IDC_CLIENT_PATH, path);
return TRUE;
}
else if (resID == IDC_RADIO_FILE || resID == IDC_RADIO_DIR)
{
IGetRadio(hDlg);
return TRUE;
}
else if (resID == IDC_BROWSE_EXPORT)
{
plBrowseFolder::GetFolder(fExportSourceDir,
fExportSourceDir,
"Choose the source directory",
hDlg);
SetDlgItemText(hDlg, IDC_EXPORT_PATH, fExportSourceDir);
return TRUE;
}
}
else if (cmd == CBN_SELCHANGE && resID == IDC_PAGE_COMBO)
{
int sel = ComboBox_GetCurSel((HWND)lParam);
// If the user selected a page, save it
if (sel != 0 && sel != CB_ERR)
ComboBox_GetText((HWND)lParam, fExportPage, sizeof(fExportPage));
// Else, clear it (export all pages)
else
fExportPage[0] = '\0';
return TRUE;
}
}
break;
}
return FALSE;
}
void plExportDlgImp::IExportCurrentFile(const char* exportPath)
{
// Delete the old prd so we don't get the stupid overwrite warning
DeleteFile(exportPath);
GetCOREInterface()->ExportToFile(exportPath);
}
#include "../plFile/hsFiles.h"
void plExportDlgImp::IDoExport()
{
fExporting = true;
// Hide the window, since we don't get control back until the export is done
ShowWindow(fDlg, SW_HIDE);
// Do the export
char exportPath[MAX_PATH];
GetDlgItemText(fDlg, IDC_CLIENT_PATH, exportPath, sizeof(exportPath));
strcat(exportPath, "Export.prd");
// For export time stats
DWORD exportTime = timeGetTime();
if (fExportFile)
IExportCurrentFile(exportPath);
else
{
hsFolderIterator sourceDir(fExportSourceDir);
while (sourceDir.NextFileSuffix(".max"))
{
char exportFile[MAX_PATH];
sourceDir.GetPathAndName(exportFile);
if (GetCOREInterface()->LoadFromFile(exportFile))
IExportCurrentFile(exportPath);
}
}
fLastExportTime = (timeGetTime() - exportTime) / 1000;
IDestroy();
fExporting = false;
}
void plExportDlgImp::IDestroy()
{
if (fDlg)
{
// Save the window pos
RECT rect;
GetWindowRect(fDlg, &rect);
fXPos = rect.left;
fYPos = rect.top;
DestroyWindow(fDlg);
fDlg = NULL;
}
}
void plExportDlgImp::Show()
{
if (!fDlg)
fDlg = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_EXPORT), GetCOREInterface()->GetMAXHWnd(), ForwardDlgProc);
}
static bool IsExcluded(const char* fileName, vector<string>& excludeFiles)
{
for (int i = 0; i < excludeFiles.size(); i++)
{
if (!strcmp(fileName, excludeFiles[i].c_str()))
return true;
}
return false;
}
static bool AutoExportDir(const char* inputDir, const char* outputDir, const char* groupFiles, vector<string>& excludeFiles)
{
bool exportedFile = false;
char outputFileName[MAX_PATH];
sprintf(outputFileName, "%s\\Export.prd", outputDir);
char outputLog[MAX_PATH];
sprintf(outputLog, "%s\\AutoExport.log", outputDir);
char doneDir[MAX_PATH];
sprintf(doneDir, "%s\\Done\\", inputDir);
CreateDirectory(doneDir, NULL);
// Don't give missing bitmap warnings
TheManager->SetSilentMode(TRUE);
hsFolderIterator sourceDir(inputDir);
while (sourceDir.NextFileSuffix(".max"))
{
char exportFile[MAX_PATH];
sourceDir.GetPathAndName(exportFile);
if (IsExcluded(sourceDir.GetFileName(), excludeFiles))
continue;
// If we're doing grouped files, and this isn't one, keep looking
if (groupFiles && strncmp(sourceDir.GetFileName(), groupFiles, strlen(groupFiles)) != 0)
continue;
hsUNIXStream log;
if (log.Open(outputLog, "ab"))
{
log.WriteFmt("%s\r\n", sourceDir.GetFileName());
log.Close();
}
if (GetCOREInterface()->LoadFromFile(exportFile))
{
sprintf(doneDir, "%s\\Done\\%s", inputDir, sourceDir.GetFileName());
MoveFileEx(exportFile, doneDir, MOVEFILE_REPLACE_EXISTING);
GetCOREInterface()->ExportToFile(outputFileName, TRUE);
exportedFile = true;
// If we're not doing grouped files, this is it, we exported our one file
if (!groupFiles)
break;
}
}
return exportedFile;
}
// I'm sure there's a better way to do this but I can't find it in the docs
static void ShutdownMax()
{
// If we're auto-exporting, write out a file to let the build scripts know
// we're done writing to disk, and if we don't exit soon we probably crashed
if (plExportDlg::Instance().IsAutoExporting())
{
hsUNIXStream s;
s.Open("log\\AutoExportDone.txt", "wb");
s.Close();
}
GetCOREInterface()->FlushUndoBuffer();
SetSaveRequiredFlag(FALSE);
PostMessage(GetCOREInterface()->GetMAXHWnd(), WM_CLOSE, 0, 0);
}
static void GetStringSection(const char* configFile, const char* keyName, vector<string>& strings)
{
char source[256];
GetPrivateProfileString("Settings", keyName, "", source, sizeof(source), configFile);
char* seps = ",";
char* token = strtok(source, seps);
while (token != NULL)
{
strings.push_back(token);
token = strtok(NULL, seps);
}
}
void plExportDlgImp::StartAutoExport()
{
char configFile[MAX_PATH];
strcpy(configFile, GetCOREInterface()->GetDir(APP_PLUGCFG_DIR));
strcat(configFile, "\\AutoExport.ini");
char inputDir[MAX_PATH];
GetPrivateProfileString("Settings", "MaxInputDir", "", inputDir, sizeof(inputDir), configFile);
char outputDir[MAX_PATH];
GetPrivateProfileString("Settings", "MaxOutputDir", "", outputDir, sizeof(outputDir), configFile);
if (inputDir[0] == '\0' || outputDir == '\0')
return;
fAutoExporting = true;
// If we're doing an autoexport, suppress prompts now
hsMessageBox_SuppressPrompts = true;
// Files to ignore
vector<string> excludeFiles;
GetStringSection(configFile, "ExcludeFiles", excludeFiles);
//
// Get the file substrings to export in one session
//
vector<string> groupedFiles;
GetStringSection(configFile, "GroupedFiles", groupedFiles);
for (int i = 0; i < groupedFiles.size(); i++)
{
if (AutoExportDir(inputDir, outputDir, groupedFiles[i].c_str(), excludeFiles))
{
ShutdownMax();
fAutoExporting = false;
return;
}
}
if (AutoExportDir(inputDir, outputDir, NULL, excludeFiles))
{
ShutdownMax();
fAutoExporting = false;
return;
}
DeleteFile(configFile);
fAutoExporting = false;
ShutdownMax();
}

View File

@ -0,0 +1,49 @@
/*==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/>.
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 plExportDlg_h_inc
#define plExportDlg_h_inc
class plExportDlg
{
public:
static plExportDlg& Instance();
virtual void Show()=0;
// Returns true if the export dialog is doing the export
virtual bool IsExporting()=0;
// Returns true if an autoexport is running (GetValidateUVs is valid)
virtual bool IsAutoExporting()=0;
virtual bool GetDoLightMap()=0;
virtual bool GetDoPreshade()=0;
virtual bool GetPhysicalsOnly()=0;
virtual const char* GetExportPage()=0;
virtual void StartAutoExport()=0;
};
#endif // plExportDlg_h_inc

View File

@ -0,0 +1,126 @@
/*==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/>.
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 "hsWindows.h"
#include "hsTypes.h"
#include "plExportErrorMsg.h"
#include "hsExceptions.h"
#include "hsUtils.h"
hsBool plExportErrorMsg::Show()
{
// If bogus, and we have something to show, show it
if( GetBogus() && (GetMsg()[0] != 0 || GetLabel()[0] != 0))
{
hsMessageBox(GetMsg(), GetLabel(), hsMessageBoxNormal/*|hsMessageBoxIconError*/);
}
return GetBogus();
}
hsBool plExportErrorMsg::Ask()
{
if( GetBogus() )
{
return IDYES == hsMessageBox(GetMsg(), GetLabel(), hsMessageBoxYesNo/*|hsMessageBoxIconExclamation*/);
}
return false;
}
hsBool plExportErrorMsg::CheckAndAsk()
{
if( GetBogus() )
{
strncat(GetMsg(), " - File corruption possible - ABORT?", 255);
if( Ask() )
{
sprintf(GetMsg(), "!Abort at user response to error!");
Check();
}
}
return GetBogus();
}
hsBool plExportErrorMsg::CheckAskOrCancel()
{
if( GetBogus() )
{
strncat(GetMsg(), " - ABORT? (Cancel to mute warnings)", 255);
int ret = hsMessageBox(GetMsg(), GetLabel(), hsMessageBoxYesNoCancel/*|hsMessageBoxIconExclamation*/);
if( IDYES == ret )
{
sprintf(GetMsg(), "!Abort at user response to error!");
Check();
}
else if( IDCANCEL == ret )
return 1;
}
return false;
}
hsBool plExportErrorMsg::CheckAndShow()
{
if ( GetBogus() )
{
Show();
Check();
}
return GetBogus();
}
hsBool plExportErrorMsg::Check()
{
if( GetBogus() )
{
strncat(GetMsg(), " !Output File Corrupt!", 255);
IDebugThrow();
}
return false;
}
void plExportErrorMsg::Quit()
{
if( GetBogus() )
{
SetBogus(false);
hsThrow( *this );
}
}
void plExportErrorMsg::IDebugThrow()
{
try {
#if HS_BUILD_FOR_WIN32
DebugBreak();
#endif // HS_BUILD_FOR_WIN32
}
catch(...)
{
hsThrow( *this );
}
}

View File

@ -0,0 +1,133 @@
/*==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/>.
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 plExportErrorMsg_inc
#define plExportErrorMsg_inc
#include <string.h>
#include "plErrorMsg.h"
#if !HS_BUILD_FOR_WIN32
#define PL_NULL_ERRMSG
#endif !HS_BUILD_FOR_WIN32
#ifndef PL_NULL_ERRMSG
class plExportErrorMsg : public plErrorMsg {
public:
plExportErrorMsg(const char* label, const char* msg) : plErrorMsg(label, msg) { }
plExportErrorMsg(hsBool bogus = false) : plErrorMsg(bogus) { }
plExportErrorMsg(hsBool bogus, const char* label, const char* msg)
: plErrorMsg(bogus, label, msg) { }
plExportErrorMsg(hsBool bogus, const char* label, const char* format, const char* str)
: plErrorMsg(bogus, label, format, str) { }
plExportErrorMsg(hsBool bogus, const char* label, const char* format, const char* str1, const char* str2)
: plErrorMsg(bogus, label, format, str1, str2) { }
plExportErrorMsg(hsBool bogus, const char* label, const char* format, int n)
: plErrorMsg(bogus, label, format, n) { }
plExportErrorMsg(hsBool bogus, const char* label, const char* format, int n, int m)
: plErrorMsg(bogus, label, format, n, m) { }
plExportErrorMsg(hsBool bogus, const char* label, const char* format, float f)
: plErrorMsg(bogus, label, format, f) { }
virtual hsBool Ask(); // if b is true and user says yes to displayed query, return true, else false
virtual hsBool CheckAndAsk(); // if b is true and user says YES, throw self. only asks if b is true. returns true if b is true but user says no, else false
virtual hsBool CheckAskOrCancel(); // if b is true ( if YES, throw, else if NO return 0, else (CANCEL) return 1
virtual hsBool Show(); // if b is true, displays message, returns true
virtual hsBool Check(); // if b was true, throws self, else return false
virtual hsBool CheckAndShow(); // if b was true, shows message box then throws self, else return false
virtual void Quit(); // if b, quietly just throw with no message
private:
void IDebugThrow();
};
#else // PL_NULL_ERRMSG
class plExportErrorMsg : public plErrorMsg {
public:
plExportErrorMsg(const char* label, const char* msg) : plErrorMsg() { }
plExportErrorMsg(hsBool bogus = false) : plErrorMsg() { }
plExportErrorMsg(hsBool bogus, const char* label, const char* msg)
: plErrorMsg() { }
plExportErrorMsg(hsBool bogus, const char* label, const char* format, const char* str)
: plErrorMsg() { }
plExportErrorMsg(hsBool bogus, const char* label, const char* format, const char* str1, const char* str2)
: plErrorMsg() { }
plExportErrorMsg(hsBool bogus, const char* label, const char* format, int n)
: plErrorMsg() { }
plExportErrorMsg(hsBool bogus, const char* label, const char* format, int n, int m)
: plErrorMsg() { }
plExportErrorMsg(hsBool bogus, const char* label, const char* format, float f)
: plErrorMsg() { }
};
#endif // PL_NULL_ERRMSG
// Compile out error messages labeled debug
// #define PL_ERR_CHECK_DEGUG_ONLY
#if defined(NDEBUG) && defined(PL_ERR_CHECK_DEGUG_ONLY)
class plExportErrorDbg : public plExportErrorMsg {
public:
plExportErrorDbg(const char* label, const char* msg) : plExportErrorMsg() { }
plExportErrorDbg(hsBool bogus = false) : plExportErrorMsg() { }
plExportErrorDbg(hsBool bogus, const char* label, const char* msg) : plExportErrorMsg() { }
plExportErrorDbg(hsBool bogus, const char* label, const char* format, const char* str) : plExportErrorMsg() { }
plExportErrorDbg(hsBool bogus, const char* label, const char* format, const char* str1, const char* str2) : plExportErrorMsg() { }
plExportErrorDbg(hsBool bogus, const char* label, const char* format, int n) : plExportErrorMsg() { }
plExportErrorDbg(hsBool bogus, const char* label, const char* format, int n, int m) : plExportErrorMsg() { }
plExportErrorDbg(hsBool bogus, const char* label, const char* format, float f) : plExportErrorMsg() { }
hsBool Ask() { return false; }
hsBool CheckAndAsk() { return false; }
hsBool CheckAskOrCancel();
hsBool Show() { return false; }
hsBool Check() { return false; }
hsBool CheckAndShow() { return false; }
void Quit() { }
};
#else // keep them as exactly the same as errormessage
class plExportErrorDbg : public plExportErrorMsg {
public:
plExportErrorDbg(const char* label, const char* msg) : plExportErrorMsg(label, msg) { }
plExportErrorDbg(hsBool bogus = true) : plExportErrorMsg(bogus) { }
plExportErrorDbg(hsBool bogus, const char* label, const char* msg)
: plExportErrorMsg(bogus, label, msg) { }
plExportErrorDbg(hsBool bogus, const char* label, const char* format, const char* str)
: plExportErrorMsg(bogus, label, format, str) { }
plExportErrorDbg(hsBool bogus, const char* label, const char* format, const char* str1, const char* str2)
: plExportErrorMsg(bogus, label, format, str1, str2) { }
plExportErrorDbg(hsBool bogus, const char* label, const char* format, int n)
: plExportErrorMsg(bogus, label, format, n) { }
plExportErrorDbg(hsBool bogus, const char* label, const char* format, int n, int m)
: plExportErrorMsg(bogus, label, format, n, m) { }
plExportErrorDbg(hsBool bogus, const char* label, const char* format, float f)
: plExportErrorMsg(bogus, label, format, f) { }
};
#endif // keep them as exactly the same as errormessage
#endif // plErrMsg_inc

View File

@ -0,0 +1,187 @@
/*==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/>.
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 "Max.h"
#include <commdlg.h>
#include <bmmlib.h>
#include <guplib.h>
#include "hsWindows.h"
#include "hsTypes.h"
#include "plExportLogErrorMsg.h"
#include "hsExceptions.h"
#include "hsUtils.h"
//
// On our way out, be sure to close the error file
// ... and remind them of how many errors they created
//
plExportLogErrorMsg::~plExportLogErrorMsg()
{
if ( fErrfile )
{
fprintf(fErrfile, "\n%d total number of error!!!! ", fNumberErrors);
if ( fNumberErrors > 10 )
if ( fNumberErrors > 20 )
if ( fNumberErrors > 50 )
fprintf(fErrfile, "(CRISIS CRISIS!)");
else
fprintf(fErrfile, "(which is a disaster!)");
else
fprintf(fErrfile, "(which is way too many!)");
fclose(fErrfile);
}
#ifdef ERRORLOG_ALWAYS_WRITE_SOMETHING
else
{
fErrfile = hsFopen(fErrfile_name, "wt");
setbuf(fErrfile, nil);
fprintf(fErrfile, "No errors found! Good job.");
fclose(fErrfile);
}
#endif // ERRORLOG_ALWAYS_WRITE_SOMETHING
}
hsBool plExportLogErrorMsg::Show()
{
if( GetBogus() )
{
IWriteErrorFile(GetLabel(),GetMsg());
}
return GetBogus();
}
hsBool plExportLogErrorMsg::Ask()
{
if( GetBogus() )
{
IWriteErrorFile(GetLabel(),GetMsg());
}
return false;
}
hsBool plExportLogErrorMsg::CheckAndAsk()
{
if( GetBogus() )
{
strncat(GetMsg(), " - File corruption possible!", 255);
IWriteErrorFile(GetLabel(),GetMsg());
}
return GetBogus();
}
hsBool plExportLogErrorMsg::CheckAskOrCancel()
{
if( GetBogus() )
{
IWriteErrorFile(GetLabel(),GetMsg());
}
return false;
}
hsBool plExportLogErrorMsg::CheckAndShow()
{
if ( GetBogus() )
{
Show();
Check();
}
return false;
}
hsBool plExportLogErrorMsg::Check()
{
if( GetBogus() )
{
// ... how many ways can you say something is bad?
strncat(GetMsg(), " !Output File Corrupt!", 255);
IWriteErrorFile(GetLabel(),GetMsg());
IDebugThrow();
}
return false;
}
//
// Not sure what to do here... it must be really bad if someone wants to Quit()
//
void plExportLogErrorMsg::Quit()
{
if( GetBogus() )
{
strncat(GetMsg(), " -- Quit! (must be real bad!)", 255);
IWriteErrorFile(GetLabel(),GetMsg());
SetBogus(false);
hsThrow( *this );
}
}
//
// Write a string to the Error Log File, be sure its open before using
//
void plExportLogErrorMsg::IWriteErrorFile(const char* label, const char* msg)
{
//make sure that there is a filename
if (fErrfile_name[0] != '\0')
{
// do we have it open, yet?
if ( !fErrfile )
{
// must be the first write... open the error file
fErrfile = hsFopen(fErrfile_name, "wt");
setbuf(fErrfile, nil);
fNumberErrors = 0;
}
fprintf(fErrfile, "%s: %s\n", label, msg);
fNumberErrors++; // oh, boy... another error to count
}
// Check to see if we are running an export server
// If so, then pass the update on to the export server
GUP* exportServerGup = OpenGupPlugIn(Class_ID(470000004,99));
if(exportServerGup)
{
exportServerGup->Control(-5); // means next control will be error msg
char buf[1024];
sprintf(buf, "%s: %s", label, msg);
exportServerGup->Control((DWORD)buf);
exportServerGup->Control(-7); // signal that we're done sending this update sequence
}
}
void plExportLogErrorMsg::IDebugThrow()
{
try {
#if HS_BUILD_FOR_WIN32
DebugBreak();
#endif // HS_BUILD_FOR_WIN32
}
catch(...)
{
hsThrow( *this );
}
}

View File

@ -0,0 +1,156 @@
/*==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/>.
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 plExportLogErrorMsg_inc
#define plExportLogErrorMsg_inc
//
// This plErrorMsg derivation will just log the error to a text file, instead of
// asking the user (because this used for unattended exporting).
// If there is no errors then there should be no file created.
//
#include <string.h>
#include "plErrorMsg.h"
#if !HS_BUILD_FOR_WIN32
#define PL_NULL_ERRMSG
#endif !HS_BUILD_FOR_WIN32
#ifndef PL_NULL_ERRMSG
#define ERROR_LOGFILE_NAME_LEN 512
class plExportLogErrorMsg : public plErrorMsg {
public:
plExportLogErrorMsg(const char* efile, const char* label, const char* msg) : plErrorMsg(label, msg)
{ strncpy(fErrfile_name,efile,ERROR_LOGFILE_NAME_LEN-1); fErrfile=nil; }
plExportLogErrorMsg(const char* efile, hsBool bogus = false) : plErrorMsg(bogus)
{ strncpy(fErrfile_name,efile,ERROR_LOGFILE_NAME_LEN-1); fErrfile=nil; }
plExportLogErrorMsg(const char* efile, hsBool bogus, const char* label, const char* msg)
: plErrorMsg(bogus, label, msg)
{ strncpy(fErrfile_name,efile,ERROR_LOGFILE_NAME_LEN-1); fErrfile=nil; }
plExportLogErrorMsg(const char* efile, hsBool bogus, const char* label, const char* format, const char* str)
: plErrorMsg(bogus, label, format, str)
{ strncpy(fErrfile_name,efile,ERROR_LOGFILE_NAME_LEN-1); fErrfile=nil; }
plExportLogErrorMsg(const char* efile, hsBool bogus, const char* label, const char* format, const char* str1, const char* str2)
: plErrorMsg(bogus, label, format, str1, str2)
{ strncpy(fErrfile_name,efile,ERROR_LOGFILE_NAME_LEN-1); fErrfile=nil; }
plExportLogErrorMsg(const char* efile, hsBool bogus, const char* label, const char* format, int n)
: plErrorMsg(bogus, label, format, n)
{ strncpy(fErrfile_name,efile,ERROR_LOGFILE_NAME_LEN-1); fErrfile=nil; }
plExportLogErrorMsg(const char* efile, hsBool bogus, const char* label, const char* format, int n, int m)
: plErrorMsg(bogus, label, format, n, m)
{ strncpy(fErrfile_name,efile,ERROR_LOGFILE_NAME_LEN-1); fErrfile=nil; }
plExportLogErrorMsg(const char* efile, hsBool bogus, const char* label, const char* format, float f)
: plErrorMsg(bogus, label, format, f)
{ strncpy(fErrfile_name,efile,ERROR_LOGFILE_NAME_LEN-1); fErrfile=nil; }
~plExportLogErrorMsg();
virtual hsBool Ask(); // if b is true and user says yes to displayed query, return true, else false
virtual hsBool CheckAndAsk(); // if b is true and user says YES, throw self. only asks if b is true. returns true if b is true but user says no, else false
virtual hsBool CheckAskOrCancel(); // if b is true ( if YES, throw, else if NO return 0, else (CANCEL) return 1
virtual hsBool Show(); // if b is true, displays message, returns true
virtual hsBool Check(); // if b was true, throws self, else return false
virtual hsBool CheckAndShow(); // if b was true, shows message box then throws self, else return false
virtual void Quit(); // if b, quietly just throw with no message
protected:
virtual void IWriteErrorFile(const char* label, const char* msg);
private:
FILE *fErrfile; // the error file to write the nasties
char fErrfile_name[ERROR_LOGFILE_NAME_LEN]; // the name of the error file
Int32 fNumberErrors;
private:
void IDebugThrow();
};
#else // PL_NULL_ERRMSG
class plExportLogErrorMsg : public plErrorMsg {
public:
plExportLogErrorMsg(const char* label, const char* msg) : plErrorMsg() { }
plExportLogErrorMsg(hsBool bogus = false) : plErrorMsg() { }
plExportLogErrorMsg(hsBool bogus, const char* label, const char* msg)
: plErrorMsg() { }
plExportLogErrorMsg(hsBool bogus, const char* label, const char* format, const char* str)
: plErrorMsg() { }
plExportLogErrorMsg(hsBool bogus, const char* label, const char* format, const char* str1, const char* str2)
: plErrorMsg() { }
plExportLogErrorMsg(hsBool bogus, const char* label, const char* format, int n)
: plErrorMsg() { }
plExportLogErrorMsg(hsBool bogus, const char* label, const char* format, int n, int m)
: plErrorMsg() { }
plExportLogErrorMsg(hsBool bogus, const char* label, const char* format, float f)
: plErrorMsg() { }
};
#endif // PL_NULL_ERRMSG
// Compile out error messages labeled debug
// #define PL_ERR_CHECK_DEGUG_ONLY
#if defined(NDEBUG) && defined(PL_ERR_CHECK_DEGUG_ONLY)
class plExportLogErrorDbg : public plExportLogErrorMsg {
public:
plExportLogErrorDbg(const char* label, const char* msg) : plExportLogErrorMsg("") { }
plExportLogErrorDbg(hsBool bogus = false) : plExportLogErrorMsg("") { }
plExportLogErrorDbg(hsBool bogus, const char* label, const char* msg) : plExportLogErrorMsg("") { }
plExportLogErrorDbg(hsBool bogus, const char* label, const char* format, const char* str) : plExportLogErrorMsg("") { }
plExportLogErrorDbg(hsBool bogus, const char* label, const char* format, const char* str1, const char* str2) : plExportLogErrorMsg("") { }
plExportLogErrorDbg(hsBool bogus, const char* label, const char* format, int n) : plExportLogErrorMsg("") { }
plExportLogErrorDbg(hsBool bogus, const char* label, const char* format, int n, int m) : plExportLogErrorMsg("") { }
plExportLogErrorDbg(hsBool bogus, const char* label, const char* format, float f) : plExportLogErrorMsg("") { }
hsBool Ask() { return false; }
hsBool CheckAndAsk() { return false; }
hsBool CheckAskOrCancel();
hsBool Show() { return false; }
hsBool Check() { return false; }
hsBool CheckAndShow() { return false; }
void Quit() { }
};
#else // keep them as exactly the same as errormessage
class plExportLogErrorDbg : public plExportLogErrorMsg {
public:
plExportLogErrorDbg(const char* label, const char* msg) : plExportLogErrorMsg("",label, msg) { }
plExportLogErrorDbg(hsBool bogus = true) : plExportLogErrorMsg("",bogus) { }
plExportLogErrorDbg(hsBool bogus, const char* label, const char* msg)
: plExportLogErrorMsg("",bogus, label, msg) { }
plExportLogErrorDbg(hsBool bogus, const char* label, const char* format, const char* str)
: plExportLogErrorMsg("",bogus, label, format, str) { }
plExportLogErrorDbg(hsBool bogus, const char* label, const char* format, const char* str1, const char* str2)
: plExportLogErrorMsg("",bogus, label, format, str1, str2) { }
plExportLogErrorDbg(hsBool bogus, const char* label, const char* format, int n)
: plExportLogErrorMsg("",bogus, label, format, n) { }
plExportLogErrorDbg(hsBool bogus, const char* label, const char* format, int n, int m)
: plExportLogErrorMsg("",bogus, label, format, n, m) { }
plExportLogErrorDbg(hsBool bogus, const char* label, const char* format, float f)
: plExportLogErrorMsg("",bogus, label, format, f) { }
};
#endif // keep them as exactly the same as errormessage
#endif // plExportLogErrorMsg_inc

View File

@ -0,0 +1,122 @@
/*==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/>.
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 "Max.h"
#include "plExportProgressBar.h"
#include <commdlg.h>
#include <bmmlib.h>
#include <guplib.h>
namespace {
DWORD WINAPI ProgressDummyFunc(LPVOID arg)
{
return(0);
}
}
plExportProgressBar::plExportProgressBar() :
fTotalSteps(0),
fCurStep(0)
{
fInterface = GetCOREInterface();
}
plExportProgressBar::~plExportProgressBar()
{
fInterface->ProgressEnd();
}
void plExportProgressBar::Start(char *name, UInt32 steps)
{
fTotalSteps = steps;
fCurStep = 0;
fInterface->ProgressEnd();
fInterface->ProgressStart(name, TRUE, ProgressDummyFunc, nil);
GUP* exportServerGup = OpenGupPlugIn(Class_ID(470000004,99));
if(exportServerGup && name)
{
exportServerGup->Control(-3); // means next control will be progress task
exportServerGup->Control((DWORD)name);
}
}
bool plExportProgressBar::Update(char *name, UInt32 inc)
{
fCurStep += inc;
// Check to see if we are running an export server
// If so, then pass the update on to the export server
GUP* exportServerGup = OpenGupPlugIn(Class_ID(470000004,99));
if(exportServerGup)
{
exportServerGup->Control(-2); // means next control will be progress pct
exportServerGup->Control((int)((fCurStep * 100) / fTotalSteps)); // send pct
if(name)
{
exportServerGup->Control(-4); // means next control will be progress subtask
exportServerGup->Control((DWORD)name);
}
exportServerGup->Control(-6); // signal that we're done sending this update sequence
}
fInterface->ProgressUpdate((int)((fCurStep * 100) / fTotalSteps), FALSE, name);
if (fInterface->GetCancel())
{
int retval = MessageBox(fInterface->GetMAXHWnd(), _T("Really Cancel?"),
_T("Question"), MB_ICONQUESTION | MB_YESNO);
if (retval == IDYES)
{
return true;
}
else if (retval == IDNO)
{
fInterface->SetCancel(FALSE);
}
}
return false;
}
UInt32 plExportProgressBar::CountNodes()
{
return INodeCount(GetCOREInterface()->GetRootNode());
}
UInt32 plExportProgressBar::INodeCount(INode *node)
{
UInt32 count = 1;
for (int i = 0; i < node->NumberOfChildren(); i++)
{
INode *child = node->GetChildNode(i);
count += INodeCount(child);
}
return count;
}

View File

@ -0,0 +1,53 @@
/*==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/>.
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 plExportProgressBar_inc
#define plExportProgressBar_inc
#include "hsTypes.h"
class INode;
class plExportProgressBar
{
public:
plExportProgressBar();
~plExportProgressBar();
void Start(char *name, UInt32 steps=CountNodes());
bool Update(char *name=nil, UInt32 inc=1);
static UInt32 CountNodes();
private:
static UInt32 INodeCount(INode *node);
Interface* fInterface;
UInt32 fTotalSteps;
UInt32 fCurStep;
};
#endif // plExportProgressBar_inc

View File

@ -0,0 +1,59 @@
/*==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/>.
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==*/
// plProgressBar.h
#ifndef plProgressBar_inc
#define plProgressBar_inc
#include "hsTypes.h"
#include "hsScalar.h"
// The progress bar displays an amount that's *fraction* of the distance between min and max.
// i.e., if min is 0.2 and max is 0.7, the bar will run the gamut from min to max; at fraction
// 0.8, it will display 0.6 ( = 0.2 + 0.8 * (0.7 - 0.2)).
// The bar runs from 0 to 1 and all values should be in that range.
class plProgressBar
{
public:
plProgressBar(hsScalar min, hsScalar max) : fMin(min), fMax(max)
{
hsAssert(min >= 0, "Min too small.");
hsAssert(min <= 1, "Min too big.");
hsAssert(max >= 0, "Max too small.");
hsAssert(max <= 1, "Max too big.");
hsAssert(min <= max, "Min and max out of order.");
}
virtual hsBool32 Update(hsScalar fraction) = 0;
hsScalar GetTotalFraction(hsScalar f) const { return fMin + f * (fMax - fMin); }
private:
hsScalar fMin;
hsScalar fMax;
};
#endif // plProgressBar_inc