]> de.git.xonotic.org Git - xonotic/netradiant.git/commitdiff
Merge branch 'master' of ssh://icculus.org/netradiant
authorRudolf Polzer <divverent@alientrap.org>
Thu, 14 Oct 2010 08:07:39 +0000 (10:07 +0200)
committerRudolf Polzer <divverent@alientrap.org>
Thu, 14 Oct 2010 08:07:39 +0000 (10:07 +0200)
26 files changed:
contrib/brushexport/callbacks.cpp
download-gamepacks.sh
include/ifiletypes.h
include/imap.h
include/qerplugin.h
libs/cmdlib.h
libs/cmdlib/cmdlib.cpp
libs/gtkutil/filechooser.cpp
libs/gtkutil/filechooser.h
plugins/mapq3/plugin.cpp
radiant/brush.h
radiant/brushmodule.cpp
radiant/brushmodule.h
radiant/camwindow.cpp
radiant/filetypes.cpp
radiant/gtkdlgs.cpp
radiant/map.cpp
radiant/qe3.cpp
radiant/watchbsp.cpp
tools/quake3/q3map2/bsp.c
tools/quake3/q3map2/convert_map.c
tools/quake3/q3map2/light.c
tools/quake3/q3map2/main.c
tools/quake3/q3map2/map.c
tools/quake3/q3map2/q3map2.h
tools/quake3/q3map2/writebsp.c

index ab6396ee94f2d557c17081046031e5041f3bafa4..0aea73da8d42d599c6bef614ab7d57e27f42db02 100644 (file)
@@ -22,7 +22,7 @@ void OnExportClicked(GtkButton* button, gpointer user_data)
 {
        GtkWidget* window = lookup_widget(GTK_WIDGET(button), "w_plugplug2");
        ASSERT_NOTNULL(window);
-       const char* cpath = GlobalRadiant().m_pfnFileDialog(window, false, "Save as Obj", 0, 0);
+       const char* cpath = GlobalRadiant().m_pfnFileDialog(window, false, "Save as Obj", 0, 0, false, false, true);
        if(!cpath)
                return;
 
index a99499e4d03aaf85529391b5aa11212c1743b767..41af47c9fb28c1829455a12a8f99bd30359a2d15 100755 (executable)
@@ -156,5 +156,5 @@ pack Quake2WorldPack GPL         svn    svn://jdolan.dyndns.org/quake2world/trun
 pack QuakePack       proprietary zip1   http://ingar.satgnu.net/files/gtkradiant/gamepacks/QuakePack.zip
 pack TremulousPack   proprietary zip1   http://ingar.satgnu.net/files/gtkradiant/gamepacks/TremulousPack.zip
 pack UFOAIPack       proprietary svn    https://zerowing.idsoftware.com/svn/radiant.gamepacks/UFOAIPack/branches/1.5/
-#pack WarsowPack      GPL         svn    https://svn.bountysource.com/wswpack/trunk/netradiant/games/WarsowPack/
+pack WarsowPack      GPL         svn    https://svn.bountysource.com/wswpack/trunk/netradiant/games/WarsowPack/
 pack XonoticPack     GPL         git    git://git.xonotic.org/xonotic/netradiant-xonoticpack.git
index e2851be29df2decd931ba4fe7caebfa8efe4fa03..0d061d2bbfb0b75ef399cf30ae5c0a9564cff7a9 100644 (file)
@@ -31,12 +31,15 @@ public:
     : name(""), pattern("")
   {
   }
-  filetype_t(const char* _name, const char* _pattern)
-    : name(_name), pattern(_pattern)
+  filetype_t(const char* _name, const char* _pattern, bool _can_load = true, bool _can_import = true, bool _can_save = true)
+    : name(_name), pattern(_pattern), can_load(_can_load), can_import(_can_import), can_save(_can_save)
   {
   }
   const char* name;
   const char* pattern;
+  bool can_load;
+  bool can_import;
+  bool can_save;
 };
 
 
@@ -53,7 +56,7 @@ public:
   STRING_CONSTANT(Name, "filetypes");
 
   virtual void addType(const char* moduleType, const char* moduleName, filetype_t type) = 0;
-  virtual void getTypeList(const char* moduleType, IFileTypeList* typelist) = 0;
+  virtual void getTypeList(const char* moduleType, IFileTypeList* typelist, bool want_load = false, bool want_import = false, bool want_save = false) = 0;
 };
 
 #include "modulesystem.h"
index 53c804e46a112cb4752b728c5848bdad0d6be6bc..c97a2ff2a326048f49fa0c5dbbc4b2a8298f8109 100644 (file)
@@ -61,6 +61,7 @@ class MapFormat
 public:
   INTEGER_CONSTANT(Version, 2);
   STRING_CONSTANT(Name, "map");
+  mutable bool wrongFormat;
 
   /// \brief Read a map graph into \p root from \p outputStream, using \p entityTable to create entities.
   virtual void readGraph(scene::Node& root, TextInputStream& inputStream, EntityCreator& entityTable) const = 0;
