X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fnetradiant.git;a=blobdiff_plain;f=radiant%2Fmap.cpp;h=2cecfe3cd81bc572af7b0c7299a69ac487ba6bdd;hp=18d25c096c17784ffbef248310e271eadb90f858;hb=fba3b3fa800b29f40276b14aa995810df86148db;hpb=ff58d04be4e8fed403a791736db05c76fa3adb65 diff --git a/radiant/map.cpp b/radiant/map.cpp index 18d25c09..2cecfe3c 100644 --- a/radiant/map.cpp +++ b/radiant/map.cpp @@ -21,10 +21,14 @@ #include "map.h" +#include + #include "debugging/debugging.h" #include "imap.h" -MapModules& ReferenceAPI_getMapModules(); + +MapModules &ReferenceAPI_getMapModules(); + #include "iselection.h" #include "iundo.h" #include "ibrush.h" @@ -42,15 +46,8 @@ MapModules& ReferenceAPI_getMapModules(); #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include "uilib/uilib.h" #include "scenelib.h" #include "transformlib.h" @@ -81,6 +78,7 @@ MapModules& ReferenceAPI_getMapModules(); #include "xywindow.h" #include "mainframe.h" #include "preferences.h" +#include "preferencesystem.h" #include "referencecache.h" #include "mru.h" #include "commands.h" @@ -88,312 +86,355 @@ MapModules& ReferenceAPI_getMapModules(); #include "brushmodule.h" #include "brush.h" -class NameObserver -{ -UniqueNames& m_names; -CopiedString m_name; +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() ) ); - } -} + 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); -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 MemberCaller NameChangedCaller; }; -class BasicNamespace : public Namespace -{ -typedef std::map Names; -Names m_names; -UniqueNames m_uniqueNames; +class BasicNamespace : public Namespace { + 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; BasicNamespace g_cloneNamespace; -class NamespaceAPI -{ -Namespace* m_namespace; +class NamespaceAPI { + Namespace *m_namespace; public: -typedef Namespace Type; -STRING_CONSTANT( Name, "*" ); + typedef Namespace Type; -NamespaceAPI(){ - m_namespace = &g_defaultNamespace; -} -Namespace* getTable(){ - return m_namespace; -} + 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; +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 -{ +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; +class WorldNode { + 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); -class Map : public ModuleObserver -{ +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; + CopiedString m_name; + Resource *m_resource; + bool m_valid; -bool m_modified; -void ( *m_modified_changed )( const Map& ); + bool m_modified; -Signal0 m_mapValidCallbacks; + void ( *m_modified_changed )(const Map &); -WorldNode m_world_node; // "classname" "worldspawn" ! + Signal0 m_mapValidCallbacks; -Map() : m_resource( 0 ), m_valid( false ), m_modified_changed( Map_UpdateTitle ){ -} + WorldNode m_world_node; // "classname" "worldspawn" ! -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(); - } + Map() : m_resource(0), m_valid(false), m_modified_changed(Map_UpdateTitle) + { + } - GlobalSceneGraph().insert_root( *m_resource->getNode() ); + 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(); + } - AutoSave_clear(); + GlobalSceneGraph().insert_root(*m_resource->getNode()); - Map_SetValid( g_map, true ); - } -} -void unrealise(){ - if ( m_resource != 0 ) { - Map_SetValid( g_map, false ); - Map_SetWorldspawn( g_map, 0 ); + AutoSave_clear(); + Map_SetValid(g_map, true); + } + } - GlobalUndoSystem().clear(); + void unrealise() + { + if (m_resource != 0) { + Map_SetValid(g_map, false); + Map_SetWorldspawn(g_map, 0); - GlobalSceneGraph().erase_root(); - } -} + + GlobalUndoSystem().clear(); + + GlobalSceneGraph().erase_root(); + } + } }; Map g_map; -Map* g_currentMap = 0; +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); } @@ -402,9 +443,9 @@ void Map_SetWorldspawn( Map& map, scene::Node* node ){ float g_MaxWorldCoord = 64 * 1024; float g_MinWorldCoord = -64 * 1024; -void AddRegionBrushes( void ); -void RemoveRegionBrushes( void ); +void AddRegionBrushes(void); +void RemoveRegionBrushes(void); /* @@ -413,64 +454,68 @@ void RemoveRegionBrushes( void ); free all map elements, reinitialize the structures that depend on them ================ */ -void Map_Free(){ - Pointfile_Clear(); +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; - Brush_unlatchPreferences(); + g_currentMap = 0; + Brush_unlatchPreferences(); } -class EntityFindByClassname : public scene::Graph::Walker -{ -const char* m_name; -Entity*& m_entity; +class EntityFindByClassname : public scene::Graph::Walker { + 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; -} + 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; -} - -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; } // @@ -478,449 +523,472 @@ 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"); } // use first worldspawn -class entity_updateworldspawn : public scene::Traversable::Walker -{ +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; +class CollectAllWalker : public scene::Traversable::Walker { + 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; +class MapMergeAll : public scene::Traversable::Walker { + 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; +class MapMergeEntities : public scene::Traversable::Walker { + 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; +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; public: -TypeCasts(){ - NodeContainedCast::install( m_casts ); -} -NodeTypeCastTable& get(){ - return m_casts; -} -}; -scene::Node m_node; -TraversableNodeSet m_traverse; -public: + typedef LazyStatic StaticTypeCasts; -typedef LazyStatic StaticTypeCasts; + scene::Traversable &get(NullType) + { + return m_traverse; + } -scene::Traversable& get( NullType){ - return m_traverse; -} + BasicContainer() : m_node(this, this, StaticTypeCasts::instance().get()) + { + } -BasicContainer() : m_node( this, this, StaticTypeCasts::instance().get() ){ -} -void release(){ - delete this; -} -scene::Node& node(){ - return m_node; -} + 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 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 MergeMap(scene::Node &node) +{ + Node_getTraversable(node)->traverse(MapMergeEntities(scene::Path(makeReference(GlobalSceneGraph().root())))); } -inline scene::Cloneable* Node_getCloneable( scene::Node& node ){ - return NodeTypeCast::cast( 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::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::Cloneable *Node_getCloneable(scene::Node &node) +{ + return NodeTypeCast::cast(node); } -class CloneAll : public scene::Traversable::Walker +inline scene::Node &node_clone(scene::Node &node) { -mutable scene::Path m_path; -public: -CloneAll( scene::Node& root ) - : m_path( makeReference( root ) ){ + scene::Cloneable *cloneable = Node_getCloneable(node); + if (cloneable != 0) { + return cloneable->clone(); + } + + return (new scene::NullNode)->node(); } -bool pre( scene::Node& node ) const { - if ( node.isRoot() ) { - return false; - } - m_path.push( makeReference( node_clone( node ) ) ); - m_path.top().get().IncRef(); +class CloneAll : public scene::Traversable::Walker { + 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(); + } +}; - return true; +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; } -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(); -} +typedef std::map EntityBreakdown; + +class EntityBreakdownWalker : public scene::Graph::Walker { + 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; + } }; -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; +void Scene_EntityBreakdown(EntityBreakdown &entitymap) +{ + GlobalSceneGraph().traverse(EntityBreakdownWalker(entitymap)); } -typedef std::map EntityBreakdown; +WindowPosition g_posMapInfoWnd(c_default_window_pos); -class EntityBreakdownWalker : public scene::Graph::Walker +void DoMapInfo() { -EntityBreakdown& m_entitymap; + ModalDialog dialog; + ui::Entry brushes_entry{ui::null}; + ui::Entry entities_entry{ui::null}; + ui::ListStore EntityBreakdownWalker{ui::null}; + + ui::Window window = MainFrame_getWindow().create_dialog_window("Map Info", G_CALLBACK(dialog_delete_callback), + &dialog); + + window_set_position(window, g_posMapInfoWnd); + + { + auto vbox = create_dialog_vbox(4, 4); + window.add(vbox); + + { + auto hbox = create_dialog_hbox(4); + vbox.pack_start(hbox, FALSE, TRUE, 0); + + { + auto table = create_dialog_table(2, 2, 4, 4); + hbox.pack_start(table, TRUE, TRUE, 0); + + { + auto entry = ui::Entry(ui::New); + entry.show(); + table.attach(entry, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); + gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE); + + brushes_entry = entry; + } + { + auto entry = ui::Entry(ui::New); + entry.show(); + table.attach(entry, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); + gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE); + + entities_entry = entry; + } + { + ui::Widget label = ui::Label("Total Brushes"); + label.show(); + table.attach(label, {0, 1, 0, 1}, {GTK_FILL, 0}); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); + } + { + ui::Widget label = ui::Label("Total Entities"); + label.show(); + table.attach(label, {0, 1, 1, 2}, {GTK_FILL, 0}); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); + } + } + { + auto vbox2 = create_dialog_vbox(4); + hbox.pack_start(vbox2, FALSE, FALSE, 0); + + { + auto button = create_dialog_button("Close", G_CALLBACK(dialog_button_ok), &dialog); + vbox2.pack_start(button, FALSE, FALSE, 0); + } + } + } + { + ui::Widget label = ui::Label("Entity breakdown"); + label.show(); + vbox.pack_start(label, FALSE, TRUE, 0); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); + } + { + auto scr = create_scrolled_window(ui::Policy::NEVER, ui::Policy::AUTOMATIC, 4); + vbox.pack_start(scr, TRUE, TRUE, 0); + + { + auto store = ui::ListStore::from(gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING)); + + auto view = ui::TreeView(ui::TreeModel::from(store._handle)); + gtk_tree_view_set_headers_clickable(view, TRUE); + + { + auto renderer = ui::CellRendererText(ui::New); + auto column = ui::TreeViewColumn("Entity", renderer, {{"text", 0}}); + gtk_tree_view_append_column(view, column); + gtk_tree_view_column_set_sort_column_id(column, 0); + } + + { + auto renderer = ui::CellRendererText(ui::New); + auto column = ui::TreeViewColumn("Count", renderer, {{"text", 1}}); + gtk_tree_view_append_column(view, column); + gtk_tree_view_column_set_sort_column_id(column, 1); + } + + view.show(); + + scr.add(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)); + EntityBreakdownWalker.append(0, (*i).first.c_str(), 1, tmp); + } + } + + EntityBreakdownWalker.unref(); + + char tmp[16]; + sprintf(tmp, "%u", Unsigned(g_brushCount.get())); + brushes_entry.text(tmp); + sprintf(tmp, "%u", Unsigned(g_entityCount.get())); + entities_entry.text(tmp); + + modal_dialog_show(window, dialog); + + // save before exit + window_get_position(window, g_posMapInfoWnd); + + window.destroy(); +} + + +class ScopeTimer { + Timer m_timer; + const char *m_message; 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; -} + 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"; + } }; -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; -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"; -} -}; +CopiedString g_strLastFolder = ""; /* ================ @@ -928,293 +996,309 @@ ScopeTimer( const char* message ) ================ */ -void Map_LoadFile( const char *filename ){ - globalOutputStream() << "Loading map from " << filename << "\n"; - ScopeDisableScreenUpdates disableScreenUpdates( "Processing...", "Loading Map" ); - - { - 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 +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; + + // refresh VFS to apply new pak filtering based on mapname + // needed for daemon DPK VFS + VFS_Refresh(); +} + +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; +class ExcludeWalker : public scene::Traversable::Walker { + 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; +class AnyInstanceSelected : public scene::Instantiable::Visitor { + 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; -} - -class SelectedDescendantWalker : public scene::Traversable::Walker +bool Node_instanceSelected(scene::Node &node) { -bool& m_selected; -public: -SelectedDescendantWalker( bool& selected ) : m_selected( selected ){ - m_selected = false; + scene::Instantiable *instantiable = Node_getInstantiable(node); + ASSERT_NOTNULL(instantiable); + bool selected; + instantiable->forEachInstance(AnyInstanceSelected(selected)); + return selected; } -bool pre( scene::Node& node ) const { - if ( node.isRoot() ) { - return false; - } - - if ( Node_instanceSelected( node ) ) { - m_selected = true; - } - - return true; -} +class SelectedDescendantWalker : public scene::Traversable::Walker { + 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; + } }; -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 -{ +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; +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; + } -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 -{ +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 ); - // refresh VFS to apply new pak filtering based on mapname - // needed for daemon DPK VFS - VFS_Refresh(); + 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(){ - Pointfile_Clear(); +bool Map_Save() +{ + Pointfile_Clear(); - ScopeTimer timer( "map save" ); - SaveReferences(); - return true; // assume success.. + ScopeTimer timer("map save"); + SaveReferences(); + return true; // assume success.. } /* @@ -1223,54 +1307,55 @@ bool Map_Save(){ =========== */ -void Map_New(){ - //globalOutputStream() << "Map_New\n"; +void Map_New() +{ + //globalOutputStream() << "Map_New\n"; - g_map.m_name = "unnamed.map"; - Map_UpdateTitle( g_map ); + g_map.m_name = "unnamed.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(); + // 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 ®ion_mins, const Vector3 ®ion_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 ){ - /*! +void ConstructRegionStartpoint(scene::Node *startpoint, const Vector3 ®ion_mins, const Vector3 ®ion_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() ) ); + 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; - } - } + 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 ); + // 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); } /* @@ -1281,11 +1366,11 @@ void ConstructRegionStartpoint( scene::Node* startpoint, const Vector3& region_m =========================================================== */ bool region_active; -Vector3 region_mins( g_MinWorldCoord, g_MinWorldCoord, g_MinWorldCoord ); -Vector3 region_maxs( g_MaxWorldCoord, g_MaxWorldCoord, g_MaxWorldCoord ); +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; +scene::Node *region_sides[6]; +scene::Node *region_startpoint = 0; /* =========== @@ -1296,103 +1381,116 @@ scene::Node* region_startpoint = 0; 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; +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; +class ExcludeAllWalker : public scene::Graph::Walker { + 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 ); + ExcludeAllWalker(bool exclude) + : m_exclude(exclude) + { + } - return true; -} + 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; +class ExcludeSelectedWalker : public scene::Graph::Walker { + 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; +class ExcludeRegionedWalker : public scene::Graph::Walker { + 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)); } /* @@ -1402,23 +1500,25 @@ void Scene_Exclude_Region( bool exclude ){ Other filtering options may still be on =========== */ -void Map_RegionOff(){ - region_active = false; +void Map_RegionOff() +{ + region_active = false; - region_maxs[0] = g_MaxWorldCoord - 64; - region_mins[0] = g_MinWorldCoord + 64; - region_maxs[1] = g_MaxWorldCoord - 64; - region_mins[1] = g_MinWorldCoord + 64; - region_maxs[2] = g_MaxWorldCoord - 64; - region_mins[2] = g_MinWorldCoord + 64; + region_maxs[0] = g_MaxWorldCoord - 64; + region_mins[0] = g_MinWorldCoord + 64; + region_maxs[1] = g_MaxWorldCoord - 64; + 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 ){ - region_active = true; +void Map_ApplyRegion(void) +{ + region_active = true; - Scene_Exclude_Region( false ); + Scene_Exclude_Region(false); } @@ -1427,18 +1527,19 @@ void Map_ApplyRegion( void ){ Map_RegionSelectedBrushes ======================== */ -void Map_RegionSelectedBrushes( void ){ - Map_RegionOff(); +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 ); + Scene_Exclude_Selected(false); - GlobalSelectionSystem().setSelectedAll( false ); - } + GlobalSelectionSystem().setSelectedAll(false); + } } @@ -1447,28 +1548,30 @@ void Map_RegionSelectedBrushes( void ){ Map_RegionXY =========== */ -void Map_RegionXY( float x_min, float y_min, float x_max, float y_max ){ - Map_RegionOff(); +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[2] = g_MaxWorldCoord - 64; + 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[2] = g_MaxWorldCoord - 64; - Map_ApplyRegion(); + 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(); } /* @@ -1476,11 +1579,12 @@ void Map_RegionBounds( const AABB& bounds ){ Map_RegionBrush =========== */ -void Map_RegionBrush( void ){ - if ( GlobalSelectionSystem().countSelected() != 0 ) { - scene::Instance& instance = GlobalSelectionSystem().ultimateSelected(); - Map_RegionBounds( instance.worldAABB() ); - } +void Map_RegionBrush(void) +{ + if (GlobalSelectionSystem().countSelected() != 0) { + scene::Instance &instance = GlobalSelectionSystem().ultimateSelected(); + Map_RegionBounds(instance.worldAABB()); + } } // @@ -1488,103 +1592,127 @@ void Map_RegionBrush( void ){ //Map_ImportFile //================ // -bool Map_ImportFile( const char* filename ){ - ScopeDisableScreenUpdates disableScreenUpdates( "Processing...", "Loading Map" ); - - 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; - -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; +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; + + tryDecompile: + + const char *type = GlobalRadiant().getGameDescriptionKeyValue("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("\""); + + // extra pakpaths + for (int i = 0; i < g_pakPathCount; i++) { + if (g_strcmp0(g_strPakPath[i].c_str(), "")) { + output.push_string(" -fs_pakpath \""); + output.push_string(g_strPakPath[i].c_str()); + output.push_string("\""); + } + } + + // extra switches + if (g_disableEnginePath) { + output.push_string(" -fs_nobasepath "); + } + + if (g_disableHomePath) { + output.push_string(" -fs_nohomepath "); + } + + 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; } /* @@ -1592,15 +1720,16 @@ tryDecompile: 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; +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; } // @@ -1610,577 +1739,642 @@ 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 +class ParentSelectedBrushesToEntityWalker : public scene::Graph::Walker { + 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); + } + } + } + } +}; + +void Scene_parentSelectedBrushesToEntity(scene::Graph &graph, scene::Node &parent) { -scene::Node& m_parent; + graph.traverse(ParentSelectedBrushesToEntityWalker(parent)); +} + +class CountSelectedBrushes : public scene::Graph::Walker { + std::size_t &m_count; + mutable std::size_t m_depth; 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 ); - } - } - } + 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; } + +enum ENodeType { + eNodeUnknown, + eNodeMap, + eNodeEntity, + eNodePrimitive, }; -void Scene_parentSelectedBrushesToEntity( scene::Graph& graph, scene::Node& parent ){ - graph.traverse( ParentSelectedBrushesToEntityWalker( parent ) ); +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; } -class CountSelectedBrushes : public scene::Graph::Walker +bool contains_entity(scene::Node &node) { -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; + return Node_getTraversable(node) != 0 && !Node_isBrush(node) && !Node_isPatch(node) && !Node_isEntity(node); } -}; -std::size_t Scene_countSelectedBrushes( scene::Graph& graph ){ - std::size_t count; - graph.traverse( CountSelectedBrushes( count ) ); - return count; +bool contains_primitive(scene::Node &node) +{ + return Node_isEntity(node) && Node_getTraversable(node) != 0 && Node_getEntity(node)->isContainer(); } -enum ENodeType +ENodeType node_get_contains(scene::Node &node) { - eNodeUnknown, - eNodeMap, - eNodeEntity, - eNodePrimitive, -}; + if (contains_entity(node)) { + return eNodeEntity; + } + if (contains_primitive(node)) { + return eNodePrimitive; + } + return eNodeUnknown; +} -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() ); - } - } - }; +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()); - ParentSelectedBrushesToEntityWalker visitor( GlobalSelectionSystem().ultimateSelected().path() ); - GlobalSelectionSystem().foreachSelected( visitor ); - } - else - { - globalOutputStream() << "failed - did not find two selected nodes.\n"; - } + 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 *getLastFolderPath() +{ + if (g_strLastFolder.empty()) { + GlobalPreferenceSystem().registerPreference("LastFolder", make_property_string(g_strLastFolder)); + if (g_strLastFolder.empty()) { + g_strLastFolder = g_qeglobals.m_userGamePath; + } + } + return g_strLastFolder.c_str(); } -const char* map_open( const char* title ){ - return file_dialog( GTK_WIDGET( MainFrame_getWindow() ), TRUE, title, getMapsPath(), MapFormat::Name(), true, false, false ); +const char *map_open(const char *title) +{ + return MainFrame_getWindow().file_dialog(TRUE, title, getLastFolderPath(), MapFormat::Name(), true, false, false); } -const char* map_import( const char* title ){ - return file_dialog( GTK_WIDGET( MainFrame_getWindow() ), TRUE, title, getMapsPath(), MapFormat::Name(), false, true, false ); +const char *map_import(const char *title) +{ + return MainFrame_getWindow().file_dialog(TRUE, title, getLastFolderPath(), MapFormat::Name(), false, true, false); } -const char* map_save( const char* title ){ - return file_dialog( GTK_WIDGET( MainFrame_getWindow() ), FALSE, title, getMapsPath(), MapFormat::Name(), false, false, true ); +const char *map_save(const char *title) +{ + return MainFrame_getWindow().file_dialog(FALSE, title, getLastFolderPath(), MapFormat::Name(), false, false, true); } -void OpenMap(){ - if ( !ConfirmModified( "Open Map" ) ) { - return; - } +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_import( "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" ); +bool Map_SaveAs() +{ + const char *filename = map_save("Save Map"); - if ( filename != 0 ) { - MRU_AddFile( filename ); - Map_Rename( filename ); - return Map_Save(); - } - return false; + if (filename != NULL) { + g_strLastFolder = g_path_get_dirname(filename); + MRU_AddFile(filename); + Map_Rename(filename); + return Map_Save(); + } + return false; } -void SaveMapAs(){ - Map_SaveAs(); +void SaveMapAs() +{ + Map_SaveAs(); } -void SaveMap(){ - if ( Map_Unnamed( g_map ) ) { - SaveMapAs(); - } - else if ( Map_Modified( g_map ) ) { - Map_Save(); - } +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" ); +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" ); +void SaveRegion() +{ + const char *filename = map_save("Export Region"); - if ( filename != 0 ) { - Map_SaveRegion( filename ); - } + if (filename != NULL) { + g_strLastFolder = g_path_get_dirname(filename); + Map_SaveRegion(filename); + } } -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 RegionOff() +{ + Map_RegionOff(); + SceneChangeNotify(); } -void RegionBrush(){ - Map_RegionBrush(); - 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 RegionSelected(){ - Map_RegionSelectedBrushes(); - SceneChangeNotify(); +void RegionSelected() +{ + Map_RegionSelectedBrushes(); + SceneChangeNotify(); } +class BrushFindByIndexWalker : public scene::Traversable::Walker { + 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; + } +}; +class EntityFindByIndexWalker : public scene::Traversable::Walker { + 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; + } +}; - -class BrushFindByIndexWalker : public scene::Traversable::Walker +void Scene_FindEntityBrush(std::size_t entity, std::size_t brush, scene::Path &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; + 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(); } -}; -class EntityFindByIndexWalker : public scene::Traversable::Walker +void SelectBrush(int entitynum, int brushnum) { -mutable std::size_t m_index; -scene::Path& m_path; + 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; 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; -} + 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; + } }; -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 ) ); - } - } -} +class EntityFindIndexWalker : public scene::Graph::Walker { + 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; + } +}; -inline bool Node_hasChildren( scene::Node& node ){ - scene::Traversable* traversable = Node_getTraversable( node ); - return traversable != 0 && !traversable->empty(); -} +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(); -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 ); - } + GlobalSceneGraph().traverse(BrushFindIndexWalker(path.top(), count_brush)); + GlobalSceneGraph().traverse(EntityFindIndexWalker(path.parent(), count_entity)); + } + *brush = int(count_brush); + *ent = int(count_entity); } - -class BrushFindIndexWalker : public scene::Graph::Walker +void DoFind() { -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; -} -}; - -class EntityFindIndexWalker : public scene::Graph::Walker + ModalDialog dialog; + ui::Entry entity{ui::null}; + ui::Entry brush{ui::null}; + + ui::Window window = MainFrame_getWindow().create_dialog_window("Find Brush", G_CALLBACK(dialog_delete_callback), + &dialog); + + auto accel = ui::AccelGroup(ui::New); + window.add_accel_group(accel); + + { + auto vbox = create_dialog_vbox(4, 4); + window.add(vbox); + { + auto table = create_dialog_table(2, 2, 4, 4); + vbox.pack_start(table, TRUE, TRUE, 0); + { + ui::Widget label = ui::Label("Entity number"); + label.show(); + (table).attach(label, {0, 1, 0, 1}, {0, 0}); + } + { + ui::Widget label = ui::Label("Brush number"); + label.show(); + (table).attach(label, {0, 1, 1, 2}, {0, 0}); + } + { + auto entry = ui::Entry(ui::New); + entry.show(); + table.attach(entry, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, 0}); + gtk_widget_grab_focus(entry); + entity = entry; + } + { + auto entry = ui::Entry(ui::New); + entry.show(); + table.attach(entry, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, 0}); + + brush = entry; + } + } + { + auto hbox = create_dialog_hbox(4); + vbox.pack_start(hbox, TRUE, TRUE, 0); + { + auto button = create_dialog_button("Find", G_CALLBACK(dialog_button_ok), &dialog); + hbox.pack_start(button, FALSE, FALSE, 0); + widget_make_default(button); + gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Return, (GdkModifierType) 0, + (GtkAccelFlags) 0); + } + { + auto button = create_dialog_button("Close", G_CALLBACK(dialog_button_cancel), &dialog); + hbox.pack_start(button, FALSE, FALSE, 0); + gtk_widget_add_accelerator(button, "clicked", accel, GDK_KEY_Escape, (GdkModifierType) 0, + (GtkAccelFlags) 0); + } + } + } + + // Initialize dialog + char buf[16]; + int ent, br; + + GetSelectionIndex(&ent, &br); + sprintf(buf, "%i", ent); + entity.text(buf); + sprintf(buf, "%i", br); + brush.text(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)); + } + + window.destroy(); +} + +void Map_constructPreferences(PreferencesPage &page) { -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; + 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; + +class MapEntityClasses : public ModuleObserver { + 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; -class MapModuleObserver : public ModuleObserver -{ -std::size_t m_unrealised; +class MapModuleObserver : public ModuleObserver { + 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", makeCallbackF(RegionOff)); + GlobalCommands_insert("RegionSetXY", makeCallbackF(RegionXY)); + GlobalCommands_insert("RegionSetBrush", makeCallbackF(RegionBrush)); + GlobalCommands_insert("RegionSetSelection", makeCallbackF(RegionSelected), + 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", make_property_string(g_strLastMap)); + GlobalPreferenceSystem().registerPreference("LoadLastMap", make_property_string(g_bLoadLastMap)); + GlobalPreferenceSystem().registerPreference("MapInfoDlg", make_property(g_posMapInfoWnd)); - PreferencesDialog_addSettingsPreferences( FreeCaller1() ); + PreferencesDialog_addSettingsPreferences(makeCallbackF(Map_constructPreferences)); - 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); }