X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fnetradiant.git;a=blobdiff_plain;f=radiant%2Fmap.cpp;h=147cfa98762e7842f734be9f8fdedbc02e839b1f;hp=3e5e8128ab1d978d03a0f25a80dd6dfc13946cde;hb=8e101344b9dcd19bd091b3bb75bce0ef717386c0;hpb=a4f89fe0f831b3ffe403dfc077e2d364677118c4 diff --git a/radiant/map.cpp b/radiant/map.cpp index 3e5e8128..147cfa98 100644 --- a/radiant/map.cpp +++ b/radiant/map.cpp @@ -1,29 +1,30 @@ /* -Copyright (C) 1999-2006 Id Software, Inc. and contributors. -For a list of contributors, see the accompanying CONTRIBUTORS file. + Copyright (C) 1999-2006 Id Software, Inc. and contributors. + For a list of contributors, see the accompanying CONTRIBUTORS file. -This file is part of GtkRadiant. + This file is part of GtkRadiant. -GtkRadiant 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 2 of the License, or -(at your option) any later version. + GtkRadiant 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 2 of the License, or + (at your option) any later version. -GtkRadiant 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. + GtkRadiant 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 GtkRadiant; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + You should have received a copy of the GNU General Public License + along with GtkRadiant; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ #include "map.h" #include "debugging/debugging.h" #include "imap.h" +MapModules& ReferenceAPI_getMapModules(); #include "iselection.h" #include "iundo.h" #include "ibrush.h" @@ -34,6 +35,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "irender.h" #include "ientity.h" #include "editable.h" +#include "iarchive.h" #include "ifilesystem.h" #include "namespace.h" #include "moduleobserver.h" @@ -79,128 +81,116 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "xywindow.h" #include "mainframe.h" #include "preferences.h" +#include "preferencesystem.h" #include "referencecache.h" #include "mru.h" #include "commands.h" #include "autosave.h" +#include "brushmodule.h" +#include "brush.h" class NameObserver { - UniqueNames& m_names; - CopiedString m_name; - - void construct() - { - if(!empty()) - { - //globalOutputStream() << "construct " << makeQuoted(c_str()) << "\n"; - m_names.insert(name_read(c_str())); - } - } - void destroy() - { - if(!empty()) - { - //globalOutputStream() << "destroy " << makeQuoted(c_str()) << "\n"; - m_names.erase(name_read(c_str())); - } - } - - NameObserver& operator=(const NameObserver& other); +UniqueNames& m_names; +CopiedString m_name; + +void construct(){ + if ( !empty() ) { + //globalOutputStream() << "construct " << makeQuoted(c_str()) << "\n"; + m_names.insert( name_read( c_str() ) ); + } +} +void destroy(){ + if ( !empty() ) { + //globalOutputStream() << "destroy " << makeQuoted(c_str()) << "\n"; + m_names.erase( name_read( c_str() ) ); + } +} + +NameObserver& operator=( const NameObserver& other ); public: - NameObserver(UniqueNames& names) : m_names(names) - { - construct(); - } - NameObserver(const NameObserver& other) : m_names(other.m_names), m_name(other.m_name) - { - construct(); - } - ~NameObserver() - { - destroy(); - } - bool empty() const - { - return string_empty(c_str()); - } - const char* c_str() const - { - return m_name.c_str(); - } - void nameChanged(const char* name) - { - destroy(); - m_name = name; - construct(); - } - typedef MemberCaller1 NameChangedCaller; +NameObserver( UniqueNames& names ) : m_names( names ){ + construct(); +} +NameObserver( const NameObserver& other ) : m_names( other.m_names ), m_name( other.m_name ){ + construct(); +} +~NameObserver(){ + destroy(); +} +bool empty() const { + return string_empty( c_str() ); +} +const char* c_str() const { + return m_name.c_str(); +} +void nameChanged( const char* name ){ + destroy(); + m_name = name; + construct(); +} +typedef MemberCaller1 NameChangedCaller; }; class BasicNamespace : public Namespace { - typedef std::map Names; - Names m_names; - UniqueNames m_uniqueNames; +typedef std::map Names; +Names m_names; +UniqueNames m_uniqueNames; public: - ~BasicNamespace() - { - ASSERT_MESSAGE(m_names.empty(), "namespace: names still registered at shutdown"); - } - void attach(const NameCallback& setName, const NameCallbackCallback& attachObserver) - { - std::pair result = m_names.insert(Names::value_type(setName, m_uniqueNames)); - ASSERT_MESSAGE(result.second, "cannot attach name"); - attachObserver(NameObserver::NameChangedCaller((*result.first).second)); - //globalOutputStream() << "attach: " << reinterpret_cast(setName) << "\n"; - } - void detach(const NameCallback& setName, const NameCallbackCallback& detachObserver) - { - Names::iterator i = m_names.find(setName); - ASSERT_MESSAGE(i != m_names.end(), "cannot detach name"); - //globalOutputStream() << "detach: " << reinterpret_cast(setName) << "\n"; - detachObserver(NameObserver::NameChangedCaller((*i).second)); - m_names.erase(i); - } - - void makeUnique(const char* name, const NameCallback& setName) const - { - char buffer[1024]; - name_write(buffer, m_uniqueNames.make_unique(name_read(name))); - setName(buffer); - } - - void mergeNames(const BasicNamespace& other) const - { - typedef std::list SetNameCallbacks; - typedef std::map NameGroups; - NameGroups groups; - - UniqueNames uniqueNames(other.m_uniqueNames); - - for(Names::const_iterator i = m_names.begin(); i != m_names.end(); ++i) - { - groups[(*i).second.c_str()].push_back((*i).first); - } - - for(NameGroups::iterator i = groups.begin(); i != groups.end(); ++i) - { - name_t uniqueName(uniqueNames.make_unique(name_read((*i).first.c_str()))); - uniqueNames.insert(uniqueName); - - char buffer[1024]; - name_write(buffer, uniqueName); - - //globalOutputStream() << "renaming " << makeQuoted((*i).first.c_str()) << " to " << makeQuoted(buffer) << "\n"; - - SetNameCallbacks& setNameCallbacks = (*i).second; - - for(SetNameCallbacks::const_iterator j = setNameCallbacks.begin(); j != setNameCallbacks.end(); ++j) - { - (*j)(buffer); - } - } - } +~BasicNamespace(){ + ASSERT_MESSAGE( m_names.empty(), "namespace: names still registered at shutdown" ); +} +void attach( const NameCallback& setName, const NameCallbackCallback& attachObserver ){ + std::pair result = m_names.insert( Names::value_type( setName, m_uniqueNames ) ); + ASSERT_MESSAGE( result.second, "cannot attach name" ); + attachObserver( NameObserver::NameChangedCaller( ( *result.first ).second ) ); + //globalOutputStream() << "attach: " << reinterpret_cast(setName) << "\n"; +} +void detach( const NameCallback& setName, const NameCallbackCallback& detachObserver ){ + Names::iterator i = m_names.find( setName ); + ASSERT_MESSAGE( i != m_names.end(), "cannot detach name" ); + //globalOutputStream() << "detach: " << reinterpret_cast(setName) << "\n"; + detachObserver( NameObserver::NameChangedCaller( ( *i ).second ) ); + m_names.erase( i ); +} + +void makeUnique( const char* name, const NameCallback& setName ) const { + char buffer[1024]; + name_write( buffer, m_uniqueNames.make_unique( name_read( name ) ) ); + setName( buffer ); +} + +void mergeNames( const BasicNamespace& other ) const { + typedef std::list SetNameCallbacks; + typedef std::map NameGroups; + NameGroups groups; + + UniqueNames uniqueNames( other.m_uniqueNames ); + + for ( Names::const_iterator i = m_names.begin(); i != m_names.end(); ++i ) + { + groups[( *i ).second.c_str()].push_back( ( *i ).first ); + } + + for ( NameGroups::iterator i = groups.begin(); i != groups.end(); ++i ) + { + name_t uniqueName( uniqueNames.make_unique( name_read( ( *i ).first.c_str() ) ) ); + uniqueNames.insert( uniqueName ); + + char buffer[1024]; + name_write( buffer, uniqueName ); + + //globalOutputStream() << "renaming " << makeQuoted((*i).first.c_str()) << " to " << makeQuoted(buffer) << "\n"; + + SetNameCallbacks& setNameCallbacks = ( *i ).second; + + for ( SetNameCallbacks::const_iterator j = setNameCallbacks.begin(); j != setNameCallbacks.end(); ++j ) + { + ( *j )( buffer ); + } + } +} }; BasicNamespace g_defaultNamespace; @@ -208,315 +198,280 @@ BasicNamespace g_cloneNamespace; class NamespaceAPI { - Namespace* m_namespace; +Namespace* m_namespace; public: - typedef Namespace Type; - STRING_CONSTANT(Name, "*"); - - NamespaceAPI() - { - m_namespace = &g_defaultNamespace; - } - Namespace* getTable() - { - return m_namespace; - } +typedef Namespace Type; +STRING_CONSTANT( Name, "*" ); + +NamespaceAPI(){ + m_namespace = &g_defaultNamespace; +} +Namespace* getTable(){ + return m_namespace; +} }; typedef SingletonModule NamespaceModule; typedef Static StaticNamespaceModule; -StaticRegisterModule staticRegisterDefaultNamespace(StaticNamespaceModule::instance()); +StaticRegisterModule staticRegisterDefaultNamespace( StaticNamespaceModule::instance() ); std::list g_cloned; -inline Namespaced* Node_getNamespaced(scene::Node& node) -{ - return NodeTypeCast::cast(node); +inline Namespaced* Node_getNamespaced( scene::Node& node ){ + return NodeTypeCast::cast( node ); } -void Node_gatherNamespaced(scene::Node& node) -{ - Namespaced* namespaced = Node_getNamespaced(node); - if(namespaced != 0) - { - g_cloned.push_back(namespaced); - } +void Node_gatherNamespaced( scene::Node& node ){ + Namespaced* namespaced = Node_getNamespaced( node ); + if ( namespaced != 0 ) { + g_cloned.push_back( namespaced ); + } } class GatherNamespaced : public scene::Traversable::Walker { public: - bool pre(scene::Node& node) const - { - Node_gatherNamespaced(node); - return true; - } +bool pre( scene::Node& node ) const { + Node_gatherNamespaced( node ); + return true; +} }; -void Map_gatherNamespaced(scene::Node& root) -{ - Node_traverseSubgraph(root, GatherNamespaced()); +void Map_gatherNamespaced( scene::Node& root ){ + Node_traverseSubgraph( root, GatherNamespaced() ); } -void Map_mergeClonedNames() -{ - for(std::list::const_iterator i = g_cloned.begin(); i != g_cloned.end(); ++i) - { - (*i)->setNamespace(g_cloneNamespace); - } - g_cloneNamespace.mergeNames(g_defaultNamespace); - for(std::list::const_iterator i = g_cloned.begin(); i != g_cloned.end(); ++i) - { - (*i)->setNamespace(g_defaultNamespace); - } +void Map_mergeClonedNames(){ + for ( std::list::const_iterator i = g_cloned.begin(); i != g_cloned.end(); ++i ) + { + ( *i )->setNamespace( g_cloneNamespace ); + } + g_cloneNamespace.mergeNames( g_defaultNamespace ); + for ( std::list::const_iterator i = g_cloned.begin(); i != g_cloned.end(); ++i ) + { + ( *i )->setNamespace( g_defaultNamespace ); + } - g_cloned.clear(); + g_cloned.clear(); } class WorldNode { - scene::Node* m_node; +scene::Node* m_node; public: - WorldNode() - : m_node(0) - { - } - void set(scene::Node* node) - { - if(m_node != 0) - m_node->DecRef(); - m_node = node; - if(m_node != 0) - m_node->IncRef(); - } - scene::Node* get() const - { - return m_node; - } +WorldNode() + : m_node( 0 ){ +} +void set( scene::Node* node ){ + if ( m_node != 0 ) { + m_node->DecRef(); + } + m_node = node; + if ( m_node != 0 ) { + m_node->IncRef(); + } +} +scene::Node* get() const { + return m_node; +} }; class Map; -void Map_SetValid(Map& map, bool valid); -void Map_UpdateTitle(const Map& map); -void Map_SetWorldspawn(Map& map, scene::Node* node); +void Map_SetValid( Map& map, bool valid ); +void Map_UpdateTitle( const Map& map ); +void Map_SetWorldspawn( Map& map, scene::Node* node ); class Map : public ModuleObserver { public: - CopiedString m_name; - Resource* m_resource; - bool m_valid; - - bool m_modified; - void (*m_modified_changed)(const Map&); - - Signal0 m_mapValidCallbacks; - - WorldNode m_world_node; // "classname" "worldspawn" ! - - Map() : m_resource(0), m_valid(false), m_modified_changed(Map_UpdateTitle) - { - } - - void realise() - { - if(m_resource != 0) - { - if(Map_Unnamed(*this)) - { - g_map.m_resource->setNode(NewMapRoot("").get_pointer()); - MapFile* map = Node_getMapFile(*g_map.m_resource->getNode()); - if(map != 0) - { - map->save(); - } - } - else - { - m_resource->load(); - } - - GlobalSceneGraph().insert_root(*m_resource->getNode()); - - AutoSave_clear(); - - Map_SetValid(g_map, true); - } - } - void unrealise() - { - if(m_resource != 0) - { - Map_SetValid(g_map, false); - Map_SetWorldspawn(g_map, 0); - - - GlobalUndoSystem().clear(); - - GlobalSceneGraph().erase_root(); - } - } +CopiedString m_name; +Resource* m_resource; +bool m_valid; + +bool m_modified; +void ( *m_modified_changed )( const Map& ); + +Signal0 m_mapValidCallbacks; + +WorldNode m_world_node; // "classname" "worldspawn" ! + +Map() : m_resource( 0 ), m_valid( false ), m_modified_changed( Map_UpdateTitle ){ +} + +void realise(){ + if ( m_resource != 0 ) { + if ( Map_Unnamed( *this ) ) { + g_map.m_resource->setNode( NewMapRoot( "" ).get_pointer() ); + MapFile* map = Node_getMapFile( *g_map.m_resource->getNode() ); + if ( map != 0 ) { + map->save(); + } + } + else + { + m_resource->load(); + } + + GlobalSceneGraph().insert_root( *m_resource->getNode() ); + + AutoSave_clear(); + + Map_SetValid( g_map, true ); + } +} +void unrealise(){ + if ( m_resource != 0 ) { + Map_SetValid( g_map, false ); + Map_SetWorldspawn( g_map, 0 ); + + + GlobalUndoSystem().clear(); + + GlobalSceneGraph().erase_root(); + } +} }; Map g_map; Map* g_currentMap = 0; -void Map_addValidCallback(Map& map, const SignalHandler& handler) -{ - map.m_mapValidCallbacks.connectLast(handler); +void Map_addValidCallback( Map& map, const SignalHandler& handler ){ + map.m_mapValidCallbacks.connectLast( handler ); } -bool Map_Valid(const Map& map) -{ - return map.m_valid; +bool Map_Valid( const Map& map ){ + return map.m_valid; } -void Map_SetValid(Map& map, bool valid) -{ - map.m_valid = valid; - map.m_mapValidCallbacks(); +void Map_SetValid( Map& map, bool valid ){ + map.m_valid = valid; + map.m_mapValidCallbacks(); } -const char* Map_Name(const Map& map) -{ - return map.m_name.c_str(); +const char* Map_Name( const Map& map ){ + return map.m_name.c_str(); } -bool Map_Unnamed(const Map& map) -{ - return string_equal(Map_Name(map), "unnamed.map"); +bool Map_Unnamed( const Map& map ){ + return string_equal( Map_Name( map ), "unnamed.map" ); } -inline const MapFormat& MapFormat_forFile(const char* filename) -{ - const char* moduleName = findModuleName(GetFileTypeRegistry(), MapFormat::Name(), path_get_extension(filename)); - MapFormat* format = Radiant_getMapModules().findModule(moduleName); - ASSERT_MESSAGE(format != 0, "map format not found for file " << makeQuoted(filename)); - return *format; +inline const MapFormat& MapFormat_forFile( const char* filename ){ + const char* moduleName = findModuleName( GetFileTypeRegistry(), MapFormat::Name(), path_get_extension( filename ) ); + MapFormat* format = Radiant_getMapModules().findModule( moduleName ); + ASSERT_MESSAGE( format != 0, "map format not found for file " << makeQuoted( filename ) ); + return *format; } -const MapFormat& Map_getFormat(const Map& map) -{ - return MapFormat_forFile(Map_Name(map)); +const MapFormat& Map_getFormat( const Map& map ){ + return MapFormat_forFile( Map_Name( map ) ); } -bool Map_Modified(const Map& map) -{ - return map.m_modified; +bool Map_Modified( const Map& map ){ + return map.m_modified; } -void Map_SetModified(Map& map, bool modified) -{ - if(map.m_modified ^ modified) - { - map.m_modified = modified; +void Map_SetModified( Map& map, bool modified ){ + if ( map.m_modified ^ modified ) { + map.m_modified = modified; - map.m_modified_changed(map); - } + map.m_modified_changed( map ); + } } -void Map_UpdateTitle(const Map& map) -{ - Sys_SetTitle(map.m_name.c_str(), Map_Modified(map)); +void Map_UpdateTitle( const Map& map ){ + Sys_SetTitle( map.m_name.c_str(), Map_Modified( map ) ); } -scene::Node* Map_GetWorldspawn(const Map& map) -{ - return map.m_world_node.get(); +scene::Node* Map_GetWorldspawn( const Map& map ){ + return map.m_world_node.get(); } -void Map_SetWorldspawn(Map& map, scene::Node* node) -{ - map.m_world_node.set(node); +void Map_SetWorldspawn( Map& map, scene::Node* node ){ + map.m_world_node.set( node ); } // TTimo // need that in a variable, will have to tweak depending on the game -float g_MaxWorldCoord = 64*1024; -float g_MinWorldCoord = -64*1024; +float g_MaxWorldCoord = 64 * 1024; +float g_MinWorldCoord = -64 * 1024; + +void AddRegionBrushes( void ); +void RemoveRegionBrushes( void ); -void AddRegionBrushes (void); -void RemoveRegionBrushes (void); /* -================ -Map_Free -free all map elements, reinitialize the structures that depend on them -================ -*/ -void Map_Free() -{ + ================ + Map_Free + free all map elements, reinitialize the structures that depend on them + ================ + */ +void Map_Free(){ Pointfile_Clear(); - g_map.m_resource->detach(g_map); - GlobalReferenceCache().release(g_map.m_name.c_str()); - g_map.m_resource = 0; + g_map.m_resource->detach( g_map ); + GlobalReferenceCache().release( g_map.m_name.c_str() ); + g_map.m_resource = 0; - FlushReferences(); + FlushReferences(); - g_currentMap = 0; + g_currentMap = 0; + Brush_unlatchPreferences(); } class EntityFindByClassname : public scene::Graph::Walker { - const char* m_name; - Entity*& m_entity; +const char* m_name; +Entity*& m_entity; public: - EntityFindByClassname(const char* name, Entity*& entity) : m_name(name), m_entity(entity) - { - m_entity = 0; - } - bool pre(const scene::Path& path, scene::Instance& instance) const - { - if(m_entity == 0) - { - Entity* entity = Node_getEntity(path.top()); - if(entity != 0 - && string_equal(m_name, entity->getKeyValue("classname"))) - { - m_entity = entity; - } - } - return true; - } -}; - -Entity* Scene_FindEntityByClass(const char* name) -{ - Entity* entity; - GlobalSceneGraph().traverse(EntityFindByClassname(name, entity)); - return entity; +EntityFindByClassname( const char* name, Entity*& entity ) : m_name( name ), m_entity( entity ){ + m_entity = 0; +} +bool pre( const scene::Path& path, scene::Instance& instance ) const { + if ( m_entity == 0 ) { + Entity* entity = Node_getEntity( path.top() ); + if ( entity != 0 + && string_equal( m_name, entity->getKeyValue( "classname" ) ) ) { + m_entity = entity; + } + } + return true; } +}; -Entity *Scene_FindPlayerStart() -{ - typedef const char* StaticString; - StaticString strings[] = { - "info_player_start", - "info_player_deathmatch", - "team_CTF_redplayer", - "team_CTF_blueplayer", - "team_CTF_redspawn", - "team_CTF_bluespawn", - }; - typedef const StaticString* StaticStringIterator; - for(StaticStringIterator i = strings, end = strings+(sizeof(strings)/sizeof(StaticString)); i != end; ++i) - { - Entity* entity = Scene_FindEntityByClass(*i); - if(entity != 0) - { - return entity; - } - } - return 0; +Entity* Scene_FindEntityByClass( const char* name ){ + Entity* entity; + GlobalSceneGraph().traverse( EntityFindByClassname( name, entity ) ); + return entity; +} + +Entity *Scene_FindPlayerStart(){ + typedef const char* StaticString; + StaticString strings[] = { + "info_player_start", + "info_player_deathmatch", + "team_CTF_redplayer", + "team_CTF_blueplayer", + "team_CTF_redspawn", + "team_CTF_bluespawn", + }; + typedef const StaticString* StaticStringIterator; + for ( StaticStringIterator i = strings, end = strings + ( sizeof( strings ) / sizeof( StaticString ) ); i != end; ++i ) + { + Entity* entity = Scene_FindEntityByClass( *i ); + if ( entity != 0 ) { + return entity; + } + } + return 0; } // @@ -524,42 +479,38 @@ Entity *Scene_FindPlayerStart() // -void FocusViews(const Vector3& point, float angle) -{ - CamWnd& camwnd = *g_pParentWnd->GetCamWnd(); - Camera_setOrigin(camwnd, point); - Vector3 angles(Camera_getAngles(camwnd)); - angles[CAMERA_PITCH] = 0; - angles[CAMERA_YAW] = angle; - Camera_setAngles(camwnd, angles); +void FocusViews( const Vector3& point, float angle ){ + CamWnd& camwnd = *g_pParentWnd->GetCamWnd(); + Camera_setOrigin( camwnd, point ); + Vector3 angles( Camera_getAngles( camwnd ) ); + angles[CAMERA_PITCH] = 0; + angles[CAMERA_YAW] = angle; + Camera_setAngles( camwnd, angles ); - XYWnd* xywnd = g_pParentWnd->GetXYWnd(); - xywnd->SetOrigin(point); + XYWnd* xywnd = g_pParentWnd->GetXYWnd(); + xywnd->SetOrigin( point ); } #include "stringio.h" -void Map_StartPosition() -{ - Entity* entity = Scene_FindPlayerStart(); +void Map_StartPosition(){ + Entity* entity = Scene_FindPlayerStart(); - if (entity) - { - Vector3 origin; - string_parse_vector3(entity->getKeyValue("origin"), origin); - FocusViews(origin, string_read_float(entity->getKeyValue("angle"))); - } - else - { - FocusViews(g_vector3_identity, 0); - } + if ( entity ) { + Vector3 origin; + string_parse_vector3( entity->getKeyValue( "origin" ), origin ); + FocusViews( origin, string_read_float( entity->getKeyValue( "angle" ) ) ); + } + else + { + FocusViews( g_vector3_identity, 0 ); + } } -inline bool node_is_worldspawn(scene::Node& node) -{ - Entity* entity = Node_getEntity(node); - return entity != 0 && string_equal(entity->getKeyValue("classname"), "worldspawn"); +inline bool node_is_worldspawn( scene::Node& node ){ + Entity* entity = Node_getEntity( node ); + return entity != 0 && string_equal( entity->getKeyValue( "classname" ), "worldspawn" ); } @@ -567,260 +518,222 @@ inline bool node_is_worldspawn(scene::Node& node) class entity_updateworldspawn : public scene::Traversable::Walker { public: - bool pre(scene::Node& node) const - { - if(node_is_worldspawn(node)) - { - if(Map_GetWorldspawn(g_map) == 0) - { - Map_SetWorldspawn(g_map, &node); - } - } - return false; - } +bool pre( scene::Node& node ) const { + if ( node_is_worldspawn( node ) ) { + if ( Map_GetWorldspawn( g_map ) == 0 ) { + Map_SetWorldspawn( g_map, &node ); + } + } + return false; +} }; -scene::Node* Map_FindWorldspawn(Map& map) -{ - Map_SetWorldspawn(map, 0); +scene::Node* Map_FindWorldspawn( Map& map ){ + Map_SetWorldspawn( map, 0 ); - Node_getTraversable(GlobalSceneGraph().root())->traverse(entity_updateworldspawn()); + Node_getTraversable( GlobalSceneGraph().root() )->traverse( entity_updateworldspawn() ); - return Map_GetWorldspawn(map); + return Map_GetWorldspawn( map ); } class CollectAllWalker : public scene::Traversable::Walker { - scene::Node& m_root; - UnsortedNodeSet& m_nodes; +scene::Node& m_root; +UnsortedNodeSet& m_nodes; public: - CollectAllWalker(scene::Node& root, UnsortedNodeSet& nodes) : m_root(root), m_nodes(nodes) - { - } - bool pre(scene::Node& node) const - { - m_nodes.insert(NodeSmartReference(node)); - Node_getTraversable(m_root)->erase(node); - return false; - } +CollectAllWalker( scene::Node& root, UnsortedNodeSet& nodes ) : m_root( root ), m_nodes( nodes ){ +} +bool pre( scene::Node& node ) const { + m_nodes.insert( NodeSmartReference( node ) ); + Node_getTraversable( m_root )->erase( node ); + return false; +} }; -void Node_insertChildFirst(scene::Node& parent, scene::Node& child) -{ - UnsortedNodeSet nodes; - Node_getTraversable(parent)->traverse(CollectAllWalker(parent, nodes)); - Node_getTraversable(parent)->insert(child); +void Node_insertChildFirst( scene::Node& parent, scene::Node& child ){ + UnsortedNodeSet nodes; + Node_getTraversable( parent )->traverse( CollectAllWalker( parent, nodes ) ); + Node_getTraversable( parent )->insert( child ); - for(UnsortedNodeSet::iterator i = nodes.begin(); i != nodes.end(); ++i) - { - Node_getTraversable(parent)->insert((*i)); - } + for ( UnsortedNodeSet::iterator i = nodes.begin(); i != nodes.end(); ++i ) + { + Node_getTraversable( parent )->insert( ( *i ) ); + } } -scene::Node& createWorldspawn() -{ - NodeSmartReference worldspawn(GlobalEntityCreator().createEntity(GlobalEntityClassManager().findOrInsert("worldspawn", true))); - Node_insertChildFirst(GlobalSceneGraph().root(), worldspawn); - return worldspawn; +scene::Node& createWorldspawn(){ + NodeSmartReference worldspawn( GlobalEntityCreator().createEntity( GlobalEntityClassManager().findOrInsert( "worldspawn", true ) ) ); + Node_insertChildFirst( GlobalSceneGraph().root(), worldspawn ); + return worldspawn; } -void Map_UpdateWorldspawn(Map& map) -{ - if(Map_FindWorldspawn(map) == 0) - { - Map_SetWorldspawn(map, &createWorldspawn()); - } +void Map_UpdateWorldspawn( Map& map ){ + if ( Map_FindWorldspawn( map ) == 0 ) { + Map_SetWorldspawn( map, &createWorldspawn() ); + } } -scene::Node& Map_FindOrInsertWorldspawn(Map& map) -{ - Map_UpdateWorldspawn(map); - return *Map_GetWorldspawn(map); +scene::Node& Map_FindOrInsertWorldspawn( Map& map ){ + Map_UpdateWorldspawn( map ); + return *Map_GetWorldspawn( map ); } class MapMergeAll : public scene::Traversable::Walker { - mutable scene::Path m_path; +mutable scene::Path m_path; public: - MapMergeAll(const scene::Path& root) - : m_path(root) - { - } - bool pre(scene::Node& node) const - { - Node_getTraversable(m_path.top())->insert(node); - m_path.push(makeReference(node)); - selectPath(m_path, true); - return false; - } - void post(scene::Node& node) const - { - m_path.pop(); - } +MapMergeAll( const scene::Path& root ) + : m_path( root ){ +} +bool pre( scene::Node& node ) const { + Node_getTraversable( m_path.top() )->insert( node ); + m_path.push( makeReference( node ) ); + selectPath( m_path, true ); + return false; +} +void post( scene::Node& node ) const { + m_path.pop(); +} }; class MapMergeEntities : public scene::Traversable::Walker { - mutable scene::Path m_path; +mutable scene::Path m_path; public: - MapMergeEntities(const scene::Path& root) - : m_path(root) - { - } - bool pre(scene::Node& node) const - { - if(node_is_worldspawn(node)) - { - scene::Node* world_node = Map_FindWorldspawn(g_map); - if(world_node == 0) - { - Map_SetWorldspawn(g_map, &node); - Node_getTraversable(m_path.top().get())->insert(node); - m_path.push(makeReference(node)); - Node_getTraversable(node)->traverse(SelectChildren(m_path)); - } - else - { - m_path.push(makeReference(*world_node)); - Node_getTraversable(node)->traverse(MapMergeAll(m_path)); - } - } - else - { - Node_getTraversable(m_path.top())->insert(node); - m_path.push(makeReference(node)); - if(node_is_group(node)) - { - Node_getTraversable(node)->traverse(SelectChildren(m_path)); - } - else - { - selectPath(m_path, true); - } - } - return false; - } - void post(scene::Node& node) const - { - m_path.pop(); - } +MapMergeEntities( const scene::Path& root ) + : m_path( root ){ +} +bool pre( scene::Node& node ) const { + if ( node_is_worldspawn( node ) ) { + scene::Node* world_node = Map_FindWorldspawn( g_map ); + if ( world_node == 0 ) { + Map_SetWorldspawn( g_map, &node ); + Node_getTraversable( m_path.top().get() )->insert( node ); + m_path.push( makeReference( node ) ); + Node_getTraversable( node )->traverse( SelectChildren( m_path ) ); + } + else + { + m_path.push( makeReference( *world_node ) ); + Node_getTraversable( node )->traverse( MapMergeAll( m_path ) ); + } + } + else + { + Node_getTraversable( m_path.top() )->insert( node ); + m_path.push( makeReference( node ) ); + if ( node_is_group( node ) ) { + Node_getTraversable( node )->traverse( SelectChildren( m_path ) ); + } + else + { + selectPath( m_path, true ); + } + } + return false; +} +void post( scene::Node& node ) const { + m_path.pop(); +} }; class BasicContainer : public scene::Node::Symbiot { - class TypeCasts - { - NodeTypeCastTable m_casts; - public: - TypeCasts() - { - NodeContainedCast::install(m_casts); - } - NodeTypeCastTable& get() - { - return m_casts; - } - }; - - scene::Node m_node; - TraversableNodeSet m_traverse; +class TypeCasts +{ +NodeTypeCastTable m_casts; +public: +TypeCasts(){ + NodeContainedCast::install( m_casts ); +} +NodeTypeCastTable& get(){ + return m_casts; +} +}; + +scene::Node m_node; +TraversableNodeSet m_traverse; public: - typedef LazyStatic StaticTypeCasts; - - scene::Traversable& get(NullType) - { - return m_traverse; - } - - BasicContainer() : m_node(this, this, StaticTypeCasts::instance().get()) - { - } - void release() - { - delete this; - } - scene::Node& node() - { - return m_node; - } +typedef LazyStatic StaticTypeCasts; + +scene::Traversable& get( NullType){ + return m_traverse; +} + +BasicContainer() : m_node( this, this, StaticTypeCasts::instance().get() ){ +} +void release(){ + delete this; +} +scene::Node& node(){ + return m_node; +} }; /// Merges the map graph rooted at \p node into the global scene-graph. -void MergeMap(scene::Node& node) -{ - Node_getTraversable(node)->traverse(MapMergeEntities(scene::Path(makeReference(GlobalSceneGraph().root())))); +void MergeMap( scene::Node& node ){ + Node_getTraversable( node )->traverse( MapMergeEntities( scene::Path( makeReference( GlobalSceneGraph().root() ) ) ) ); } -void Map_ImportSelected(TextInputStream& in, const MapFormat& format) -{ - NodeSmartReference node((new BasicContainer)->node()); - format.readGraph(node, in, GlobalEntityCreator()); - Map_gatherNamespaced(node); - Map_mergeClonedNames(); - MergeMap(node); +void Map_ImportSelected( TextInputStream& in, const MapFormat& format ){ + NodeSmartReference node( ( new BasicContainer )->node() ); + format.readGraph( node, in, GlobalEntityCreator() ); + Map_gatherNamespaced( node ); + Map_mergeClonedNames(); + MergeMap( node ); } -inline scene::Cloneable* Node_getCloneable(scene::Node& node) -{ - return NodeTypeCast::cast(node); +inline scene::Cloneable* Node_getCloneable( scene::Node& node ){ + return NodeTypeCast::cast( node ); } -inline scene::Node& node_clone(scene::Node& node) -{ - scene::Cloneable* cloneable = Node_getCloneable(node); - if(cloneable != 0) - { - return cloneable->clone(); - } - - return (new scene::NullNode)->node(); +inline scene::Node& node_clone( scene::Node& node ){ + scene::Cloneable* cloneable = Node_getCloneable( node ); + if ( cloneable != 0 ) { + return cloneable->clone(); + } + + return ( new scene::NullNode )->node(); } class CloneAll : public scene::Traversable::Walker { - mutable scene::Path m_path; +mutable scene::Path m_path; public: - CloneAll(scene::Node& root) - : m_path(makeReference(root)) - { - } - bool pre(scene::Node& node) const - { - if(node.isRoot()) - { - return false; - } - - m_path.push(makeReference(node_clone(node))); - m_path.top().get().IncRef(); - - return true; - } - void post(scene::Node& node) const - { - if(node.isRoot()) - { - return; - } - - Node_getTraversable(m_path.parent())->insert(m_path.top()); - - m_path.top().get().DecRef(); - m_path.pop(); - } +CloneAll( scene::Node& root ) + : m_path( makeReference( root ) ){ +} +bool pre( scene::Node& node ) const { + if ( node.isRoot() ) { + return false; + } + + m_path.push( makeReference( node_clone( node ) ) ); + m_path.top().get().IncRef(); + + return true; +} +void post( scene::Node& node ) const { + if ( node.isRoot() ) { + return; + } + + Node_getTraversable( m_path.parent() )->insert( m_path.top() ); + + m_path.top().get().DecRef(); + m_path.pop(); +} }; -scene::Node& Node_Clone(scene::Node& node) -{ - scene::Node& clone = node_clone(node); - scene::Traversable* traversable = Node_getTraversable(node); - if(traversable != 0) - { - traversable->traverse(CloneAll(clone)); - } - return clone; +scene::Node& Node_Clone( scene::Node& node ){ + scene::Node& clone = node_clone( node ); + scene::Traversable* traversable = Node_getTraversable( node ); + if ( traversable != 0 ) { + traversable->traverse( CloneAll( clone ) ); + } + return clone; } @@ -828,700 +741,674 @@ typedef std::map EntityBreakdown; class EntityBreakdownWalker : public scene::Graph::Walker { - EntityBreakdown& m_entitymap; +EntityBreakdown& m_entitymap; public: - EntityBreakdownWalker(EntityBreakdown& entitymap) - : m_entitymap(entitymap) - { - } - bool pre(const scene::Path& path, scene::Instance& instance) const - { - Entity* entity = Node_getEntity(path.top()); - if(entity != 0) - { - const EntityClass& eclass = entity->getEntityClass(); - if(m_entitymap.find(eclass.name()) == m_entitymap.end()) - { - m_entitymap[eclass.name()] = 1; - } - else ++m_entitymap[eclass.name()]; - } - return true; - } -}; - -void Scene_EntityBreakdown(EntityBreakdown& entitymap) -{ - GlobalSceneGraph().traverse(EntityBreakdownWalker(entitymap)); +EntityBreakdownWalker( EntityBreakdown& entitymap ) + : m_entitymap( entitymap ){ +} +bool pre( const scene::Path& path, scene::Instance& instance ) const { + Entity* entity = Node_getEntity( path.top() ); + if ( entity != 0 ) { + const EntityClass& eclass = entity->getEntityClass(); + if ( m_entitymap.find( eclass.name() ) == m_entitymap.end() ) { + m_entitymap[eclass.name()] = 1; + } + else{ ++m_entitymap[eclass.name()]; } + } + return true; } +}; - -WindowPosition g_posMapInfoWnd(c_default_window_pos); - -void DoMapInfo() -{ - ModalDialog dialog; - GtkEntry* brushes_entry; - GtkEntry* entities_entry; - GtkListStore* EntityBreakdownWalker; - - GtkWindow* window = create_dialog_window(MainFrame_getWindow(), "Map Info", G_CALLBACK(dialog_delete_callback), &dialog); - - window_set_position(window, g_posMapInfoWnd); - - { - GtkVBox* vbox = create_dialog_vbox(4, 4); - gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(vbox)); - - { - GtkHBox* hbox = create_dialog_hbox(4); - gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(hbox), FALSE, TRUE, 0); - - { - GtkTable* table = create_dialog_table(2, 2, 4, 4); - gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(table), TRUE, TRUE, 0); - - { - GtkEntry* entry = GTK_ENTRY(gtk_entry_new()); - gtk_widget_show(GTK_WIDGET(entry)); - gtk_table_attach(table, GTK_WIDGET(entry), 1, 2, 0, 1, - (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_entry_set_editable(entry, FALSE); - - brushes_entry = entry; - } - { - GtkEntry* entry = GTK_ENTRY(gtk_entry_new()); - gtk_widget_show(GTK_WIDGET(entry)); - gtk_table_attach(table, GTK_WIDGET(entry), 1, 2, 1, 2, - (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_entry_set_editable(entry, FALSE); - - entities_entry = entry; - } - { - GtkWidget* label = gtk_label_new ("Total Brushes"); - gtk_widget_show (label); - gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - { - GtkWidget* label = gtk_label_new ("Total Entities"); - gtk_widget_show (label); - gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, - (GtkAttachOptions) (GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - } - { - GtkVBox* vbox2 = create_dialog_vbox(4); - gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(vbox2), FALSE, FALSE, 0); - - { - GtkButton* button = create_dialog_button("Close", G_CALLBACK(dialog_button_ok), &dialog); - gtk_box_pack_start(GTK_BOX(vbox2), GTK_WIDGET(button), FALSE, FALSE, 0); - } - } - } - { - GtkWidget* label = gtk_label_new ("Entity breakdown"); - gtk_widget_show (label); - gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(label), FALSE, TRUE, 0); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - } - { - GtkScrolledWindow* scr = create_scrolled_window(GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC, 4); - gtk_box_pack_start(GTK_BOX (vbox), GTK_WIDGET(scr), TRUE, TRUE, 0); - - { - GtkListStore* store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING); - - GtkWidget* view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)); - gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(view), TRUE); - - { - GtkCellRenderer* renderer = gtk_cell_renderer_text_new(); - GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes("Entity", renderer, "text", 0, 0); - gtk_tree_view_append_column(GTK_TREE_VIEW(view), column); - gtk_tree_view_column_set_sort_column_id(column, 0); - } - - { - GtkCellRenderer* renderer = gtk_cell_renderer_text_new(); - GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes("Count", renderer, "text", 1, 0); - gtk_tree_view_append_column(GTK_TREE_VIEW(view), column); - gtk_tree_view_column_set_sort_column_id(column, 1); - } - - gtk_widget_show(view); - - gtk_container_add(GTK_CONTAINER(scr), view); - - EntityBreakdownWalker = store; - } - } - } - - // Initialize fields - - { - EntityBreakdown entitymap; - Scene_EntityBreakdown(entitymap); - - for(EntityBreakdown::iterator i=entitymap.begin(); i != entitymap.end(); ++i) - { - char tmp[16]; - sprintf (tmp, "%u", Unsigned((*i).second)); - GtkTreeIter iter; - gtk_list_store_append(GTK_LIST_STORE(EntityBreakdownWalker), &iter); - gtk_list_store_set(GTK_LIST_STORE(EntityBreakdownWalker), &iter, 0, (*i).first.c_str(), 1, tmp, -1); - } - } - - g_object_unref(G_OBJECT(EntityBreakdownWalker)); - - char tmp[16]; - sprintf (tmp, "%u", Unsigned(g_brushCount.get())); - gtk_entry_set_text (GTK_ENTRY (brushes_entry), tmp); - sprintf (tmp, "%u", Unsigned(g_entityCount.get())); - gtk_entry_set_text (GTK_ENTRY (entities_entry), tmp); - - modal_dialog_show(window, dialog); - - // save before exit - window_get_position(window, g_posMapInfoWnd); - - gtk_widget_destroy(GTK_WIDGET(window)); +void Scene_EntityBreakdown( EntityBreakdown& entitymap ){ + GlobalSceneGraph().traverse( EntityBreakdownWalker( entitymap ) ); +} + + +WindowPosition g_posMapInfoWnd( c_default_window_pos ); + +void DoMapInfo(){ + ModalDialog dialog; + GtkEntry* brushes_entry; + GtkEntry* entities_entry; + GtkListStore* EntityBreakdownWalker; + + GtkWindow* window = create_dialog_window( MainFrame_getWindow(), "Map Info", G_CALLBACK( dialog_delete_callback ), &dialog ); + + window_set_position( window, g_posMapInfoWnd ); + + { + GtkVBox* vbox = create_dialog_vbox( 4, 4 ); + gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( vbox ) ); + + { + GtkHBox* hbox = create_dialog_hbox( 4 ); + gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( hbox ), FALSE, TRUE, 0 ); + + { + GtkTable* table = create_dialog_table( 2, 2, 4, 4 ); + gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( table ), TRUE, TRUE, 0 ); + + { + GtkEntry* entry = GTK_ENTRY( gtk_entry_new() ); + gtk_widget_show( GTK_WIDGET( entry ) ); + gtk_table_attach( table, GTK_WIDGET( entry ), 1, 2, 0, 1, + (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), + (GtkAttachOptions) ( 0 ), 0, 0 ); + gtk_entry_set_editable( entry, FALSE ); + + brushes_entry = entry; + } + { + GtkEntry* entry = GTK_ENTRY( gtk_entry_new() ); + gtk_widget_show( GTK_WIDGET( entry ) ); + gtk_table_attach( table, GTK_WIDGET( entry ), 1, 2, 1, 2, + (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), + (GtkAttachOptions) ( 0 ), 0, 0 ); + gtk_entry_set_editable( entry, FALSE ); + + entities_entry = entry; + } + { + GtkWidget* label = gtk_label_new( "Total Brushes" ); + gtk_widget_show( label ); + gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 0, 1, + (GtkAttachOptions) ( GTK_FILL ), + (GtkAttachOptions) ( 0 ), 0, 0 ); + gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 ); + } + { + GtkWidget* label = gtk_label_new( "Total Entities" ); + gtk_widget_show( label ); + gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 1, 2, + (GtkAttachOptions) ( GTK_FILL ), + (GtkAttachOptions) ( 0 ), 0, 0 ); + gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 ); + } + } + { + GtkVBox* vbox2 = create_dialog_vbox( 4 ); + gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( vbox2 ), FALSE, FALSE, 0 ); + + { + GtkButton* button = create_dialog_button( "Close", G_CALLBACK( dialog_button_ok ), &dialog ); + gtk_box_pack_start( GTK_BOX( vbox2 ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); + } + } + } + { + GtkWidget* label = gtk_label_new( "Entity breakdown" ); + gtk_widget_show( label ); + gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( label ), FALSE, TRUE, 0 ); + gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 ); + } + { + GtkScrolledWindow* scr = create_scrolled_window( GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC, 4 ); + gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( scr ), TRUE, TRUE, 0 ); + + { + GtkListStore* store = gtk_list_store_new( 2, G_TYPE_STRING, G_TYPE_STRING ); + + GtkWidget* view = gtk_tree_view_new_with_model( GTK_TREE_MODEL( store ) ); + gtk_tree_view_set_headers_clickable( GTK_TREE_VIEW( view ), TRUE ); + + { + GtkCellRenderer* renderer = gtk_cell_renderer_text_new(); + GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes( "Entity", renderer, "text", 0, 0 ); + gtk_tree_view_append_column( GTK_TREE_VIEW( view ), column ); + gtk_tree_view_column_set_sort_column_id( column, 0 ); + } + + { + GtkCellRenderer* renderer = gtk_cell_renderer_text_new(); + GtkTreeViewColumn* column = gtk_tree_view_column_new_with_attributes( "Count", renderer, "text", 1, 0 ); + gtk_tree_view_append_column( GTK_TREE_VIEW( view ), column ); + gtk_tree_view_column_set_sort_column_id( column, 1 ); + } + + gtk_widget_show( view ); + + gtk_container_add( GTK_CONTAINER( scr ), view ); + + EntityBreakdownWalker = store; + } + } + } + + // Initialize fields + + { + EntityBreakdown entitymap; + Scene_EntityBreakdown( entitymap ); + + for ( EntityBreakdown::iterator i = entitymap.begin(); i != entitymap.end(); ++i ) + { + char tmp[16]; + sprintf( tmp, "%u", Unsigned( ( *i ).second ) ); + GtkTreeIter iter; + gtk_list_store_append( GTK_LIST_STORE( EntityBreakdownWalker ), &iter ); + gtk_list_store_set( GTK_LIST_STORE( EntityBreakdownWalker ), &iter, 0, ( *i ).first.c_str(), 1, tmp, -1 ); + } + } + + g_object_unref( G_OBJECT( EntityBreakdownWalker ) ); + + char tmp[16]; + sprintf( tmp, "%u", Unsigned( g_brushCount.get() ) ); + gtk_entry_set_text( GTK_ENTRY( brushes_entry ), tmp ); + sprintf( tmp, "%u", Unsigned( g_entityCount.get() ) ); + gtk_entry_set_text( GTK_ENTRY( entities_entry ), tmp ); + + modal_dialog_show( window, dialog ); + + // save before exit + window_get_position( window, g_posMapInfoWnd ); + + gtk_widget_destroy( GTK_WIDGET( window ) ); } class ScopeTimer { - Timer m_timer; - const char* m_message; +Timer m_timer; +const char* m_message; public: - ScopeTimer(const char* message) - : m_message(message) - { - m_timer.start(); - } - ~ScopeTimer() - { - double elapsed_time = m_timer.elapsed_msec() / 1000.f; - globalOutputStream() << m_message << " timer: " << FloatFormat(elapsed_time, 5, 2) << " second(s) elapsed\n"; - } +ScopeTimer( const char* message ) + : m_message( message ){ + m_timer.start(); +} +~ScopeTimer(){ + double elapsed_time = m_timer.elapsed_msec() / 1000.f; + globalOutputStream() << m_message << " timer: " << FloatFormat( elapsed_time, 5, 2 ) << " second(s) elapsed\n"; +} }; -/* -================ -Map_LoadFile -================ -*/ - -void Map_LoadFile (const char *filename) -{ - globalOutputStream() << "Loading map from " << filename << "\n"; - ScopeDisableScreenUpdates disableScreenUpdates("Processing...", "Loading Map"); - - g_map.m_name = filename; - Map_UpdateTitle(g_map); - - { - ScopeTimer timer("map load"); - - g_map.m_resource = GlobalReferenceCache().capture(g_map.m_name.c_str()); - g_map.m_resource->attach(g_map); - - Node_getTraversable(GlobalSceneGraph().root())->traverse(entity_updateworldspawn()); - } - - globalOutputStream() << "--- LoadMapFile ---\n"; - globalOutputStream() << g_map.m_name.c_str() << "\n"; - - globalOutputStream() << Unsigned(g_brushCount.get()) << " primitive\n"; - globalOutputStream() << Unsigned(g_entityCount.get()) << " entities\n"; - - //GlobalEntityCreator().printStatistics(); - - // - // move the view to a start position - // - Map_StartPosition(); +CopiedString g_strLastFolder = ""; - g_currentMap = &g_map; +/* + ================ + Map_LoadFile + ================ + */ + +void Map_LoadFile( const char *filename ){ + globalOutputStream() << "Loading map from " << filename << "\n"; + ScopeDisableScreenUpdates disableScreenUpdates( "Processing...", "Loading Map" ); + + MRU_AddFile( filename ); + g_strLastFolder = g_path_get_dirname( filename ); + + { + ScopeTimer timer( "map load" ); + + const MapFormat* format = NULL; + const char* moduleName = findModuleName( &GlobalFiletypes(), MapFormat::Name(), path_get_extension( filename ) ); + if ( string_not_empty( moduleName ) ) { + format = ReferenceAPI_getMapModules().findModule( moduleName ); + } + + for ( int i = 0; i < Brush_toggleFormatCount(); ++i ) + { + if ( i ) { + Map_Free(); + } + Brush_toggleFormat( i ); + g_map.m_name = filename; + Map_UpdateTitle( g_map ); + g_map.m_resource = GlobalReferenceCache().capture( g_map.m_name.c_str() ); + if ( format ) { + format->wrongFormat = false; + } + g_map.m_resource->attach( g_map ); + if ( format ) { + if ( !format->wrongFormat ) { + break; + } + } + } + + Node_getTraversable( GlobalSceneGraph().root() )->traverse( entity_updateworldspawn() ); + } + + globalOutputStream() << "--- LoadMapFile ---\n"; + globalOutputStream() << g_map.m_name.c_str() << "\n"; + + globalOutputStream() << Unsigned( g_brushCount.get() ) << " primitive\n"; + globalOutputStream() << Unsigned( g_entityCount.get() ) << " entities\n"; + + //GlobalEntityCreator().printStatistics(); + + // + // move the view to a start position + // + Map_StartPosition(); + + g_currentMap = &g_map; + + // restart VFS to apply new pak filtering based on mapname + // needed for daemon DPK VFS + VFS_Restart(); } class Excluder { public: - virtual bool excluded(scene::Node& node) const = 0; +virtual bool excluded( scene::Node& node ) const = 0; }; class ExcludeWalker : public scene::Traversable::Walker { - const scene::Traversable::Walker& m_walker; - const Excluder* m_exclude; - mutable bool m_skip; +const scene::Traversable::Walker& m_walker; +const Excluder* m_exclude; +mutable bool m_skip; public: - ExcludeWalker(const scene::Traversable::Walker& walker, const Excluder& exclude) - : m_walker(walker), m_exclude(&exclude), m_skip(false) - { - } - bool pre(scene::Node& node) const - { - if(m_exclude->excluded(node) || node.isRoot()) - { - m_skip = true; - return false; - } - else - { - m_walker.pre(node); - } - return true; - } - void post(scene::Node& node) const - { - if(m_skip) - { - m_skip = false; - } - else - { - m_walker.post(node); - } - } +ExcludeWalker( const scene::Traversable::Walker& walker, const Excluder& exclude ) + : m_walker( walker ), m_exclude( &exclude ), m_skip( false ){ +} +bool pre( scene::Node& node ) const { + if ( m_exclude->excluded( node ) || node.isRoot() ) { + m_skip = true; + return false; + } + else + { + m_walker.pre( node ); + } + return true; +} +void post( scene::Node& node ) const { + if ( m_skip ) { + m_skip = false; + } + else + { + m_walker.post( node ); + } +} }; class AnyInstanceSelected : public scene::Instantiable::Visitor { - bool& m_selected; +bool& m_selected; public: - AnyInstanceSelected(bool& selected) : m_selected(selected) - { - m_selected = false; - } - void visit(scene::Instance& instance) const - { - Selectable* selectable = Instance_getSelectable(instance); - if(selectable != 0 - && selectable->isSelected()) - { - m_selected = true; - } - } +AnyInstanceSelected( bool& selected ) : m_selected( selected ){ + m_selected = false; +} +void visit( scene::Instance& instance ) const { + Selectable* selectable = Instance_getSelectable( instance ); + if ( selectable != 0 + && selectable->isSelected() ) { + m_selected = true; + } +} }; -bool Node_instanceSelected(scene::Node& node) -{ - scene::Instantiable* instantiable = Node_getInstantiable(node); - ASSERT_NOTNULL(instantiable); - bool selected; - instantiable->forEachInstance(AnyInstanceSelected(selected)); - return selected; +bool Node_instanceSelected( scene::Node& node ){ + scene::Instantiable* instantiable = Node_getInstantiable( node ); + ASSERT_NOTNULL( instantiable ); + bool selected; + instantiable->forEachInstance( AnyInstanceSelected( selected ) ); + return selected; } class SelectedDescendantWalker : public scene::Traversable::Walker { - bool& m_selected; +bool& m_selected; public: - SelectedDescendantWalker(bool& selected) : m_selected(selected) - { - m_selected = false; - } - - bool pre(scene::Node& node) const - { - if(node.isRoot()) - { - return false; - } - - if(Node_instanceSelected(node)) - { - m_selected = true; - } - - return true; - } +SelectedDescendantWalker( bool& selected ) : m_selected( selected ){ + m_selected = false; +} + +bool pre( scene::Node& node ) const { + if ( node.isRoot() ) { + return false; + } + + if ( Node_instanceSelected( node ) ) { + m_selected = true; + } + + return true; +} }; -bool Node_selectedDescendant(scene::Node& node) -{ - bool selected; - Node_traverseSubgraph(node, SelectedDescendantWalker(selected)); - return selected; +bool Node_selectedDescendant( scene::Node& node ){ + bool selected; + Node_traverseSubgraph( node, SelectedDescendantWalker( selected ) ); + return selected; } class SelectionExcluder : public Excluder { public: - bool excluded(scene::Node& node) const - { - return !Node_selectedDescendant(node); - } +bool excluded( scene::Node& node ) const { + return !Node_selectedDescendant( node ); +} }; class IncludeSelectedWalker : public scene::Traversable::Walker { - const scene::Traversable::Walker& m_walker; - mutable std::size_t m_selected; - mutable bool m_skip; - - bool selectedParent() const - { - return m_selected != 0; - } +const scene::Traversable::Walker& m_walker; +mutable std::size_t m_selected; +mutable bool m_skip; + +bool selectedParent() const { + return m_selected != 0; +} public: - IncludeSelectedWalker(const scene::Traversable::Walker& walker) - : m_walker(walker), m_selected(0), m_skip(false) - { - } - bool pre(scene::Node& node) const - { - // include node if: - // node is not a 'root' AND ( node is selected OR any child of node is selected OR any parent of node is selected ) - if(!node.isRoot() && (Node_selectedDescendant(node) || selectedParent())) - { - if(Node_instanceSelected(node)) - { - ++m_selected; - } - m_walker.pre(node); - return true; - } - else - { - m_skip = true; - return false; - } - } - void post(scene::Node& node) const - { - if(m_skip) - { - m_skip = false; - } - else - { - if(Node_instanceSelected(node)) - { - --m_selected; - } - m_walker.post(node); - } - } +IncludeSelectedWalker( const scene::Traversable::Walker& walker ) + : m_walker( walker ), m_selected( 0 ), m_skip( false ){ +} +bool pre( scene::Node& node ) const { + // include node if: + // node is not a 'root' AND ( node is selected OR any child of node is selected OR any parent of node is selected ) + if ( !node.isRoot() && ( Node_selectedDescendant( node ) || selectedParent() ) ) { + if ( Node_instanceSelected( node ) ) { + ++m_selected; + } + m_walker.pre( node ); + return true; + } + else + { + m_skip = true; + return false; + } +} +void post( scene::Node& node ) const { + if ( m_skip ) { + m_skip = false; + } + else + { + if ( Node_instanceSelected( node ) ) { + --m_selected; + } + m_walker.post( node ); + } +} }; -void Map_Traverse_Selected(scene::Node& root, const scene::Traversable::Walker& walker) -{ - scene::Traversable* traversable = Node_getTraversable(root); - if(traversable != 0) - { +void Map_Traverse_Selected( scene::Node& root, const scene::Traversable::Walker& walker ){ + scene::Traversable* traversable = Node_getTraversable( root ); + if ( traversable != 0 ) { #if 0 - traversable->traverse(ExcludeWalker(walker, SelectionExcluder())); + traversable->traverse( ExcludeWalker( walker, SelectionExcluder() ) ); #else - traversable->traverse(IncludeSelectedWalker(walker)); + traversable->traverse( IncludeSelectedWalker( walker ) ); #endif - } + } } -void Map_ExportSelected(TextOutputStream& out, const MapFormat& format) -{ - format.writeGraph(GlobalSceneGraph().root(), Map_Traverse_Selected, out); +void Map_ExportSelected( TextOutputStream& out, const MapFormat& format ){ + format.writeGraph( GlobalSceneGraph().root(), Map_Traverse_Selected, out ); } -void Map_Traverse(scene::Node& root, const scene::Traversable::Walker& walker) -{ - scene::Traversable* traversable = Node_getTraversable(root); - if(traversable != 0) - { - traversable->traverse(walker); - } +void Map_Traverse( scene::Node& root, const scene::Traversable::Walker& walker ){ + scene::Traversable* traversable = Node_getTraversable( root ); + if ( traversable != 0 ) { + traversable->traverse( walker ); + } } class RegionExcluder : public Excluder { public: - bool excluded(scene::Node& node) const - { - return node.excluded(); - } +bool excluded( scene::Node& node ) const { + return node.excluded(); +} }; -void Map_Traverse_Region(scene::Node& root, const scene::Traversable::Walker& walker) -{ - scene::Traversable* traversable = Node_getTraversable(root); - if(traversable != 0) - { - traversable->traverse(ExcludeWalker(walker, RegionExcluder())); - } +void Map_Traverse_Region( scene::Node& root, const scene::Traversable::Walker& walker ){ + scene::Traversable* traversable = Node_getTraversable( root ); + if ( traversable != 0 ) { + traversable->traverse( ExcludeWalker( walker, RegionExcluder() ) ); + } } -bool Map_SaveRegion(const char *filename) -{ - AddRegionBrushes(); +bool Map_SaveRegion( const char *filename ){ + AddRegionBrushes(); - bool success = MapResource_saveFile(MapFormat_forFile(filename), GlobalSceneGraph().root(), Map_Traverse_Region, filename); + bool success = MapResource_saveFile( MapFormat_forFile( filename ), GlobalSceneGraph().root(), Map_Traverse_Region, filename ); - RemoveRegionBrushes(); + RemoveRegionBrushes(); - return success; + return success; } -void Map_RenameAbsolute(const char* absolute) -{ - Resource* resource = GlobalReferenceCache().capture(absolute); - NodeSmartReference clone(NewMapRoot(path_make_relative(absolute, GlobalFileSystem().findRoot(absolute)))); - resource->setNode(clone.get_pointer()); +void Map_RenameAbsolute( const char* absolute ){ + Resource* resource = GlobalReferenceCache().capture( absolute ); + NodeSmartReference clone( NewMapRoot( path_make_relative( absolute, GlobalFileSystem().findRoot( absolute ) ) ) ); + resource->setNode( clone.get_pointer() ); - { - //ScopeTimer timer("clone subgraph"); - Node_getTraversable(GlobalSceneGraph().root())->traverse(CloneAll(clone)); - } + { + //ScopeTimer timer("clone subgraph"); + Node_getTraversable( GlobalSceneGraph().root() )->traverse( CloneAll( clone ) ); + } - g_map.m_resource->detach(g_map); - GlobalReferenceCache().release(g_map.m_name.c_str()); + g_map.m_resource->detach( g_map ); + GlobalReferenceCache().release( g_map.m_name.c_str() ); - g_map.m_resource = resource; + g_map.m_resource = resource; - g_map.m_name = absolute; - Map_UpdateTitle(g_map); + g_map.m_name = absolute; + Map_UpdateTitle( g_map ); - g_map.m_resource->attach(g_map); + g_map.m_resource->attach( g_map ); + // refresh VFS to apply new pak filtering based on mapname + // needed for daemon DPK VFS + VFS_Refresh(); } -void Map_Rename(const char* filename) -{ - if(!string_equal(g_map.m_name.c_str(), filename)) - { - ScopeDisableScreenUpdates disableScreenUpdates("Processing...", "Saving Map"); +void Map_Rename( const char* filename ){ + if ( !string_equal( g_map.m_name.c_str(), filename ) ) { + ScopeDisableScreenUpdates disableScreenUpdates( "Processing...", "Saving Map" ); + + Map_RenameAbsolute( filename ); - Map_RenameAbsolute(filename); - - SceneChangeNotify(); - } - else - { - SaveReferences(); - } + SceneChangeNotify(); + } + else + { + SaveReferences(); + } } -bool Map_Save() -{ +bool Map_Save(){ Pointfile_Clear(); - ScopeTimer timer("map save"); - SaveReferences(); - return true; // assume success.. + ScopeTimer timer( "map save" ); + SaveReferences(); + return true; // assume success.. } /* -=========== -Map_New + =========== + Map_New -=========== -*/ -void Map_New() -{ + =========== + */ +void Map_New(){ //globalOutputStream() << "Map_New\n"; g_map.m_name = "unnamed.map"; - Map_UpdateTitle(g_map); + Map_UpdateTitle( g_map ); - { - g_map.m_resource = GlobalReferenceCache().capture(g_map.m_name.c_str()); + { + g_map.m_resource = GlobalReferenceCache().capture( g_map.m_name.c_str() ); // ASSERT_MESSAGE(g_map.m_resource->getNode() == 0, "bleh"); - g_map.m_resource->attach(g_map); + g_map.m_resource->attach( g_map ); - SceneChangeNotify(); - } + SceneChangeNotify(); + } - FocusViews(g_vector3_identity, 0); + FocusViews( g_vector3_identity, 0 ); - g_currentMap = &g_map; + g_currentMap = &g_map; + + // restart VFS to apply new pak filtering based on mapname + // needed for daemon DPK VFS + VFS_Restart(); } -extern void ConstructRegionBrushes(scene::Node* brushes[6], const Vector3& region_mins, const Vector3& region_maxs); +extern void ConstructRegionBrushes( scene::Node * brushes[6], const Vector3 ®ion_mins, const Vector3 ®ion_maxs ); -void ConstructRegionStartpoint(scene::Node* startpoint, const Vector3& region_mins, const Vector3& region_maxs) -{ - /*! - \todo we need to make sure that the player start IS inside the region and bail out if it's not - the compiler will refuse to compile a map with a player_start somewhere in empty space.. - for now, let's just print an error - */ - - Vector3 vOrig(Camera_getOrigin(*g_pParentWnd->GetCamWnd())); - - for (int i=0 ; i<3 ; i++) - { - if (vOrig[i] > region_maxs[i] || vOrig[i] < region_mins[i]) - { - globalErrorStream() << "Camera is NOT in the region, it's likely that the region won't compile correctly\n"; - break; - } - } - - // write the info_playerstart - char sTmp[1024]; - sprintf(sTmp, "%d %d %d", (int)vOrig[0], (int)vOrig[1], (int)vOrig[2]); - Node_getEntity(*startpoint)->setKeyValue("origin", sTmp); - sprintf(sTmp, "%d", (int)Camera_getAngles(*g_pParentWnd->GetCamWnd())[CAMERA_YAW]); - Node_getEntity(*startpoint)->setKeyValue("angle", sTmp); +void ConstructRegionStartpoint( scene::Node* startpoint, const Vector3& region_mins, const Vector3& region_maxs ){ + /*! + \todo we need to make sure that the player start IS inside the region and bail out if it's not + the compiler will refuse to compile a map with a player_start somewhere in empty space.. + for now, let's just print an error + */ + + Vector3 vOrig( Camera_getOrigin( *g_pParentWnd->GetCamWnd() ) ); + + for ( int i = 0 ; i < 3 ; i++ ) + { + if ( vOrig[i] > region_maxs[i] || vOrig[i] < region_mins[i] ) { + globalErrorStream() << "Camera is NOT in the region, it's likely that the region won't compile correctly\n"; + break; + } + } + + // write the info_playerstart + char sTmp[1024]; + sprintf( sTmp, "%d %d %d", (int)vOrig[0], (int)vOrig[1], (int)vOrig[2] ); + Node_getEntity( *startpoint )->setKeyValue( "origin", sTmp ); + sprintf( sTmp, "%d", (int)Camera_getAngles( *g_pParentWnd->GetCamWnd() )[CAMERA_YAW] ); + Node_getEntity( *startpoint )->setKeyValue( "angle", sTmp ); } /* -=========================================================== + =========================================================== - REGION + REGION -=========================================================== -*/ -bool region_active; -Vector3 region_mins(g_MinWorldCoord, g_MinWorldCoord, g_MinWorldCoord); -Vector3 region_maxs(g_MaxWorldCoord, g_MaxWorldCoord, g_MaxWorldCoord); + =========================================================== + */ +bool region_active; +Vector3 region_mins( g_MinWorldCoord, g_MinWorldCoord, g_MinWorldCoord ); +Vector3 region_maxs( g_MaxWorldCoord, g_MaxWorldCoord, g_MaxWorldCoord ); scene::Node* region_sides[6]; scene::Node* region_startpoint = 0; /* -=========== -AddRegionBrushes -a regioned map will have temp walls put up at the region boundary -\todo TODO TTimo old implementation of region brushes - we still add them straight in the worldspawn and take them out after the map is saved - with the new implementation we should be able to append them in a temporary manner to the data we pass to the map module -=========== -*/ -void AddRegionBrushes (void) -{ - int i; + =========== + AddRegionBrushes + a regioned map will have temp walls put up at the region boundary + \todo TODO TTimo old implementation of region brushes + we still add them straight in the worldspawn and take them out after the map is saved + with the new implementation we should be able to append them in a temporary manner to the data we pass to the map module + =========== + */ +void AddRegionBrushes( void ){ + int i; - for(i=0; i<6; i++) - { - region_sides[i] = &GlobalBrushCreator().createBrush(); - Node_getTraversable(Map_FindOrInsertWorldspawn(g_map))->insert(NodeSmartReference(*region_sides[i])); - } + for ( i = 0; i < 6; i++ ) + { + region_sides[i] = &GlobalBrushCreator().createBrush(); + Node_getTraversable( Map_FindOrInsertWorldspawn( g_map ) )->insert( NodeSmartReference( *region_sides[i] ) ); + } - region_startpoint = &GlobalEntityCreator().createEntity(GlobalEntityClassManager().findOrInsert("info_player_start", false)); + region_startpoint = &GlobalEntityCreator().createEntity( GlobalEntityClassManager().findOrInsert( "info_player_start", false ) ); - ConstructRegionBrushes(region_sides, region_mins, region_maxs); - ConstructRegionStartpoint(region_startpoint, region_mins, region_maxs); + ConstructRegionBrushes( region_sides, region_mins, region_maxs ); + ConstructRegionStartpoint( region_startpoint, region_mins, region_maxs ); - Node_getTraversable(GlobalSceneGraph().root())->insert(NodeSmartReference(*region_startpoint)); + Node_getTraversable( GlobalSceneGraph().root() )->insert( NodeSmartReference( *region_startpoint ) ); } -void RemoveRegionBrushes (void) -{ - for(std::size_t i=0; i<6; i++) - { - Node_getTraversable(*Map_GetWorldspawn(g_map))->erase(*region_sides[i]); - } - Node_getTraversable(GlobalSceneGraph().root())->erase(*region_startpoint); +void RemoveRegionBrushes( void ){ + for ( std::size_t i = 0; i < 6; i++ ) + { + Node_getTraversable( *Map_GetWorldspawn( g_map ) )->erase( *region_sides[i] ); + } + Node_getTraversable( GlobalSceneGraph().root() )->erase( *region_startpoint ); } -inline void exclude_node(scene::Node& node, bool exclude) -{ - exclude - ? node.enable(scene::Node::eExcluded) - : node.disable(scene::Node::eExcluded); +inline void exclude_node( scene::Node& node, bool exclude ){ + exclude + ? node.enable( scene::Node::eExcluded ) + : node.disable( scene::Node::eExcluded ); } class ExcludeAllWalker : public scene::Graph::Walker { - bool m_exclude; +bool m_exclude; public: - ExcludeAllWalker(bool exclude) - : m_exclude(exclude) - { - } - bool pre(const scene::Path& path, scene::Instance& instance) const - { - exclude_node(path.top(), m_exclude); - - return true; - } +ExcludeAllWalker( bool exclude ) + : m_exclude( exclude ){ +} +bool pre( const scene::Path& path, scene::Instance& instance ) const { + exclude_node( path.top(), m_exclude ); + + return true; +} }; -void Scene_Exclude_All(bool exclude) -{ - GlobalSceneGraph().traverse(ExcludeAllWalker(exclude)); +void Scene_Exclude_All( bool exclude ){ + GlobalSceneGraph().traverse( ExcludeAllWalker( exclude ) ); } -bool Instance_isSelected(const scene::Instance& instance) -{ - const Selectable* selectable = Instance_getSelectable(instance); - return selectable != 0 && selectable->isSelected(); +bool Instance_isSelected( const scene::Instance& instance ){ + const Selectable* selectable = Instance_getSelectable( instance ); + return selectable != 0 && selectable->isSelected(); } class ExcludeSelectedWalker : public scene::Graph::Walker { - bool m_exclude; +bool m_exclude; public: - ExcludeSelectedWalker(bool exclude) - : m_exclude(exclude) - { - } - bool pre(const scene::Path& path, scene::Instance& instance) const - { - exclude_node(path.top(), (instance.isSelected() || instance.childSelected() || instance.parentSelected()) == m_exclude); - return true; - } +ExcludeSelectedWalker( bool exclude ) + : m_exclude( exclude ){ +} +bool pre( const scene::Path& path, scene::Instance& instance ) const { + exclude_node( path.top(), ( instance.isSelected() || instance.childSelected() || instance.parentSelected() ) == m_exclude ); + return true; +} }; -void Scene_Exclude_Selected(bool exclude) -{ - GlobalSceneGraph().traverse(ExcludeSelectedWalker(exclude)); +void Scene_Exclude_Selected( bool exclude ){ + GlobalSceneGraph().traverse( ExcludeSelectedWalker( exclude ) ); } class ExcludeRegionedWalker : public scene::Graph::Walker { - bool m_exclude; +bool m_exclude; public: - ExcludeRegionedWalker(bool exclude) - : m_exclude(exclude) - { - } - bool pre(const scene::Path& path, scene::Instance& instance) const - { - exclude_node( - path.top(), - !( - ( - aabb_intersects_aabb( - instance.worldAABB(), - aabb_for_minmax(region_mins, region_maxs) - ) != 0 - ) ^ m_exclude - ) - ); - - return true; - } +ExcludeRegionedWalker( bool exclude ) + : m_exclude( exclude ){ +} +bool pre( const scene::Path& path, scene::Instance& instance ) const { + exclude_node( + path.top(), + !( + ( + aabb_intersects_aabb( + instance.worldAABB(), + aabb_for_minmax( region_mins, region_maxs ) + ) != 0 + ) ^ m_exclude + ) + ); + + return true; +} }; -void Scene_Exclude_Region(bool exclude) -{ - GlobalSceneGraph().traverse(ExcludeRegionedWalker(exclude)); +void Scene_Exclude_Region( bool exclude ){ + GlobalSceneGraph().traverse( ExcludeRegionedWalker( exclude ) ); } /* -=========== -Map_RegionOff + =========== + Map_RegionOff -Other filtering options may still be on -=========== -*/ -void Map_RegionOff() -{ + Other filtering options may still be on + =========== + */ +void Map_RegionOff(){ region_active = false; region_maxs[0] = g_MaxWorldCoord - 64; @@ -1530,83 +1417,76 @@ void Map_RegionOff() region_mins[1] = g_MinWorldCoord + 64; region_maxs[2] = g_MaxWorldCoord - 64; region_mins[2] = g_MinWorldCoord + 64; - - Scene_Exclude_All(false); + + Scene_Exclude_All( false ); } -void Map_ApplyRegion (void) -{ +void Map_ApplyRegion( void ){ region_active = true; - Scene_Exclude_Region(false); + Scene_Exclude_Region( false ); } /* -======================== -Map_RegionSelectedBrushes -======================== -*/ -void Map_RegionSelectedBrushes (void) -{ + ======================== + Map_RegionSelectedBrushes + ======================== + */ +void Map_RegionSelectedBrushes( void ){ Map_RegionOff(); - if(GlobalSelectionSystem().countSelected() != 0 - && GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive) - { - region_active = true; - Select_GetBounds (region_mins, region_maxs); + if ( GlobalSelectionSystem().countSelected() != 0 + && GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive ) { + region_active = true; + Select_GetBounds( region_mins, region_maxs ); - Scene_Exclude_Selected(false); - - GlobalSelectionSystem().setSelectedAll(false); - } + Scene_Exclude_Selected( false ); + + GlobalSelectionSystem().setSelectedAll( false ); + } } /* -=========== -Map_RegionXY -=========== -*/ -void Map_RegionXY(float x_min, float y_min, float x_max, float y_max) -{ + =========== + Map_RegionXY + =========== + */ +void Map_RegionXY( float x_min, float y_min, float x_max, float y_max ){ Map_RegionOff(); region_mins[0] = x_min; - region_maxs[0] = x_max; - region_mins[1] = y_min; - region_maxs[1] = y_max; - region_mins[2] = g_MinWorldCoord + 64; + region_maxs[0] = x_max; + region_mins[1] = y_min; + region_maxs[1] = y_max; + region_mins[2] = g_MinWorldCoord + 64; region_maxs[2] = g_MaxWorldCoord - 64; Map_ApplyRegion(); } -void Map_RegionBounds(const AABB& bounds) -{ - Map_RegionOff(); +void Map_RegionBounds( const AABB& bounds ){ + Map_RegionOff(); - region_mins = vector3_subtracted(bounds.origin, bounds.extents); - region_maxs = vector3_added(bounds.origin, bounds.extents); + region_mins = vector3_subtracted( bounds.origin, bounds.extents ); + region_maxs = vector3_added( bounds.origin, bounds.extents ); - deleteSelection(); + deleteSelection(); - Map_ApplyRegion(); + Map_ApplyRegion(); } /* -=========== -Map_RegionBrush -=========== -*/ -void Map_RegionBrush (void) -{ - if(GlobalSelectionSystem().countSelected() != 0) - { - scene::Instance& instance = GlobalSelectionSystem().ultimateSelected(); - Map_RegionBounds(instance.worldAABB()); - } + =========== + Map_RegionBrush + =========== + */ +void Map_RegionBrush( void ){ + if ( GlobalSelectionSystem().countSelected() != 0 ) { + scene::Instance& instance = GlobalSelectionSystem().ultimateSelected(); + Map_RegionBounds( instance.worldAABB() ); + } } // @@ -1614,45 +1494,121 @@ void Map_RegionBrush (void) //Map_ImportFile //================ // -bool Map_ImportFile(const char* filename) -{ - ScopeDisableScreenUpdates disableScreenUpdates("Processing...", "Loading Map"); - - bool success = false; - { - Resource* resource = GlobalReferenceCache().capture(filename); - resource->refresh(); // avoid loading old version if map has changed on disk since last import - if(resource->load()) - { - NodeSmartReference clone(NewMapRoot("")); - - { - //ScopeTimer timer("clone subgraph"); - Node_getTraversable(*resource->getNode())->traverse(CloneAll(clone)); - } - - Map_gatherNamespaced(clone); - Map_mergeClonedNames(); - MergeMap(clone); - success = true; - } - GlobalReferenceCache().release(filename); - } +bool Map_ImportFile( const char* filename ){ + ScopeDisableScreenUpdates disableScreenUpdates( "Processing...", "Loading Map" ); + + g_strLastFolder = g_path_get_dirname( filename ); + + bool success = false; + + if ( extension_equal( path_get_extension( filename ), "bsp" ) ) { + goto tryDecompile; + } + + { + const MapFormat* format = NULL; + const char* moduleName = findModuleName( &GlobalFiletypes(), MapFormat::Name(), path_get_extension( filename ) ); + if ( string_not_empty( moduleName ) ) { + format = ReferenceAPI_getMapModules().findModule( moduleName ); + } + + if ( format ) { + format->wrongFormat = false; + } + Resource* resource = GlobalReferenceCache().capture( filename ); + resource->refresh(); // avoid loading old version if map has changed on disk since last import + if ( !resource->load() ) { + GlobalReferenceCache().release( filename ); + goto tryDecompile; + } + if ( format ) { + if ( format->wrongFormat ) { + GlobalReferenceCache().release( filename ); + goto tryDecompile; + } + } + NodeSmartReference clone( NewMapRoot( "" ) ); + Node_getTraversable( *resource->getNode() )->traverse( CloneAll( clone ) ); + Map_gatherNamespaced( clone ); + Map_mergeClonedNames(); + MergeMap( clone ); + success = true; + GlobalReferenceCache().release( filename ); + } SceneChangeNotify(); - return success; + return success; + +tryDecompile: + + const char *type = GlobalRadiant().getRequiredGameDescriptionKeyValue( "q3map2_type" ); + int n = string_length( path_get_extension( filename ) ); + if ( n && ( extension_equal( path_get_extension( filename ), "bsp" ) || extension_equal( path_get_extension( filename ), "map" ) ) ) { + StringBuffer output; + output.push_string( AppPath_get() ); + output.push_string( "q3map2." ); + output.push_string( RADIANT_EXECUTABLE ); + output.push_string( " -v -game " ); + output.push_string( ( type && *type ) ? type : "quake3" ); + output.push_string( " -fs_basepath \"" ); + output.push_string( EnginePath_get() ); + output.push_string( "\" -fs_homepath \"" ); + output.push_string( g_qeglobals.m_userEnginePath.c_str() ); + output.push_string( "\" -fs_game " ); + output.push_string( gamename_get() ); + output.push_string( " -convert -format " ); + output.push_string( Brush::m_type == eBrushTypeQuake3BP ? "map_bp" : "map" ); + if ( extension_equal( path_get_extension( filename ), "map" ) ) { + output.push_string( " -readmap " ); + } + output.push_string( " \"" ); + output.push_string( filename ); + output.push_string( "\"" ); + + // run + Q_Exec( NULL, output.c_str(), NULL, false, true ); + + // rebuild filename as "filenamewithoutext_converted.map" + output.clear(); + output.push_range( filename, filename + string_length( filename ) - ( n + 1 ) ); + output.push_string( "_converted.map" ); + filename = output.c_str(); + + // open + Resource* resource = GlobalReferenceCache().capture( filename ); + resource->refresh(); // avoid loading old version if map has changed on disk since last import + if ( !resource->load() ) { + GlobalReferenceCache().release( filename ); + goto tryDecompile; + } + NodeSmartReference clone( NewMapRoot( "" ) ); + Node_getTraversable( *resource->getNode() )->traverse( CloneAll( clone ) ); + Map_gatherNamespaced( clone ); + Map_mergeClonedNames(); + MergeMap( clone ); + success = true; + GlobalReferenceCache().release( filename ); + } + + SceneChangeNotify(); + return success; } /* -=========== -Map_SaveFile -=========== -*/ -bool Map_SaveFile(const char* filename) -{ - ScopeDisableScreenUpdates disableScreenUpdates("Processing...", "Saving Map"); - return MapResource_saveFile(MapFormat_forFile(filename), GlobalSceneGraph().root(), Map_Traverse, filename); + =========== + Map_SaveFile + =========== + */ +bool Map_SaveFile( const char* filename ){ + ScopeDisableScreenUpdates disableScreenUpdates( "Processing...", "Saving Map" ); + bool success = MapResource_saveFile( MapFormat_forFile( filename ), GlobalSceneGraph().root(), Map_Traverse, filename ); + if ( success ) { + // refresh VFS to apply new pak filtering based on mapname + // needed for daemon DPK VFS + VFS_Refresh(); + } + return success; } // @@ -1662,336 +1618,302 @@ bool Map_SaveFile(const char* filename) // // Saves selected world brushes and whole entities with partial/full selections // -bool Map_SaveSelected(const char* filename) -{ - return MapResource_saveFile(MapFormat_forFile(filename), GlobalSceneGraph().root(), Map_Traverse_Selected, filename); +bool Map_SaveSelected( const char* filename ){ + return MapResource_saveFile( MapFormat_forFile( filename ), GlobalSceneGraph().root(), Map_Traverse_Selected, filename ); } class ParentSelectedBrushesToEntityWalker : public scene::Graph::Walker { - scene::Node& m_parent; +scene::Node& m_parent; public: - ParentSelectedBrushesToEntityWalker(scene::Node& parent) : m_parent(parent) - { - } - bool pre(const scene::Path& path, scene::Instance& instance) const - { - if(path.top().get_pointer() != &m_parent - && Node_isPrimitive(path.top())) - { - Selectable* selectable = Instance_getSelectable(instance); - if(selectable != 0 - && selectable->isSelected() - && path.size() > 1) - { - return false; - } - } - return true; - } - void post(const scene::Path& path, scene::Instance& instance) const - { - if(path.top().get_pointer() != &m_parent - && Node_isPrimitive(path.top())) - { - Selectable* selectable = Instance_getSelectable(instance); - if(selectable != 0 - && selectable->isSelected() - && path.size() > 1) - { - scene::Node& parent = path.parent(); - if(&parent != &m_parent) - { - NodeSmartReference node(path.top().get()); - Node_getTraversable(parent)->erase(node); - Node_getTraversable(m_parent)->insert(node); - } - } - } - } +ParentSelectedBrushesToEntityWalker( scene::Node& parent ) : m_parent( parent ){ +} +bool pre( const scene::Path& path, scene::Instance& instance ) const { + if ( path.top().get_pointer() != &m_parent + && Node_isPrimitive( path.top() ) ) { + Selectable* selectable = Instance_getSelectable( instance ); + if ( selectable != 0 + && selectable->isSelected() + && path.size() > 1 ) { + return false; + } + } + return true; +} +void post( const scene::Path& path, scene::Instance& instance ) const { + if ( path.top().get_pointer() != &m_parent + && Node_isPrimitive( path.top() ) ) { + Selectable* selectable = Instance_getSelectable( instance ); + if ( selectable != 0 + && selectable->isSelected() + && path.size() > 1 ) { + scene::Node& parent = path.parent(); + if ( &parent != &m_parent ) { + NodeSmartReference node( path.top().get() ); + Node_getTraversable( parent )->erase( node ); + Node_getTraversable( m_parent )->insert( node ); + } + } + } +} }; -void Scene_parentSelectedBrushesToEntity(scene::Graph& graph, scene::Node& parent) -{ - graph.traverse(ParentSelectedBrushesToEntityWalker(parent)); +void Scene_parentSelectedBrushesToEntity( scene::Graph& graph, scene::Node& parent ){ + graph.traverse( ParentSelectedBrushesToEntityWalker( parent ) ); } class CountSelectedBrushes : public scene::Graph::Walker { - std::size_t& m_count; - mutable std::size_t m_depth; +std::size_t& m_count; +mutable std::size_t m_depth; public: - CountSelectedBrushes(std::size_t& count) : m_count(count), m_depth(0) - { - m_count = 0; - } - bool pre(const scene::Path& path, scene::Instance& instance) const - { - if(++m_depth != 1 && path.top().get().isRoot()) - { - return false; - } - Selectable* selectable = Instance_getSelectable(instance); - if(selectable != 0 - && selectable->isSelected() - && Node_isPrimitive(path.top())) - { - ++m_count; - } - return true; - } - void post(const scene::Path& path, scene::Instance& instance) const - { - --m_depth; - } +CountSelectedBrushes( std::size_t& count ) : m_count( count ), m_depth( 0 ){ + m_count = 0; +} +bool pre( const scene::Path& path, scene::Instance& instance ) const { + if ( ++m_depth != 1 && path.top().get().isRoot() ) { + return false; + } + Selectable* selectable = Instance_getSelectable( instance ); + if ( selectable != 0 + && selectable->isSelected() + && Node_isPrimitive( path.top() ) ) { + ++m_count; + } + return true; +} +void post( const scene::Path& path, scene::Instance& instance ) const { + --m_depth; +} }; -std::size_t Scene_countSelectedBrushes(scene::Graph& graph) -{ - std::size_t count; - graph.traverse(CountSelectedBrushes(count)); - return count; +std::size_t Scene_countSelectedBrushes( scene::Graph& graph ){ + std::size_t count; + graph.traverse( CountSelectedBrushes( count ) ); + return count; } enum ENodeType { - eNodeUnknown, - eNodeMap, - eNodeEntity, - eNodePrimitive, + eNodeUnknown, + eNodeMap, + eNodeEntity, + eNodePrimitive, }; -const char* nodetype_get_name(ENodeType type) -{ - if(type == eNodeMap) - return "map"; - if(type == eNodeEntity) - return "entity"; - if(type == eNodePrimitive) - return "primitive"; - return "unknown"; -} +const char* nodetype_get_name( ENodeType type ){ + if ( type == eNodeMap ) { + return "map"; + } + if ( type == eNodeEntity ) { + return "entity"; + } + if ( type == eNodePrimitive ) { + return "primitive"; + } + return "unknown"; +} + +ENodeType node_get_nodetype( scene::Node& node ){ + if ( Node_isEntity( node ) ) { + return eNodeEntity; + } + if ( Node_isPrimitive( node ) ) { + return eNodePrimitive; + } + return eNodeUnknown; +} + +bool contains_entity( scene::Node& node ){ + return Node_getTraversable( node ) != 0 && !Node_isBrush( node ) && !Node_isPatch( node ) && !Node_isEntity( node ); +} + +bool contains_primitive( scene::Node& node ){ + return Node_isEntity( node ) && Node_getTraversable( node ) != 0 && Node_getEntity( node )->isContainer(); +} + +ENodeType node_get_contains( scene::Node& node ){ + if ( contains_entity( node ) ) { + return eNodeEntity; + } + if ( contains_primitive( node ) ) { + return eNodePrimitive; + } + return eNodeUnknown; +} + +void Path_parent( const scene::Path& parent, const scene::Path& child ){ + ENodeType contains = node_get_contains( parent.top() ); + ENodeType type = node_get_nodetype( child.top() ); + + if ( contains != eNodeUnknown && contains == type ) { + NodeSmartReference node( child.top().get() ); + Path_deleteTop( child ); + Node_getTraversable( parent.top() )->insert( node ); + SceneChangeNotify(); + } + else + { + globalErrorStream() << "failed - " << nodetype_get_name( type ) << " cannot be parented to " << nodetype_get_name( contains ) << " container.\n"; + } +} + +void Scene_parentSelected(){ + UndoableCommand undo( "parentSelected" ); + + if ( GlobalSelectionSystem().countSelected() > 1 ) { + class ParentSelectedBrushesToEntityWalker : public SelectionSystem::Visitor + { + const scene::Path& m_parent; +public: + ParentSelectedBrushesToEntityWalker( const scene::Path& parent ) : m_parent( parent ){ + } + void visit( scene::Instance& instance ) const { + if ( &m_parent != &instance.path() ) { + Path_parent( m_parent, instance.path() ); + } + } + }; -ENodeType node_get_nodetype(scene::Node& node) -{ - if(Node_isEntity(node)) - { - return eNodeEntity; - } - if(Node_isPrimitive(node)) - { - return eNodePrimitive; - } - return eNodeUnknown; -} - -bool contains_entity(scene::Node& node) -{ - return Node_getTraversable(node) != 0 && !Node_isBrush(node) && !Node_isPatch(node) && !Node_isEntity(node); + ParentSelectedBrushesToEntityWalker visitor( GlobalSelectionSystem().ultimateSelected().path() ); + GlobalSelectionSystem().foreachSelected( visitor ); + } + else + { + globalOutputStream() << "failed - did not find two selected nodes.\n"; + } } -bool contains_primitive(scene::Node& node) -{ - return Node_isEntity(node) && Node_getTraversable(node) != 0 && Node_getEntity(node)->isContainer(); -} -ENodeType node_get_contains(scene::Node& node) -{ - if(contains_entity(node)) - { - return eNodeEntity; - } - if(contains_primitive(node)) - { - return eNodePrimitive; - } - return eNodeUnknown; -} - -void Path_parent(const scene::Path& parent, const scene::Path& child) -{ - ENodeType contains = node_get_contains(parent.top()); - ENodeType type = node_get_nodetype(child.top()); - - if(contains != eNodeUnknown && contains == type) - { - NodeSmartReference node(child.top().get()); - Path_deleteTop(child); - Node_getTraversable(parent.top())->insert(node); - SceneChangeNotify(); - } - else - { - globalErrorStream() << "failed - " << nodetype_get_name(type) << " cannot be parented to " << nodetype_get_name(contains) << " container.\n"; - } -} - -void Scene_parentSelected() -{ - UndoableCommand undo("parentSelected"); - - if(GlobalSelectionSystem().countSelected() > 1) - { - class ParentSelectedBrushesToEntityWalker : public SelectionSystem::Visitor - { - const scene::Path& m_parent; - public: - ParentSelectedBrushesToEntityWalker(const scene::Path& parent) : m_parent(parent) - { - } - void visit(scene::Instance& instance) const - { - if(&m_parent != &instance.path()) - { - Path_parent(m_parent, instance.path()); - } - } - }; - - ParentSelectedBrushesToEntityWalker visitor(GlobalSelectionSystem().ultimateSelected().path()); - GlobalSelectionSystem().foreachSelected(visitor); - } - else - { - globalOutputStream() << "failed - did not find two selected nodes.\n"; - } -} - - - -void NewMap() -{ - if (ConfirmModified("New Map")) - { - Map_RegionOff(); - Map_Free(); - Map_New(); - } + +void NewMap(){ + if ( ConfirmModified( "New Map" ) ) { + Map_RegionOff(); + Map_Free(); + Map_New(); + } } CopiedString g_mapsPath; -const char* getMapsPath() -{ - return g_mapsPath.c_str(); +const char* getMapsPath(){ + return g_mapsPath.c_str(); } -const char* map_open(const char* title) -{ - return file_dialog(GTK_WIDGET(MainFrame_getWindow()), TRUE, title, getMapsPath(), MapFormat::Name()); +const char* getLastFolderPath(){ + if (g_strLastFolder.empty()) { + GlobalPreferenceSystem().registerPreference( "LastFolder", CopiedStringImportStringCaller( g_strLastFolder ), CopiedStringExportStringCaller( g_strLastFolder ) ); + if (g_strLastFolder.empty()) { + g_strLastFolder = g_qeglobals.m_userGamePath; + } + } + return g_strLastFolder.c_str(); } -const char* map_save(const char* title) -{ - return file_dialog(GTK_WIDGET(MainFrame_getWindow()), FALSE, title, getMapsPath(), MapFormat::Name()); +const char* map_open( const char* title ){ + return file_dialog( GTK_WIDGET( MainFrame_getWindow() ), TRUE, title, getLastFolderPath(), MapFormat::Name(), false, true, false ); } -void OpenMap() -{ - if (!ConfirmModified("Open Map")) - return; +const char* map_import( const char* title ){ + return file_dialog( GTK_WIDGET( MainFrame_getWindow() ), TRUE, title, getLastFolderPath(), MapFormat::Name(), false, true, false ); +} + +const char* map_save( const char* title ){ + return file_dialog( GTK_WIDGET( MainFrame_getWindow() ), FALSE, title, getLastFolderPath(), MapFormat::Name(), false, false, true ); +} + +void OpenMap(){ + if ( !ConfirmModified( "Open Map" ) ) { + return; + } - const char* filename = map_open("Open Map"); + const char* filename = map_open( "Open Map" ); - if (filename != 0) - { - MRU_AddFile(filename); - Map_RegionOff(); - Map_Free(); - Map_LoadFile(filename); - } + if ( filename != NULL ) { + MRU_AddFile( filename ); + Map_RegionOff(); + Map_Free(); + Map_LoadFile( filename ); + } } -void ImportMap() -{ - const char* filename = map_open("Import Map"); +void ImportMap(){ + const char* filename = map_import( "Import Map" ); - if(filename != 0) - { - UndoableCommand undo("mapImport"); - Map_ImportFile(filename); - } + if ( filename != NULL ) { + UndoableCommand undo( "mapImport" ); + Map_ImportFile( filename ); + } } -bool Map_SaveAs() -{ - const char* filename = map_save("Save Map"); - - if(filename != 0) - { - MRU_AddFile(filename); - Map_Rename(filename); - return Map_Save(); - } - return false; -} - -void SaveMapAs() -{ - Map_SaveAs(); +bool Map_SaveAs(){ + const char* filename = map_save( "Save Map" ); + + if ( filename != NULL ) { + g_strLastFolder = g_path_get_dirname( filename ); + MRU_AddFile( filename ); + Map_Rename( filename ); + return Map_Save(); + } + return false; } -void SaveMap() -{ - if(Map_Unnamed(g_map)) - { - SaveMapAs(); - } - else if(Map_Modified(g_map)) - { - Map_Save(); - } +void SaveMapAs(){ + Map_SaveAs(); } -void ExportMap() -{ - const char* filename = map_save("Export Selection"); +void SaveMap(){ + if ( Map_Unnamed( g_map ) ) { + SaveMapAs(); + } + else if ( Map_Modified( g_map ) ) { + Map_Save(); + } +} + +void ExportMap(){ + const char* filename = map_save( "Export Selection" ); - if(filename != 0) - { - Map_SaveSelected(filename); - } + if ( filename != NULL ) { + g_strLastFolder = g_path_get_dirname( filename ); + Map_SaveSelected( filename ); + } } -void SaveRegion() -{ - const char* filename = map_save("Export Region"); - - if(filename != 0) - { - Map_SaveRegion(filename); - } +void SaveRegion(){ + const char* filename = map_save( "Export Region" ); + + if ( filename != NULL ) { + g_strLastFolder = g_path_get_dirname( filename ); + Map_SaveRegion( filename ); + } } -void RegionOff() -{ - Map_RegionOff(); - SceneChangeNotify(); +void RegionOff(){ + Map_RegionOff(); + SceneChangeNotify(); } -void RegionXY() -{ - Map_RegionXY( - g_pParentWnd->GetXYWnd()->GetOrigin()[0] - 0.5f * g_pParentWnd->GetXYWnd()->Width() / g_pParentWnd->GetXYWnd()->Scale(), - g_pParentWnd->GetXYWnd()->GetOrigin()[1] - 0.5f * g_pParentWnd->GetXYWnd()->Height() / g_pParentWnd->GetXYWnd()->Scale(), - g_pParentWnd->GetXYWnd()->GetOrigin()[0] + 0.5f * g_pParentWnd->GetXYWnd()->Width() / g_pParentWnd->GetXYWnd()->Scale(), - g_pParentWnd->GetXYWnd()->GetOrigin()[1] + 0.5f * g_pParentWnd->GetXYWnd()->Height() / g_pParentWnd->GetXYWnd()->Scale() - ); - SceneChangeNotify(); +void RegionXY(){ + Map_RegionXY( + g_pParentWnd->GetXYWnd()->GetOrigin()[0] - 0.5f * g_pParentWnd->GetXYWnd()->Width() / g_pParentWnd->GetXYWnd()->Scale(), + g_pParentWnd->GetXYWnd()->GetOrigin()[1] - 0.5f * g_pParentWnd->GetXYWnd()->Height() / g_pParentWnd->GetXYWnd()->Scale(), + g_pParentWnd->GetXYWnd()->GetOrigin()[0] + 0.5f * g_pParentWnd->GetXYWnd()->Width() / g_pParentWnd->GetXYWnd()->Scale(), + g_pParentWnd->GetXYWnd()->GetOrigin()[1] + 0.5f * g_pParentWnd->GetXYWnd()->Height() / g_pParentWnd->GetXYWnd()->Scale() + ); + SceneChangeNotify(); } -void RegionBrush() -{ - Map_RegionBrush(); - SceneChangeNotify(); +void RegionBrush(){ + Map_RegionBrush(); + SceneChangeNotify(); } -void RegionSelected() -{ - Map_RegionSelectedBrushes(); - SceneChangeNotify(); +void RegionSelected(){ + Map_RegionSelectedBrushes(); + SceneChangeNotify(); } @@ -2000,269 +1922,235 @@ void RegionSelected() class BrushFindByIndexWalker : public scene::Traversable::Walker { - mutable std::size_t m_index; - scene::Path& m_path; +mutable std::size_t m_index; +scene::Path& m_path; public: - BrushFindByIndexWalker(std::size_t index, scene::Path& path) - : m_index(index), m_path(path) - { - } - bool pre(scene::Node& node) const - { - if(Node_isPrimitive(node) && m_index-- == 0) - { - m_path.push(makeReference(node)); - } - return false; - } +BrushFindByIndexWalker( std::size_t index, scene::Path& path ) + : m_index( index ), m_path( path ){ +} +bool pre( scene::Node& node ) const { + if ( Node_isPrimitive( node ) && m_index-- == 0 ) { + m_path.push( makeReference( node ) ); + } + return false; +} }; class EntityFindByIndexWalker : public scene::Traversable::Walker { - mutable std::size_t m_index; - scene::Path& m_path; +mutable std::size_t m_index; +scene::Path& m_path; public: - EntityFindByIndexWalker(std::size_t index, scene::Path& path) - : m_index(index), m_path(path) - { - } - bool pre(scene::Node& node) const - { - if(Node_isEntity(node) && m_index-- == 0) - { - m_path.push(makeReference(node)); - } - return false; - } +EntityFindByIndexWalker( std::size_t index, scene::Path& path ) + : m_index( index ), m_path( path ){ +} +bool pre( scene::Node& node ) const { + if ( Node_isEntity( node ) && m_index-- == 0 ) { + m_path.push( makeReference( node ) ); + } + return false; +} }; -void Scene_FindEntityBrush(std::size_t entity, std::size_t brush, scene::Path& path) -{ - path.push(makeReference(GlobalSceneGraph().root())); - { - Node_getTraversable(path.top())->traverse(EntityFindByIndexWalker(entity, path)); - } - if(path.size() == 2) - { - scene::Traversable* traversable = Node_getTraversable(path.top()); - if(traversable != 0) - { - traversable->traverse(BrushFindByIndexWalker(brush, path)); - } - } -} - -inline bool Node_hasChildren(scene::Node& node) -{ - scene::Traversable* traversable = Node_getTraversable(node); - return traversable != 0 && !traversable->empty(); +void Scene_FindEntityBrush( std::size_t entity, std::size_t brush, scene::Path& path ){ + path.push( makeReference( GlobalSceneGraph().root() ) ); + { + Node_getTraversable( path.top() )->traverse( EntityFindByIndexWalker( entity, path ) ); + } + if ( path.size() == 2 ) { + scene::Traversable* traversable = Node_getTraversable( path.top() ); + if ( traversable != 0 ) { + traversable->traverse( BrushFindByIndexWalker( brush, path ) ); + } + } } -void SelectBrush (int entitynum, int brushnum) -{ - scene::Path path; - Scene_FindEntityBrush(entitynum, brushnum, path); - if(path.size() == 3 || (path.size() == 2 && !Node_hasChildren(path.top()))) - { - scene::Instance* instance = GlobalSceneGraph().find(path); - ASSERT_MESSAGE(instance != 0, "SelectBrush: path not found in scenegraph"); - Selectable* selectable = Instance_getSelectable(*instance); - ASSERT_MESSAGE(selectable != 0, "SelectBrush: path not selectable"); - selectable->setSelected(true); - g_pParentWnd->GetXYWnd()->PositionView(instance->worldAABB().origin); - } +inline bool Node_hasChildren( scene::Node& node ){ + scene::Traversable* traversable = Node_getTraversable( node ); + return traversable != 0 && !traversable->empty(); +} + +void SelectBrush( int entitynum, int brushnum ){ + scene::Path path; + Scene_FindEntityBrush( entitynum, brushnum, path ); + if ( path.size() == 3 || ( path.size() == 2 && !Node_hasChildren( path.top() ) ) ) { + scene::Instance* instance = GlobalSceneGraph().find( path ); + ASSERT_MESSAGE( instance != 0, "SelectBrush: path not found in scenegraph" ); + Selectable* selectable = Instance_getSelectable( *instance ); + ASSERT_MESSAGE( selectable != 0, "SelectBrush: path not selectable" ); + selectable->setSelected( true ); + g_pParentWnd->GetXYWnd()->PositionView( instance->worldAABB().origin ); + } } class BrushFindIndexWalker : public scene::Graph::Walker { - mutable const scene::Node* m_node; - std::size_t& m_count; +mutable const scene::Node* m_node; +std::size_t& m_count; public: - BrushFindIndexWalker(const scene::Node& node, std::size_t& count) - : m_node(&node), m_count(count) - { - } - bool pre(const scene::Path& path, scene::Instance& instance) const - { - if(Node_isPrimitive(path.top())) - { - if(m_node == path.top().get_pointer()) - { - m_node = 0; - } - if(m_node) - { - ++m_count; - } - } - return true; - } +BrushFindIndexWalker( const scene::Node& node, std::size_t& count ) + : m_node( &node ), m_count( count ){ +} +bool pre( const scene::Path& path, scene::Instance& instance ) const { + if ( Node_isPrimitive( path.top() ) ) { + if ( m_node == path.top().get_pointer() ) { + m_node = 0; + } + if ( m_node ) { + ++m_count; + } + } + return true; +} }; class EntityFindIndexWalker : public scene::Graph::Walker { - mutable const scene::Node* m_node; - std::size_t& m_count; +mutable const scene::Node* m_node; +std::size_t& m_count; public: - EntityFindIndexWalker(const scene::Node& node, std::size_t& count) - : m_node(&node), m_count(count) - { - } - bool pre(const scene::Path& path, scene::Instance& instance) const - { - if(Node_isEntity(path.top())) - { - if(m_node == path.top().get_pointer()) - { - m_node = 0; - } - if(m_node) - { - ++m_count; - } - } - return true; - } -}; - -static void GetSelectionIndex (int *ent, int *brush) -{ - std::size_t count_brush = 0; - std::size_t count_entity = 0; - if(GlobalSelectionSystem().countSelected() != 0) - { - const scene::Path& path = GlobalSelectionSystem().ultimateSelected().path(); - - GlobalSceneGraph().traverse(BrushFindIndexWalker(path.top(), count_brush)); - GlobalSceneGraph().traverse(EntityFindIndexWalker(path.parent(), count_entity)); - } - *brush = int(count_brush); - *ent = int(count_entity); +EntityFindIndexWalker( const scene::Node& node, std::size_t& count ) + : m_node( &node ), m_count( count ){ +} +bool pre( const scene::Path& path, scene::Instance& instance ) const { + if ( Node_isEntity( path.top() ) ) { + if ( m_node == path.top().get_pointer() ) { + m_node = 0; + } + if ( m_node ) { + ++m_count; + } + } + return true; } +}; -void DoFind() -{ - ModalDialog dialog; - GtkEntry* entity; - GtkEntry* brush; - - GtkWindow* window = create_dialog_window(MainFrame_getWindow(), "Find Brush", G_CALLBACK(dialog_delete_callback), &dialog); - - GtkAccelGroup* accel = gtk_accel_group_new(); - gtk_window_add_accel_group(window, accel); - - { - GtkVBox* vbox = create_dialog_vbox(4, 4); - gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(vbox)); - { - GtkTable* table = create_dialog_table(2, 2, 4, 4); - gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(table), TRUE, TRUE, 0); - { - GtkWidget* label = gtk_label_new ("Entity number"); - gtk_widget_show (label); - gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, - (GtkAttachOptions) (0), - (GtkAttachOptions) (0), 0, 0); - } - { - GtkWidget* label = gtk_label_new ("Brush number"); - gtk_widget_show (label); - gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, - (GtkAttachOptions) (0), - (GtkAttachOptions) (0), 0, 0); - } - { - GtkEntry* entry = GTK_ENTRY(gtk_entry_new()); - gtk_widget_show(GTK_WIDGET(entry)); - gtk_table_attach(table, GTK_WIDGET(entry), 1, 2, 0, 1, - (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - gtk_widget_grab_focus(GTK_WIDGET(entry)); - entity = entry; - } - { - GtkEntry* entry = GTK_ENTRY(gtk_entry_new()); - gtk_widget_show(GTK_WIDGET(entry)); - gtk_table_attach(table, GTK_WIDGET(entry), 1, 2, 1, 2, - (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), - (GtkAttachOptions) (0), 0, 0); - - brush = entry; - } - } - { - GtkHBox* hbox = create_dialog_hbox(4); - gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(hbox), TRUE, TRUE, 0); - { - GtkButton* button = create_dialog_button("Find", G_CALLBACK(dialog_button_ok), &dialog); - gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(button), FALSE, FALSE, 0); - widget_make_default(GTK_WIDGET(button)); - gtk_widget_add_accelerator(GTK_WIDGET(button), "clicked", accel, GDK_Return, (GdkModifierType)0, (GtkAccelFlags)0); - } - { - GtkButton* button = create_dialog_button("Close", G_CALLBACK(dialog_button_cancel), &dialog); - gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(button), FALSE, FALSE, 0); - gtk_widget_add_accelerator(GTK_WIDGET(button), "clicked", accel, GDK_Escape, (GdkModifierType)0, (GtkAccelFlags)0); - } - } - } - - // Initialize dialog - char buf[16]; - int ent, br; - - GetSelectionIndex (&ent, &br); - sprintf (buf, "%i", ent); - gtk_entry_set_text(entity, buf); - sprintf (buf, "%i", br); - gtk_entry_set_text(brush, buf); - - if(modal_dialog_show(window, dialog) == eIDOK) - { - const char *entstr = gtk_entry_get_text(entity); - const char *brushstr = gtk_entry_get_text(brush); - SelectBrush (atoi(entstr), atoi(brushstr)); - } - - gtk_widget_destroy(GTK_WIDGET(window)); -} - -void Map_constructPreferences(PreferencesPage& page) -{ - page.appendCheckBox("", "Load last map on open", g_bLoadLastMap); +static void GetSelectionIndex( int *ent, int *brush ){ + std::size_t count_brush = 0; + std::size_t count_entity = 0; + if ( GlobalSelectionSystem().countSelected() != 0 ) { + const scene::Path& path = GlobalSelectionSystem().ultimateSelected().path(); + + GlobalSceneGraph().traverse( BrushFindIndexWalker( path.top(), count_brush ) ); + GlobalSceneGraph().traverse( EntityFindIndexWalker( path.parent(), count_entity ) ); + } + *brush = int(count_brush); + *ent = int(count_entity); +} + +void DoFind(){ + ModalDialog dialog; + GtkEntry* entity; + GtkEntry* brush; + + GtkWindow* window = create_dialog_window( MainFrame_getWindow(), "Find Brush", G_CALLBACK( dialog_delete_callback ), &dialog ); + + GtkAccelGroup* accel = gtk_accel_group_new(); + gtk_window_add_accel_group( window, accel ); + + { + GtkVBox* vbox = create_dialog_vbox( 4, 4 ); + gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( vbox ) ); + { + GtkTable* table = create_dialog_table( 2, 2, 4, 4 ); + gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( table ), TRUE, TRUE, 0 ); + { + GtkWidget* label = gtk_label_new( "Entity number" ); + gtk_widget_show( label ); + gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 0, 1, + (GtkAttachOptions) ( 0 ), + (GtkAttachOptions) ( 0 ), 0, 0 ); + } + { + GtkWidget* label = gtk_label_new( "Brush number" ); + gtk_widget_show( label ); + gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 1, 2, + (GtkAttachOptions) ( 0 ), + (GtkAttachOptions) ( 0 ), 0, 0 ); + } + { + GtkEntry* entry = GTK_ENTRY( gtk_entry_new() ); + gtk_widget_show( GTK_WIDGET( entry ) ); + gtk_table_attach( table, GTK_WIDGET( entry ), 1, 2, 0, 1, + (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), + (GtkAttachOptions) ( 0 ), 0, 0 ); + gtk_widget_grab_focus( GTK_WIDGET( entry ) ); + entity = entry; + } + { + GtkEntry* entry = GTK_ENTRY( gtk_entry_new() ); + gtk_widget_show( GTK_WIDGET( entry ) ); + gtk_table_attach( table, GTK_WIDGET( entry ), 1, 2, 1, 2, + (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), + (GtkAttachOptions) ( 0 ), 0, 0 ); + + brush = entry; + } + } + { + GtkHBox* hbox = create_dialog_hbox( 4 ); + gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( hbox ), TRUE, TRUE, 0 ); + { + GtkButton* button = create_dialog_button( "Find", G_CALLBACK( dialog_button_ok ), &dialog ); + gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); + widget_make_default( GTK_WIDGET( button ) ); + gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_Return, (GdkModifierType)0, (GtkAccelFlags)0 ); + } + { + GtkButton* button = create_dialog_button( "Close", G_CALLBACK( dialog_button_cancel ), &dialog ); + gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 ); + gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_Escape, (GdkModifierType)0, (GtkAccelFlags)0 ); + } + } + } + + // Initialize dialog + char buf[16]; + int ent, br; + + GetSelectionIndex( &ent, &br ); + sprintf( buf, "%i", ent ); + gtk_entry_set_text( entity, buf ); + sprintf( buf, "%i", br ); + gtk_entry_set_text( brush, buf ); + + if ( modal_dialog_show( window, dialog ) == eIDOK ) { + const char *entstr = gtk_entry_get_text( entity ); + const char *brushstr = gtk_entry_get_text( brush ); + SelectBrush( atoi( entstr ), atoi( brushstr ) ); + } + + gtk_widget_destroy( GTK_WIDGET( window ) ); +} + +void Map_constructPreferences( PreferencesPage& page ){ + page.appendCheckBox( "", "Load last map on open", g_bLoadLastMap ); } class MapEntityClasses : public ModuleObserver { - std::size_t m_unrealised; +std::size_t m_unrealised; public: - MapEntityClasses() : m_unrealised(1) - { - } - void realise() - { - if(--m_unrealised == 0) - { - if(g_map.m_resource != 0) - { - ScopeDisableScreenUpdates disableScreenUpdates("Processing...", "Loading Map"); - g_map.m_resource->realise(); - } - } - } - void unrealise() - { - if(++m_unrealised == 1) - { - if(g_map.m_resource != 0) - { - g_map.m_resource->flush(); - g_map.m_resource->unrealise(); - } - } - } +MapEntityClasses() : m_unrealised( 1 ){ +} +void realise(){ + if ( --m_unrealised == 0 ) { + if ( g_map.m_resource != 0 ) { + ScopeDisableScreenUpdates disableScreenUpdates( "Processing...", "Loading Map" ); + g_map.m_resource->realise(); + } + } +} +void unrealise(){ + if ( ++m_unrealised == 1 ) { + if ( g_map.m_resource != 0 ) { + g_map.m_resource->flush(); + g_map.m_resource->unrealise(); + } + } +} }; MapEntityClasses g_MapEntityClasses; @@ -2270,57 +2158,48 @@ MapEntityClasses g_MapEntityClasses; class MapModuleObserver : public ModuleObserver { - std::size_t m_unrealised; +std::size_t m_unrealised; public: - MapModuleObserver() : m_unrealised(1) - { - } - void realise() - { - if(--m_unrealised == 0) - { - ASSERT_MESSAGE(!string_empty(g_qeglobals.m_userGamePath.c_str()), "maps_directory: user-game-path is empty"); - StringOutputStream buffer(256); - buffer << g_qeglobals.m_userGamePath.c_str() << "maps/"; - Q_mkdir(buffer.c_str()); - g_mapsPath = buffer.c_str(); - } - } - void unrealise() - { - if(++m_unrealised == 1) - { - g_mapsPath = ""; - } - } +MapModuleObserver() : m_unrealised( 1 ){ +} +void realise(){ + if ( --m_unrealised == 0 ) { + ASSERT_MESSAGE( !string_empty( g_qeglobals.m_userGamePath.c_str() ), "maps_directory: user-game-path is empty" ); + StringOutputStream buffer( 256 ); + buffer << g_qeglobals.m_userGamePath.c_str() << "maps/"; + Q_mkdir( buffer.c_str() ); + g_mapsPath = buffer.c_str(); + } +} +void unrealise(){ + if ( ++m_unrealised == 1 ) { + g_mapsPath = ""; + } +} }; MapModuleObserver g_MapModuleObserver; -#include "preferencesystem.h" - CopiedString g_strLastMap; bool g_bLoadLastMap = false; -void Map_Construct() -{ - GlobalCommands_insert("RegionOff", FreeCaller()); - GlobalCommands_insert("RegionSetXY", FreeCaller()); - GlobalCommands_insert("RegionSetBrush", FreeCaller()); - GlobalCommands_insert("RegionSetSelection", FreeCaller(), Accelerator('R', (GdkModifierType)(GDK_SHIFT_MASK|GDK_CONTROL_MASK))); +void Map_Construct(){ + GlobalCommands_insert( "RegionOff", FreeCaller() ); + GlobalCommands_insert( "RegionSetXY", FreeCaller() ); + GlobalCommands_insert( "RegionSetBrush", FreeCaller() ); + GlobalCommands_insert( "RegionSetSelection", FreeCaller(), Accelerator( 'R', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) ); + + GlobalPreferenceSystem().registerPreference( "LastMap", CopiedStringImportStringCaller( g_strLastMap ), CopiedStringExportStringCaller( g_strLastMap ) ); + GlobalPreferenceSystem().registerPreference( "LoadLastMap", BoolImportStringCaller( g_bLoadLastMap ), BoolExportStringCaller( g_bLoadLastMap ) ); + GlobalPreferenceSystem().registerPreference( "MapInfoDlg", WindowPositionImportStringCaller( g_posMapInfoWnd ), WindowPositionExportStringCaller( g_posMapInfoWnd ) ); - GlobalPreferenceSystem().registerPreference("LastMap", CopiedStringImportStringCaller(g_strLastMap), CopiedStringExportStringCaller(g_strLastMap)); - GlobalPreferenceSystem().registerPreference("LoadLastMap", BoolImportStringCaller(g_bLoadLastMap), BoolExportStringCaller(g_bLoadLastMap)); - GlobalPreferenceSystem().registerPreference("MapInfoDlg", WindowPositionImportStringCaller(g_posMapInfoWnd), WindowPositionExportStringCaller(g_posMapInfoWnd)); - - PreferencesDialog_addSettingsPreferences(FreeCaller1()); + PreferencesDialog_addSettingsPreferences( FreeCaller1() ); - GlobalEntityClassManager().attach(g_MapEntityClasses); - Radiant_attachHomePathsObserver(g_MapModuleObserver); + GlobalEntityClassManager().attach( g_MapEntityClasses ); + Radiant_attachHomePathsObserver( g_MapModuleObserver ); } -void Map_Destroy() -{ - Radiant_detachHomePathsObserver(g_MapModuleObserver); - GlobalEntityClassManager().detach(g_MapEntityClasses); +void Map_Destroy(){ + Radiant_detachHomePathsObserver( g_MapModuleObserver ); + GlobalEntityClassManager().detach( g_MapEntityClasses ); }