index a6a08d372817d70f9c7b8b79ab2b83e3fa739573..cac311ab9da11a9c55cf30fde8fcde76ef059dd0 100644 (file)
@@ -71,7 +71,7 @@ typedef EMessageBoxReturn (* PFN_QERAPP_MESSAGEBOX) (GtkWidget *parent, const ch
 // - 'title' is the dialog title (can be null)
 // - 'path' is used to set the initial directory (can be null)
 // - 'pattern': the first pattern is for the win32 mode, then comes the Gtk pattern list, see Radiant source for samples
-typedef const char* (* PFN_QERAPP_FILEDIALOG) (GtkWidget *parent, bool open, const char* title, const char* path/* = 0*/, const char* pattern/* = 0*/);
+typedef const char* (* PFN_QERAPP_FILEDIALOG) (GtkWidget *parent, bool open, const char* title, const char* path/* = 0*/, const char* pattern/* = 0*/, bool want_load/* = false*/, bool want_import/* = false*/, bool want_save/* = false*/);
 
 // returns a gchar* string that must be g_free'd by the user
 typedef char* (* PFN_QERAPP_DIRDIALOG) (GtkWidget *parent, const char* title/* = "Choose Directory"*/, const char* path/* = 0*/);
index ffeb4271827a16a84cc3bf763692f7f4e7cb6251..8961bd2a2e09bd5704c751926ba2a83f34e27c70 100644 (file)
@@ -43,7 +43,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 //   if the spawn was fine
 //   TODO TTimo add functionality to track the process until it dies
 
-bool Q_Exec(const char *cmd, char *cmdline, const char *execdir, bool bCreateConsole);
+bool Q_Exec(const char *cmd, char *cmdline, const char *execdir, bool bCreateConsole, bool waitfor);
 
 // some easy portability crap
 
index a09ed9ead1a39e9106e08a534d85b0bde7c2fea5..f6ace0fe117f3424ae6d4108d83840f73b88cef1 100644 (file)
@@ -36,16 +36,23 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #if defined (POSIX)
 
 #include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
 
-bool Q_Exec(const char *cmd, char *cmdline, const char *, bool)
+bool Q_Exec(const char *cmd, char *cmdline, const char *, bool, bool waitfor)
 {
   char fullcmd[2048];
   char *pCmd;
+  pid_t pid;
 #ifdef _DEBUG
   printf("Q_Exec damnit\n");
 #endif
-  switch (fork())
+  switch ((pid = fork()))
   {
+  default:
+    if(waitfor)
+      waitpid(pid, NULL, 0);
+    break;
   case -1:
     return true;
     break;
@@ -84,7 +91,7 @@ bool Q_Exec(const char *cmd, char *cmdline, const char *, bool)
 #include <windows.h>
 
 // NOTE TTimo windows is VERY nitpicky about the syntax in CreateProcess
-bool Q_Exec(const char *cmd, char *cmdline, const char *execdir, bool bCreateConsole)
+bool Q_Exec(const char *cmd, char *cmdline, const char *execdir, bool bCreateConsole, bool waitfor)
 {
   PROCESS_INFORMATION ProcessInformation;
   STARTUPINFO startupinfo = {0};
@@ -121,7 +128,11 @@ bool Q_Exec(const char *cmd, char *cmdline, const char *execdir, bool bCreateCon
                     &startupinfo,
                     &ProcessInformation
                     ))
+  {
+    if(waitfor)
+      WaitForSingleObject(ProcessInformation.hProcess, INFINITE);
     return true;
+  }
   return false;
 }
 
index f164d220d8f3cdcd1a2099b9e042b7e9155f953e..2246b57bd60608f5651c3a4c66ae5769cb21c820 100644 (file)
@@ -137,7 +137,7 @@ public:
 
 static char g_file_dialog_file[1024];
 
-const char* file_dialog_show(GtkWidget* parent, bool open, const char* title, const char* path, const char* pattern)
+const char* file_dialog_show(GtkWidget* parent, bool open, const char* title, const char* path, const char* pattern, bool want_load, bool want_import, bool want_save)
 {
   filetype_t type;
 
@@ -147,7 +147,7 @@ const char* file_dialog_show(GtkWidget* parent, bool open, const char* title, co
   }
 
   FileTypeList typelist;
-  GlobalFiletypes().getTypeList(pattern, &typelist);
+  GlobalFiletypes().getTypeList(pattern, &typelist, want_load, want_import, want_save);
 
   GTKMasks masks(typelist);
 
@@ -288,11 +288,11 @@ char* dir_dialog(GtkWidget* parent, const char* title, const char* path)
   return filename;
 }
 
-const char* file_dialog(GtkWidget* parent, bool open, const char* title, const char* path, const char* pattern)
+const char* file_dialog(GtkWidget* parent, bool open, const char* title, const char* path, const char* pattern, bool want_load, bool want_import, bool want_save)
 {
   for(;;)
   {
-    const char* file = file_dialog_show(parent, open, title, path, pattern);
+    const char* file = file_dialog_show(parent, open, title, path, pattern, want_load, want_import, want_save);
 
     if(open
       || file == 0
index d23beb5da320da8d165e1f9ab197eaf680efe1e6..3789321e4b13b9a8be1b3f6d2b115c30f6249f2b 100644 (file)
@@ -26,7 +26,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 /// GTK+ file-chooser dialogs.
 
 typedef struct _GtkWidget GtkWidget;
-const char* file_dialog(GtkWidget *parent, bool open, const char* title, const char* path = 0, const char* pattern = 0);
+const char* file_dialog(GtkWidget *parent, bool open, const char* title, const char* path = 0, const char* pattern = 0, bool want_load = false, bool want_import = false, bool want_save = false);
 
 
 /// \brief Prompts the user to browse for a directory.
index a11dc4a9bf3633a25e10642aa6f4449f8f8cc3f6..fdb68a2e979610a3d59856d026a8681be0472110 100644 (file)
@@ -257,14 +257,16 @@ public:
 
 class MapQ3API : public TypeSystemRef, public MapFormat, public PrimitiveParser
 {
+  mutable bool detectedFormat;
 public:
   typedef MapFormat Type;
   STRING_CONSTANT(Name, "mapq3");
 
   MapQ3API()
   {
-    GlobalFiletypesModule::getTable().addType(Type::Name(), Name(), filetype_t("quake3 maps", "*.map"));
-    GlobalFiletypesModule::getTable().addType(Type::Name(), Name(), filetype_t("quake3 region", "*.reg"));
+    GlobalFiletypesModule::getTable().addType(Type::Name(), Name(), filetype_t("quake3 maps", "*.map", true, true, true));
+    GlobalFiletypesModule::getTable().addType(Type::Name(), Name(), filetype_t("quake3 region", "*.reg", true, true, true));
+    GlobalFiletypesModule::getTable().addType(Type::Name(), Name(), filetype_t("quake3 compiled maps", "*.bsp", false, true, false));
   }
   MapFormat* getTable()
   {
@@ -284,16 +286,32 @@ public:
       {
         if(string_equal(primitive, "brushDef"))
         {
+         detectedFormat = true;
           return GlobalBrushModule::getTable().createBrush();
         }
+       else if(!detectedFormat && string_equal(primitive, "("))
+       {
+         detectedFormat = true;
+         wrongFormat = true;
+         Tokeniser_unexpectedError(tokeniser, primitive, "#quake3-switch-to-texdef");
+         return g_nullNode;
+       }
       }
       else
       {
         if(string_equal(primitive, "("))
         {
+         detectedFormat = true;
           tokeniser.ungetToken(); // (
           return GlobalBrushModule::getTable().createBrush();
         }
+       else if(!detectedFormat && string_equal(primitive, "("))
+       {
+         detectedFormat = true;
+         wrongFormat = true;
+         Tokeniser_unexpectedError(tokeniser, primitive, "#quake3-switch-to-brush-primitives");
+         return g_nullNode;
+       }
       }
     }
 
@@ -303,6 +321,8 @@ public:
 
   void readGraph(scene::Node& root, TextInputStream& inputStream, EntityCreator& entityTable) const
   {
+    detectedFormat = false;
+    wrongFormat = false;
     Tokeniser& tokeniser = GlobalScripLibModule::getTable().m_pfnNewSimpleTokeniser(inputStream);
     Map_Read(root, tokeniser, entityTable, *this);
     tokeniser.release();
index 38ee475d8110b1ef74d9a5f38524c3b5b198d8b8..80e0bd0265ae99e0aec49e9905c1ccc6b8212343 100644 (file)
@@ -1193,9 +1193,7 @@ public:
   void transform(const Matrix4& matrix, bool mirror)
   {
     if(g_brush_texturelock_enabled)
-    {
       Texdef_transformLocked(m_texdefTransformed, m_shader.width(), m_shader.height(), m_plane.plane3(), matrix);
-    }
 
     m_planeTransformed.transform(matrix, mirror);
 
@@ -1203,6 +1201,9 @@ public:
     ASSERT_MESSAGE(projectionaxis_for_normal(normal) == projectionaxis_for_normal(plane3().normal()), "bleh");
 #endif
     m_observer->planeChanged();
+
+    if(g_brush_texturelock_enabled)
+      Brush_textureChanged();
   }
 
   void assign_planepts(const PlanePoints planepts)
index 6b47e0926e6990d2ac228942b2165e2f5fbcddfd..21cec0ee8b8ff385cc766cf8f47e452bc301c128 100644 (file)
@@ -90,6 +90,27 @@ void Brush_registerPreferencesPage()
   PreferencesDialog_addSettingsPage(FreeCaller1<PreferenceGroup&, Brush_constructPage>());
 }
 
+void Brush_unlatchPreferences()
+{
+       Brush_toggleFormat(0);
+}
+
+void Brush_toggleFormat(int i)
+{
+       if(g_showAlternativeTextureProjectionOption)
+       {
+               g_useAlternativeTextureProjection.m_value = g_useAlternativeTextureProjection.m_latched ^ i;
+               Brush::destroyStatic();
+               Brush::constructStatic(g_useAlternativeTextureProjection.m_value ? eBrushTypeQuake3BP : eBrushTypeQuake3);
+       }
+}
+
+int Brush_toggleFormatCount()
+{
+       if(g_showAlternativeTextureProjectionOption)
+               return 2;
+       return 1;
+}
 
 void Brush_Construct(EBrushType type)
 {
index 20f73473de2389bdd13f099ea6e504d3c5dd324a..ac89a8907adbcacc137b59a3d4710c0e82746789 100644 (file)
@@ -23,5 +23,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #define INCLUDED_BRUSHMODULE_H
 
 void Brush_clipperColourChanged();
+void Brush_unlatchPreferences();
+int Brush_toggleFormatCount();
+void Brush_toggleFormat(int i);
 
 #endif
index 65090136278dd3dd2c11e40202e593589a0826cb..8a0c89494887640218331a7ea687992ef8a0d7ec 100644 (file)
@@ -1553,6 +1553,7 @@ void CamWnd::Cam_Draw()
 
   // enable depth buffer writes
   glDepthMask(GL_TRUE);
+  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
 
   Vector3 clearColour(0, 0, 0);
   if(m_Camera.draw_mode != cd_lighting)
index b76b968e765d2311cea17f4d46b0ba42d636b020..11c0a272eceb97788479abc36d0b4a3c93815e25 100644 (file)
@@ -35,7 +35,7 @@ class RadiantFileTypeRegistry : public IFileTypeRegistry
   struct filetype_copy_t
   {
     filetype_copy_t(const char* moduleName, const filetype_t other)
-      : m_moduleName(moduleName), m_name(other.name), m_pattern(other.pattern)
+      : m_moduleName(moduleName), m_name(other.name), m_pattern(other.pattern), m_can_load(other.can_load), m_can_import(other.can_import), m_can_save(other.can_save)
     {
     }
     const char* getModuleName() const
@@ -44,8 +44,11 @@ class RadiantFileTypeRegistry : public IFileTypeRegistry
     }
     filetype_t getType() const
     {
-      return filetype_t(m_name.c_str(), m_pattern.c_str());
+      return filetype_t(m_name.c_str(), m_pattern.c_str(), m_can_load, m_can_save, m_can_import);
     }
+    bool m_can_load;
+    bool m_can_import;
+    bool m_can_save;
   private:
     CopiedString m_moduleName;
     CopiedString m_name;
@@ -62,11 +65,14 @@ public:
   {
     m_typelists[moduleType].push_back(filetype_copy_t(moduleName, type));
   }
-  void getTypeList(const char* moduleType, IFileTypeList* typelist)
+  void getTypeList(const char* moduleType, IFileTypeList* typelist, bool want_load, bool want_import, bool want_save)
   {
     filetype_list_t& list_ref = m_typelists[moduleType];
     for(filetype_list_t::iterator i = list_ref.begin(); i != list_ref.end(); ++i)
     {
+      if(want_load && !(*i).m_can_load) return;
+      if(want_import && !(*i).m_can_import) return;
+      if(want_save && !(*i).m_can_save) return;
       typelist->addType((*i).getModuleName(), (*i).getType());
     }
   }
index 2ba3e3f4eca57f3bd7cf2abf7094ce5769d5ab36..57ed278d6e8c511e1390eb0c17ab3123d01aa552 100644 (file)
@@ -1089,7 +1089,7 @@ void DoTextEditor (const char* filename, int cursorpos)
     
     globalOutputStream() << "Launching: " << strEditCommand.c_str() << "\n";
     // note: linux does not return false if the command failed so it will assume success
-    if (Q_Exec(0, const_cast<char*>(strEditCommand.c_str()), 0, true) == false)
+    if (Q_Exec(0, const_cast<char*>(strEditCommand.c_str()), 0, true, false) == false)
     {
       globalOutputStream() << "Failed to execute " << strEditCommand.c_str() << ", using default\n";
     }
index 3e5e8128ab1d978d03a0f25a80dd6dfc13946cde..7b8c570de4d5f54610ee5cfa7d6a24c9e6203fc5 100644 (file)
@@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #include "debugging/debugging.h"
 
 #include "imap.h"
+MapModules& ReferenceAPI_getMapModules();
 #include "iselection.h"
 #include "iundo.h"
 #include "ibrush.h"
@@ -83,6 +84,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #include "mru.h"
 #include "commands.h"
 #include "autosave.h"
+#include "brushmodule.h"
+#include "brush.h"
 
 class NameObserver
 {
@@ -463,6 +466,7 @@ void Map_Free()
   FlushReferences();
 
   g_currentMap = 0;
+  Brush_unlatchPreferences();
 }
 
 class EntityFindByClassname : public scene::Graph::Walker
@@ -1029,14 +1033,29 @@ void Map_LoadFile (const char *filename)
   globalOutputStream() << "Loading map from " << filename << "\n";
   ScopeDisableScreenUpdates disableScreenUpdates("Processing...", "Loading Map");
 
-  g_map.m_name = filename;
-  Map_UpdateTitle(g_map);
-
   {
     ScopeTimer timer("map load");
 
-    g_map.m_resource = GlobalReferenceCache().capture(g_map.m_name.c_str());
-    g_map.m_resource->attach(g_map);
+    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());
   }
@@ -1619,29 +1638,81 @@ bool Map_ImportFile(const char* filename)
   ScopeDisableScreenUpdates disableScreenUpdates("Processing...", "Loading Map");
 
   bool success = false;
+
+  if(extension_equal(path_get_extension(filename), "bsp"))
+    goto tryDecompile;
+
   {
     Resource* resource = GlobalReferenceCache().capture(filename);
     resource->refresh(); // avoid loading old version if map has changed on disk since last import
-    if(resource->load())
+    if(!resource->load())
     {
-      NodeSmartReference clone(NewMapRoot(""));
-
-      {
-        //ScopeTimer timer("clone subgraph");
-        Node_getTraversable(*resource->getNode())->traverse(CloneAll(clone));
-      }
-
-      Map_gatherNamespaced(clone);
-      Map_mergeClonedNames();
-      MergeMap(clone);
-      success = true;
+      GlobalReferenceCache().release(filename);
+      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();
+  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_game ");
+    output.push_string(gamename_get());
+    output.push_string(" -convert -format ");
+    output.push_string(Brush::m_type == eBrushTypeQuake3BP ? "map_bp" : "map");
+    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;
 }
 
 /*
@@ -1879,12 +1950,17 @@ const char* getMapsPath()
 
 const char* map_open(const char* title)
 {
-  return file_dialog(GTK_WIDGET(MainFrame_getWindow()), TRUE, title, getMapsPath(), MapFormat::Name());
+  return file_dialog(GTK_WIDGET(MainFrame_getWindow()), TRUE, title, getMapsPath(), 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_save(const char* title)
 {
-  return file_dialog(GTK_WIDGET(MainFrame_getWindow()), FALSE, title, getMapsPath(), MapFormat::Name());
+  return file_dialog(GTK_WIDGET(MainFrame_getWindow()), FALSE, title, getMapsPath(), MapFormat::Name(), false, false, true);
 }
 
 void OpenMap()
@@ -1905,7 +1981,7 @@ void OpenMap()
 
 void ImportMap()
 {
-  const char* filename = map_open("Import Map");
+  const char* filename = map_import("Import Map");
 
   if(filename != 0)
   {
index 0291d2cfb9b2a12014a13cf4f9696ff66c4de4c2..c707d5613304b81c9e76b14aa4dfec796c668e7d 100644 (file)
@@ -333,7 +333,7 @@ void RunBSP(const char* name)
 #endif
       globalOutputStream() << "Writing the compile script to '" << batpath << "'\n";
       globalOutputStream() << "The build output will be saved in '" << junkpath << "'\n";
-      Q_Exec(batpath, NULL, NULL, true);
+      Q_Exec(batpath, NULL, NULL, true, false);
     }
   }
 
index 83fba9009a45258516115baf151f3d1b4cf0f57a..5c170b6662c36f29a10717e22797d5bbc6e4e61a 100644 (file)
@@ -577,7 +577,7 @@ void CWatchBSP::DoEBeginStep()
     globalOutputStream() << "=== running build command ===\n"
       << static_cast<const char*>(g_ptr_array_index( m_pCmd, m_iCurrentStep )) << "\n";
     
-    if (!Q_Exec(NULL, (char *)g_ptr_array_index( m_pCmd, m_iCurrentStep ), NULL, true ))
+    if (!Q_Exec(NULL, (char *)g_ptr_array_index( m_pCmd, m_iCurrentStep ), NULL, true, false ))
     {
       StringOutputStream msg(256);
       msg << "Failed to execute the following command: ";
@@ -815,7 +815,7 @@ void CWatchBSP::RoutineProcessing()
             globalOutputStream() << cmd.c_str() << " " << cmdline.c_str() << "\n";
 
             // execute now
-            if (!Q_Exec(cmd.c_str(), (char *)cmdline.c_str(), EnginePath_get(), false))
+            if (!Q_Exec(cmd.c_str(), (char *)cmdline.c_str(), EnginePath_get(), false, false))
             {
               StringOutputStream msg;
               msg << "Failed to execute the following command: " << cmd.c_str() << cmdline.c_str();
index 214f62f084ca0ee0ff9ade690c31320ce613657f..7901979237dc0b8bfc7a676e15d33e3f26410dcd 100644 (file)
@@ -639,7 +639,7 @@ void OnlyEnts( void )
        numEntities = 0;
 
        LoadShaderInfo();
-       LoadMapFile( name, qfalse );
+       LoadMapFile( name, qfalse, qfalse );
        SetModelNumbers();
        SetLightStyles();
 
@@ -955,9 +955,9 @@ int BSPMain( int argc, char **argv )
        
        /* load original file from temp spot in case it was renamed by the editor on the way in */
        if( strlen( tempSource ) > 0 )
-               LoadMapFile( tempSource, qfalse );
+               LoadMapFile( tempSource, qfalse, qfalse );
        else
-               LoadMapFile( name, qfalse );
+               LoadMapFile( name, qfalse, qfalse );
        
        /* div0: inject command line parameters */
        InjectCommandLine(argv, 1, argc - 1);
@@ -978,7 +978,7 @@ int BSPMain( int argc, char **argv )
        ProcessAdvertisements();
 
        /* finish and write bsp */
-       EndBSPFile();
+       EndBSPFile(qtrue);
        
        /* remove temp map source file if appropriate */
        if( strlen( tempSource ) > 0)
index 69418854eef79ffbea9017183e8faa1e66792d35..0f37665d672aef5ba8136d2d23bed45416db7c02 100644 (file)
@@ -493,7 +493,10 @@ static void ConvertBrush( FILE *f, int num, bspBrush_t *brush, vec3_t origin, qb
                        if(strncmp(buildSide->shaderInfo->shader, "textures/common/", 16))
                        if(strcmp(buildSide->shaderInfo->shader, "noshader"))
                        if(strcmp(buildSide->shaderInfo->shader, "default"))
+                       {
                                fprintf(stderr, "no matching triangle for brushside using %s (hopefully nobody can see this side anyway)\n", buildSide->shaderInfo->shader);
+                               texture = "common/WTF";
+                       }
 
                        MakeNormalVectors( buildPlane->normal, vecs[ 0 ], vecs[ 1 ] );
                        VectorMA( vec3_origin, buildPlane->dist, buildPlane->normal, pts[ 0 ] );
index 3af7ddbf93d3a670d78dfc064aea3c893bd82f6c..59ceab8e42d9872c3588e5e9985a87a43154c252 100644 (file)
@@ -2800,7 +2800,7 @@ int LightMain( int argc, char **argv )
        /* load map file */
        value = ValueForKey( &entities[ 0 ], "_keepLights" );
        if( value[ 0 ] != '1' )
-               LoadMapFile( mapSource, qtrue );
+               LoadMapFile( mapSource, qtrue, qfalse );
        
        /* set the entity/model origins and init yDrawVerts */
        SetEntityOrigins();
index d922efc25840fbce12af5358e53d23ff788eab67..acb060ac84201e50fd52ba42bc4da66c0d9ddc87 100644 (file)
@@ -1430,6 +1430,89 @@ int ScaleBSPMain( int argc, char **argv )
 }
 
 
+/*
+PseudoCompileBSP()
+a stripped down ProcessModels
+*/
+void PseudoCompileBSP(qboolean need_tree)
+{
+       int models;
+       char modelValue[10];
+       entity_t *entity;
+       face_t *faces;
+       tree_t *tree;
+       node_t *node;
+       brush_t *brush;
+       side_t *side;
+       int i;
+
+        SetDrawSurfacesBuffer();
+       mapDrawSurfs = safe_malloc( sizeof( mapDrawSurface_t ) * MAX_MAP_DRAW_SURFS );
+       memset( mapDrawSurfs, 0, sizeof( mapDrawSurface_t ) * MAX_MAP_DRAW_SURFS );
+       numMapDrawSurfs = 0;
+
+       BeginBSPFile();
+       models = 1;
+       for( mapEntityNum = 0; mapEntityNum < numEntities; mapEntityNum++ )
+       {
+               /* get entity */
+               entity = &entities[ mapEntityNum ];
+               if( entity->brushes == NULL && entity->patches == NULL )
+                       continue;
+
+               if(mapEntityNum != 0)
+               {
+                       sprintf( modelValue, "*%d", models++);
+                       SetKeyValue(entity, "model", modelValue);
+               }
+               
+               /* process the model */
+               Sys_FPrintf( SYS_VRB, "############### model %i ###############\n", numBSPModels );
+               BeginModel();
+
+               entity->firstDrawSurf = numMapDrawSurfs;
+
+               if(mapEntityNum == 0 && need_tree)
+               {
+                       faces = MakeStructuralBSPFaceList(entities[0].brushes);
+                       tree = FaceBSP(faces);
+                       node = tree->headnode;
+               }
+               else
+               {
+                       node = AllocNode();
+                       node->planenum = PLANENUM_LEAF;
+                       tree = AllocTree();
+                       tree->headnode = node;
+               }
+
+               /* a minimized ClipSidesIntoTree */
+               for( brush = entity->brushes; brush; brush = brush->next )
+               {
+                       /* walk the brush sides */
+                       for( i = 0; i < brush->numsides; i++ )
+                       {
+                               /* get side */
+                               side = &brush->sides[ i ];
+                               if( side->winding == NULL )
+                                       continue;
+                               /* shader? */
+                               if( side->shaderInfo == NULL )
+                                       continue;
+                               /* save this winding as a visible surface */
+                               DrawSurfaceForSide(entity, brush, side, side->winding);
+                       }
+               }
+
+               FilterDrawsurfsIntoTree(entity, tree);
+               FilterStructuralBrushesIntoTree(entity, tree);
+               FilterDetailBrushesIntoTree(entity, tree);
+
+               EmitBrushes(entity->brushes, &entity->firstBrush, &entity->numBrushes );
+               EndModel(entity, node);
+       }
+       EndBSPFile(qfalse);
+}
 
 /*
 ConvertBSPMain()
@@ -1441,11 +1524,14 @@ int ConvertBSPMain( int argc, char **argv )
        int             i;
        int             (*convertFunc)( char * );
        game_t  *convertGame;
+       char            ext[1024];
+       qboolean        map_allowed;
        
        
        /* set default */
        convertFunc = ConvertBSPToASE;
        convertGame = NULL;
+       map_allowed = qtrue;
        
        /* arg checking */
        if( argc < 1 )
@@ -1462,14 +1548,24 @@ int ConvertBSPMain( int argc, char **argv )
                {
                        i++;
                        if( !Q_stricmp( argv[ i ], "ase" ) )
+                       {
                                convertFunc = ConvertBSPToASE;
+                               map_allowed = qfalse;
+                       }
                        else if( !Q_stricmp( argv[ i ], "map_bp" ) )
+                       {
                                convertFunc = ConvertBSPToMap_BP;
+                               map_allowed = qtrue;
+                       }
                        else if( !Q_stricmp( argv[ i ], "map" ) )
+                       {
                                convertFunc = ConvertBSPToMap;
+                               map_allowed = qtrue;
+                       }
                        else
                        {
                                convertGame = GetGame( argv[ i ] );
+                               map_allowed = qfalse;
                                if( convertGame == NULL )
                                        Sys_Printf( "Unknown conversion format \"%s\". Defaulting to ASE.\n", argv[ i ] );
                        }
@@ -1489,23 +1585,30 @@ int ConvertBSPMain( int argc, char **argv )
                else if( !strcmp( argv[ i ],  "-shadersasbitmap" ) )
                        shadersAsBitmap = qtrue;
        }
-       
-       /* clean up map name */
-       strcpy( source, ExpandArg( argv[ i ] ) );
-       StripExtension( source );
-       DefaultExtension( source, ".bsp" );
-       
+
        LoadShaderInfo();
        
-       Sys_Printf( "Loading %s\n", source );
-       
-       /* ydnar: load surface file */
-       //%     LoadSurfaceExtraFile( source );
-       
-       LoadBSPFile( source );
-       
-       /* parse bsp entities */
-       ParseEntities();
+       /* clean up map name */
+       strcpy(source, ExpandArg(argv[i]));
+       ExtractFileExtension(source, ext);
+       if(!Q_stricmp(ext, "map"))
+       {
+               if(!map_allowed)
+                       Sys_Printf("WARNING: the requested conversion should not be done from .map files. Compile a .bsp first.\n");
+               StripExtension(source);
+               DefaultExtension(source, ".map");
+               Sys_Printf("Loading %s\n", source);
+               LoadMapFile(source, qfalse, convertGame == NULL);
+               PseudoCompileBSP(convertGame != NULL);
+       }
+       else
+       {
+               StripExtension(source);
+               DefaultExtension(source, ".bsp");
+               Sys_Printf("Loading %s\n", source);
+               LoadBSPFile(source);
+               ParseEntities();
+       }
        
        /* bsp format convert? */
        if( convertGame != NULL )
index 3bc4e6f9fc02c65c6ec9c3a5685c181b757f9d90..448a24fb2398b3e023d9d477e31e93dd29434d0b 100644 (file)
@@ -620,7 +620,7 @@ static void MergeOrigin(entity_t *ent, vec3_t origin)
        SetKeyValue(ent, "origin", string);
 }
 
-brush_t *FinishBrush( void )
+brush_t *FinishBrush( qboolean noCollapseGroups )
 {
        brush_t         *b;
        
@@ -665,7 +665,8 @@ brush_t *FinishBrush( void )
        }
        
        /* add bevel planes */
-       AddBrushBevels();
+       if(!noCollapseGroups)
+               AddBrushBevels();
        
        /* keep it */
        b = CopyBrush( buildBrush );
@@ -1034,7 +1035,7 @@ ParseBrush()
 parses a brush out of a map file and sets it up
 */
 
-static void ParseBrush( qboolean onlyLights )
+static void ParseBrush( qboolean onlyLights, qboolean noCollapseGroups )
 {
        brush_t *b;
        
@@ -1081,7 +1082,7 @@ static void ParseBrush( qboolean onlyLights )
        }
        
        /* finish the brush */
-       b = FinishBrush();
+       b = FinishBrush(noCollapseGroups);
 }
 
 
@@ -1418,7 +1419,7 @@ ParseMapEntity()
 parses a single entity out of a map file
 */
 
-static qboolean ParseMapEntity( qboolean onlyLights )
+static qboolean ParseMapEntity( qboolean onlyLights, qboolean noCollapseGroups )
 {
        epair_t                 *ep;
        const char              *classname, *value;
@@ -1497,7 +1498,7 @@ static qboolean ParseMapEntity( qboolean onlyLights )
                                g_bBrushPrimit = BPRIMIT_NEWBRUSHES;
                                
                                /* parse brush primitive */
-                               ParseBrush( onlyLights );
+                               ParseBrush( onlyLights, noCollapseGroups );
                        }
                        else
                        {
@@ -1507,7 +1508,7 @@ static qboolean ParseMapEntity( qboolean onlyLights )
                                
                                /* parse old brush format */
                                UnGetToken();
-                               ParseBrush( onlyLights );
+                               ParseBrush( onlyLights, noCollapseGroups );
                        }
                        entitySourceBrushes++;
                }
@@ -1664,14 +1665,14 @@ static qboolean ParseMapEntity( qboolean onlyLights )
                AdjustBrushesForOrigin( mapEnt );
 
        /* group_info entities are just for editor grouping (fixme: leak!) */
-       if( !Q_stricmp( "group_info", classname ) )
+       if( !noCollapseGroups && !Q_stricmp( "group_info", classname ) )
        {
                numEntities--;
                return qtrue;
        }
        
        /* group entities are just for editor convenience, toss all brushes into worldspawn */
-       if( funcGroup )
+       if( !noCollapseGroups && funcGroup )
        {
                MoveBrushesToWorld( mapEnt );
                numEntities--;
@@ -1689,7 +1690,7 @@ LoadMapFile()
 loads a map file into a list of entities
 */
 
-void LoadMapFile( char *filename, qboolean onlyLights )
+void LoadMapFile( char *filename, qboolean onlyLights, qboolean noCollapseGroups )
 {              
        FILE            *file;
        brush_t         *b;
@@ -1722,7 +1723,7 @@ void LoadMapFile( char *filename, qboolean onlyLights )
        buildBrush = AllocBrush( MAX_BUILD_SIDES );
        
        /* parse the map file */
-       while( ParseMapEntity( onlyLights ) );
+       while( ParseMapEntity( onlyLights, noCollapseGroups ) );
        
        /* light loading */
        if( onlyLights )
index 39f60d9ae79e2f477adc837fec33670aaeed30d9..bf0d5c663b60817a98789aeabaf78f9497597e92 100644 (file)
@@ -1576,11 +1576,11 @@ void                                            MakeNormalVectors( vec3_t forward, vec3_t right, vec3_t up );
 
 
 /* map.c */
-void                                           LoadMapFile( char *filename, qboolean onlyLights );
+void                                           LoadMapFile( char *filename, qboolean onlyLights, qboolean noCollapseGroups );
 int                                                    FindFloatPlane( vec3_t normal, vec_t dist, int numPoints, vec3_t *points );
 int                                                    PlaneTypeForNormal( vec3_t normal );
 void                                           AddBrushBevels( void );
-brush_t                                                *FinishBrush( void );
+brush_t                                                *FinishBrush(qboolean noCollapseGroups);
 
 
 /* portals.c */
@@ -1615,7 +1615,7 @@ void                                              SetLightStyles( void );
 int                                                    EmitShader( const char *shader, int *contentFlags, int *surfaceFlags );
 
 void                                           BeginBSPFile( void );
-void                                           EndBSPFile( void );
+void                                           EndBSPFile( qboolean do_write );
 void                                           EmitBrushes( brush_t *brushes, int *firstBrush, int *numBrushes );
 void                                           EmitFogs( void );
 
index 2ef8962b688cfad06dcb7ad864e9fb5a1a97813f..2e6e67a0e73d06857089a7477d63c186229812c2 100644 (file)
@@ -399,7 +399,7 @@ EndBSPFile()
 finishes a new bsp and writes to disk
 */
 
-void EndBSPFile( void )
+void EndBSPFile(qboolean do_write)
 {
        char    path[ 1024 ];
        
@@ -411,13 +411,16 @@ void EndBSPFile( void )
        numBSPEntities = numEntities;
        UnparseEntities();
        
-       /* write the surface extra file */
-       WriteSurfaceExtraFile( source );
-       
-       /* write the bsp */
-       sprintf( path, "%s.bsp", source );
-       Sys_Printf( "Writing %s\n", path );
-       WriteBSPFile( path );
+       if(do_write)
+       {
+               /* write the surface extra file */
+               WriteSurfaceExtraFile( source );
+
+               /* write the bsp */
+               sprintf( path, "%s.bsp", source );
+               Sys_Printf( "Writing %s\n", path );
+               WriteBSPFile( path );
+       }
 }