From a1a7dac59c8304584caedb847c7e5b87962340e8 Mon Sep 17 00:00:00 2001 From: Ykkrosh Date: Fri, 22 Sep 2006 17:43:00 +0000 Subject: [PATCH] # Integrated Actor Viewer and Actor Editor tools ObjectManager: Removed ObjectTypes because it hasn't been used for years. Atlas: Fixed leak when saving with Xerces. Changed range of water shininess slider. Actor Editor: Relabelled "Freq" to "Ratio". Made modal dialogs use the correct parent. This was SVN commit r4376. --- .../data/mods/official/shaders/water_high.vs | 2 +- source/graphics/GameView.cpp | 1 - source/graphics/ObjectEntry.cpp | 7 +- source/graphics/ObjectEntry.h | 4 +- source/graphics/ObjectManager.cpp | 117 +++++++----------- source/graphics/ObjectManager.h | 18 +-- source/lib/path_util.cpp | 2 +- source/lib/res/graphics/tex.cpp | 4 +- source/renderer/Renderer.cpp | 7 +- source/scripting/ScriptingHost.cpp | 2 +- .../atlas/AtlasObject/AtlasObjectXML.cpp | 9 +- .../atlas/AtlasUI/ActorEditor/ActorEditor.cpp | 46 ------- .../ActorEditor/ActorEditorListCtrl.cpp | 9 +- .../AtlasUI/ActorEditor/AnimListEditor.cpp | 6 +- .../AtlasUI/ActorEditor/AnimListEditor.h | 5 +- .../AtlasUI/ActorEditor/PropListEditor.cpp | 6 +- .../AtlasUI/ActorEditor/PropListEditor.h | 5 +- .../atlas/AtlasUI/ActorViewer/ActorViewer.cpp | 34 ++++- .../atlas/AtlasUI/ActorViewer/ActorViewer.h | 8 +- .../DraggableListCtrl/DraggableListCtrl.h | 5 + .../EditableListCtrl/FieldEditCtrl.cpp | 6 +- .../EditableListCtrl/FieldEditCtrl.h | 10 +- .../CustomControls/Windows/AtlasDialog.h | 5 + .../CustomControls/Windows/AtlasWindow.cpp | 4 +- .../CustomControls/Windows/AtlasWindow.h | 4 +- .../atlas/AtlasUI/General/Observable.cpp | 22 ++++ .../tools/atlas/AtlasUI/General/Observable.h | 30 +++++ .../tools/atlas/AtlasUI/Misc/DLLInterface.cpp | 5 + .../Sections/Environment/Environment.cpp | 2 +- .../tools/atlas/GameInterface/ActorViewer.cpp | 1 - .../Handlers/GraphicsSetupHandlers.cpp | 21 +++- source/tools/atlas/GameInterface/Messages.h | 1 + 32 files changed, 217 insertions(+), 191 deletions(-) create mode 100644 source/tools/atlas/AtlasUI/General/Observable.cpp diff --git a/binaries/data/mods/official/shaders/water_high.vs b/binaries/data/mods/official/shaders/water_high.vs index ae4d5466a3..8894abf39d 100644 --- a/binaries/data/mods/official/shaders/water_high.vs +++ b/binaries/data/mods/official/shaders/water_high.vs @@ -19,5 +19,5 @@ void main() gl_TexCoord[1] = reflectionMatrix * gl_Vertex; // projective texturing gl_TexCoord[2] = reflectionMatrix * gl_Vertex; w = gl_TexCoord[1].w; - gl_Position = ftransform(); + gl_Position = ftransform(); } diff --git a/source/graphics/GameView.cpp b/source/graphics/GameView.cpp index d9adcd3146..d9c756d253 100644 --- a/source/graphics/GameView.cpp +++ b/source/graphics/GameView.cpp @@ -140,7 +140,6 @@ void CGameView::RegisterInit(CGameAttributes *pAttribs) // previously done by CGameView::InitResources RegMemFun(g_TexMan.GetSingletonPtr(), &CTextureManager::LoadTerrainTextures, L"LoadTerrainTextures", 60); - RegMemFun(g_ObjMan.GetSingletonPtr(), &CObjectManager::LoadObjects, L"LoadObjects", 1); RegMemFun(g_Renderer.GetSingletonPtr(), &CRenderer::LoadAlphaMaps, L"LoadAlphaMaps", 5); RegMemFun(g_Renderer.GetSingletonPtr()->GetWaterManager(), &WaterManager::LoadWaterTextures, L"LoadWaterTextures", 80); RegMemFun(g_Renderer.GetSingletonPtr()->GetSkyManager(), &SkyManager::LoadSkyTextures, L"LoadSkyTextures", 15); diff --git a/source/graphics/ObjectEntry.cpp b/source/graphics/ObjectEntry.cpp index 8538ccd0ff..7b50367268 100644 --- a/source/graphics/ObjectEntry.cpp +++ b/source/graphics/ObjectEntry.cpp @@ -22,9 +22,9 @@ #define LOG_CATEGORY "graphics" -CObjectEntry::CObjectEntry(int type, CObjectBase* base) +CObjectEntry::CObjectEntry(CObjectBase* base) : m_Base(base), m_Color(1.0f, 1.0f, 1.0f, 1.0f), - m_ProjectileModel(NULL), m_AmmunitionModel(NULL), m_AmmunitionPoint(NULL), m_Model(NULL), m_Type(type) + m_ProjectileModel(NULL), m_AmmunitionModel(NULL), m_AmmunitionPoint(NULL), m_Model(NULL) { } @@ -65,9 +65,6 @@ bool CObjectEntry::BuildVariation(const std::vector >& selection // Build the model: - // get the root directory of this object - CStr dirname = g_ObjMan.m_ObjectTypes[m_Type].m_Name; - // remember the old model so we can replace any models using it later on CModelDefPtr oldmodeldef = m_Model ? m_Model->GetModelDef() : CModelDefPtr(); diff --git a/source/graphics/ObjectEntry.h b/source/graphics/ObjectEntry.h index 8b1bbe7329..9ae2f27817 100644 --- a/source/graphics/ObjectEntry.h +++ b/source/graphics/ObjectEntry.h @@ -15,7 +15,7 @@ struct SPropPoint; class CObjectEntry { public: - CObjectEntry(int type, CObjectBase* base); + CObjectEntry(CObjectBase* base); ~CObjectEntry(); // Construct this actor, using the specified variation selections @@ -45,8 +45,6 @@ public: // corresponding model CModel* m_Model; - // type of object; index into object managers types array - int m_Type; private: typedef std::multimap SkeletonAnimMap; diff --git a/source/graphics/ObjectManager.cpp b/source/graphics/ObjectManager.cpp index 0f82132aaf..440a98be96 100644 --- a/source/graphics/ObjectManager.cpp +++ b/source/graphics/ObjectManager.cpp @@ -19,6 +19,20 @@ #define LOG_CATEGORY "graphics" +template +static void delete_pair_2nd(std::pair v) +{ + delete v.second; +} + +template +struct second_equals +{ + T x; + second_equals(const T& x) : x(x) {} + template bool operator()(const S& v) { return v.second == x; } +}; + bool operator< (const CObjectManager::ObjectKey& a, const CObjectManager::ObjectKey& b) { if (a.ActorName < b.ActorName) @@ -31,47 +45,35 @@ bool operator< (const CObjectManager::ObjectKey& a, const CObjectManager::Object CObjectManager::CObjectManager() { - m_ObjectTypes.reserve(32); } -template static void delete_pair_2nd(std::pair v) { delete v.second; } - CObjectManager::~CObjectManager() { UnloadObjects(); } -// TODO (PT): Work out what the object 'types' are for, since they're not -// doing anything obvious. (And if they're useless, remove them.) - CObjectBase* CObjectManager::FindObjectBase(const char* objectname) { debug_assert(strcmp(objectname, "") != 0); // See if the base type has been loaded yet: - for (uint k = 0; k < m_ObjectTypes.size(); k++) - { - std::map::iterator it = m_ObjectTypes[k].m_ObjectBases.find(objectname); - if (it != m_ObjectTypes[k].m_ObjectBases.end()) - return it->second; - } + std::map::iterator it = m_ObjectBases.find(objectname); + if (it != m_ObjectBases.end()) + return it->second; // Not already loaded, so try to load it: - for (uint k = 0; k < m_ObjectTypes.size(); k++) - { - CObjectBase* obj = new CObjectBase(); + CObjectBase* obj = new CObjectBase(); - if (obj->Load(objectname)) - { - m_ObjectTypes[k].m_ObjectBases[objectname] = obj; - return obj; - } - else - delete obj; + if (obj->Load(objectname)) + { + m_ObjectBases[objectname] = obj; + return obj; } + else + delete obj; LOG(ERROR, LOG_CATEGORY, "CObjectManager::FindObjectBase(): Cannot find object '%s'", objectname); @@ -80,7 +82,7 @@ CObjectBase* CObjectManager::FindObjectBase(const char* objectname) CObjectEntry* CObjectManager::FindObject(const char* objname) { - std::vector > selections; // TODO - should this really be empty? + std::vector > selections; // TODO - should this really be empty? return FindObjectVariation(objname, selections); } @@ -103,13 +105,13 @@ CObjectEntry* CObjectManager::FindObjectVariation(CObjectBase* base, const std:: std::vector choices = base->CalculateVariationKey(selections); ObjectKey key (base->m_Name, choices); - std::map::iterator it = m_ObjectTypes[0].m_Objects.find(key); - if (it != m_ObjectTypes[0].m_Objects.end()) + std::map::iterator it = m_Objects.find(key); + if (it != m_Objects.end()) return it->second; // If it hasn't been loaded, load it now - CObjectEntry* obj = new CObjectEntry(0, base); // TODO: type ? + CObjectEntry* obj = new CObjectEntry(base); // TODO: type ? // TODO (for some efficiency): use the pre-calculated choices for this object, // which has already worked out what to do for props, instead of passing the @@ -121,66 +123,37 @@ CObjectEntry* CObjectManager::FindObjectVariation(CObjectBase* base, const std:: return NULL; } - m_ObjectTypes[0].m_Objects[key] = obj; + m_Objects[key] = obj; return obj; } -void CObjectManager::AddObjectType(const char* name) -{ - m_ObjectTypes.resize(m_ObjectTypes.size()+1); - SObjectType& type=m_ObjectTypes.back(); - type.m_Name=name; - type.m_Index=(int)m_ObjectTypes.size()-1; -} - - -void CObjectManager::AddObject(ObjectKey& key, CObjectEntry* entry, int type) -{ - debug_assert((uint)type& objects = m_ObjectTypes[entry->m_Type].m_Objects; - - for (std::map::iterator it = objects.begin(); it != objects.end(); ) - if (it->second == entry) - objects.erase(it++); - else - ++it; + std::map::iterator it; + while (m_Objects.end() != (it = find_if(m_Objects.begin(), m_Objects.end(), second_equals(entry)))) + m_Objects.erase(it); delete entry; } -int CObjectManager::LoadObjects() -{ - // This is kind of useless - it should probably be removed, - // and UnloadObject moved into the destructor, and singletonness - // removed if we still want to unload the object manager and reuse it - // again later. - AddObjectType(""); - return 0; -} - void CObjectManager::UnloadObjects() { - for (size_t i = 0; i < m_ObjectTypes.size(); i++) { - std::for_each( - m_ObjectTypes[i].m_Objects.begin(), - m_ObjectTypes[i].m_Objects.end(), - delete_pair_2nd - ); - std::for_each( - m_ObjectTypes[i].m_ObjectBases.begin(), - m_ObjectTypes[i].m_ObjectBases.end(), - delete_pair_2nd - ); - } - m_ObjectTypes.clear(); + std::for_each( + m_Objects.begin(), + m_Objects.end(), + delete_pair_2nd + ); + m_Objects.clear(); + + std::for_each( + m_ObjectBases.begin(), + m_ObjectBases.end(), + delete_pair_2nd + ); + m_ObjectBases.clear(); } diff --git a/source/graphics/ObjectManager.h b/source/graphics/ObjectManager.h index f7f01693e3..1ce691ea23 100644 --- a/source/graphics/ObjectManager.h +++ b/source/graphics/ObjectManager.h @@ -29,30 +29,15 @@ public: }; - struct SObjectType - { - // name of this object type (derived from directory name) - CStr m_Name; - // index in parent array - int m_Index; - // list of objects of this type (found from the objects directory) - std::map m_Objects; - std::map m_ObjectBases; - }; - public: // constructor, destructor CObjectManager(); ~CObjectManager(); - int LoadObjects(); void UnloadObjects(); - void AddObjectType(const char* name); - CObjectEntry* FindObject(const char* objname); - void AddObject(ObjectKey& key, CObjectEntry* entry, int type); void DeleteObject(CObjectEntry* entry); CObjectBase* FindObjectBase(const char* objname); @@ -64,7 +49,8 @@ public: void GetAllObjectNames(std::vector& names); void GetPropObjectNames(std::vector& names); - std::vector m_ObjectTypes; + std::map m_Objects; + std::map m_ObjectBases; }; diff --git a/source/lib/path_util.cpp b/source/lib/path_util.cpp index 8b1f4ce144..b30f66a273 100644 --- a/source/lib/path_util.cpp +++ b/source/lib/path_util.cpp @@ -33,7 +33,7 @@ AT_STARTUP(\ error_setDescription(ERR::PATH_LENGTH, "Path exceeds PATH_MAX characters");\ error_setDescription(ERR::PATH_EMPTY, "Path is an empty string");\ error_setDescription(ERR::PATH_NOT_RELATIVE, "Path is not relative");\ - error_setDescription(ERR::PATH_NON_PORTABLE, "Path contains OSspecific dir separator");\ + error_setDescription(ERR::PATH_NON_PORTABLE, "Path contains OS-specific dir separator");\ error_setDescription(ERR::PATH_NON_CANONICAL, "Path contains unsupported .. or ./");\ error_setDescription(ERR::PATH_COMPONENT_SEPARATOR, "Path component contains dir separator");\ \ diff --git a/source/lib/res/graphics/tex.cpp b/source/lib/res/graphics/tex.cpp index 90fa3e2903..dfe49907e6 100644 --- a/source/lib/res/graphics/tex.cpp +++ b/source/lib/res/graphics/tex.cpp @@ -37,8 +37,8 @@ AT_STARTUP(\ error_setDescription(ERR::TEX_FMT_INVALID, "Invalid/unsupported texture format");\ error_setDescription(ERR::TEX_INVALID_COLOR_TYPE, "Invalid color type");\ - error_setDescription(ERR::TEX_NOT_8BIT_PRECISION, "Not 8bit channel precision");\ - error_setDescription(ERR::TEX_INVALID_LAYOUT, "Unsupported texel layout, e.g. righttoleft");\ + error_setDescription(ERR::TEX_NOT_8BIT_PRECISION, "Not 8-bit channel precision");\ + error_setDescription(ERR::TEX_INVALID_LAYOUT, "Unsupported texel layout, e.g. right-to-left");\ error_setDescription(ERR::TEX_COMPRESSED, "Unsupported texture compression");\ error_setDescription(WARN::TEX_INVALID_DATA, "Warning: invalid texel data encountered");\ error_setDescription(ERR::TEX_INVALID_SIZE, "Texture size is incorrect");\ diff --git a/source/renderer/Renderer.cpp b/source/renderer/Renderer.cpp index e1fca1b96a..1aa6267b05 100644 --- a/source/renderer/Renderer.cpp +++ b/source/renderer/Renderer.cpp @@ -1235,8 +1235,11 @@ void CRenderer::FlushFrame() RenderPatches(); oglCheck(); - g_Game->GetWorld()->GetTerritoryManager()->renderTerritories(); - oglCheck(); + if (g_Game) + { + g_Game->GetWorld()->GetTerritoryManager()->renderTerritories(); + oglCheck(); + } // render debug-related terrain overlays TerrainOverlay::RenderOverlays(); diff --git a/source/scripting/ScriptingHost.cpp b/source/scripting/ScriptingHost.cpp index f93c14116f..ac4e7d5798 100644 --- a/source/scripting/ScriptingHost.cpp +++ b/source/scripting/ScriptingHost.cpp @@ -445,7 +445,7 @@ void* ScriptingHost::jshook_function( JSContext* cx, JSStackFrame* fp, JSBool be g_Profiler.StartScript( JS_GetFunctionName( fn ) ); } else - g_Profiler.StartScript( "function invokation" ); + g_Profiler.StartScript( "function invocation" ); } else g_Profiler.Stop(); diff --git a/source/tools/atlas/AtlasObject/AtlasObjectXML.cpp b/source/tools/atlas/AtlasObject/AtlasObjectXML.cpp index ebf8474a91..273ea6c1de 100644 --- a/source/tools/atlas/AtlasObject/AtlasObjectXML.cpp +++ b/source/tools/atlas/AtlasObject/AtlasObjectXML.cpp @@ -277,12 +277,11 @@ bool AtlasObject::SaveToXML(AtObj& obj, const wchar_t* filename) try { - DOMDocument* doc = impl->createDocument(); - doc->appendChild(BuildDOMNode(doc, rootName, firstChild)); + std::auto_ptr doc (impl->createDocument()); + doc->appendChild(BuildDOMNode(doc.get(), rootName, firstChild)); - XMLFormatTarget* FormatTarget = new LocalFileFormatTarget((XMLCh*)filename); - writer->writeNode(FormatTarget, *doc); - delete FormatTarget; + LocalFileFormatTarget formatTarget ((XMLCh*)filename); + writer->writeNode(&formatTarget, *doc); } catch (const XMLException& e) { char* message = XMLString::transcode(e.getMessage()); diff --git a/source/tools/atlas/AtlasUI/ActorEditor/ActorEditor.cpp b/source/tools/atlas/AtlasUI/ActorEditor/ActorEditor.cpp index e74362630a..f034b5c204 100644 --- a/source/tools/atlas/AtlasUI/ActorEditor/ActorEditor.cpp +++ b/source/tools/atlas/AtlasUI/ActorEditor/ActorEditor.cpp @@ -419,49 +419,3 @@ wxString ActorEditor::GetDefaultOpenDirectory() dir.MakeAbsolute(Datafile::GetDataDirectory()); return dir.GetPath(); } - - -#if 0 -// TODO: delete this -void merge_actors(const char* newFn, const char* oldFn_b, const char* oldFn_a, const char* oldFn_e) -{ -wxFAIL; - /* - wxLogDebug(L"Converting %s -> %s", wxString::FromAscii(oldFn_b), wxString::FromAscii(newFn)); - - AtObj obj0 = AtlasObject::LoadFromXML(L"e:/0ad/svnc/trunk/binaries/data/mods/official/art/actors_clean/" + wxString::FromAscii(oldFn_b)); - AtObj obj1 = AtlasObject::LoadFromXML(L"e:/0ad/svnc/trunk/binaries/data/mods/official/art/actors_clean/" + wxString::FromAscii(oldFn_a)); - AtObj obj2 = AtlasObject::LoadFromXML(L"e:/0ad/svnc/trunk/binaries/data/mods/official/art/actors_clean/" + wxString::FromAscii(oldFn_e)); - wxASSERT(obj0.defined()); - wxASSERT(obj2.defined()); - wxASSERT(obj1.defined()); - obj0 = ConvertToLatestFormat(obj0); - obj1 = ConvertToLatestFormat(obj1); - obj2 = ConvertToLatestFormat(obj2); -// wxString x = AtlasObject::ConvertToString(obj).c_str(); -// wxLogDebug(x); - bool ok = AtlasObject::SaveToXML(obj, L"e:/0ad/svnc/trunk/binaries/data/mods/official/art/actors_new/" + wxString::FromAscii(newFn)); - wxASSERT(ok); -*/ -} - -void convert_file(const char* newFn, const char* oldFn) -{ -//* - wxLogDebug(L"Converting %s -> %s", wxString::FromAscii(oldFn), wxString::FromAscii(newFn)); - AtObj obj = AtlasObject::LoadFromXML(L"e:/0ad/svnc/trunk/binaries/data/mods/official/art/actors_clean/" + wxString::FromAscii(oldFn)); - wxASSERT(obj.defined()); - obj = ConvertToLatestFormat(obj); -// wxString x = AtlasObject::ConvertToString(obj).c_str(); -// wxLogDebug(x); - bool ok = AtlasObject::SaveToXML(obj, L"e:/0ad/svnc/trunk/binaries/data/mods/official/art/actors_new/" + wxString::FromAscii(newFn)); - wxASSERT(ok); -//*/ -} - -void convert_actors() -{ -// convert_file("fauna/deer1.xml", "fauna/temp_deer1.xml"); -#include "e:/0ad/svnc/trunk/binaries/data/mods/official/art/convert.cpp" -} -#endif diff --git a/source/tools/atlas/AtlasUI/ActorEditor/ActorEditorListCtrl.cpp b/source/tools/atlas/AtlasUI/ActorEditor/ActorEditorListCtrl.cpp index 2d431ea5e4..90ab8e03e6 100644 --- a/source/tools/atlas/AtlasUI/ActorEditor/ActorEditorListCtrl.cpp +++ b/source/tools/atlas/AtlasUI/ActorEditor/ActorEditorListCtrl.cpp @@ -2,6 +2,9 @@ #include "ActorEditorListCtrl.h" +#include "AnimListEditor.h" +#include "PropListEditor.h" + #include "AtlasObject/AtlasObject.h" #include "EditableListCtrl/FieldEditCtrl.h" @@ -26,11 +29,11 @@ ActorEditorListCtrl::ActorEditorListCtrl(wxWindow* parent) #undef COLOUR AddColumnType(_("Variant"), 90, "@name", new FieldEditCtrl_Text()); - AddColumnType(_("Freq"), 50, "@frequency", new FieldEditCtrl_Text()); + AddColumnType(_("Ratio"), 50, "@frequency", new FieldEditCtrl_Text()); AddColumnType(_("Model"), 140, "mesh", new FieldEditCtrl_File(_T("art/meshes/"), _("Mesh files (*.pmd)|*.pmd|All files (*.*)|*.*"))); AddColumnType(_("Texture"), 140, "texture", new FieldEditCtrl_File(_T("art/textures/skins/"), _("All files (*.*)|*.*"))); // could be dds, or tga, or png, or bmp, etc, so just allow * - AddColumnType(_("Animations"), 250, "animations", new FieldEditCtrl_Dialog(_T("AnimListEditor"))); - AddColumnType(_("Props"), 220, "props", new FieldEditCtrl_Dialog(_T("PropListEditor"))); + AddColumnType(_("Animations"), 250, "animations", new FieldEditCtrl_Dialog(&AnimListEditor::Create)); + AddColumnType(_("Props"), 220, "props", new FieldEditCtrl_Dialog(&PropListEditor::Create)); AddColumnType(_("Colour"), 80, "colour", new FieldEditCtrl_Colour()); } diff --git a/source/tools/atlas/AtlasUI/ActorEditor/AnimListEditor.cpp b/source/tools/atlas/AtlasUI/ActorEditor/AnimListEditor.cpp index e3551410f4..696d598a2c 100644 --- a/source/tools/atlas/AtlasUI/ActorEditor/AnimListEditor.cpp +++ b/source/tools/atlas/AtlasUI/ActorEditor/AnimListEditor.cpp @@ -7,10 +7,8 @@ ////////////////////////////////////////////////////////////////////////// -IMPLEMENT_DYNAMIC_CLASS(AnimListEditor, AtlasDialog); - -AnimListEditor::AnimListEditor() - : AtlasDialog(NULL, _("Animation editor"), wxSize(480, 280)) +AnimListEditor::AnimListEditor(wxWindow* parent) + : AtlasDialog(parent, _("Animation editor"), wxSize(480, 280)) { m_MainListBox = new AnimListEditorListCtrl(m_MainPanel); diff --git a/source/tools/atlas/AtlasUI/ActorEditor/AnimListEditor.h b/source/tools/atlas/AtlasUI/ActorEditor/AnimListEditor.h index b761615d6a..2b8ab095ae 100644 --- a/source/tools/atlas/AtlasUI/ActorEditor/AnimListEditor.h +++ b/source/tools/atlas/AtlasUI/ActorEditor/AnimListEditor.h @@ -8,10 +8,9 @@ class AnimListEditorListCtrl; class AnimListEditor : public AtlasDialog { - DECLARE_DYNAMIC_CLASS(AnimListEditor); - public: - AnimListEditor(); + AnimListEditor(wxWindow* parent); + static AtlasDialog* Create(wxWindow* parent) { return new AnimListEditor(parent); } protected: AtObj FreezeData(); diff --git a/source/tools/atlas/AtlasUI/ActorEditor/PropListEditor.cpp b/source/tools/atlas/AtlasUI/ActorEditor/PropListEditor.cpp index e269b18dff..bf52a54411 100644 --- a/source/tools/atlas/AtlasUI/ActorEditor/PropListEditor.cpp +++ b/source/tools/atlas/AtlasUI/ActorEditor/PropListEditor.cpp @@ -7,10 +7,8 @@ ////////////////////////////////////////////////////////////////////////// -IMPLEMENT_DYNAMIC_CLASS(PropListEditor, AtlasDialog); - -PropListEditor::PropListEditor() - : AtlasDialog(NULL, _("Prop editor"), wxSize(400, 280)) +PropListEditor::PropListEditor(wxWindow* parent) + : AtlasDialog(parent, _("Prop editor"), wxSize(400, 280)) { m_MainListBox = new PropListEditorListCtrl(m_MainPanel); diff --git a/source/tools/atlas/AtlasUI/ActorEditor/PropListEditor.h b/source/tools/atlas/AtlasUI/ActorEditor/PropListEditor.h index 51dd3bbb6f..5d41f9e567 100644 --- a/source/tools/atlas/AtlasUI/ActorEditor/PropListEditor.h +++ b/source/tools/atlas/AtlasUI/ActorEditor/PropListEditor.h @@ -8,10 +8,9 @@ class PropListEditorListCtrl; class PropListEditor : public AtlasDialog { - DECLARE_DYNAMIC_CLASS(PropListEditor); - public: - PropListEditor(); + PropListEditor(wxWindow* parent); + static AtlasDialog* Create(wxWindow* parent) { return new PropListEditor(parent); } protected: AtObj FreezeData(); diff --git a/source/tools/atlas/AtlasUI/ActorViewer/ActorViewer.cpp b/source/tools/atlas/AtlasUI/ActorViewer/ActorViewer.cpp index f99d8ab085..e9f9433a93 100644 --- a/source/tools/atlas/AtlasUI/ActorViewer/ActorViewer.cpp +++ b/source/tools/atlas/AtlasUI/ActorViewer/ActorViewer.cpp @@ -12,6 +12,8 @@ #include "CustomControls/Canvas/Canvas.h" #include "CustomControls/SnapSplitterWindow/SnapSplitterWindow.h" +#include "ActorEditor/ActorEditor.h" + using namespace AtlasMessage; ////////////////////////////////////////////////////////////////////////// @@ -102,6 +104,7 @@ enum ID_Play, ID_Pause, ID_Slow, + ID_Edit }; BEGIN_EVENT_TABLE(ActorViewer, wxFrame) @@ -112,6 +115,7 @@ BEGIN_EVENT_TABLE(ActorViewer, wxFrame) EVT_BUTTON(ID_Play, ActorViewer::OnSpeedButton) EVT_BUTTON(ID_Pause, ActorViewer::OnSpeedButton) EVT_BUTTON(ID_Slow, ActorViewer::OnSpeedButton) + EVT_BUTTON(ID_Edit, ActorViewer::OnEditButton) END_EVENT_TABLE() static void SendToGame(const AtlasMessage::sEnvironmentSettings& settings) @@ -219,7 +223,7 @@ ActorViewer::ActorViewer(wxWindow* parent) m_EnvironmentSettings.terraincolour = Colour(164, 164, 164); m_EnvironmentSettings.unitcolour = Colour(164, 164, 164); LightControl* lightControl = new LightControl(sidePanel, wxSize(100, 100), m_EnvironmentSettings); - m_Conn = m_EnvironmentSettings.RegisterObserver(0, &SendToGame); + m_EnvConn = m_EnvironmentSettings.RegisterObserver(0, &SendToGame); SendToGame(m_EnvironmentSettings); wxSizer* mainSizer = new wxBoxSizer(wxVERTICAL); @@ -239,6 +243,9 @@ ActorViewer::ActorViewer(wxWindow* parent) bottomRightSizer->Add(m_AnimationBox, wxSizerFlags().Expand()); bottomRightSizer->Add(playButtonSizer, wxSizerFlags().Expand()); + + bottomRightSizer->Add(new wxButton(sidePanel, ID_Edit, _("Edit actor")), wxSizerFlags().Expand()); + sidePanel->SetSizer(mainSizer); ////////////////////////////////////////////////////////////////////////// @@ -261,9 +268,9 @@ void ActorViewer::OnClose(wxCloseEvent& WXUNUSED(event)) Destroy(); } -void ActorViewer::SetActorView() +void ActorViewer::SetActorView(bool flushCache) { - POST_MESSAGE(SetActorViewer, (m_CurrentActor.c_str(), m_AnimationBox->GetValue().c_str(), m_CurrentSpeed)); + POST_MESSAGE(SetActorViewer, (m_CurrentActor.c_str(), m_AnimationBox->GetValue().c_str(), m_CurrentSpeed, flushCache)); } void ActorViewer::OnTreeSelection(wxTreeEvent& event) @@ -296,4 +303,23 @@ void ActorViewer::OnSpeedButton(wxCommandEvent& event) } SetActorView(); -} \ No newline at end of file +} + +void ActorViewer::OnActorEdited() +{ + SetActorView(true); +} + +void ActorViewer::OnEditButton(wxCommandEvent& WXUNUSED(event)) +{ + wxFileName dir (_T("mods/official/art/actors/") + m_CurrentActor, wxPATH_UNIX); + dir.MakeAbsolute(Datafile::GetDataDirectory()); + + ActorEditor* ed = new ActorEditor(NULL); + ed->OpenFile(dir.GetFullPath()); + ed->Show(); + + m_ActorConns.Add(ed->sig_FileSaved.connect( + boost::bind(std::mem_fun(&ActorViewer::OnActorEdited), this) + )); +} diff --git a/source/tools/atlas/AtlasUI/ActorViewer/ActorViewer.h b/source/tools/atlas/AtlasUI/ActorViewer/ActorViewer.h index 1a710bbf42..6b68246529 100644 --- a/source/tools/atlas/AtlasUI/ActorViewer/ActorViewer.h +++ b/source/tools/atlas/AtlasUI/ActorViewer/ActorViewer.h @@ -11,11 +11,15 @@ public: ActorViewer(wxWindow* parent); private: - void SetActorView(); + void SetActorView(bool flushCache = false); void OnClose(wxCloseEvent& event); void OnTreeSelection(wxTreeEvent& event); void OnAnimationSelection(wxCommandEvent& event); void OnSpeedButton(wxCommandEvent& event); + void OnEditButton(wxCommandEvent& event); + + void OnActorEdited(); + ObservableScopedConnections m_ActorConns; wxTreeCtrl* m_TreeCtrl; wxComboBox* m_AnimationBox; @@ -23,7 +27,7 @@ private: float m_CurrentSpeed; Observable m_EnvironmentSettings; - ObservableScopedConnection m_Conn; + ObservableScopedConnection m_EnvConn; DECLARE_EVENT_TABLE(); }; diff --git a/source/tools/atlas/AtlasUI/CustomControls/DraggableListCtrl/DraggableListCtrl.h b/source/tools/atlas/AtlasUI/CustomControls/DraggableListCtrl/DraggableListCtrl.h index fbf00ff0e9..29e26d3ac6 100644 --- a/source/tools/atlas/AtlasUI/CustomControls/DraggableListCtrl/DraggableListCtrl.h +++ b/source/tools/atlas/AtlasUI/CustomControls/DraggableListCtrl/DraggableListCtrl.h @@ -1,3 +1,6 @@ +#ifndef DRAGGABLELISTCTRL_H__ +#define DRAGGABLELISTCTRL_H__ + /* DraggableListCtrl @@ -35,3 +38,5 @@ private: DECLARE_EVENT_TABLE(); }; + +#endif // DRAGGABLELISTCTRL_H__ diff --git a/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/FieldEditCtrl.cpp b/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/FieldEditCtrl.cpp index a3341507c7..983ba6780d 100644 --- a/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/FieldEditCtrl.cpp +++ b/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/FieldEditCtrl.cpp @@ -81,14 +81,14 @@ void FieldEditCtrl_List::StartEdit(wxWindow* parent, wxRect rect, long row, int ////////////////////////////////////////////////////////////////////////// -FieldEditCtrl_Dialog::FieldEditCtrl_Dialog(const wxString& dialogType) - : m_DialogType(dialogType) +FieldEditCtrl_Dialog::FieldEditCtrl_Dialog(AtlasDialog* (*dialogCtor)(wxWindow*)) + : m_DialogCtor(dialogCtor) { } void FieldEditCtrl_Dialog::StartEdit(wxWindow* parent, wxRect WXUNUSED(rect), long row, int col) { - AtlasDialog* dialog = wxDynamicCast(wxCreateDynamicObject(m_DialogType), AtlasDialog); + AtlasDialog* dialog = m_DialogCtor(parent); wxCHECK2(dialog, return); dialog->SetParent(parent); diff --git a/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/FieldEditCtrl.h b/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/FieldEditCtrl.h index b3695b3bb3..19974c1e1b 100644 --- a/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/FieldEditCtrl.h +++ b/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/FieldEditCtrl.h @@ -1,4 +1,8 @@ +#ifndef FIELDEDITCTRL_H__ +#define FIELDEDITCTRL_H__ + class EditableListCtrl; +class AtlasDialog; class FieldEditCtrl { @@ -47,13 +51,13 @@ private: class FieldEditCtrl_Dialog : public FieldEditCtrl { public: - FieldEditCtrl_Dialog(const wxString& dialogType); + FieldEditCtrl_Dialog(AtlasDialog* (*dialogCtor)(wxWindow*)); protected: void StartEdit(wxWindow* parent, wxRect rect, long row, int col); private: - wxString m_DialogType; + AtlasDialog* (*m_DialogCtor)(wxWindow*); }; ////////////////////////////////////////////////////////////////////////// @@ -73,3 +77,5 @@ private: wxString m_FileMask; wxString m_RememberedDir; }; + +#endif // FIELDEDITCTRL_H__ diff --git a/source/tools/atlas/AtlasUI/CustomControls/Windows/AtlasDialog.h b/source/tools/atlas/AtlasUI/CustomControls/Windows/AtlasDialog.h index 4bebf42e7f..d690a008b7 100644 --- a/source/tools/atlas/AtlasUI/CustomControls/Windows/AtlasDialog.h +++ b/source/tools/atlas/AtlasUI/CustomControls/Windows/AtlasDialog.h @@ -1,3 +1,6 @@ +#ifndef ATLASDIALOG_H__ +#define ATLASDIALOG_H__ + #include "wx/dialog.h" #include "General/AtlasWindowCommandProc.h" @@ -28,3 +31,5 @@ private: DECLARE_EVENT_TABLE() }; + +#endif // ATLASDIALOG_H__ diff --git a/source/tools/atlas/AtlasUI/CustomControls/Windows/AtlasWindow.cpp b/source/tools/atlas/AtlasUI/CustomControls/Windows/AtlasWindow.cpp index 7a770d4166..8ad4a08355 100644 --- a/source/tools/atlas/AtlasUI/CustomControls/Windows/AtlasWindow.cpp +++ b/source/tools/atlas/AtlasUI/CustomControls/Windows/AtlasWindow.cpp @@ -265,10 +265,12 @@ bool AtlasWindow::SaveChanges(bool forceSaveAs) AtlasObject::SaveToXML(file, GetCurrentFilename().GetFullPath()); + sig_FileSaved(); + return true; } -bool AtlasWindow::OpenFile(wxString filename) +bool AtlasWindow::OpenFile(const wxString& filename) { AtObj file (AtlasObject::LoadFromXML(filename)); // TODO: Make sure it succeeded. diff --git a/source/tools/atlas/AtlasUI/CustomControls/Windows/AtlasWindow.h b/source/tools/atlas/AtlasUI/CustomControls/Windows/AtlasWindow.h index 3e39ad696b..7958bef4b2 100644 --- a/source/tools/atlas/AtlasUI/CustomControls/Windows/AtlasWindow.h +++ b/source/tools/atlas/AtlasUI/CustomControls/Windows/AtlasWindow.h @@ -34,6 +34,8 @@ public: AtlasWindow(wxWindow* parent, const wxString& title, const wxSize& size); + boost::signal sig_FileSaved; + private: void OnNew(wxCommandEvent& event); @@ -63,7 +65,7 @@ protected: bool SaveChanges(bool forceSaveAs); public: - bool OpenFile(wxString filename); + bool OpenFile(const wxString& filename); private: AtlasWindowCommandProc m_CommandProc; diff --git a/source/tools/atlas/AtlasUI/General/Observable.cpp b/source/tools/atlas/AtlasUI/General/Observable.cpp new file mode 100644 index 0000000000..1f001f4272 --- /dev/null +++ b/source/tools/atlas/AtlasUI/General/Observable.cpp @@ -0,0 +1,22 @@ +#include "stdafx.h" + +#include "Observable.h" + +void ObservableScopedConnections::Add(const ObservableConnection& conn) +{ + // Clean up any disconnected connections that might be left in here + m_Conns.erase( + remove_if(m_Conns.begin(), m_Conns.end(), + not1(std::mem_fun_ref(&ObservableConnection::connected))), + m_Conns.end() + ); + + // Add the new connection + m_Conns.push_back(conn); +} + +ObservableScopedConnections::~ObservableScopedConnections() +{ + // Disconnect all connections that we hold + for_each(m_Conns.begin(), m_Conns.end(), std::mem_fun_ref(&ObservableConnection::disconnect)); +} diff --git a/source/tools/atlas/AtlasUI/General/Observable.h b/source/tools/atlas/AtlasUI/General/Observable.h index 23f610c60a..d9d9f39130 100644 --- a/source/tools/atlas/AtlasUI/General/Observable.h +++ b/source/tools/atlas/AtlasUI/General/Observable.h @@ -1,6 +1,27 @@ #ifndef OBSERVABLE_H__ #define OBSERVABLE_H__ +/* +Wrapper around Boost.Signals to make watching objects for changes more convenient. + +General usage: + +Observable variable_to_be_watched; +... +class Thing { + ObservableScopedConnection m_Conn; + Thing() { + m_Conn = variable_to_be_watched.RegisterObserver(OnChange); + } + void OnChange(const int& var) { + do_something_with(var); + } +} +... +variable_to_be_watched.NotifyObservers(); + +*/ + #include #include @@ -59,4 +80,13 @@ private: boost::signal m_Signal; }; +class ObservableScopedConnections +{ +public: + void Add(const ObservableConnection& conn); + ~ObservableScopedConnections(); +private: + std::vector m_Conns; +}; + #endif // OBSERVABLE_H__ diff --git a/source/tools/atlas/AtlasUI/Misc/DLLInterface.cpp b/source/tools/atlas/AtlasUI/Misc/DLLInterface.cpp index e269c17a48..ac9eecef67 100644 --- a/source/tools/atlas/AtlasUI/Misc/DLLInterface.cpp +++ b/source/tools/atlas/AtlasUI/Misc/DLLInterface.cpp @@ -92,6 +92,9 @@ ATLASDLLIMPEXP void Atlas_DisplayError(const wchar_t* text, unsigned int WXUNUSE // is still running and won't block before showing the dialog to the user) // and where it matters (i.e. errors, not warnings (unless they're going to // turn into errors after continuing)) + + // TODO: 'text' (or at least some copy of it) appears to get leaked when + // this function is called } class AtlasDLLApp : public wxApp @@ -100,6 +103,8 @@ public: virtual bool OnInit() { +// _CrtSetBreakAlloc(5632); + if (! wxIsDebuggerRunning()) wxHandleFatalExceptions(); diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Environment/Environment.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Environment/Environment.cpp index 578ba50abc..abd124b3f7 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Environment/Environment.cpp +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Environment/Environment.cpp @@ -190,7 +190,7 @@ EnvironmentSidebar::EnvironmentSidebar(wxWindow* sidebarContainer, wxWindow* bot m_MainSizer->Add(waterSizer, wxSizerFlags().Expand()); waterSizer->Add(new VariableSliderBox(this, _("Water height"), g_EnvironmentSettings.waterheight, 0.f, 1.2f), wxSizerFlags().Expand()); - waterSizer->Add(new VariableSliderBox(this, _("Water shininess"), g_EnvironmentSettings.watershininess, 0.f, 500.f), wxSizerFlags().Expand()); + waterSizer->Add(new VariableSliderBox(this, _("Water shininess"), g_EnvironmentSettings.watershininess, 0.f, 250.f), wxSizerFlags().Expand()); waterSizer->Add(new VariableSliderBox(this, _("Water waviness"), g_EnvironmentSettings.waterwaviness, 0.f, 10.f), wxSizerFlags().Expand()); waterSizer->Add(new VariableSliderBox(this, _("Water murkiness"), g_EnvironmentSettings.watermurkiness, 0.f, 1.f), wxSizerFlags().Expand()); diff --git a/source/tools/atlas/GameInterface/ActorViewer.cpp b/source/tools/atlas/GameInterface/ActorViewer.cpp index 755a51c566..9f53281645 100644 --- a/source/tools/atlas/GameInterface/ActorViewer.cpp +++ b/source/tools/atlas/GameInterface/ActorViewer.cpp @@ -34,7 +34,6 @@ ActorViewer::ActorViewer() // Set up the renderer g_TexMan.LoadTerrainTextures(); - g_ObjMan.LoadObjects(); g_Renderer.LoadAlphaMaps(); // (TODO: should these be unloaded properly some time? and what should // happen if we want the actor viewer and scenario editor loaded at diff --git a/source/tools/atlas/GameInterface/Handlers/GraphicsSetupHandlers.cpp b/source/tools/atlas/GameInterface/Handlers/GraphicsSetupHandlers.cpp index c9fcaa1444..0b87eb6d03 100644 --- a/source/tools/atlas/GameInterface/Handlers/GraphicsSetupHandlers.cpp +++ b/source/tools/atlas/GameInterface/Handlers/GraphicsSetupHandlers.cpp @@ -6,16 +6,17 @@ #include "../ActorViewer.h" #include "../View.h" -#include "renderer/Renderer.h" #include "graphics/GameView.h" -#include "gui/GUIbase.h" +#include "graphics/ObjectManager.h" #include "gui/CGUI.h" +#include "gui/GUIbase.h" +#include "lib/res/file/vfs.h" +#include "maths/MathUtil.h" #include "ps/CConsole.h" #include "ps/Game.h" -#include "maths/MathUtil.h" - #include "ps/GameSetup/Config.h" #include "ps/GameSetup/GameSetup.h" +#include "renderer/Renderer.h" namespace AtlasMessage { @@ -81,6 +82,18 @@ MESSAGEHANDLER(RenderEnable) MESSAGEHANDLER(SetActorViewer) { + if (msg->flushcache) + { + // TODO EXTREME DANGER: this'll break horribly if any units remain + // in existence and use their actors after we've deleted all the actors. + // (The actor viewer currently only has one unit at a time, so it's + // alright.) + // Should replace this with proper actor hot-loading system, or something. + + View::GetView_Actor()->GetActorViewer().SetActor(L"", L""); + g_ObjMan.UnloadObjects(); + vfs_reload_changed_files(); + } View::GetView_Actor()->SetSpeedMultiplier(msg->speed); View::GetView_Actor()->GetActorViewer().SetActor(*msg->id, *msg->animation); } diff --git a/source/tools/atlas/GameInterface/Messages.h b/source/tools/atlas/GameInterface/Messages.h index 221ca23248..01f6388957 100644 --- a/source/tools/atlas/GameInterface/Messages.h +++ b/source/tools/atlas/GameInterface/Messages.h @@ -154,6 +154,7 @@ MESSAGE(SetActorViewer, ((std::wstring, id)) ((std::wstring, animation)) ((float, speed)) + ((bool, flushcache)) // true => unload all actor files before starting the preview (because we don't have proper hotloading yet) ); //////////////////////////////////////////////////////////////////////////