From: namespace Date: Mon, 11 Sep 2006 11:29:09 +0000 (+0000) Subject: - Added sunplug (Mapcoordinator-plugin for ET) by Topsun X-Git-Tag: xonotic-v0.7.0~16^2~12^2~191 X-Git-Url: https://git.xonotic.org/?a=commitdiff_plain;h=c9fe7c049871b899889a82ec57b67647afa4f79b;p=xonotic%2Fnetradiant.git - Added sunplug (Mapcoordinator-plugin for ET) by Topsun ET only: setting mapcoordsmins and mapcoordsmaxs in the worldspawn Tester: Shaderman - Added brushexport Plugin by namespace Exports selected brushes as wavefront object. Tester: Shaderman git-svn-id: svn://svn.icculus.org/gtkradiant/GtkRadiant/trunk@103 8a3a26a2-13c4-0310-b231-cf6edde360e5 --- diff --git a/CHANGES b/CHANGES index 560d252d..5447e93c 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,15 @@ This is the changelog for developers, != changelog for the end user that we distribute with the binaries. (see changelog) +11/09/2006 +namespace +- Added sunplug (Mapcoordinator-plugin for ET) by Topsun + ET only: setting mapcoordsmins and mapcoordsmaxs in the worldspawn + Tester: Shaderman +- Added brushexport Plugin by namespace + Exports selected brushes as wavefront object. + Tester: Shaderman + 11/09/2006 namespace - Fixed compile error on x86_64, see http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=1105 diff --git a/GtkRadiant.sln b/GtkRadiant.sln index 2eacd630..544534f3 100644 --- a/GtkRadiant.sln +++ b/GtkRadiant.sln @@ -150,6 +150,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bobtoolz", "contrib\bobtool ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sunplug", "contrib\sunplug\sunplug.vcproj", "{46B36F0C-5E17-458E-AE6F-AECE52F66EDF}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "brushexport", "contrib\brushexport\brushexport.vcproj", "{46B36F0C-5E17-458E-AE6F-AECE52F66EDE}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug @@ -280,6 +288,14 @@ Global {B20364D1-4329-4D4E-B9CE-C9767618FDD6}.Debug.Build.0 = Debug|Win32 {B20364D1-4329-4D4E-B9CE-C9767618FDD6}.Release.ActiveCfg = Release|Win32 {B20364D1-4329-4D4E-B9CE-C9767618FDD6}.Release.Build.0 = Release|Win32 + {46B36F0C-5E17-458E-AE6F-AECE52F66EDF}.Debug.ActiveCfg = Debug|Win32 + {46B36F0C-5E17-458E-AE6F-AECE52F66EDF}.Debug.Build.0 = Debug|Win32 + {46B36F0C-5E17-458E-AE6F-AECE52F66EDF}.Release.ActiveCfg = Release|Win32 + {46B36F0C-5E17-458E-AE6F-AECE52F66EDF}.Release.Build.0 = Release|Win32 + {46B36F0C-5E17-458E-AE6F-AECE52F66EDE}.Debug.ActiveCfg = Debug|Win32 + {46B36F0C-5E17-458E-AE6F-AECE52F66EDE}.Debug.Build.0 = Debug|Win32 + {46B36F0C-5E17-458E-AE6F-AECE52F66EDE}.Release.ActiveCfg = Release|Win32 + {46B36F0C-5E17-458E-AE6F-AECE52F66EDE}.Release.Build.0 = Release|Win32 EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection diff --git a/SConscript b/SConscript index ed437ba3..f33c75fe 100644 --- a/SConscript +++ b/SConscript @@ -473,6 +473,21 @@ prtview_lib = prtview_env.SharedLibrarySafe(target='prtview', source=prtview_lst prtview_env.Depends(prtview_lib, profile_lib) prtview_env.Install(INSTALL + '/plugins', prtview_lib) + +brushexport_env = module_env.Copy() +brushexport_lst = build_list('contrib/brushexport', 'plugin.cpp') +brushexport_env.useGlib2() +brushexport_env.useGtk2() +brushexport_lib = brushexport_env.SharedLibrarySafe(target='brushexport', source=brushexport_lst, LIBPATH='libs') +brushexport_env.Install(INSTALL + '/plugins', brushexport_lib) + +sunplug_env = module_env.Copy() +sunplug_lst = build_list('contrib/sunplug', 'sunplug.cpp') +sunplug_env.useGlib2() +sunplug_env.useGtk2() +sunplug_lib = sunplug_env.SharedLibrarySafe(target='sunplug', source=sunplug_lst, LIBPATH='libs') +sunplug_env.Install(INSTALL + '/plugins', sunplug_lib) + #gensurf_lst = build_list('contrib/gtkgensurf', #'bitmap.cpp dec.cpp face.cpp font.cpp gendlgs.cpp genmap.cpp gensurf.cpp heretic.cpp plugin.cpp view.cpp triangle.c') #bob_env.SharedLibrarySafe(target='gensurf', source=gensurf_lst) diff --git a/contrib/brushexport/brushexport.def b/contrib/brushexport/brushexport.def new file mode 100644 index 00000000..44d97f3f --- /dev/null +++ b/contrib/brushexport/brushexport.def @@ -0,0 +1,7 @@ +; brushexport.def : Declares the module parameters for the DLL. + +LIBRARY "BRUSHEXPORT" + +EXPORTS + ; Explicit exports can go here + Radiant_RegisterModules @1 diff --git a/contrib/brushexport/brushexport.vcproj b/contrib/brushexport/brushexport.vcproj new file mode 100644 index 00000000..a978947a --- /dev/null +++ b/contrib/brushexport/brushexport.vcproj @@ -0,0 +1,163 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/contrib/brushexport/plugin.cpp b/contrib/brushexport/plugin.cpp new file mode 100644 index 00000000..8954473d --- /dev/null +++ b/contrib/brushexport/plugin.cpp @@ -0,0 +1,236 @@ +/* +Copyright (C) 2006, Thomas Nitschke. +All Rights Reserved. + +This file is part of GtkRadiant. + +GtkRadiant is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +GtkRadiant is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GtkRadiant; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#include "plugin.h" + +#include "iplugin.h" +#include "qerplugin.h" + +#include + +#include "debugging/debugging.h" +#include "string/string.h" +#include "modulesystem/singletonmodule.h" +#include "stream/textfilestream.h" +#include "stream/stringstream.h" +#include "gtkutil/messagebox.h" +#include "gtkutil/filechooser.h" + +#include "ibrush.h" +#include "iscenegraph.h" +#include "iselection.h" +#include "ifilesystem.h" +#include "ifiletypes.h" + +#include "../../radiant/brush.h" + +namespace BrushExport +{ + GtkWindow* g_mainwnd; + + class CExportFormatWavefront : public BrushVisitor + { + TextFileOutputStream& m_file; + + StringOutputStream vertexbuffer; + StringOutputStream texcoordbuffer; + StringOutputStream facebuffer; + + size_t vertices; + size_t exported; + + public: + + CExportFormatWavefront(TextFileOutputStream& file) + : m_file(file) + { + exported = 0; + vertices = 0; + } + + virtual ~CExportFormatWavefront(void) {} + + void visit(scene::Instance& instance) + { + BrushInstance* bptr = InstanceTypeCast::cast(instance); + if(bptr) + { + Brush& brush(bptr->getBrush()); + + m_file << "\ng " << brush.name() << exported << "\n"; + + brush.forEachFace(*this); + + m_file << vertexbuffer.c_str() << "\n"; + m_file << texcoordbuffer.c_str(); + m_file << facebuffer.c_str() << "\n"; + + vertexbuffer.clear(); + texcoordbuffer.clear(); + facebuffer.clear(); + ++exported; + } + } + + void visit(Face& face) const + { + // cast the stupid const away + const_cast(this)->visit(face); + } + + void visit(Face& face) + { + size_t v_start = vertices; + const Winding& w(face.getWinding()); + for(size_t i = 0; i < w.numpoints; ++i) + { + vertexbuffer << "v " << w[i].vertex.x() << " " << w[i].vertex.y() << " " << w[i].vertex.z() << "\n"; + texcoordbuffer << "vt " << w[i].texcoord.x() << " " << w[i].texcoord.y() << "\n"; + ++vertices; + } + + facebuffer << "\nf"; + for(size_t i = v_start; i < vertices; ++i) + facebuffer << " " << i+1 << "/" << i+1; + } + }; + + /** + Exporterclass which will pass every visit-call + to a special formatexporter. + */ + template + class CExporter : public SelectionSystem::Visitor + { + public: + CExporter(TextFileOutputStream& file) + : m_exporter(file) + {} + + virtual ~CExporter(void) {} + + void visit(scene::Instance& instance) const + { + m_exporter.visit(instance); + } + + private: + mutable TExporterFormat m_exporter; + }; + + template + void export_selected(TextFileOutputStream& file) + { + CExporter exporter(file); + GlobalSelectionSystem().foreachSelected(exporter); + } + + const char* init(void* hApp, void* pMainWidget) + { + g_mainwnd = (GtkWindow*)pMainWidget; + ASSERT_NOTNULL(g_mainwnd); + return ""; + } + const char* getName() + { + return "Brush export Plugin"; + } + const char* getCommandList() + { + return "Export selected as Wavefront Object;About"; + } + const char* getCommandTitleList() + { + return ""; + } + + void dispatch(const char* command, float* vMin, float* vMax, bool bSingleBrush) + { + if(string_equal(command, "About")) + { + GlobalRadiant().m_pfnMessageBox(GTK_WIDGET(g_mainwnd), "Brushexport plugin v 1.0 by namespace (www.codecreator.net)\n" + "Enjoy!\n\nSend feedback to spam@codecreator.net", "About me...", + eMB_OK, + eMB_ICONDEFAULT); + } + else if(string_equal(command, "Export selected as Wavefront Object")) + { + if(const char* path = GlobalRadiant().m_pfnFileDialog(GTK_WIDGET(g_mainwnd), false, "Save as Obj", 0, 0)) + { + TextFileOutputStream file(path); + if(file.failed()) + { + GlobalRadiant().m_pfnMessageBox(GTK_WIDGET(g_mainwnd), "Unable to write to file", "Error", + eMB_OK, + eMB_ICONERROR); + } + else + { + export_selected(file); + } + } + } + } + +} // namespace + +class BrushExportDependencies : + public GlobalRadiantModuleRef, + public GlobalFiletypesModuleRef, + public GlobalBrushModuleRef, + public GlobalFileSystemModuleRef, + public GlobalSceneGraphModuleRef, + public GlobalSelectionModuleRef +{ +public: + BrushExportDependencies(void) + : GlobalBrushModuleRef(GlobalRadiant().getRequiredGameDescriptionKeyValue("brushtypes")) + {} +}; + +class BrushExportModule : public TypeSystemRef +{ + _QERPluginTable m_plugin; +public: + typedef _QERPluginTable Type; + STRING_CONSTANT(Name, "brushexport"); + + BrushExportModule() + { + m_plugin.m_pfnQERPlug_Init = &BrushExport::init; + m_plugin.m_pfnQERPlug_GetName = &BrushExport::getName; + m_plugin.m_pfnQERPlug_GetCommandList = &BrushExport::getCommandList; + m_plugin.m_pfnQERPlug_GetCommandTitleList = &BrushExport::getCommandTitleList; + m_plugin.m_pfnQERPlug_Dispatch = &BrushExport::dispatch; + } + _QERPluginTable* getTable() + { + return &m_plugin; + } +}; + +typedef SingletonModule SingletonBrushExportModule; +SingletonBrushExportModule g_BrushExportModule; + +extern "C" void RADIANT_DLLEXPORT Radiant_RegisterModules(ModuleServer& server) +{ + initialiseModule(server); + g_BrushExportModule.selfRegister(); +} diff --git a/contrib/brushexport/plugin.h b/contrib/brushexport/plugin.h new file mode 100644 index 00000000..99396819 --- /dev/null +++ b/contrib/brushexport/plugin.h @@ -0,0 +1,25 @@ +/* +Copyright (C) 2006, Thomas Nitschke. +All Rights Reserved. + +This file is part of GtkRadiant. + +GtkRadiant is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +GtkRadiant is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GtkRadiant; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#if !defined(INCLUDED_BRUSH_EXPORT_H) +#define INCLUDED_BRUSH_EXPORT_H + +#endif diff --git a/contrib/sunplug/sunplug.cpp b/contrib/sunplug/sunplug.cpp new file mode 100644 index 00000000..67103018 --- /dev/null +++ b/contrib/sunplug/sunplug.cpp @@ -0,0 +1,462 @@ +/* +Sunplug plugin for GtkRadiant +Copyright (C) 2004 Topsun +Thanks to SPoG for help! + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "sunplug.h" + +#include "debugging/debugging.h" + +#include "iplugin.h" + +#include "string/string.h" +#include "modulesystem/singletonmodule.h" + +#include "iundo.h" // declaration of undo system +#include "ientity.h" // declaration of entity system +#include "iscenegraph.h" // declaration of datastructure of the map + +#include "scenelib.h" // declaration of datastructure of the map +#include "qerplugin.h" // declaration to use other interfaces as a plugin + +#include // to display something with gtk (windows, buttons etc.), the whole package might not be necessary + +void about_plugin_window(); +void MapCoordinator(); + +#ifdef __linux__ +// linux itoa implementation +char* itoa( int value, char* result, int base ) +{ + // check that the base if valid + if (base < 2 || base > 16) + { + *result = 0; + return result; + } + + char* out = result; + int quotient = value; + + do + { + *out = "0123456789abcdef"[abs(quotient % base)]; + ++out; + + quotient /= base; + } while (quotient); + + // Only apply negative sign for base 10 + if( value < 0 && base == 10) + *out++ = '-'; + + std::reverse(result, out); + + *out = 0; + return result; +} +#endif + +typedef struct _mapcoord_setting_packet { + GtkSpinButton *spinner1, *spinner2, *spinner3, *spinner4; + Entity* worldspawn; +} mapcoord_setting_packet; + +static int map_minX, map_maxX, map_minY, map_maxY; +static int minX, maxX, minY, maxY; +mapcoord_setting_packet msp; + +// ************************** +// ** find entities by class ** from radiant/map.cpp +// ************************** +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; + } +}; + +Entity* Scene_FindEntityByClass(const char* name) +{ + Entity* entity; + GlobalSceneGraph().traverse(EntityFindByClassname(name, entity)); + return entity; +} + +// ************************** +// ** GTK callback functions ** +// ************************** + +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer data) +{ + /* If you return FALSE in the "delete_event" signal handler, + * GTK will emit the "destroy" signal. Returning TRUE means + * you don't want the window to be destroyed. + * This is useful for popping up 'are you sure you want to quit?' + * type dialogs. */ + + return FALSE; +} + +// destroy widget if destroy signal is passed to widget +static void destroy(GtkWidget *widget, gpointer data) +{ + gtk_widget_destroy(widget); +} + +// function for close button to destroy the toplevel widget +static void close_window(GtkWidget *widget, gpointer data) +{ + gtk_widget_destroy(gtk_widget_get_toplevel(widget)); +} + +// callback function to assign the optimal mapcoords to the spinboxes +static void input_optimal(GtkWidget *widget, gpointer data) +{ + gtk_spin_button_set_value(msp.spinner1, minX); + gtk_spin_button_set_value(msp.spinner2, maxY); + gtk_spin_button_set_value(msp.spinner3, maxX); + gtk_spin_button_set_value(msp.spinner4, minY); +} + +// Spinner return value function +gint grab_int_value(GtkSpinButton *a_spinner, gpointer user_data) { + return gtk_spin_button_get_value_as_int(a_spinner); +} + +// write the values of the Spinner-Boxes to the worldspawn +static void set_coordinates(GtkWidget *widget, gpointer data) +{ + //Str str_min, str_max; + char buffer[10], str_min[20], str_max[20]; + + itoa(gtk_spin_button_get_value_as_int(msp.spinner1), str_min, 10); + itoa(gtk_spin_button_get_value_as_int(msp.spinner2), buffer, 10); + strcat(str_min, " "); + strcat(str_min, buffer); + msp.worldspawn->setKeyValue("mapcoordsmins", str_min); + + itoa(gtk_spin_button_get_value_as_int(msp.spinner3), str_max, 10); + itoa(gtk_spin_button_get_value_as_int(msp.spinner4), buffer, 10); + strcat(str_max, " "); + strcat(str_max, buffer); + UndoableCommand undo("SunPlug.entitySetMapcoords"); + msp.worldspawn->setKeyValue("mapcoordsmaxs", str_max); + + close_window(widget, NULL); +} + +class SunPlugPluginDependencies : + public GlobalRadiantModuleRef, // basic class for all other module refs + public GlobalUndoModuleRef, // used to say radiant that something has changed and to undo that + public GlobalSceneGraphModuleRef, // necessary to handle data in the mapfile (change, retrieve data) + public GlobalEntityModuleRef // to access and modify the entities +{ +public: + SunPlugPluginDependencies() : + GlobalEntityModuleRef(GlobalRadiant().getRequiredGameDescriptionKeyValue("entities"))//, + { + } +}; + +// ************************* +// ** standard plugin stuff ** +// ************************* +namespace SunPlug +{ + GtkWindow* main_window; + char MenuList[100] = ""; + + const char* init(void* hApp, void* pMainWidget) + { + main_window = GTK_WINDOW(pMainWidget); + return "Initializing SunPlug for GTKRadiant"; + } + const char* getName() + { + return "SunPlug"; // name that is shown in the menue + } + const char* getCommandList() + { + const char about[] = "About..."; + const char etMapCoordinator[] = ";ET-MapCoordinator"; + + strcat(MenuList, about); + if (strncmp(GlobalRadiant().getGameName(), "etmain", 6) == 0) strcat(MenuList, etMapCoordinator); + return (const char*)MenuList; + } + const char* getCommandTitleList() + { + return ""; + } + void dispatch(const char* command, float* vMin, float* vMax, bool bSingleBrush) // message processing + { + if(string_equal(command, "About...")) + { + about_plugin_window(); + } + if(string_equal(command, "ET-MapCoordinator")) + { + MapCoordinator(); + } + } +} // namespace + +class SunPlugModule : public TypeSystemRef +{ + _QERPluginTable m_plugin; +public: + typedef _QERPluginTable Type; + STRING_CONSTANT(Name, "SunPlug"); + + SunPlugModule() + { + m_plugin.m_pfnQERPlug_Init = &SunPlug::init; + m_plugin.m_pfnQERPlug_GetName = &SunPlug::getName; + m_plugin.m_pfnQERPlug_GetCommandList = &SunPlug::getCommandList; + m_plugin.m_pfnQERPlug_GetCommandTitleList = &SunPlug::getCommandTitleList; + m_plugin.m_pfnQERPlug_Dispatch = &SunPlug::dispatch; + } + _QERPluginTable* getTable() + { + return &m_plugin; + } +}; + +typedef SingletonModule SingletonSunPlugModule; + +SingletonSunPlugModule g_SunPlugModule; + + +extern "C" void RADIANT_DLLEXPORT Radiant_RegisterModules(ModuleServer& server) +{ + initialiseModule(server); + + g_SunPlugModule.selfRegister(); +} + +// ************ +// ** my stuff ** +// ************ + +// About dialog +void about_plugin_window() +{ + GtkWidget *window, *vbox, *label, *button; + + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); // create a window + gtk_window_set_transient_for(GTK_WINDOW(window), SunPlug::main_window); // make the window to stay in front of the main window + g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(delete_event), NULL); // connect the delete event + g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(destroy), NULL); // connect the destroy event for the window + gtk_window_set_title(GTK_WINDOW(window), "About SunPlug"); // set the title of the window for the window + gtk_window_set_resizable(GTK_WINDOW(window), FALSE); // don't let the user resize the window + gtk_window_set_modal(GTK_WINDOW(window), TRUE); // force the user not to do something with the other windows + gtk_container_set_border_width(GTK_CONTAINER(window), 10); // set the border of the window + + vbox = gtk_vbox_new(FALSE, 10); // create a box to arrange new objects vertically + gtk_container_add(GTK_CONTAINER(window), vbox); // add the box to the window + + label = gtk_label_new("SunPlug v1.0 for GtkRadiant 1.5\nby Topsun"); // create a label + gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT); // text align left + gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 2); // insert the label in the box + + button = gtk_button_new_with_label("OK"); // create a button with text + g_signal_connect_swapped(G_OBJECT(button), "clicked", G_CALLBACK (gtk_widget_destroy), window); // connect the click event to close the window + gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 2); // insert the button in the box + + gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); // center the window on screen + + gtk_widget_show_all(window); // show the window and all subelements +} + +// get the current bounding box and return the optimal coordinates +void GetOptimalCoordinates(AABB *levelBoundingBox) +{ + int half_width, half_heigth, center_x, center_y; + + half_width = levelBoundingBox->extents.x(); + half_heigth = levelBoundingBox->extents.y(); + center_x = levelBoundingBox->origin.x(); + center_y = levelBoundingBox->origin.y(); + + if (half_width > 175 || half_heigth > 175) // the square must be at least 350x350 units + { + // the wider side is the indicator for the square + if (half_width >= half_heigth) + { + minX = center_x - half_width; + maxX = center_x + half_width; + minY = center_y - half_width; + maxY = center_y + half_width; + } else { + minX = center_x - half_heigth; + maxX = center_x + half_heigth; + minY = center_y - half_heigth; + maxY = center_y + half_heigth; + } + } else { + minX = center_x - 175; + maxX = center_x + 175; + minY = center_y - 175; + maxY = center_y + 175; + } +} + +// MapCoordinator dialog window +void MapCoordinator() +{ + GtkWidget *window, *vbox, *table, *label, *spinnerMinX, *spinnerMinY, *spinnerMaxX, *spinnerMaxY, *button; + GtkAdjustment *spinner_adj_MinX, *spinner_adj_MinY, *spinner_adj_MaxX, *spinner_adj_MaxY; + Entity *theWorldspawn = NULL; + const char *buffer; + char line[20]; + + // in any case we need a window to show the user what to do + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); // create the window + gtk_window_set_transient_for(GTK_WINDOW(window), SunPlug::main_window); // make the window to stay in front of the main window + g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(delete_event), NULL); // connect the delete event for the window + g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(destroy), NULL); // connect the destroy event for the window + gtk_window_set_title(GTK_WINDOW(window), "ET-MapCoordinator"); // set the title of the window for the window + gtk_window_set_resizable(GTK_WINDOW(window), FALSE); // don't let the user resize the window + gtk_window_set_modal(GTK_WINDOW(window), TRUE); // force the user not to do something with the other windows + gtk_container_set_border_width(GTK_CONTAINER(window), 10); // set the border of the window + + vbox = gtk_vbox_new(FALSE, 10); // create a box to arrange new objects vertically + gtk_container_add(GTK_CONTAINER(window), vbox); // add the box to the window + + scene::Path path = makeReference(GlobalSceneGraph().root()); // get the path to the root element of the graph + scene::Instance* instance = GlobalSceneGraph().find(path); // find the instance to the given path + AABB levelBoundingBox = instance->worldAABB(); // get the bounding box of the level + + theWorldspawn = Scene_FindEntityByClass("worldspawn"); // find the entity worldspawn + if (theWorldspawn != 0) { // need to have a worldspawn otherwise setting a value crashes the radiant + // next two if's: get the current values of the mapcoords + buffer = theWorldspawn->getKeyValue("mapcoordsmins"); // upper left corner + if (strlen(buffer) > 0) { + strncpy(line, buffer, 19); + map_minX = atoi(strtok(line, " ")); // minimum of x value + map_minY = atoi(strtok(NULL, " ")); // maximum of y value + } else { + map_minX = 0; + map_minY = 0; + } + buffer = theWorldspawn->getKeyValue("mapcoordsmaxs"); // lower right corner + if (strlen(buffer) > 0) { + strncpy(line, buffer, 19); + map_maxX = atoi(strtok(line, " ")); // maximum of x value + map_maxY = atoi(strtok(NULL, " ")); // minimum of y value + } else { + map_maxX = 0; + map_maxY = 0; + } + + globalOutputStream() << "SunPlug: calculating optimal coordinates\n"; // write to console that we are calculating the coordinates + GetOptimalCoordinates(&levelBoundingBox); // calculate optimal mapcoords with the dimensions of the level bounding box + globalOutputStream() << "SunPlug: adviced mapcoordsmins=" << minX << " " << maxY << "\n"; // console info about mapcoordsmins + globalOutputStream() << "SunPlug: adviced mapcoordsmaxs=" << maxX << " " << minY << "\n"; // console info about mapcoordsmaxs + + spinner_adj_MinX = (GtkAdjustment *)gtk_adjustment_new(map_minX, -65536.0, 65536.0, 1.0, 5.0, 5.0); // create adjustment for value and range of minimum x value + spinner_adj_MinY = (GtkAdjustment *)gtk_adjustment_new(map_minY, -65536.0, 65536.0, 1.0, 5.0, 5.0); // create adjustment for value and range of minimum y value + spinner_adj_MaxX = (GtkAdjustment *)gtk_adjustment_new(map_maxX, -65536.0, 65536.0, 1.0, 5.0, 5.0); // create adjustment for value and range of maximum x value + spinner_adj_MaxY = (GtkAdjustment *)gtk_adjustment_new(map_maxY, -65536.0, 65536.0, 1.0, 5.0, 5.0); // create adjustment for value and range of maximum y value + + button = gtk_button_new_with_label("Get optimal mapcoords"); // create button with text + g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(input_optimal), NULL); // connect button with callback function + gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 2); // insert button into vbox + + gtk_box_pack_start(GTK_BOX(vbox), gtk_hseparator_new(), FALSE, FALSE, 2); // insert separator into vbox + + table = gtk_table_new(4, 3, TRUE); // create table + gtk_table_set_row_spacings(GTK_TABLE(table), 8); // set row spacings + gtk_table_set_col_spacings(GTK_TABLE(table), 8); // set column spacings + gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 2); // insert table into vbox + + label = gtk_label_new("x"); // create label + gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT); // align text to the left side + gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 2, 0, 1); // insert label into table + + label = gtk_label_new("y"); // create label + gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT); // align text to the left side + gtk_table_attach_defaults(GTK_TABLE(table), label, 2, 3, 0, 1); // insert label into table + + label = gtk_label_new("mapcoordsmins"); // create label + gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT); // align text to the left side + gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2); // insert label into table + + spinnerMinX = gtk_spin_button_new(spinner_adj_MinX, 1.0, 0); // create textbox wiht value spin, value and value range + gtk_table_attach_defaults(GTK_TABLE(table), spinnerMinX, 1, 2, 1, 2); // insert spinbox into table + + spinnerMinY = gtk_spin_button_new(spinner_adj_MinY, 1.0, 0); // create textbox wiht value spin, value and value range + gtk_table_attach_defaults(GTK_TABLE(table), spinnerMinY, 2, 3, 1, 2); // insert spinbox into table + + label = gtk_label_new("mapcoordsmaxs"); // create label + gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT); // align text to the left side + gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 2, 3); // insert label into table + + spinnerMaxX = gtk_spin_button_new(spinner_adj_MaxX, 1.0, 0); // create textbox wiht value spin, value and value range + gtk_table_attach_defaults(GTK_TABLE(table), spinnerMaxX, 1, 2, 2, 3); // insert spinbox into table + + spinnerMaxY = gtk_spin_button_new(spinner_adj_MaxY, 1.0, 0); // create textbox wiht value spin, value and value range + gtk_table_attach_defaults(GTK_TABLE(table), spinnerMaxY, 2, 3, 2, 3); // insert spinbox into table + + // put the references to the spinboxes and the worldspawn into the global exchange + msp.spinner1 = GTK_SPIN_BUTTON(spinnerMinX); + msp.spinner2 = GTK_SPIN_BUTTON(spinnerMinY); + msp.spinner3 = GTK_SPIN_BUTTON(spinnerMaxX); + msp.spinner4 = GTK_SPIN_BUTTON(spinnerMaxY); + msp.worldspawn = theWorldspawn; + + button = gtk_button_new_with_label("Set"); // create button with text + g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(set_coordinates), NULL); // connect button with callback function + gtk_table_attach_defaults(GTK_TABLE(table), button, 1, 2, 3, 4); // insert button into table + + button = gtk_button_new_with_label("Cancel"); // create button with text + g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(close_window), NULL); // connect button with callback function + gtk_table_attach_defaults(GTK_TABLE(table), button, 2, 3, 3, 4); // insert button into table + } else { + globalOutputStream() << "SunPlug: no worldspawn found!\n"; // output error to console + + label = gtk_label_new("ERROR: No worldspawn was found in the map!\nIn order to use this tool the map must have at least one brush in the worldspawn. "); // create a label + gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT); // text align left + gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 2); // insert the label in the box + + button = gtk_button_new_with_label("OK"); // create a button with text + g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(close_window), NULL); // connect the click event to close the window + gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 2); // insert the button in the box + } + + gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); // center the window + gtk_widget_show_all(window); // show the window and all subelements +} \ No newline at end of file diff --git a/contrib/sunplug/sunplug.def b/contrib/sunplug/sunplug.def new file mode 100644 index 00000000..6d260776 --- /dev/null +++ b/contrib/sunplug/sunplug.def @@ -0,0 +1,7 @@ +; sunplug.def : Declares the module parameters for the DLL. + +LIBRARY "SUNPLUG" + +EXPORTS + ; Explicit exports can go here + Radiant_RegisterModules @1 diff --git a/contrib/sunplug/sunplug.h b/contrib/sunplug/sunplug.h new file mode 100644 index 00000000..9649a743 --- /dev/null +++ b/contrib/sunplug/sunplug.h @@ -0,0 +1,25 @@ +/* +Sunplug plugin for GtkRadiant +Copyright (C) 2004 Topsun +Thanks to SPoG for help! + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _PLUGIN_SUNPLUG_ + #define _PLUGIN_SUNPLUG_ + + +#endif // _PLUGIN_SUNPLUG_ diff --git a/contrib/sunplug/sunplug.vcproj b/contrib/sunplug/sunplug.vcproj new file mode 100644 index 00000000..2d6fce90 --- /dev/null +++ b/contrib/sunplug/sunplug.vcproj @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +