]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - plugins/model/plugin.cpp
merge branch work back into trunk
[xonotic/netradiant.git] / plugins / model / plugin.cpp
index e032e3981a4378727317e0dad037f87077226c2b..a69ce21f910f4b883d2f32e5cfc58f6f754476af 100644 (file)
@@ -1,6 +1,7 @@
+
 /*
-Copyright (C) 2001-2006, William Joseph.
-All Rights Reserved.
+Copyright (C) 1999-2007 id Software, Inc. and contributors.
+For a list of contributors, see the accompanying CONTRIBUTORS file.
 
 This file is part of GtkRadiant.
 
@@ -21,62 +22,81 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
 #include "plugin.h"
 
-#include <stdio.h>
+// toolbar implementation
+
+class CFlushReloadSelectedToolbarButton : public IToolbarButton
+{
+public:
+  virtual const char* getImage() const
+  {
+    return "model_reload_entity.bmp";
+  }
+  virtual const char* getText() const
+  {
+    return "Reload";
+  }
+  virtual const char* getTooltip() const
+  {
+    return "Flush & Reload Selected Model";
+  }
+  virtual void activate() const
+  {
+    DoFlushReloadSelected();
+  }
+  virtual EType getType() const
+  {
+    return eButton;
+  }
+};
+
+CFlushReloadSelectedToolbarButton g_flushreloadselected;
+
+unsigned int ToolbarButtonCount()
+{
+  return 1;
+}
+
+const IToolbarButton* GetToolbarButton(unsigned int index)
+{
+  return &g_flushreloadselected;
+}
+
+// =============================================================================
+// Pico utility functions
+
 #include "picomodel.h"
-typedef unsigned char byte;
-#include <stdlib.h>
-#include <algorithm>
-#include <list>
-
-#include "iscenegraph.h"
-#include "irender.h"
-#include "iselection.h"
-#include "iimage.h"
-#include "imodel.h"
-#include "igl.h"
-#include "ifilesystem.h"
-#include "iundo.h"
-#include "ifiletypes.h"
-
-#include "modulesystem/singletonmodule.h"
-#include "stream/textstream.h"
-#include "string/string.h"
-#include "stream/stringstream.h"
-#include "typesystem.h"
-
-#include "model.h"
 
 void PicoPrintFunc( int level, const char *str )
 {
-       if( str == 0 )
+       if( str == NULL )
                return;
        switch( level )
        {
                case PICO_NORMAL:
-                       globalOutputStream() << str << "\n";
+                       Sys_Printf( "%s\n", str );
                        break;
                
                case PICO_VERBOSE:
-                       //globalOutputStream() << "PICO_VERBOSE: " << str << "\n";
+                       Sys_FPrintf( SYS_VRB, "%s\n", str );
                        break;
                
                case PICO_WARNING:
-                       globalErrorStream() << "PICO_WARNING: " << str << "\n";
+                       Sys_Printf( "WARNING: %s\n", str );
                        break;
                
                case PICO_ERROR:
-                       globalErrorStream() << "PICO_ERROR: " << str << "\n";
+                       Sys_FPrintf( SYS_VRB, "ERROR: %s\n", str );
                        break;
                
                case PICO_FATAL:
-                       globalErrorStream() << "PICO_FATAL: " << str << "\n";
+      Sys_Printf( "ERROR: %s\n", str );
                        break;
        }
 }
 
 void PicoLoadFileFunc( char *name, byte **buffer, int *bufSize )
 {
-       *bufSize = vfsLoadFile( (const char*) name, (void**) buffer);
+       *bufSize = vfsLoadFile( (const char*) name, (void**) buffer, 0 );
 }
 
 void PicoFreeFileFunc( void* file )
@@ -84,7 +104,7 @@ void PicoFreeFileFunc( void* file )
        vfsFreeFile(file);
 }
 
-void pico_initialise()
+static void initialise()
 {
        PicoInit();
        PicoSetMallocFunc( malloc );
@@ -94,96 +114,199 @@ void pico_initialise()
        PicoSetFreeFileFunc( PicoFreeFileFunc );
 }
 
+static void add_model_apis(CSynapseClient& client)
+{
+  const picoModule_t** modules = PicoModuleList( NULL );
+  while(*modules != NULL)
+  {
+    const picoModule_t* module = *modules++;
+    if(module->canload && module->load)
+      for(unsigned int j = 0; module->defaultExts[j] != NULL; j++)
+        client.AddAPI(MODEL_MAJOR, module->defaultExts[j], sizeof(_QERPlugModelTable));
+  }   
+}
 
-class PicoModelLoader : public ModelLoader
+static bool model_is_supported(const char* extension)
 {
-  const picoModule_t* m_module;
-public:
-  PicoModelLoader(const picoModule_t* module) : m_module(module)
+  const picoModule_t** modules = PicoModuleList( NULL );
+  while(*modules != NULL)
   {
+    const picoModule_t* module = *modules++;
+    if(module->canload && module->load)
+      for(unsigned int j = 0; module->defaultExts[j] != NULL; j++)
+        if(strcmp(extension, module->defaultExts[j]) == 0)
+          return true;
   }
-  scene::Node& loadModel(ArchiveFile& file)
+  return false;
+}
+
+void init_filetypes()
+{
+  const picoModule_t **modules = PicoModuleList(NULL);
+  while(*modules != NULL)
   {
-    return loadPicoModel(m_module, file);
+    const picoModule_t* module = *modules++;
+    if(module->canload && module->load)
+    {
+      for(char*const* ext = module->defaultExts; *ext != NULL; ++ext)
+      {
+        char buf[16];
+        buf[0] = '*';
+        buf[1] = '.';
+        strcpy(buf+2, *ext);
+        GetFileTypeRegistry()->addType(MODEL_MAJOR, filetype_t(module->displayName, buf));
+      }
+    }
   }
-};
+}
+
+// plugin implementation
+
+static const char *PLUGIN_NAME = "Model loading module";
+static const char *PLUGIN_COMMANDS = "About;-;Flush & Reload Models;Flush & Reload Selected";
+static const char *PLUGIN_ABOUT = "Model Module v1.0 for GtkRadiant\nby Arnout van Meer (rr2do2@splashdamage.com)\n\nBased on the MD3Model Module by SPoG\nPicoModel Library Copyright (c) 2002, Randy Reddig & seaw0lf\n\nSupported models:\n";
 
-class ModelPicoDependencies :
-  public GlobalFileSystemModuleRef,
-  public GlobalOpenGLModuleRef,
-  public GlobalUndoModuleRef,
-  public GlobalSceneGraphModuleRef,
-  public GlobalShaderCacheModuleRef,
-  public GlobalSelectionModuleRef,
-  public GlobalFiletypesModuleRef
+extern "C" const char* QERPlug_Init (void *hApp, void* pMainWidget)
 {
-};
+  init_filetypes();
+  return (char *) PLUGIN_NAME;
+}
 
-class ModelPicoAPI : public TypeSystemRef
+extern "C" const char* QERPlug_GetName ()
 {
-  PicoModelLoader m_modelLoader;
-public:
-  typedef ModelLoader Type;
+  return (char *) PLUGIN_NAME;
+}
 
-  ModelPicoAPI(const char* extension, const picoModule_t* module) :
-    m_modelLoader(module)
-  {
-    StringOutputStream filter(128);
-    filter << "*." << extension;
-    GlobalFiletypesModule::getTable().addType(Type::Name(), extension, filetype_t(module->displayName, filter.c_str()));
+extern "C" const char* QERPlug_GetCommandList ()
+{
+  return (char *) PLUGIN_COMMANDS;
+}
+
+extern "C" void QERPlug_Dispatch (const char *p, vec3_t vMin, vec3_t vMax, bool bSingleBrush)
+{
+  if( !strcmp( p, "Flush & Reload Selected" ) )
+    DoFlushReloadSelected();
+  else if( !strcmp( p, "Flush & Reload Models" ) )
+    DoFlushReloadAll();
+  else if( !strcmp( p, "About" ) ) {
+    const picoModule_t** modules = PicoModuleList( NULL );
+    char about_buf[1024];
+    strncpy(about_buf, PLUGIN_ABOUT, sizeof(about_buf) - 1);
+    while(*modules != NULL) {
+      const picoModule_t* module = *modules++;
+      strncat(about_buf, module->displayName, sizeof(about_buf) - 1);
+      strncat(about_buf, " (", sizeof(about_buf) - 1);
+      strncat(about_buf, module->defaultExts[0], sizeof(about_buf) - 1);
+      strncat(about_buf, ")\n\t", sizeof(about_buf) - 1);
+      strncat(about_buf, module->copyright, sizeof(about_buf) - 1);
+      strncat(about_buf, "\n", sizeof(about_buf) - 1);
+    }
+    g_FuncTable.m_pfnMessageBox(NULL, about_buf, "About", MB_OK, NULL);
   }
-  ModelLoader* getTable()
+}
+
+
+void DoFlushReloadSelected() {
+}
+
+void DoFlushReloadAll() {
+  GetModelCache()->RefreshAll();
+}
+
+// =============================================================================
+
+// function tables
+_QERFuncTable_1 g_FuncTable;
+_QERQglTable g_QglTable;
+_QERShadersTable g_ShadersTable;
+_QERFileSystemTable g_FileSystemTable;
+
+// =============================================================================
+// SYNAPSE
+
+CSynapseServer* g_pSynapseServer = NULL;
+CSynapseClientModel g_SynapseClient;
+
+static const XMLConfigEntry_t entries[] = 
+  { { SHADERS_MAJOR, SYN_REQUIRE, sizeof(g_ShadersTable), &g_ShadersTable }, 
+    { VFS_MAJOR, SYN_REQUIRE, sizeof(g_FileSystemTable), &g_FileSystemTable },
+    { NULL, SYN_UNKNOWN, 0, NULL } };
+
+#if __GNUC__ >= 4
+#pragma GCC visibility push(default)
+#endif
+extern "C" CSynapseClient* SYNAPSE_DLL_EXPORT Synapse_EnumerateInterfaces( const char *version, CSynapseServer *pServer ) {
+#if __GNUC__ >= 4
+#pragma GCC visibility pop
+#endif
+  if (strcmp(version, SYNAPSE_VERSION))
   {
-    return &m_modelLoader;
+    Syn_Printf("ERROR: synapse API version mismatch: should be '" SYNAPSE_VERSION "', got '%s'\n", version);
+    return NULL;
   }
-};
+  g_pSynapseServer = pServer;
+  g_pSynapseServer->IncRef();
+  Set_Syn_Printf( g_pSynapseServer->Get_Syn_Printf() );
 
-class PicoModelAPIConstructor
-{
-  CopiedString m_extension;
-  const picoModule_t* m_module;
-public:
-  PicoModelAPIConstructor(const char* extension, const picoModule_t* module) :
-    m_extension(extension), m_module(module)
-  {
+  initialise();
+  
+  add_model_apis(g_SynapseClient);
+  g_SynapseClient.AddAPI(TOOLBAR_MAJOR, "model", sizeof(_QERPlugToolbarTable));
+  g_SynapseClient.AddAPI(PLUGIN_MAJOR, "model", sizeof(_QERPluginTable));
+
+  g_SynapseClient.AddAPI(RADIANT_MAJOR, NULL, sizeof(g_FuncTable), SYN_REQUIRE, &g_FuncTable);
+  g_SynapseClient.AddAPI(QGL_MAJOR, NULL, sizeof(g_QglTable), SYN_REQUIRE, &g_QglTable);
+
+  if ( !g_SynapseClient.ConfigXML( pServer, NULL, entries ) ) {
+    return NULL;
   }
-  const char* getName()
+  
+  return &g_SynapseClient;
+}
+
+bool CSynapseClientModel::RequestAPI(APIDescriptor_t *pAPI)
+{
+  if (!strcmp(pAPI->major_name, MODEL_MAJOR))
   {
-    return m_extension.c_str();
+    _QERPlugModelTable* pTable= static_cast<_QERPlugModelTable*>(pAPI->mpTable);
+
+    if (model_is_supported(pAPI->minor_name))
+    {
+      pTable->m_pfnLoadModel = &LoadModel;
+      return true;
+    }
   }
-  ModelPicoAPI* constructAPI(ModelPicoDependencies& dependencies)
+  else if (!strcmp(pAPI->major_name, TOOLBAR_MAJOR))
   {
-    return new ModelPicoAPI(m_extension.c_str(), m_module);
+    _QERPlugToolbarTable* pTable= static_cast<_QERPlugToolbarTable*>(pAPI->mpTable);
+
+    pTable->m_pfnToolbarButtonCount = &ToolbarButtonCount;
+    pTable->m_pfnGetToolbarButton = &GetToolbarButton;
+    return true;
   }
-  void destroyAPI(ModelPicoAPI* api)
+  else if (!strcmp(pAPI->major_name, PLUGIN_MAJOR))
   {
-    delete api;
-  }
-};
+    _QERPluginTable* pTable= static_cast<_QERPluginTable*>(pAPI->mpTable);
 
+    pTable->m_pfnQERPlug_Init = QERPlug_Init;
+    pTable->m_pfnQERPlug_GetName = QERPlug_GetName;
+    pTable->m_pfnQERPlug_GetCommandList = QERPlug_GetCommandList;
+    pTable->m_pfnQERPlug_Dispatch = QERPlug_Dispatch;
+    return true;
+  }
 
-typedef SingletonModule<ModelPicoAPI, ModelPicoDependencies, PicoModelAPIConstructor> PicoModelModule;
-typedef std::list<PicoModelModule> PicoModelModules;
-PicoModelModules g_PicoModelModules;
+  Syn_Printf("ERROR: RequestAPI( '%s' ) not found in '%s'\n", pAPI->major_name, GetInfo());
+  return false;
+}
 
+#include "version.h"
 
-extern "C" void RADIANT_DLLEXPORT Radiant_RegisterModules(ModuleServer& server)
+const char* CSynapseClientModel::GetInfo()
 {
-  initialiseModule(server);
-
-  pico_initialise();
+  return "picomodel loader module built " __DATE__ " " RADIANT_VERSION;
+}
 
-  const picoModule_t** modules = PicoModuleList( 0 );
-  while(*modules != 0)
-  {
-    const picoModule_t* module = *modules++;
-    if(module->canload && module->load)
-    {
-      for(char*const* ext = module->defaultExts; *ext != 0; ++ext)
-      {
-        g_PicoModelModules.push_back(PicoModelModule(PicoModelAPIConstructor(*ext, module)));
-        g_PicoModelModules.back().selfRegister();
-      }
-    }
-  }
+const char* CSynapseClientModel::GetName()
+{
+  return "model";
 }