From 7a0665f15618af649d736d25d8e56bc8eeab8f24 Mon Sep 17 00:00:00 2001 From: Rudolf Polzer Date: Sun, 10 Oct 2010 16:04:41 +0200 Subject: [PATCH 1/1] automatically run the decompiler when specifying a BSP file in Import... --- libs/cmdlib.h | 2 +- libs/cmdlib/cmdlib.cpp | 17 +++++++-- plugins/mapq3/plugin.cpp | 5 ++- radiant/gtkdlgs.cpp | 2 +- radiant/map.cpp | 79 +++++++++++++++++++++++++++++++++------- radiant/qe3.cpp | 2 +- radiant/watchbsp.cpp | 4 +- 7 files changed, 88 insertions(+), 23 deletions(-) diff --git a/libs/cmdlib.h b/libs/cmdlib.h index ffeb4271..8961bd2a 100644 --- a/libs/cmdlib.h +++ b/libs/cmdlib.h @@ -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 diff --git a/libs/cmdlib/cmdlib.cpp b/libs/cmdlib/cmdlib.cpp index a09ed9ea..f6ace0fe 100644 --- a/libs/cmdlib/cmdlib.cpp +++ b/libs/cmdlib/cmdlib.cpp @@ -36,16 +36,23 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #if defined (POSIX) #include +#include +#include -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 // 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; } diff --git a/plugins/mapq3/plugin.cpp b/plugins/mapq3/plugin.cpp index c08a7e2e..fdb68a2e 100644 --- a/plugins/mapq3/plugin.cpp +++ b/plugins/mapq3/plugin.cpp @@ -264,8 +264,9 @@ public: 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() { diff --git a/radiant/gtkdlgs.cpp b/radiant/gtkdlgs.cpp index 2ba3e3f4..57ed278d 100644 --- a/radiant/gtkdlgs.cpp +++ b/radiant/gtkdlgs.cpp @@ -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(strEditCommand.c_str()), 0, true) == false) + if (Q_Exec(0, const_cast(strEditCommand.c_str()), 0, true, false) == false) { globalOutputStream() << "Failed to execute " << strEditCommand.c_str() << ", using default\n"; } diff --git a/radiant/map.cpp b/radiant/map.cpp index ac95068a..7b8c570d 100644 --- a/radiant/map.cpp +++ b/radiant/map.cpp @@ -85,6 +85,7 @@ MapModules& ReferenceAPI_getMapModules(); #include "commands.h" #include "autosave.h" #include "brushmodule.h" +#include "brush.h" class NameObserver { @@ -1637,28 +1638,80 @@ 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; } diff --git a/radiant/qe3.cpp b/radiant/qe3.cpp index 0291d2cf..c707d561 100644 --- a/radiant/qe3.cpp +++ b/radiant/qe3.cpp @@ -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); } } diff --git a/radiant/watchbsp.cpp b/radiant/watchbsp.cpp index 83fba900..5c170b66 100644 --- a/radiant/watchbsp.cpp +++ b/radiant/watchbsp.cpp @@ -577,7 +577,7 @@ void CWatchBSP::DoEBeginStep() globalOutputStream() << "=== running build command ===\n" << static_cast(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(); -- 2.39.2