X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=plugins%2Fmodel%2Fplugin.cpp;h=d23809a6571a2514675542229a66bb4f78e55af4;hb=ff327d248de9b70a1c280e87be3a621ec5ed03fe;hp=add809f6e5fc2124b077e90d95732ed6f8eb9c6e;hpb=33efc9089296fc4e5f54d43581a0db81576ba848;p=xonotic%2Fnetradiant.git diff --git a/plugins/model/plugin.cpp b/plugins/model/plugin.cpp index add809f6..d23809a6 100644 --- a/plugins/model/plugin.cpp +++ b/plugins/model/plugin.cpp @@ -1,248 +1,86 @@ - /* -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. - -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" - -#if 0 // stop using windowing systems in plugins - put the text in SynapseClient::GetInfo -// ============================================================================= -// Utility functions -static void dialog_button_callback (GtkWidget *widget, gpointer data) -{ - GtkWidget *parent; - int *loop, *ret; - - parent = gtk_widget_get_toplevel (widget); - loop = (int*)g_object_get_data (G_OBJECT (parent), "loop"); - ret = (int*)g_object_get_data (G_OBJECT (parent), "ret"); - - *loop = 0; - *ret = (int)data; -} - -static gint dialog_delete_callback (GtkWidget *widget, GdkEvent* event, gpointer data) -{ - int *loop; - - gtk_widget_hide (widget); - loop = (int*)g_object_get_data (G_OBJECT (widget), "loop"); - *loop = 0; + Copyright (C) 2001-2006, William Joseph. + All Rights Reserved. - return TRUE; -} - -int DoAboutBox( GtkWidget *parent ) -{ - GtkWidget *window, *w, *text, *vbox, *hbox, *hbox2, *frame; - GdkPixmap *pixmap; - GdkBitmap *mask; - GtkStyle *style; - int ret, loop = 1; - char buf[2048]; - const picoModule_t **modules, *pm; - - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_signal_connect (GTK_OBJECT (window), "delete_event", - GTK_SIGNAL_FUNC (dialog_delete_callback), NULL); - gtk_signal_connect (GTK_OBJECT (window), "destroy", - GTK_SIGNAL_FUNC (gtk_widget_destroy), NULL); - gtk_window_set_title (GTK_WINDOW (window), "About..."); - gtk_container_border_width (GTK_CONTAINER (window), 10); - g_object_set_data (G_OBJECT (window), "loop", &loop); - g_object_set_data (G_OBJECT (window), "ret", &ret); - gtk_widget_realize (window); + This file is part of GtkRadiant. - if (parent != NULL) - gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (parent)); + 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. - vbox = gtk_vbox_new (FALSE, 10); - gtk_container_add (GTK_CONTAINER (window), vbox); - gtk_widget_show (vbox); + 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. - style = gtk_widget_get_style(window); + 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 + */ - hbox2 = gtk_hbox_new (FALSE, 10); - gtk_box_pack_start (GTK_BOX (vbox), hbox2, FALSE, FALSE, 2); - gtk_widget_show (hbox2); - - frame = gtk_frame_new (NULL); - gtk_box_pack_start (GTK_BOX (hbox2), frame, FALSE, FALSE, 2); - gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN); - gtk_widget_show (frame); - - if( g_FuncTable.m_pfnLoadBitmap( "picomodel.bmp", (void **)&pixmap, (void **)&mask ) ) { - w = gtk_pixmap_new (pixmap, mask); - gtk_container_add (GTK_CONTAINER (frame), w); - gtk_widget_show (w); +#include +#include "picomodel.h" +typedef unsigned char byte; +#include +#include +#include + +#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 ) { + return; } + switch ( level ) + { + case PICO_NORMAL: + globalOutputStream() << str << "\n"; + break; - w = gtk_label_new ("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" ); - gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, FALSE, 2); - gtk_label_set_justify (GTK_LABEL (w), GTK_JUSTIFY_LEFT); - gtk_widget_show (w); - - w = gtk_scrolled_window_new(NULL, NULL); - gtk_box_pack_start(GTK_BOX(vbox), w, TRUE, TRUE, 2); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(w), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); - gtk_widget_show(w); - - text = gtk_text_new(NULL, NULL); - gtk_text_set_editable(GTK_TEXT(text), FALSE); - gtk_container_add(GTK_CONTAINER(w), text); - - strcpy( buf, "#Supported Model Formats:\n" ); - gtk_text_insert(GTK_TEXT(text), NULL, NULL, NULL, buf, -1); - - for( modules = PicoModuleList( NULL ); *modules != NULL; modules++ ) - { - pm = *modules; - - if( pm == NULL) - break; - - sprintf( buf, "\n%s, version %s, (c) %s", pm->displayName, pm->version, pm->copyright ); - gtk_text_insert(GTK_TEXT(text), NULL, NULL, NULL, buf, -1); - } - - gtk_text_set_word_wrap(GTK_TEXT(text), FALSE); - gtk_widget_show(text); - - gtk_text_set_point(GTK_TEXT(text), 0); - gtk_text_forward_delete(GTK_TEXT(text), 1); - - w = gtk_hseparator_new (); - gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, FALSE, 2); - gtk_widget_show (w); - - hbox = gtk_hbox_new (FALSE, 10); - gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 2); - gtk_widget_show (hbox); - - w = gtk_button_new_with_label ("Ok"); - gtk_box_pack_start (GTK_BOX (hbox), w, TRUE, TRUE, 0); - gtk_signal_connect (GTK_OBJECT (w), "clicked", - GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDOK)); - GTK_WIDGET_SET_FLAGS (w, GTK_CAN_DEFAULT); - gtk_widget_grab_default (w); - gtk_widget_show (w); - ret = IDOK; - - gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER); - gtk_widget_show (window); - gtk_grab_add (window); - - while (loop) - gtk_main_iteration (); - - gtk_grab_remove (window); - gtk_widget_destroy (window); - - return ret; -} -#endif - -// 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; -} + case PICO_VERBOSE: + //globalOutputStream() << "PICO_VERBOSE: " << str << "\n"; + break; -// ============================================================================= -// Pico utility functions + case PICO_WARNING: + globalErrorStream() << "PICO_WARNING: " << str << "\n"; + break; -#include "picomodel.h" + case PICO_ERROR: + globalErrorStream() << "PICO_ERROR: " << str << "\n"; + break; -void PicoPrintFunc( int level, const char *str ) -{ - if( str == NULL ) - return; - switch( level ) - { - case PICO_NORMAL: - Sys_Printf( "%s\n", str ); - break; - - case PICO_VERBOSE: - Sys_FPrintf( SYS_VRB, "%s\n", str ); - break; - - case PICO_WARNING: - Sys_Printf( "WARNING: %s\n", str ); - break; - - case PICO_ERROR: - Sys_FPrintf( SYS_VRB, "ERROR: %s\n", str ); - break; - - case PICO_FATAL: - Sys_Printf( "ERROR: %s\n", str ); - break; + case PICO_FATAL: + globalErrorStream() << "PICO_FATAL: " << str << "\n"; + break; } } -void PicoLoadFileFunc( char *name, byte **buffer, int *bufSize ) -{ - *bufSize = vfsLoadFile( (const char*) name, (void**) buffer, 0 ); +void PicoLoadFileFunc( const char *name, byte **buffer, int *bufSize ){ + *bufSize = vfsLoadFile( name, (void**) buffer ); } -void PicoFreeFileFunc( void* file ) -{ - vfsFreeFile(file); +void PicoFreeFileFunc( void* file ){ + vfsFreeFile( file ); } -static void initialise() -{ +void pico_initialise(){ PicoInit(); PicoSetMallocFunc( malloc ); PicoSetFreeFunc( free ); @@ -251,184 +89,86 @@ static void 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)); - } -} -static bool model_is_supported(const char* extension) +class PicoModelLoader : public ModelLoader { - 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; - } - return false; +const picoModule_t* m_module; +public: +PicoModelLoader( const picoModule_t* module ) : m_module( module ){ } - -void init_filetypes() -{ - const picoModule_t **modules = PicoModuleList(NULL); - while(*modules != NULL) - { - 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)); - } - } - } +scene::Node& loadModel( ArchiveFile& file ){ + return loadPicoModel( m_module, file ); } +}; -// plugin implementation - -static const char *PLUGIN_NAME = "Model loading module"; -static const char *PLUGIN_COMMANDS = "Flush & Reload Models,Flush & Reload Selected"; -static const char *PLUGIN_ABOUT = "Model loading module"; - -extern "C" const char* QERPlug_Init (void *hApp, void* pMainWidget) +class ModelPicoDependencies : + public GlobalFileSystemModuleRef, + public GlobalOpenGLModuleRef, + public GlobalUndoModuleRef, + public GlobalSceneGraphModuleRef, + public GlobalShaderCacheModuleRef, + public GlobalSelectionModuleRef, + public GlobalFiletypesModuleRef { - init_filetypes(); - return (char *) PLUGIN_NAME; -} +}; -extern "C" const char* QERPlug_GetName () +class ModelPicoAPI : public TypeSystemRef { - return (char *) PLUGIN_NAME; -} +PicoModelLoader m_modelLoader; +public: +typedef ModelLoader Type; -extern "C" const char* QERPlug_GetCommandList () -{ - return (char *) PLUGIN_COMMANDS; +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() ) ); +} +ModelLoader* getTable(){ + return &m_modelLoader; } +}; -extern "C" void QERPlug_Dispatch (const char *p, vec3_t vMin, vec3_t vMax, bool bSingleBrush) +class PicoModelAPIConstructor { - if( !strcmp( p, "Flush & Reload Selected" ) ) - DoFlushReloadSelected(); - else if( !strcmp( p, "Flush & Reload Models" ) ) - DoFlushReloadAll(); +CopiedString m_extension; +const picoModule_t* m_module; +public: +PicoModelAPIConstructor( const char* extension, const picoModule_t* module ) : + m_extension( extension ), m_module( module ){ } - - -void DoFlushReloadSelected() { +const char* getName(){ + return m_extension.c_str(); } - -void DoFlushReloadAll() { - GetModelCache()->RefreshAll(); +ModelPicoAPI* constructAPI( ModelPicoDependencies& dependencies ){ + return new ModelPicoAPI( m_extension.c_str(), m_module ); } - -// ============================================================================= - -// 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)) - { - 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() ); - - 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; - } - - return &g_SynapseClient; +void destroyAPI( ModelPicoAPI* api ){ + delete api; } +}; -bool CSynapseClientModel::RequestAPI(APIDescriptor_t *pAPI) -{ - if (!strcmp(pAPI->major_name, MODEL_MAJOR)) - { - _QERPlugModelTable* pTable= static_cast<_QERPlugModelTable*>(pAPI->mpTable); - - if (model_is_supported(pAPI->minor_name)) - { - pTable->m_pfnLoadModel = &LoadModel; - return true; - } - } - else if (!strcmp(pAPI->major_name, TOOLBAR_MAJOR)) - { - _QERPlugToolbarTable* pTable= static_cast<_QERPlugToolbarTable*>(pAPI->mpTable); - - pTable->m_pfnToolbarButtonCount = &ToolbarButtonCount; - pTable->m_pfnGetToolbarButton = &GetToolbarButton; - return true; - } - else if (!strcmp(pAPI->major_name, PLUGIN_MAJOR)) - { - _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 PicoModelModule; +typedef std::list 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 ){ + initialiseModule( server ); -const char* CSynapseClientModel::GetInfo() -{ - return "picomodel loader module built " __DATE__ " " RADIANT_VERSION; -} + pico_initialise(); -const char* CSynapseClientModel::GetName() -{ - return "model"; + 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(); + } + } + } }