X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fnetradiant.git;a=blobdiff_plain;f=radiant%2Fpluginmanager.cpp;h=01ef70fae62c9aaf99cf2baaf042e45c37aad600;hp=d9ed04abce560ff892cdafa55b1a7897883eb0a6;hb=a54ff4a83e324df7206626a0e8a10951e46c4fb3;hpb=12b372f89ce109a4db9d510884fbe7d05af79870 diff --git a/radiant/pluginmanager.cpp b/radiant/pluginmanager.cpp index d9ed04ab..01ef70fa 100644 --- a/radiant/pluginmanager.cpp +++ b/radiant/pluginmanager.cpp @@ -1,5 +1,5 @@ /* -Copyright (C) 1999-2006 Id Software, Inc. and contributors. +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. @@ -23,172 +23,589 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // ////////////////////////////////////////////////////////////////////// +#include "stdafx.h" +#if defined (__linux__) || defined (__APPLE__) + #include + #include +#endif +#ifdef __APPLE__ + #ifdef __cplusplus + extern "C" { + #endif + #include + #ifdef __cplusplus + } + #endif +#endif +#ifdef _WIN32 + #include "objbase.h" +#endif #include "pluginmanager.h" +#include "plugin.h" +#include "missing.h" +#include "filters.h" -#include "modulesystem.h" -#include "qerplugin.h" -#include "iplugin.h" +#include "version.h" -#include "math/vector.h" -#include "string/string.h" +CRadiantImageManager g_ImageManager; +CRadiantPluginManager g_PluginsManager; -#include "error.h" -#include "select.h" -#include "plugin.h" +_QERPlugSurfaceTable g_SurfaceTable; +_QERFileSystemTable g_FileSystemTable; +_QERShadersTable g_ShadersTable; +_QERPlugMapTable g_MapTable; +_QERPlugMapTable g_MapTable2; +_QEREntityTable g_EntityTable; +_EClassTable g_EClassDefTable; + +/*! + extending entity class formats + this approach only allows a single additional format, but it is enough for now +*/ +bool g_bHaveEClassExt = false; +_EClassTable g_EClassExtTable; -#include "modulesystem.h" -#include +filetype_t g_pattern_all("all files", "*.*"); +filetype_t g_pattern_projqe4v2("qe4 v2 project files", "*.qe4"); +filetype_t g_pattern_projxml("xml project files", "*.proj"); +filetype_t g_pattern_mapq3("quake3 maps", "*.map"); +filetype_t g_pattern_mapxml("xml quake3 maps", "*.xmap"); +filetype_t g_pattern_modelmd3("md3 models", "*.md3"); +filetype_t g_pattern_modelmdc("mdc models", "*.mdc"); +filetype_t g_pattern_modelmd2("md2 models", "*.md2"); +filetype_t g_pattern_modelmdl("mdl models", "*.mdl"); +//filetype_t g_pattern_modelea3("EA3 models", "*.ea3"); +filetype_t g_pattern_soundwav("PCM sound files", "*.wav"); +filetype_t g_pattern_regq3("quake3 region", "*.reg"); -/* plugin manager --------------------------------------- */ -class CPluginSlot : public IPlugIn -{ - CopiedString m_menu_name; - const _QERPluginTable *mpTable; - std::list m_CommandStrings; - std::list m_CommandTitleStrings; - std::list m_CommandIDs; - +#include + +class RadiantFileTypeRegistry : public IFileTypeRegistry +{ public: - /*! - build directly from a SYN_PROVIDE interface - */ - CPluginSlot(GtkWidget* main_window, const char* name, const _QERPluginTable& table); - /*! - dispatching a command by name to the plugin + virtual ~RadiantFileTypeRegistry() {} + virtual void addType(const char* key, filetype_t type) + { + m_typelists[key].push_back(type); + } + virtual void getTypeList(const char* key, IFileTypeList* typelist) + { + filetype_list_t& list_ref = m_typelists[key]; + for(unsigned int i=0; iaddType(list_ref[i].getType()); + } +private: + struct filetype_copy_t + { + inline filetype_copy_t(const filetype_t other) + : m_name(other.name), m_pattern(other.pattern) + {} + inline filetype_t getType() const + { + return filetype_t(m_name.c_str(), m_pattern.c_str()); + } + private: + string_t m_name; + string_t m_pattern; + }; + typedef vector filetype_list_t; + map m_typelists; +}; + +static RadiantFileTypeRegistry g_patterns; + +IFileTypeRegistry* GetFileTypeRegistry() +{ + return &g_patterns; +} + +void InitFileTypes() +{ + //GetFileTypeRegistry()->addType("project", g_pattern_projqe4v2); + GetFileTypeRegistry()->addType("project", g_pattern_projxml); + + GetFileTypeRegistry()->addType(MAP_MAJOR, g_pattern_mapq3); + GetFileTypeRegistry()->addType(MAP_MAJOR, g_pattern_mapxml); + + GetFileTypeRegistry()->addType("region", g_pattern_regq3); +/* + GetFileTypeRegistry()->addType(MODEL_MAJOR, g_pattern_modelmd3); + GetFileTypeRegistry()->addType(MODEL_MAJOR, g_pattern_modelmd2); + GetFileTypeRegistry()->addType(MODEL_MAJOR, g_pattern_modelmdl); + GetFileTypeRegistry()->addType(MODEL_MAJOR, g_pattern_modelmdc); + //GetFileTypeRegistry()->addType(MODEL_MAJOR, g_pattern_modelea3); */ - void Dispatch(const char *p); - - // IPlugIn ------------------------------------------------------------ - const char* getMenuName(); - std::size_t getCommandCount(); - const char* getCommand(std::size_t n); - const char* getCommandTitle(std::size_t n); - void addMenuID(std::size_t n); - bool ownsCommandID(std::size_t n); - + + GetFileTypeRegistry()->addType("sound", g_pattern_soundwav); +} + + +class CRadiantModelModuleManager : public CSynapseAPIManager +{ + typedef list APIDescriptorList; + + APIDescriptorList mAPIs; +public: + CRadiantModelModuleManager() + { + SetMatchAPI(MODEL_MAJOR, "*"); + } + virtual ~CRadiantModelModuleManager() + { + APIDescriptorList::iterator i; + for(i=mAPIs.begin(); i!=mAPIs.end(); i++) + { + delete (_QERPlugModelTable*)(*i)->mpTable; + delete *i; + *i = NULL; + } + mAPIs.clear(); + } + + // CSynapseAPIManager interface ------------------- + APIDescriptor_t* BuildRequireAPI(APIDescriptor_t* pAPI) + { + APIDescriptor_t* pRequireAPI = CSynapseAPIManager::PrepareRequireAPI(pAPI); + pRequireAPI->mpTable = new _QERPlugModelTable; + ((_QERPlugModelTable*)pRequireAPI->mpTable)->m_nSize = sizeof(_QERPlugModelTable); + pRequireAPI->mSize = sizeof(_QERPlugModelTable); + mAPIs.push_front(pRequireAPI); + return pRequireAPI; + } + + // Model Manager specific + const _QERPlugModelTable* GetModelTable(const char* version) + { + APIDescriptorList::iterator i; + for(i=mAPIs.begin(); i!=mAPIs.end(); i++) + if(strcmp(version, (*i)->minor_name) == 0) + return ((_QERPlugModelTable*)(*i)->mpTable); + return NULL; + } }; -CPluginSlot::CPluginSlot(GtkWidget* main_window, const char* name, const _QERPluginTable& table) +CRadiantModelModuleManager g_ModelManager; + +/*! One of these exists for each unique model ID in use */ +class CModelWrapper { - mpTable = &table; - m_menu_name = name; + friend class CModelManager; +public: + CModelWrapper (const char *id, const char* version) : refcount(1) + { + copy(id, version); + construct(); + } + void Refresh() + { + destroy(); + construct(); + } + ~CModelWrapper () + { + destroy(); + } +private: + void copy(const char* id, const char* version) + { + m_id = id; + m_version = version; + } + void construct() + { + m_model.pRender = NULL; + m_model.pSelect = NULL; + m_model.pEdit = NULL; - const char* commands = mpTable->m_pfnQERPlug_GetCommandList(); - const char* titles = mpTable->m_pfnQERPlug_GetCommandTitleList(); + const _QERPlugModelTable* pTable = g_ModelManager.GetModelTable(m_version.c_str()); + + if(pTable != NULL) + pTable->m_pfnLoadModel(&m_model, m_id.c_str()); + } + void destroy() + { + if (m_model.pRender) m_model.pRender->DecRef(); + if (m_model.pSelect) m_model.pSelect->DecRef(); + if (m_model.pEdit) m_model.pEdit->DecRef(); + } + string_t m_id; + string_t m_version; + entity_interfaces_t m_model; + int refcount; +}; + +/*! Creates and tracks CModelWrapper instances. +Creates a new instance for each unique ID requested, keeps count of the number of +times an ID is being referenced, and destroys any instance that is no longer in use */ +class CModelManager : public IModelCache +{ +public: + CModelManager() + { + m_ptrs = g_ptr_array_new (); + } + virtual ~CModelManager() + { + g_ptr_array_free(m_ptrs, FALSE); + } - StringTokeniser commandTokeniser(commands, ",;"); - StringTokeniser titleTokeniser(titles, ",;"); - - const char* cmdToken = commandTokeniser.getToken(); - const char *titleToken = titleTokeniser.getToken(); - while (!string_empty(cmdToken)) + virtual void DeleteByID(const char *id, const char* version) { - if(string_empty(titleToken)) + unsigned int i; + CModelWrapper *elem; + for(i=0; ilen; i++) { - m_CommandStrings.push_back(cmdToken); - m_CommandTitleStrings.push_back(cmdToken); - cmdToken = commandTokeniser.getToken(); - titleToken = ""; + elem = (CModelWrapper*)m_ptrs->pdata[i]; + if(strcmp(elem->m_version.c_str(), version) == 0 + && strcmp(elem->m_id.c_str(), id) == 0 + && --elem->refcount == 0) + { + g_ptr_array_remove_index_fast(m_ptrs, i); + delete elem; + return; + } } - else + } + + virtual entity_interfaces_t *GetByID(const char *id, const char* version) + { + unsigned int i; + CModelWrapper *elem; + for(i=0; ilen; i++) { - m_CommandStrings.push_back(cmdToken); - m_CommandTitleStrings.push_back(titleToken); - cmdToken = commandTokeniser.getToken(); - titleToken = titleTokeniser.getToken(); + elem = (CModelWrapper*)m_ptrs->pdata[i]; + if(strcmp(elem->m_version.c_str(), version) == 0 + && strcmp(elem->m_id.c_str(), id) == 0) + { + elem->refcount++; + return &elem->m_model; + } } + + elem = new CModelWrapper(id, version); + g_ptr_array_add(m_ptrs, elem); + + return &elem->m_model; + } + + virtual void RefreshAll() + { + for(unsigned int i=0; ilen; ++i) + ((CModelWrapper*)m_ptrs->pdata[i])->Refresh(); } - mpTable->m_pfnQERPlug_Init(0, (void*)main_window); +private: + GPtrArray *m_ptrs; // array of CModelWrapper* +}; + +CModelManager g_model_cache; + +IModelCache* GetModelCache() +{ + return &g_model_cache; } -const char* CPluginSlot::getMenuName() +// toolbar manager +class CRadiantToolbarModuleManager : public CSynapseAPIManager +{ + typedef list APIDescriptorList; + + APIDescriptorList mAPIs; +public: + CRadiantToolbarModuleManager() + { + SetMatchAPI(TOOLBAR_MAJOR, "*"); + } + virtual ~CRadiantToolbarModuleManager() + { + APIDescriptorList::iterator i; + for(i=mAPIs.begin(); i!=mAPIs.end(); i++) + { + delete (_QERPlugToolbarTable*)(*i)->mpTable; + delete *i; + *i = NULL; + } + mAPIs.clear(); + } + + // CSynapseAPIManager interface ------------------- + APIDescriptor_t* BuildRequireAPI(APIDescriptor_t* pAPI) + { + APIDescriptor_t* pRequireAPI = CSynapseAPIManager::PrepareRequireAPI(pAPI); + pRequireAPI->mpTable = new _QERPlugToolbarTable; + ((_QERPlugToolbarTable*)pRequireAPI->mpTable)->m_nSize = sizeof(_QERPlugToolbarTable); + pRequireAPI->mSize = sizeof(_QERPlugToolbarTable); + mAPIs.push_front(pRequireAPI); + return pRequireAPI; + } + + // Toolbar Manager specific + void ConstructToolbar() + { + APIDescriptorList::iterator i; + for(i=mAPIs.begin(); i!=mAPIs.end(); i++) + AddItem((_QERPlugToolbarTable*)(*i)->mpTable); + } + +private: + + void AddItem(_QERPlugToolbarTable* pTable) + { + const unsigned int count = pTable->m_pfnToolbarButtonCount(); + for(unsigned int i=0; im_pfnGetToolbarButton(i); + g_pParentWnd->AddPlugInToolbarButton(button); + } + } +}; + +CRadiantToolbarModuleManager g_ToolbarModuleManager; + + +/* image manager ---------------------------------------- */ + +CRadiantImageManager::~CRadiantImageManager() { - return m_menu_name.c_str(); + list::iterator iSlot; + for(iSlot = mSlots.begin(); iSlot != mSlots.end(); iSlot++) + { + delete *iSlot; + *iSlot = NULL; + } } -std::size_t CPluginSlot::getCommandCount() +void CImageTableSlot::InitForFillAPITable(APIDescriptor_t *pAPI) { - return m_CommandStrings.size(); + mpAPI = pAPI; + mpTable = new _QERPlugImageTable; + mpTable->m_nSize = sizeof(_QERPlugImageTable); + mpAPI->mSize = sizeof(_QERPlugImageTable); + mpAPI->mpTable = mpTable; } - -const char* CPluginSlot::getCommand(std::size_t n) + +void CRadiantImageManager::FillAPITable(APIDescriptor_t *pAPI) { - std::list::iterator i = m_CommandStrings.begin(); - while(n-- != 0) - ++i; - return (*i).c_str(); + CImageTableSlot *pSlot = new CImageTableSlot(); + pSlot->InitForFillAPITable(pAPI); + mSlots.push_front(pSlot); } -const char* CPluginSlot::getCommandTitle(std::size_t n) +/*! + Loads an image by calling the module that handles the extension extracted from the filename + \param name The filename to load. If no extension is provided, we walk the list of supported extensions. + \param pic The returned image data + \param width The returned width of the image + \param height The returned height of the image +*/ +void CRadiantImageManager::LoadImage(const char *name, byte **pic, int *width, int *height) { - std::list::iterator i = m_CommandTitleStrings.begin(); - while(n-- != 0) - ++i; - return (*i).c_str(); + const char *ext = NULL; + int len; + + // extract extension + len = strlen (name); + if ((len > 5) && (name[len-4] == '.')) + ext = &name[len-3]; + + if (ext == NULL) + { + // if no extension is provided, start walking through the list + Str fullname; + list::iterator iSlot; + for(iSlot = mSlots.begin(); iSlot != mSlots.end(); iSlot++) + { + APIDescriptor_t *pAPI = (*iSlot)->GetDescriptor(); + fullname.Format("%s.%s", name, pAPI->minor_name); + (*iSlot)->GetTable()->m_pfnLoadImage(fullname.GetBuffer(), pic, width, height); + if (*pic) + return; // this was the right extension, we loaded + } + return; + } + + // start walking the interfaces + list::iterator iSlot; + for(iSlot = mSlots.begin(); iSlot != mSlots.end(); iSlot++) + { + APIDescriptor_t *pAPI = (*iSlot)->GetDescriptor(); + if (!strcmp(pAPI->minor_name, ext)) + { + (*iSlot)->GetTable()->m_pfnLoadImage(name, pic, width, height); + return; + } + } + Sys_FPrintf(SYS_WRN, "WARNING: no image table for extension '%s'\n", ext); } -void CPluginSlot::addMenuID(std::size_t n) +void CRadiantImageManager::BeginExtensionsScan() { - m_CommandIDs.push_back(n); + mExtScanSlot = mSlots.begin(); } -bool CPluginSlot::ownsCommandID(std::size_t n) +const char* CRadiantImageManager::GetNextExtension() { - for(std::list::iterator i = m_CommandIDs.begin(); i != m_CommandIDs.end(); ++i) + if (mExtScanSlot != mSlots.end()) { - if (*i == n) - return true; + char *ext = (*mExtScanSlot)->GetDescriptor()->minor_name; + mExtScanSlot++; + return ext; } - return false; + return NULL; } -void CPluginSlot::Dispatch(const char *p) +/* plugin manager --------------------------------------- */ +APIDescriptor_t* CRadiantPluginManager::BuildRequireAPI(APIDescriptor_t *pAPI) { - Vector3 vMin, vMax; - Select_GetBounds (vMin, vMax); - mpTable->m_pfnQERPlug_Dispatch(p, reinterpret_cast(&vMin), reinterpret_cast(&vMax), true);//QE_SingleBrush(true)); + CPluginSlot *pSlot = new CPluginSlot(pAPI); + mSlots.push_front(pSlot); + return pSlot->GetDescriptor(); } +void CRadiantPluginManager::PopulateMenu() +{ + list::iterator iPlug; + for(iPlug=mSlots.begin(); iPlug != mSlots.end(); iPlug++) + { + g_pParentWnd->AddPlugInMenuItem(*iPlug); + } +} -class CPluginSlots +void CSynapseClientRadiant::ImportMap(IDataStream *in, CPtrArray *ents, const char *type) { - std::list mSlots; -public: - virtual ~CPluginSlots(); + if (strcmp(type,"map")==0) + { + g_MapTable.m_pfnMap_Read(in, ents); + } + else if (strcmp(type,"xmap")==0) + { + g_MapTable2.m_pfnMap_Read(in, ents); + } + else + Sys_FPrintf(SYS_WRN, "WARNING: no module found for map interface type '%s'\n", type); +} - void AddPluginSlot(GtkWidget* main_window, const char* name, const _QERPluginTable& table) +void CSynapseClientRadiant::ExportMap(CPtrArray *ents, IDataStream *out, const char *type) +{ + if (strcmp(type,"map")==0) { - mSlots.push_back(new CPluginSlot(main_window, name, table)); + g_MapTable.m_pfnMap_Write(ents, out); } - - void PopulateMenu(PluginsVisitor& menu); - bool Dispatch(std::size_t n, const char* p); -}; + else if (strcmp(type,"xmap")==0) + { + g_MapTable2.m_pfnMap_Write(ents, out); + } + else + Sys_FPrintf(SYS_WRN, "WARNING: no module found for map interface type '%s'\n", type); +} + +CPluginSlot::CPluginSlot(APIDescriptor_t *pAPI) +{ + mpAPI = CSynapseAPIManager::PrepareRequireAPI(pAPI); + mpTable = new _QERPluginTable; + mpTable->m_nSize = sizeof(_QERPluginTable); + mpAPI->mSize = sizeof(_QERPluginTable); + mpAPI->mpTable = mpTable; + m_CommandStrings = NULL; + m_CommandIDs = NULL; + m_bReady = false; +} -CPluginSlots::~CPluginSlots() +CPluginSlot::~CPluginSlot() { - std::list::iterator iSlot; - for(iSlot=mSlots.begin(); iSlot!=mSlots.end(); ++iSlot) + delete mpAPI; + delete mpTable; + while (m_CommandStrings) { - delete *iSlot; - *iSlot = 0; + ::free (m_CommandStrings->data); + m_CommandStrings = g_slist_remove (m_CommandStrings, m_CommandStrings->data); + } +} + +void CPluginSlot::Init() +{ + CString str = mpTable->m_pfnQERPlug_GetCommandList(); + char cTemp[1024]; + strcpy(cTemp, str); + char* token = strtok(cTemp, ",;"); + if (token && *token == ' ') + { + while (*token == ' ') + token++; + } + while (token != NULL) + { + m_CommandStrings = g_slist_append (m_CommandStrings, strdup (token)); + token = strtok(NULL, ",;"); + } + mpTable->m_pfnQERPlug_Init(NULL, (void*)g_pParentWnd->m_pWidget); + m_bReady = true; +} + +const char* CPluginSlot::getMenuName() +{ + return mpAPI->minor_name; +} + +int CPluginSlot::getCommandCount() +{ + if (!m_bReady) + Init(); + return g_slist_length (m_CommandStrings); +} + +const char* CPluginSlot::getCommand(int n) +{ + if (!m_bReady) + Init(); + return (char*)g_slist_nth_data (m_CommandStrings, n); +} + +void CPluginSlot::addMenuID(int n) +{ + m_CommandIDs = g_slist_append (m_CommandIDs, GINT_TO_POINTER (n)); +} + +bool CPluginSlot::ownsCommandID(int n) +{ + GSList* lst; + + for (lst = m_CommandIDs; lst != NULL; lst = g_slist_next (lst)) + { + if (GPOINTER_TO_INT (lst->data) == n) + return true; + } + return false; +} + +void CPluginSlot::Dispatch(const char *p) +{ + vec3_t vMin, vMax; + if (selected_brushes.next == &selected_brushes) + { + vMin[0] = vMin[1] = vMin[2] = 0; + VectorCopy(vMin, vMax); + } else + { + Select_GetBounds (vMin, vMax); } + mpTable->m_pfnQERPlug_Dispatch(p, vMin, vMax, QE_SingleBrush(true)); } -void CPluginSlots::PopulateMenu(PluginsVisitor& menu) +CRadiantPluginManager::~CRadiantPluginManager() { - std::list::iterator iPlug; - for(iPlug=mSlots.begin(); iPlug != mSlots.end(); ++iPlug) + list::iterator iSlot; + for(iSlot=mSlots.begin(); iSlot!=mSlots.end(); iSlot++) { - menu.visit(*(*iPlug)); + delete *iSlot; + *iSlot = NULL; } } -bool CPluginSlots::Dispatch(std::size_t n, const char* p) +bool CRadiantPluginManager::Dispatch(int n, const char* p) { - std::list::iterator iPlug; - for(iPlug=mSlots.begin(); iPlug!=mSlots.end(); ++iPlug) + list::iterator iPlug; + for(iPlug=mSlots.begin(); iPlug!=mSlots.end(); iPlug++) { CPluginSlot *pPlug = *iPlug; if (pPlug->ownsCommandID(n)) @@ -200,54 +617,1909 @@ bool CPluginSlots::Dispatch(std::size_t n, const char* p) return false; } -CPluginSlots g_plugin_slots; +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +CPlugInManager::CPlugInManager() +{ + PatchesMode = EActivePatches; + m_PlugIns = NULL; +} + +CPlugInManager::~CPlugInManager() +{ + Cleanup(); +} + +void CPlugInManager::InitForDir(const Str &dir) +{ + Str path; + + path = dir; + path += g_strPluginsDir; + // SYNAPSE + g_pParentWnd->GetSynapseServer().AddSearchPath(path); + + if (strcmp(g_strPluginsDir.GetBuffer(), g_strModulesDir.GetBuffer()) != 0) + { + path = dir; + path += g_strModulesDir; + // SYNAPSE + g_pParentWnd->GetSynapseServer().AddSearchPath(path); + } +} +static const XMLConfigEntry_t manager_entries[] = + { + { VFS_MAJOR, SYN_REQUIRE, sizeof(g_FileSystemTable), &g_FileSystemTable }, + { SHADERS_MAJOR, SYN_REQUIRE, sizeof(g_ShadersTable), &g_ShadersTable }, + { MAP_MAJOR, SYN_REQUIRE, sizeof(g_MapTable), &g_MapTable }, + { ECLASS_MAJOR, SYN_REQUIRE, sizeof(g_EClassDefTable), &g_EClassDefTable }, + { SURFACEDIALOG_MAJOR, SYN_REQUIRE, sizeof(g_SurfaceTable), &g_SurfaceTable }, + { NULL, SYN_UNKNOWN, 0, NULL } }; -void FillPluginSlots(CPluginSlots& slots, GtkWidget* main_window) +void CPlugInManager::Init() { - class AddPluginVisitor : public PluginModules::Visitor + Str synapse_config; + + Cleanup(); + + // set some globals + g_qeglobals.bBSPFrontendPlugin = false; + + InitForDir(g_strGameToolsPath); + InitForDir(g_strAppPath); + + synapse_config = g_strGameToolsPath; + synapse_config += "synapse.config"; + if (!g_pParentWnd->GetSynapseServer().Initialize(synapse_config.GetBuffer(), &Sys_Printf_VA)) + Error("Synpase server initialization failed (see console)\n"); + + // builtin modules + g_pParentWnd->GetSynapseServer().EnumerateBuiltinModule(&eclass_def); + + // APIs we provide + g_pParentWnd->GetSynapseClient().AddAPI(RADIANT_MAJOR, NULL, sizeof(_QERFuncTable_1)); + g_pParentWnd->GetSynapseClient().AddAPI(SCRIPLIB_MAJOR, NULL, sizeof(_QERScripLibTable)); + g_pParentWnd->GetSynapseClient().AddAPI(BRUSH_MAJOR, NULL, sizeof(_QERBrushTable)); + g_pParentWnd->GetSynapseClient().AddAPI(APPSHADERS_MAJOR, NULL, sizeof(_QERAppShadersTable)); + g_pParentWnd->GetSynapseClient().AddAPI(QGL_MAJOR, NULL, sizeof(_QERQglTable)); + g_pParentWnd->GetSynapseClient().AddAPI(DATA_MAJOR, NULL, sizeof(_QERAppDataTable)); + g_pParentWnd->GetSynapseClient().AddAPI(PATCH_MAJOR, NULL, sizeof(_QERPatchTable)); + g_pParentWnd->GetSynapseClient().AddAPI(ECLASSMANAGER_MAJOR, NULL, sizeof(_EClassManagerTable)); + g_pParentWnd->GetSynapseClient().AddAPI(SELECTEDFACE_MAJOR, NULL, sizeof(_QERSelectedFaceTable)); + g_pParentWnd->GetSynapseClient().AddAPI(APPSURFACEDIALOG_MAJOR, NULL, sizeof(_QERAppSurfaceTable)); + g_pParentWnd->GetSynapseClient().AddAPI(UNDO_MAJOR, NULL, sizeof(_QERUndoTable)); + g_pParentWnd->GetSynapseClient().AddAPI(UI_MAJOR, NULL, sizeof(_QERUITable)); + g_pParentWnd->GetSynapseClient().AddAPI(UIGTK_MAJOR, NULL, sizeof(_QERUIGtkTable)); + g_pParentWnd->GetSynapseClient().AddAPI(CAMERA_MAJOR, NULL, sizeof(_QERCameraTable)); + + // modules configured by XML + if ( !g_pParentWnd->GetSynapseClient().ConfigXML( &g_pParentWnd->GetSynapseServer(), "core", manager_entries ) ) { + Error("Synapse server initialization failed (see console)\n"); + } + + // adding a manager is a special case that ConfigXML doesn't take care of + g_pParentWnd->GetSynapseServer().SelectClientConfig( "core" ); + char *minor; + if ( !g_pParentWnd->GetSynapseServer().GetConfigForAPI( IMAGE_MAJOR, &minor ) ) { + Syn_Printf( "GetConfigForAPI '%s' failed - invalid XML config file?\n", IMAGE_MAJOR ); + Error("Synapse server initialization failed (see console)\n"); + } + g_ImageManager.SetMatchAPI( IMAGE_MAJOR, minor ); + g_pParentWnd->GetSynapseClient().AddManager( &g_ImageManager ); + + // SYN_REQUIRE entries which are still hardcoded + g_pParentWnd->GetSynapseClient().AddAPI(MAP_MAJOR, "mapxml", sizeof(g_MapTable2), SYN_REQUIRE, &g_MapTable2); + g_pParentWnd->GetSynapseClient().AddAPI(ENTITY_MAJOR, NULL, sizeof(g_EntityTable), SYN_REQUIRE, &g_EntityTable); + + // plugins: load anything that claims to be a plugin + // minor becomes some kind of matching pattern + // g_PluginsManager is an API any class, it receives several function tables as needed + // you can't do a SYN_PROVIDE with that, has to be a SYN_REQUIRE ? + g_PluginsManager.SetMatchAPI(PLUGIN_MAJOR, "*"); + g_pParentWnd->GetSynapseClient().AddManager(&g_PluginsManager); + g_pParentWnd->GetSynapseClient().AddManager(&g_ToolbarModuleManager); + g_pParentWnd->GetSynapseClient().AddManager(&g_ModelManager); + if (!g_pParentWnd->GetSynapseServer().Resolve(&g_pParentWnd->GetSynapseClient())) { - CPluginSlots& m_slots; - GtkWidget* m_main_window; - public: - AddPluginVisitor(CPluginSlots& slots, GtkWidget* main_window) - : m_slots(slots), m_main_window(main_window) - { - } - void visit(const char* name, const _QERPluginTable& table) - { - m_slots.AddPluginSlot(m_main_window, name, table); - } - } visitor(slots, main_window); + Error("synapse initialization fail (see console)"); + } + g_PluginsManager.PopulateMenu(); + g_ToolbarModuleManager.ConstructToolbar(); + InitFileTypes(); +} - Radiant_getPluginModules().foreachModule(visitor); +void CPlugInManager::Shutdown() +{ + g_pParentWnd->GetSynapseServer().Shutdown(); } +void CPlugInManager::Cleanup() +{ + int i; + + for (i = 0; i < m_BrushHandles.GetSize(); i++) + { + brush_t *pb = reinterpret_cast(m_BrushHandles.GetAt(i)); + Brush_Free(pb); + } + m_BrushHandles.RemoveAll(); -#include "pluginmanager.h" + for (i = 0; i < m_EntityHandles.GetSize(); i++) + { + entity_t *pe = reinterpret_cast(m_EntityHandles.GetAt(i)); + Entity_Free(pe); + } + m_EntityHandles.RemoveAll(); -CPlugInManager g_PlugInMgr; + // patches + // these are linked into the map + m_PatchesHandles.RemoveAll(); + // these patches were allocated by Radiant on plugin request + // if the list is not empty, it means either the plugin asked for allocation and never commited them to the map + // in which case we are supposed to delete them + // or it commited them but never called m_pfnReleasePatchHandles, in case the patches may have already been + // erased and we are trying a second time, therefore crashing .. + //++timo FIXME: for now I leave a leak warning, we'd need a table to keep track of commited patches +#ifdef _DEBUG + if (m_PluginPatches.GetSize() != 0) + Sys_Printf("WARNING: m_PluginPatches.GetSize() != 0 in CPlugInManager::Cleanup, possible leak\n"); +#endif + +/* for (i = 0; i < m_PluginPatches.GetSize(); i++) + { + patchMesh_t *pMesh = reinterpret_cast(m_PluginPatches.GetAt(i)); + if (pMesh->pSymbiot) + delete pMesh; + } + m_PluginPatches.RemoveAll(); */ +} -CPlugInManager& GetPlugInMgr() +void CPlugInManager::Dispatch(int n, const char * p) { - return g_PlugInMgr; + g_PluginsManager.Dispatch(n, p); } -void CPlugInManager::Dispatch(std::size_t n, const char * p) +void WINAPI QERApp_GetDispatchParams(vec3_t vMin, vec3_t vMax, bool *bSingleBrush) { - g_plugin_slots.Dispatch(n, p); + if (selected_brushes.next == &selected_brushes) + { + vMin[0] = vMin[1] = vMin[2] = 0; + VectorCopy(vMin, vMax); + } else + { + Select_GetBounds (vMin, vMax); + } + + if( bSingleBrush ) + *bSingleBrush = QE_SingleBrush(true); } -void CPlugInManager::Init(GtkWidget* main_window) + +// creates a dummy brush in the active brushes list +// FIXME : is this one really USED ? +void WINAPI QERApp_CreateBrush(vec3_t vMin, vec3_t vMax) { - FillPluginSlots(g_plugin_slots, main_window); + + brush_t* pBrush = Brush_Create(vMin, vMax, &g_qeglobals.d_texturewin.texdef); + Entity_LinkBrush (world_entity, pBrush); + Brush_Build(pBrush); + Brush_AddToList (pBrush, &active_brushes); + Select_Brush(pBrush); + Sys_UpdateWindows(W_ALL); } -void CPlugInManager::constructMenu(PluginsVisitor& menu) +void* CPlugInManager::CreateBrushHandle() { - g_plugin_slots.PopulateMenu(menu); + brush_t *pb = Brush_Alloc(); + pb->numberId = g_nBrushId++; + m_BrushHandles.Add(pb); + return(void*)pb; } -void CPlugInManager::Shutdown() +void CPlugInManager::DeleteBrushHandle(void * vp) +{ + CPtrArray* pHandles[3]; + pHandles[0] = &m_SelectedBrushHandles; + pHandles[1] = &m_ActiveBrushHandles; + pHandles[2] = &m_BrushHandles; + + for (int j = 0; j < 3; j++) + { + for (int i = 0; i < pHandles[j]->GetSize(); i++) + { + brush_t *pb = reinterpret_cast(pHandles[j]->GetAt(i)); + if (pb == reinterpret_cast(vp)) + { + if (j == 2) + { + // only remove it from the list if it is work area + // this allows the selected and active list indexes to remain constant + // throughout a session (i.e. between an allocate and release) + pHandles[j]->RemoveAt(i); + } + Brush_Free(pb); + Sys_MarkMapModified(); // PGM + return; + } + } + } +} + +void CPlugInManager::CommitBrushHandleToMap(void * vp) +{ + g_bScreenUpdates = false; + for (int i = 0; i < m_BrushHandles.GetSize(); i++) + { + brush_t *pb = reinterpret_cast(m_BrushHandles.GetAt(i)); + if (pb == reinterpret_cast(vp)) + { + m_BrushHandles.RemoveAt(i); + Entity_LinkBrush (world_entity, pb); + Brush_Build(pb); + Brush_AddToList (pb, &active_brushes); + Select_Brush(pb); + } + } + g_bScreenUpdates = true; + Sys_UpdateWindows(W_ALL); +} + +void CPlugInManager::AddFaceToBrushHandle(void * vp, vec3_t v1, vec3_t v2, vec3_t v3) +{ + brush_t *bp = FindBrushHandle(vp); + if (bp != NULL) + { + face_t *f = Face_Alloc(); + f->texdef = g_qeglobals.d_texturewin.texdef; + f->texdef.flags &= ~SURF_KEEP; + f->texdef.contents &= ~CONTENTS_KEEP; + f->next = bp->brush_faces; + bp->brush_faces = f; + VectorCopy (v1, f->planepts[0]); + VectorCopy (v2, f->planepts[1]); + VectorCopy (v3, f->planepts[2]); + } +} + +brush_t* CPlugInManager::FindBrushHandle(void * vp) +{ + CPtrArray* pHandles[4]; + pHandles[0] = &m_SelectedBrushHandles; + pHandles[1] = &m_ActiveBrushHandles; + pHandles[2] = &m_BrushHandles; + pHandles[3] = &m_EntityBrushHandles; + + for (int j = 0; j < 4; j++) + { + for (int i = 0; i < pHandles[j]->GetSize(); i++) + { + brush_t *pb = reinterpret_cast(pHandles[j]->GetAt(i)); + if (pb == reinterpret_cast(vp)) + { + return pb; + } + } + } + return NULL; +} + +patchMesh_t* CPlugInManager::FindPatchHandle(int index) +{ + switch (PatchesMode) + { + case EActivePatches: + case ESelectedPatches: + if ( index < m_PatchesHandles.GetSize() ) + { + brush_t *pb = reinterpret_cast(m_PatchesHandles.GetAt(index)); + return pb->pPatch; + } +#ifdef _DEBUG + Sys_Printf("WARNING: out of bounds in CPlugInManager::FindPatchHandle\n"); +#endif + break; + case EAllocatedPatches: + if ( index < m_PluginPatches.GetSize() ) + { + patchMesh_t *pPatch = reinterpret_cast(m_PluginPatches.GetAt(index)); + return pPatch; + } +#ifdef _DEBUG + Sys_Printf("WARNING: out of bounds in CPlugInManager::FindPatchHandle\n"); +#endif + break; + } + return NULL; +} + +void* WINAPI QERApp_CreateBrushHandle() +{ + return g_pParentWnd->GetPlugInMgr().CreateBrushHandle(); +} + +void WINAPI QERApp_DeleteBrushHandle(void* vp) +{ + g_pParentWnd->GetPlugInMgr().DeleteBrushHandle(vp); +} + +void WINAPI QERApp_CommitBrushHandleToMap(void* vp) +{ + g_pParentWnd->GetPlugInMgr().CommitBrushHandleToMap(vp); +} + +void WINAPI QERApp_AddFace(void* vp, vec3_t v1, vec3_t v2, vec3_t v3) +{ + g_pParentWnd->GetPlugInMgr().AddFaceToBrushHandle(vp, v1, v2, v3); +} + +void WINAPI QERApp_DeleteSelection() +{ + Select_Delete(); +} + +void QERApp_GetCamera( vec3_t origin, vec3_t angles ) +{ + VectorCopy( g_pParentWnd->GetCamWnd()->Camera()->origin, origin ); + VectorCopy( g_pParentWnd->GetCamWnd()->Camera()->angles, angles ); +} + +void QERApp_SetCamera( vec3_t origin, vec3_t angles ) +{ + VectorCopy( origin, g_pParentWnd->GetCamWnd()->Camera()->origin ); + VectorCopy( angles, g_pParentWnd->GetCamWnd()->Camera()->angles ); + + Sys_UpdateWindows( W_ALL ); // specify + g_pParentWnd->OnTimer(); +} + +void QERApp_GetCamWindowExtents( int *x, int *y, int *width, int *height ) +{ + GtkWidget *widget; + + if (g_pParentWnd->CurrentStyle() == MainFrame::eFloating) + widget = g_pParentWnd->GetCamWnd()->m_pParent; + else + widget = g_pParentWnd->GetCamWnd()->GetWidget(); + + get_window_pos (widget, x, y); + + *width = g_pParentWnd->GetCamWnd()->Camera()->width; + *height = g_pParentWnd->GetCamWnd()->Camera()->height; +} + +//FIXME: this AcquirePath stuff is pretty much a mess and needs cleaned up +bool g_bPlugWait = false; +bool g_bPlugOK = false; +int g_nPlugCount = 0; + +void _PlugDone(bool b, int n) +{ + g_bPlugWait = false; + g_bPlugOK = b; + g_nPlugCount = n; +} + +void WINAPI QERApp_GetPoints(int nMax, _QERPointData *pData, char* pMsg) +{ + ShowInfoDialog(pMsg); + g_bPlugWait = true; + g_bPlugOK = false; + g_nPlugCount = 0; +// g_nPlugCount=nMax-1; + AcquirePath(nMax, &_PlugDone); + + while (g_bPlugWait) + gtk_main_iteration (); + + HideInfoDialog(); + + pData->m_nCount = 0; + pData->m_pVectors = NULL; + + if (g_bPlugOK && g_nPlugCount > 0) + { + pData->m_nCount = g_nPlugCount; + pData->m_pVectors = reinterpret_cast(qmalloc(g_nPlugCount * sizeof(vec3_t))); + vec3_t *pOut = pData->m_pVectors; + for (int i = 0; i < g_nPlugCount; i++) + { + memcpy(pOut, &g_PathPoints[i],sizeof(vec3_t)); + pOut++; + } + } +} + +//#define DBG_PAPI + +void CheckTexture(face_t *f) +{ + if (!f->d_texture) + { +#ifdef DBG_PAPI + Sys_Printf("CheckTexture: requesting %s\n", f->texdef.name); +#endif + f->pShader = QERApp_Shader_ForName (f->texdef.GetName()); + f->pShader->IncRef(); + f->d_texture = f->pShader->getTexture(); + } +} + +// expects pData->m_TextureName to be relative to "textures/" +void WINAPI QERApp_AddFaceData(void* pv, _QERFaceData *pData) +{ +#ifdef DBG_PAPI + Sys_Printf("FindBrushHandle..."); +#endif + brush_t* pBrush = g_pParentWnd->GetPlugInMgr().FindBrushHandle(pv); +#ifdef DBG_PAPI + Sys_Printf("Done\n"); +#endif + if (pBrush != NULL) + { + face_t *f = Face_Alloc(); + f->texdef = g_qeglobals.d_texturewin.texdef; + f->texdef.flags = pData->m_nFlags; + f->texdef.contents = pData->m_nContents; + f->texdef.value = pData->m_nValue; + f->texdef.SetName(pData->m_TextureName); + f->next = pBrush->brush_faces; + pBrush->brush_faces = f; + VectorCopy (pData->m_v1, f->planepts[0]); + VectorCopy (pData->m_v2, f->planepts[1]); + VectorCopy (pData->m_v3, f->planepts[2]); + // we might need to convert one way or the other if the input and the brush coordinates setting don't match + if (pData->m_bBPrimit == true) + { + f->brushprimit_texdef = pData->brushprimit_texdef; + if (!g_qeglobals.m_bBrushPrimitMode) + { + // before calling into the conversion, make sure we have a texture! + CheckTexture (f); +#ifdef DBG_PAPI + Sys_Printf("BrushPrimitFaceToFace..."); +#endif + + // convert BP to regular + BrushPrimitFaceToFace (f); +#ifdef DBG_PAPI + Sys_Printf("Done\n"); +#endif + } + } else + { +#ifdef _DEBUG + if (pData->m_bBPrimit != false) + Sys_FPrintf (SYS_WRN, "non-initialized pData->m_bBPrimit in QERApp_AddFaceData\n"); +#endif + f->texdef.rotate = pData->m_fRotate; + f->texdef.shift[0] = pData->m_fShift[0]; + f->texdef.shift[1] = pData->m_fShift[1]; + f->texdef.scale[0] = pData->m_fScale[0]; + f->texdef.scale[1] = pData->m_fScale[1]; + if (g_qeglobals.m_bBrushPrimitMode) + { + CheckTexture (f); +#ifdef DBG_PAPI + Sys_Printf("FaceToBrushPrimitFace..."); +#endif + + // convert regular to BP + FaceToBrushPrimitFace (f); +#ifdef DBG_PAPI + Sys_Printf("Done\n"); +#endif + } + } + Sys_MarkMapModified(); // PGM + } +} + +int WINAPI QERApp_GetFaceCount(void* pv) +{ + int n = 0; + brush_t *pBrush = g_pParentWnd->GetPlugInMgr().FindBrushHandle(pv); + if (pBrush != NULL) + { + for (face_t *f = pBrush->brush_faces ; f; f = f->next) + { + n++; + } + } + return n; +} + +_QERFaceData* WINAPI QERApp_GetFaceData(void* pv, int nFaceIndex) +{ + static _QERFaceData face; + int n = 0; + brush_t *pBrush = g_pParentWnd->GetPlugInMgr().FindBrushHandle(pv); + + if (pBrush != NULL) + { + for (face_t *f = pBrush->brush_faces ; f; f = f->next) + { + +#ifdef _DEBUG + if (!pBrush->brush_faces) + { + Sys_Printf( "Warning : pBrush->brush_faces is NULL in QERApp_GetFaceData\n" ); + return NULL; + } +#endif + + if (n == nFaceIndex) + { + face.m_nContents = f->texdef.contents; + face.m_nFlags = f->texdef.flags; + face.m_nValue = f->texdef.value; + if (g_qeglobals.m_bBrushPrimitMode) + { + //++timo NOTE: we may want to convert back to old format for backward compatibility with some old plugins? + face.m_bBPrimit = true; + face.brushprimit_texdef = f->brushprimit_texdef; + } else + { + face.m_fRotate = f->texdef.rotate; + face.m_fScale[0] = f->texdef.scale[0]; + face.m_fScale[1] = f->texdef.scale[1]; + face.m_fShift[0] = f->texdef.shift[0]; + face.m_fShift[1] = f->texdef.shift[1]; + } + strcpy(face.m_TextureName, f->texdef.GetName()); + VectorCopy(f->planepts[0], face.m_v1); + VectorCopy(f->planepts[1], face.m_v2); + VectorCopy(f->planepts[2], face.m_v3); + return &face; + } + n++; + } + } + return NULL; +} + +void WINAPI QERApp_SetFaceData(void* pv, int nFaceIndex, _QERFaceData *pData) +{ + int n = 0; + brush_t *pBrush = g_pParentWnd->GetPlugInMgr().FindBrushHandle(pv); + + if (pBrush != NULL) + { + for (face_t *f = pBrush->brush_faces ; f; f = f->next) + { + if (n == nFaceIndex) + { + f->texdef.flags = pData->m_nFlags; + f->texdef.contents = pData->m_nContents; + f->texdef.value = pData->m_nValue; + f->texdef.rotate = pData->m_fRotate; + f->texdef.shift[0] = pData->m_fShift[0]; + f->texdef.shift[1] = pData->m_fShift[1]; + f->texdef.scale[0] = pData->m_fScale[0]; + f->texdef.scale[1] = pData->m_fScale[1]; + //strcpy(f->texdef.name, pData->m_TextureName); + f->texdef.SetName(pData->m_TextureName); + VectorCopy(pData->m_v1, f->planepts[0]); + VectorCopy(pData->m_v2, f->planepts[1]); + VectorCopy(pData->m_v3, f->planepts[2]); + Sys_MarkMapModified(); // PGM + return; // PGM + } + n++; + } + } +} + +void WINAPI QERApp_DeleteFace(void* pv, int nFaceIndex) +{ + int n = 0; + brush_t *pBrush = g_pParentWnd->GetPlugInMgr().FindBrushHandle(pv); + if (pBrush != NULL) + { + face_t *pPrev = pBrush->brush_faces; + for (face_t *f = pBrush->brush_faces; f; f = f->next) + { + if (n == nFaceIndex) + { + pPrev->next = f->next; + Face_Free (f); + Sys_MarkMapModified(); // PGM + return; + } + n++; + pPrev = f; + } + } +} + +//========== +//PGM +void WINAPI QERApp_BuildBrush (void* pv) +{ + brush_t *pBrush = g_pParentWnd->GetPlugInMgr().FindBrushHandle(pv); + if (pBrush != NULL) + { + Brush_Build(pBrush); + Sys_UpdateWindows(W_ALL); + } +} + +//Timo : another version with bConvert flag +//++timo since 1.7 is not compatible with earlier plugin versions, remove this one and update QERApp_BuildBrush +void WINAPI QERApp_BuildBrush2 (void* pv, int bConvert) +{ + brush_t *pBrush = g_pParentWnd->GetPlugInMgr().FindBrushHandle(pv); + if (pBrush != NULL) + { + Brush_Build( pBrush, true, true, bConvert ); + Sys_UpdateWindows(W_ALL); + } +} + +void WINAPI QERApp_SelectBrush (void* pv) +{ + brush_t *pBrush = g_pParentWnd->GetPlugInMgr().FindBrushHandle(pv); + if (pBrush != NULL) + { + Select_Brush(pBrush, false); + Sys_UpdateWindows(W_ALL); + } + +} + +void WINAPI QERApp_DeselectBrush (void* pv) +{ + // FIXME - implement this! +} + +void WINAPI QERApp_ResetPlugins() +{ + g_pParentWnd->OnPluginsRefresh(); +} + +void WINAPI QERApp_DeselectAllBrushes () +{ + Select_Deselect(); + Sys_UpdateWindows(W_ALL); +} +//PGM +//========== + +void WINAPI QERApp_TextureBrush(void* pv, char* pName) +{ + brush_t *pBrush = g_pParentWnd->GetPlugInMgr().FindBrushHandle(pv); + if (pBrush != NULL) + { + for (face_t *f = pBrush->brush_faces ; f; f = f->next) + { + //strcpy(f->texdef.name, pName); + f->texdef.SetName(pName); + } + Sys_MarkMapModified(); // PGM + } +} + +int WINAPI QERApp_SelectedBrushCount() +{ + int n = 0; + for (brush_t *pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next) + { + n++; + } + return n; +} + +int WINAPI QERApp_ActiveBrushCount() +{ + int n = 0; + for (brush_t *pb = active_brushes.next ; pb != &active_brushes ; pb = pb->next) + { + n++; + } + return n; +} + +int WINAPI QERApp_AllocateSelectedBrushHandles() +{ + int n = 0; + for (brush_t *pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next) + { + n++; + g_pParentWnd->GetPlugInMgr().GetSelectedHandles().Add(pb); + } + return n; +} + +int WINAPI QERApp_AllocateActiveBrushHandles() +{ + int n = 0; + for (brush_t *pb = active_brushes.next ; pb != &active_brushes ; pb = pb->next) + { + n++; + g_pParentWnd->GetPlugInMgr().GetActiveHandles().Add(pb); + } + return n; +} + +void WINAPI QERApp_ReleaseSelectedBrushHandles() +{ + g_pParentWnd->GetPlugInMgr().GetSelectedHandles().RemoveAll(); + Sys_UpdateWindows(W_ALL); +} + +void WINAPI QERApp_ReleaseActiveBrushHandles() +{ + g_pParentWnd->GetPlugInMgr().GetActiveHandles().RemoveAll(); + Sys_UpdateWindows(W_ALL); +} + +void* WINAPI QERApp_GetActiveBrushHandle(int nIndex) +{ + if (nIndex < g_pParentWnd->GetPlugInMgr().GetActiveHandles().GetSize()) + { + return reinterpret_cast(g_pParentWnd->GetPlugInMgr().GetActiveHandles().GetAt(nIndex)); + } + return NULL; +} + +void* WINAPI QERApp_GetSelectedBrushHandle(int nIndex) +{ + if (nIndex < g_pParentWnd->GetPlugInMgr().GetSelectedHandles().GetSize()) + { + return reinterpret_cast(g_pParentWnd->GetPlugInMgr().GetSelectedHandles().GetAt(nIndex)); + } + return NULL; +} + +int WINAPI QERApp_TextureCount() +{ + //++timo TODO: replace by QERApp_GetActiveShaderCount and verify + Texture_StartPos (); + int x, y; + int n = 0; + while (1) + { + IShader *pShader = Texture_NextPos (&x, &y); + if (!pShader) + break; + n++; + } + return n; +} + +char* WINAPI QERApp_GetTexture(int nIndex) +{ + //++timo TODO: replace by QERApp_ActiveShader_ForIndex + // these funcs would end up being provided for backward compatibility + static char name[QER_MAX_NAMELEN]; + Texture_StartPos (); + int x, y; + int n = 0; + while (1) + { + IShader *pShader = Texture_NextPos (&x, &y); + if (!pShader) + break; + if (n == nIndex) + { + strcpy(name, pShader->getName()); + return name; + } + n++; + } + return NULL; +} + +char* WINAPI QERApp_GetCurrentTexture() +{ + static char current_tex[1024]; + strcpy(current_tex,g_qeglobals.d_texturewin.texdef.GetName()); + return current_tex; +} + +void WINAPI QERApp_SetCurrentTexture(char* strName) +{ + //++timo hu ?? tex is not initialized ?? can be any value .. + texdef_t tex; + //++timo added a brushprimit_texdef .. + // smthg to be done here + brushprimit_texdef_t brushprimit_tex; + //strcpy(tex.name, strName); + tex.SetName(strName); + Texture_SetTexture(&tex,&brushprimit_tex); +} + +int WINAPI QERApp_GetEClassCount() +{ + int n = 0; + for (eclass_t *e = eclass ; e ; e = e->next) + { + n++; + } + return n; +} + +char* WINAPI QERApp_GetEClass(int nIndex) +{ + int n = 0; + for (eclass_t *e = eclass ; e ; e = e->next) + { + if (n == nIndex) + { + return e->name; + } + } + return NULL; +} + +// v1.70 code +// world_entity holds the worldspawn and is indexed as 0 +// other entities are in the entities doubly linked list +// QERApp_GetEntityCount counts the entities like in any C array: [0..length-1] +int WINAPI QERApp_GetEntityCount() +{ + int n = 1; + for (entity_t *pe = entities.next ; pe != &entities ; pe = pe->next) + { + n++; + } + return n; +} + +// We don't store entities in CPtrArray, we need to walk the list +void* WINAPI QERApp_GetEntityHandle(int nIndex) +{ + if (nIndex==0) + // looks for the worldspawn + return static_cast(world_entity); + entity_t *pe = &entities; + int n = 0; + while ( n < nIndex ) + { + pe = pe->next; + n++; + } + return static_cast(pe); +} + +epair_t* WINAPI QERApp_AllocateEpair( const char *key, const char *val ) +{ + epair_t *e = (epair_t*)qmalloc (sizeof(*e)); + e->key = (char*)qmalloc(strlen(key)+1); + strcpy (e->key, key); + e->value = (char*)qmalloc(strlen(val)+1); + strcpy (e->value, val); + return e; +} + +/* +IEpair* WINAPI QERApp_IEpairForEntityHandle(void *vp) +{ + entity_t *pe = static_cast(vp); + CEpairsWrapper *pEp = new CEpairsWrapper(pe); + pEp->IncRef(); + return pEp; +} + +IEpair* WINAPI QERApp_IEpairForProjectKeys() +{ + CEpairsWrapper *pEp = new CEpairsWrapper(g_qeglobals.d_project_entity); + pEp->IncRef(); + return pEp; +} +*/ + +int WINAPI QERApp_AllocateEntityBrushHandles(void* vp) +{ + entity_t *pe = static_cast(vp); + int n = 0; + if (!pe->brushes.onext) + return 0; + g_pParentWnd->GetPlugInMgr().GetEntityBrushHandles().RemoveAll(); + for (brush_t *pb = pe->brushes.onext ; pb != &pe->brushes ; pb=pb->onext) + { + n++; + g_pParentWnd->GetPlugInMgr().GetEntityBrushHandles().Add(pb); + } + return n; +} + +void WINAPI QERApp_ReleaseEntityBrushHandles() +{ + g_pParentWnd->GetPlugInMgr().GetEntityBrushHandles().RemoveAll(); +} + +void* WINAPI QERApp_GetEntityBrushHandle(int nIndex) +{ + if (nIndex < g_pParentWnd->GetPlugInMgr().GetEntityBrushHandles().GetSize()) + return g_pParentWnd->GetPlugInMgr().GetEntityBrushHandles().GetAt(nIndex); + return NULL; +} + +// FIXME TTimo that entity handles thing sucks .. we should get rid of it .. + +void* WINAPI QERApp_CreateEntityHandle() +{ + entity_t *pe = reinterpret_cast(qmalloc(sizeof(entity_t))); + pe->brushes.onext = pe->brushes.oprev = &pe->brushes; + g_pParentWnd->GetPlugInMgr().GetEntityHandles().Add(static_cast(pe)); + return static_cast(pe); +} + +// the vpBrush needs to be in m_BrushHandles +//++timo we don't have allocation nor storage for vpEntity, no checks for this one +void WINAPI QERApp_CommitBrushHandleToEntity(void* vpBrush, void* vpEntity) +{ + g_pParentWnd->GetPlugInMgr().CommitBrushHandleToEntity(vpBrush, vpEntity); + return; +} + +const char* QERApp_ReadProjectKey(const char* key) +{ + return ValueForKey(g_qeglobals.d_project_entity, key); +} + +#ifdef USEPLUGINENTITIES + +int WINAPI QERApp_ScanFileForEClass(char *filename ) +{ + // set single class parsing + parsing_single = true; + Eclass_ScanFile(filename); + if (eclass_found) + { + eclass_e->nShowFlags |= ECLASS_PLUGINENTITY; + return 1; + } + return 0; +} +#endif // USEPLUGINENTITIES + +// the vpBrush needs to be in m_BrushHandles +//++timo add a debug check to see if we found the brush handle +// NOTE : seems there's no way to check vpEntity is valid .. this is dangerous +// links the brush to its entity, everything else is done when commiting the entity to the map +void CPlugInManager::CommitBrushHandleToEntity(void* vpBrush, void* vpEntity) +{ + brush_t* pb; + entity_t* pe; + for (int i=0 ; i < m_BrushHandles.GetSize() ; i++) + { + if (vpBrush == m_BrushHandles.GetAt(i)) + { + m_BrushHandles.RemoveAt(i); + pb = reinterpret_cast(vpBrush); + pe = reinterpret_cast(vpEntity); + Entity_LinkBrush (pe, pb); + } + } + Sys_UpdateWindows(W_ALL); +} + +// the vpEntity must be in m_EntityHandles +void WINAPI QERApp_CommitEntityHandleToMap(void* vpEntity) +{ + g_pParentWnd->GetPlugInMgr().CommitEntityHandleToMap(vpEntity); + return; +} + +int WINAPI QERApp_LoadFile( const char *pLocation, void ** buffer ) +{ + int nSize = vfsLoadFile(pLocation, buffer, 0); + return nSize; +} + +char * WINAPI QERApp_ExpandReletivePath (char *p) +{ + return ExpandReletivePath(p); +} + +qtexture_t* WINAPI QERApp_Texture_ForName (const char *name) +{ + // if the texture is not loaded yet, this call will get it loaded + // but: when we assign a GL bind number, we need to be in the g_qeglobals.d_xxxBase GL context + // the plugin may set the GL context to whatever he likes, but then load would fail + // NOTE: is context switching time-consuming? then maybe the plugin could handle the context + // switch and only add a sanity check in debug mode here + // read current context + gtk_glwidget_make_current (g_qeglobals_gui.d_glBase); + + //++timo debugging + Sys_Printf("WARNING: QERApp_Texture_ForName ... don't call that!!\n"); + qtexture_t* qtex = QERApp_Texture_ForName2( name ); + return qtex; +} + +char* QERApp_Token() +{ + return token; +} + +int QERApp_ScriptLine() +{ + return scriptline; +} + +// we save the map and return the name .. either .map or .reg to support region compiling +char* QERApp_GetMapName() +{ + static char name[PATH_MAX]; + SaveWithRegion (name); + return name; +} + +void CPlugInManager::CommitEntityHandleToMap(void* vpEntity) +{ + entity_t *pe; + eclass_t *e; + brush_t *b; + vec3_t mins,maxs; + bool has_brushes; + for (int i=0 ; i < m_EntityHandles.GetSize() ; i++ ) + { + if (vpEntity == m_EntityHandles.GetAt(i)) + { + m_EntityHandles.RemoveAt(i); + pe = reinterpret_cast(vpEntity); + // fill additional fields + // straight copy from Entity_Parse + // entity_t::origin + GetVectorForKey (pe, "origin", pe->origin); + // entity_t::eclass + if (pe->brushes.onext == &pe->brushes) + has_brushes = false; + else + has_brushes = true; + e = Eclass_ForName (ValueForKey (pe, "classname"), has_brushes); + pe->eclass = e; + // fixedsize + if (e->fixedsize) + { + if (pe->brushes.onext != &pe->brushes) + { + Sys_Printf("Warning : Fixed size entity with brushes in CPlugInManager::CommitEntityHandleToMap\n"); + } + // create a custom brush + VectorAdd(e->mins, pe->origin, mins); + VectorAdd(e->maxs, pe->origin, maxs); +/* + float a = 0; + if (e->nShowFlags & ECLASS_MISCMODEL) + { + char* p = ValueForKey(pe, "model"); + if (p != NULL && strlen(p) > 0) + { + vec3_t vMin, vMax; + a = FloatForKey (pe, "angle"); + if (GetCachedModel(pe, p, vMin, vMax)) + { + // create a custom brush + VectorAdd (pe->md3Class->mins, pe->origin, mins); + VectorAdd (pe->md3Class->maxs, pe->origin, maxs); + } + } + } +*/ + b = Brush_Create (mins, maxs, &e->texdef); +/* + if (a) + { + vec3_t vAngle; + vAngle[0] = vAngle[1] = 0; + vAngle[2] = a; + Brush_Rotate(b, vAngle, pe->origin, false); + } +*/ + b->owner = pe; + + b->onext = pe->brushes.onext; + b->oprev = &pe->brushes; + pe->brushes.onext->oprev = b; + pe->brushes.onext = b; + } else + { // brush entity + if (pe->brushes.next == &pe->brushes) + Sys_Printf ("Warning: Brush entity with no brushes in CPlugInManager::CommitEntityHandleToMap\n"); + } + + // add brushes to the active brushes list + // and build them along the way + for (b=pe->brushes.onext ; b != &pe->brushes ; b=b->onext) + { + // convert between old brushes and brush primitive + if (g_qeglobals.m_bBrushPrimitMode) + { + // we only filled the shift scale rot fields, needs conversion + Brush_Build( b, true, true, true ); + } else + { + // we are using old brushes + Brush_Build( b ); + } + b->next = active_brushes.next; + active_brushes.next->prev = b; + b->prev = &active_brushes; + active_brushes.next = b; + } + + // handle worldspawn entities + // if worldspawn has no brushes, use the new one + if (!strcmp(ValueForKey (pe, "classname"), "worldspawn")) + { + if ( world_entity && ( world_entity->brushes.onext != &world_entity->brushes ) ) + { + // worldspawn already has brushes + Sys_Printf ("Commiting worldspawn as func_group\n"); + SetKeyValue(pe, "classname", "func_group"); + // add the entity to the end of the entity list + pe->next = &entities; + pe->prev = entities.prev; + entities.prev->next = pe; + entities.prev = pe; + g_qeglobals.d_num_entities++; + } else + { + // there's a worldspawn with no brushes, we assume the map is empty + if ( world_entity ) + { + Entity_Free( world_entity ); + world_entity = pe; + } else + Sys_Printf("Warning : unexpected world_entity == NULL in CommitEntityHandleToMap\n"); + } + } else + { + // add the entity to the end of the entity list + pe->next = &entities; + pe->prev = entities.prev; + entities.prev->next = pe; + entities.prev = pe; + g_qeglobals.d_num_entities++; + } + } + } +} + +void WINAPI QERApp_SetScreenUpdate(int bScreenUpdates) +{ + g_bScreenUpdates = bScreenUpdates; +} + +texturewin_t* QERApp_QeglobalsTexturewin() +{ + return &g_qeglobals.d_texturewin; +} + +texdef_t* QERApp_QeglobalsSavedinfo_SIInc() +{ + return &g_qeglobals.d_savedinfo.m_SIIncrement; +} + +patchMesh_t* QERApp_GetSelectedPatch( ) +{ + for (brush_t *pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next) + { + if (pb->patchBrush) + { + return pb->pPatch; + } + } +#ifdef _DEBUG + Sys_Printf("WARNING: QERApp_GetSelectedPatchTexdef called with no patch selected\n"); +#endif + return NULL; +} + +const char* WINAPI QERApp_GetGamePath() +{ + return g_pGameDescription->mEnginePath.GetBuffer(); +} + +/*! +\todo the name of this API should prolly be changed +would also need to prompt g_strAppPath / g_strGameToolsPath independently? +*/ +// SPoG +// changed g_strGameToolsPath to g_strAppPath +const char* WINAPI QERApp_GetQERPath() +{ + return g_strAppPath.GetBuffer(); +} + +const char* WINAPI QERApp_GetGameFile() +{ + // FIXME: Arnout: temp solution, need proper 'which game is this' indicator or a different solution for plugins/modules + return g_pGameDescription->mGameFile.GetBuffer(); +} + +// patches in/out ----------------------------------- +int WINAPI QERApp_AllocateActivePatchHandles() +{ + return g_pParentWnd->GetPlugInMgr().AllocateActivePatchHandles(); +} + +// Grid Size +float QERApp_QeglobalsGetGridSize() +{ + return g_qeglobals.d_gridsize; +} + +int CPlugInManager::AllocateActivePatchHandles() +{ + int n = 0; + for (brush_t *pb = active_brushes.next ; pb != &active_brushes ; pb = pb->next) + { + if (pb->patchBrush) + { + n++; + m_PatchesHandles.Add(pb); + } + } + return n; +} + +int WINAPI QERApp_AllocateSelectedPatchHandles() +{ + return g_pParentWnd->GetPlugInMgr().AllocateSelectedPatchHandles(); +} + +int CPlugInManager::AllocateSelectedPatchHandles() +{ + int n = 0; + // change mode + PatchesMode = ESelectedPatches; + for (brush_t *pb = selected_brushes.next ; pb != &selected_brushes ; pb = pb->next) + { + if (pb->patchBrush) + { + n++; + m_PatchesHandles.Add(pb); + } + } + return n; +} + +void WINAPI QERApp_ReleasePatchHandles() +{ + g_pParentWnd->GetPlugInMgr().ReleasePatchesHandles(); +} + +patchMesh_t* WINAPI QERApp_GetPatchData(int index) +{ + static patchMesh_t patch; + patchMesh_t *pPatch = g_pParentWnd->GetPlugInMgr().FindPatchHandle(index); + if (pPatch) + { + memcpy( &patch, pPatch, sizeof(patchMesh_t) ); + return &patch; + } + return NULL; +} + +patchMesh_t* WINAPI QERApp_GetPatchHandle(int index) +{ + return g_pParentWnd->GetPlugInMgr().FindPatchHandle(index); +} + +void WINAPI QERApp_DeletePatch(int index) +{ + patchMesh_t *pPatch = g_pParentWnd->GetPlugInMgr().FindPatchHandle(index); + if (pPatch) + { + brush_t *pb = pPatch->pSymbiot; + Patch_Delete( pPatch ); + if (pb) + Brush_Free( pb ); + } +#ifdef _DEBUG + Sys_Printf("Warning: QERApp_DeletePatch: FindPatchHandle failed\n"); +#endif +} + +int WINAPI QERApp_CreatePatchHandle() +{ + return g_pParentWnd->GetPlugInMgr().CreatePatchHandle(); +} + +int CPlugInManager::CreatePatchHandle() +{ + // NOTE: we can't call the AddBrushForPatch until we have filled the patchMesh_t structure + patchMesh_t *pPatch = MakeNewPatch(); + m_PluginPatches.Add( pPatch ); + // change mode + PatchesMode = EAllocatedPatches; + return m_PluginPatches.GetSize()-1; +} + +void WINAPI QERApp_CommitPatchHandleToMap(int index, patchMesh_t *pMesh, char *texName) +{ +#ifdef DBG_PAPI + Sys_Printf ("QERApp_CommitPatchHandleToMap %i..", index); +#endif + g_pParentWnd->GetPlugInMgr().CommitPatchHandleToMap(index, pMesh, texName); +#ifdef DBG_PAPI + Sys_Printf ("Done\n"); +#endif +} + +void WINAPI QERApp_CommitPatchHandleToEntity(int index, patchMesh_t *pMesh, char *texName, void* vpEntity) +{ +#ifdef DBG_PAPI + Sys_Printf ("QERApp_CommitPatchHandleToEntity %i..", index); +#endif + g_pParentWnd->GetPlugInMgr().CommitPatchHandleToEntity(index, pMesh, texName, vpEntity); +#ifdef DBG_PAPI + Sys_Printf ("Done\n"); +#endif +} + +void CPlugInManager::CommitPatchHandleToMap(int index, patchMesh_t *pMesh, char *texName) +{ + if (PatchesMode==EAllocatedPatches) + { + patchMesh_t *pPatch = reinterpret_cast( m_PluginPatches.GetAt(index) ); + memcpy( pPatch, pMesh, sizeof( patchMesh_t ) ); + // patch texturing, if none given use current texture + if (texName) + pPatch->pShader = QERApp_Shader_ForName (texName); + else + pPatch->pShader = QERApp_Shader_ForName(g_qeglobals.d_texturewin.texdef.GetName()); + pPatch->d_texture = pPatch->pShader->getTexture(); + pPatch->pShader->IncRef(); + g_bScreenUpdates = false; + // the bLinkToWorld flag in AddBrushForPatch takes care of Brush_AddToList Entity_linkBrush and Brush_Build + brush_t *pb = AddBrushForPatch( pPatch, true ); + Select_Brush( pb ); + g_bScreenUpdates = true; + Sys_UpdateWindows(W_ALL); + } else + { + brush_t *pBrush = reinterpret_cast( m_PatchesHandles.GetAt(index) ); + patchMesh_t *pPatch = pBrush->pPatch; + pPatch->width = pMesh->width; + pPatch->height = pMesh->height; + pPatch->contents = pMesh->contents; + pPatch->flags = pMesh->flags; + pPatch->value = pMesh->value; + pPatch->type = pMesh->type; + memcpy( pPatch->ctrl, pMesh->ctrl, sizeof(drawVert_t)*MAX_PATCH_HEIGHT*MAX_PATCH_WIDTH ); + pPatch->bDirty = true; + } +} + +void CPlugInManager::CommitPatchHandleToEntity(int index, patchMesh_t *pMesh, char *texName, void *vpEntity) +{ + entity_t* pe = reinterpret_cast(vpEntity); + + if (PatchesMode==EAllocatedPatches) + { + patchMesh_t *pPatch = reinterpret_cast( m_PluginPatches.GetAt(index) ); + memcpy( pPatch, pMesh, sizeof( patchMesh_t ) ); + // patch texturing, if none given use current texture + if (texName) + pPatch->pShader = QERApp_Shader_ForName (texName); + else + pPatch->pShader = QERApp_Shader_ForName(g_qeglobals.d_texturewin.texdef.GetName()); + pPatch->d_texture = pPatch->pShader->getTexture(); + pPatch->pShader->IncRef(); + g_bScreenUpdates = false; + brush_t *pb = AddBrushForPatch( pPatch, false ); // false, sp have to do the brush building/entity linking ourself + Brush_AddToList (pb, &active_brushes); + Entity_LinkBrush (pe, pb); + Brush_Build( pb ); + g_bScreenUpdates = true; + Sys_UpdateWindows(W_ALL); + } else + { + brush_t *pBrush = reinterpret_cast( m_PatchesHandles.GetAt(index) ); + patchMesh_t *pPatch = pBrush->pPatch; + pPatch->width = pMesh->width; + pPatch->height = pMesh->height; + pPatch->contents = pMesh->contents; + pPatch->flags = pMesh->flags; + pPatch->value = pMesh->value; + pPatch->type = pMesh->type; + memcpy( pPatch->ctrl, pMesh->ctrl, sizeof(drawVert_t)*MAX_PATCH_HEIGHT*MAX_PATCH_WIDTH ); + pPatch->bDirty = true; + } +} + +#if 0 + +#if defined (__linux__) || defined (__APPLE__) + #include + +XVisualInfo* QEX_ChooseVisual (bool zbuffer) +{ + int attrlist_z[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 16, 0}; + int attrlist[] = { GLX_RGBA, GLX_DOUBLEBUFFER, 0}; + XVisualInfo *vi; + Display *dpy; + + dpy = GDK_DISPLAY(); + if (dpy == NULL) + Error ("OpenGL fatal error: Cannot get display.\n"); + vi = qglXChooseVisual(dpy, DefaultScreen(dpy), zbuffer ? attrlist_z : attrlist); + if (vi == NULL) + Error ("OpenGL fatal error: glXChooseVisual failed.\n"); + + return vi; +} +#endif + +#endif + +/*! +\todo FIXME TTimo broken most likely +actually .. that's not enough, you have to go down for the game pack specific? +*/ +const char* WINAPI QERApp_ProfileGetDirectory () +{ + return g_strTempPath; +} + +GtkWidget* WINAPI QERApp_GetQeGlobalsGLWidget () +{ + return g_qeglobals_gui.d_glBase; +} + +qboolean WINAPI BrushPrimitMode () +{ + return g_qeglobals.m_bBrushPrimitMode; +} + +brush_t* WINAPI QERApp_ActiveBrushes() +{ + return &active_brushes; +} + +brush_t* WINAPI QERApp_SelectedBrushes() +{ + return &selected_brushes; +} + +brush_t* WINAPI QERApp_FilteredBrushes() +{ + return &filtered_brushes; +} + +CPtrArray* WINAPI QERApp_LstSkinCache() +{ + return &g_lstSkinCache; +} + +qtexture_t** WINAPI QERApp_QTextures() +{ + return &g_qeglobals.d_qtextures; +} + +GHashTable* WINAPI QERApp_QTexmap() +{ + return g_qeglobals.d_qtexmap; +} + +// a simplified version of Texture_SetTexture +void WINAPI QERApp_Texture_SetTexture (texdef_t *texdef, brushprimit_texdef_t *brushprimit_texdef) +{ + Texture_SetTexture (texdef, brushprimit_texdef); +} + +void QERApp_LoadImage (const char *name, unsigned char **pic, int *width, int *height) +{ + g_ImageManager.LoadImage(name, pic, width, height); +} + +unsigned long QERApp_GetTickCount() +{ +#ifdef _WIN32 + return GetTickCount(); +#else + struct timeval tp; + struct timezone tzp; + static int basetime=0; + + gettimeofday(&tp, &tzp); + if (!basetime) + basetime = tp.tv_sec; + return (tp.tv_sec-basetime) + tp.tv_usec/1000; +#endif +} + +bool CSynapseClientRadiant::RequestAPI(APIDescriptor_t *pAPI) +{ + if (!strcmp(pAPI->major_name, RADIANT_MAJOR)) + { + _QERFuncTable_1* pTable= static_cast<_QERFuncTable_1*>(pAPI->mpTable); + pTable->m_pfnCreateBrush = &QERApp_CreateBrush; + pTable->m_pfnCreateBrushHandle = &QERApp_CreateBrushHandle; + pTable->m_pfnDeleteBrushHandle = &QERApp_DeleteBrushHandle; + pTable->m_pfnCommitBrushHandle = &QERApp_CommitBrushHandleToMap; + pTable->m_pfnAddFace = &QERApp_AddFace; + pTable->m_pfnAddFaceData = &QERApp_AddFaceData; + pTable->m_pfnGetFaceData = &QERApp_GetFaceData; + pTable->m_pfnGetFaceCount = &QERApp_GetFaceCount; + pTable->m_pfnSetFaceData = &QERApp_SetFaceData; + pTable->m_pfnDeleteFace = &QERApp_DeleteFace; + pTable->m_pfnTextureBrush = &QERApp_TextureBrush; + pTable->m_pfnBuildBrush = &QERApp_BuildBrush; // PGM + pTable->m_pfnSelectBrush = &QERApp_SelectBrush; // PGM + pTable->m_pfnDeselectBrush = &QERApp_DeselectBrush; // PGM + pTable->m_pfnDeselectAllBrushes = &QERApp_DeselectAllBrushes; // PGM + pTable->m_pfnDeleteSelection = &QERApp_DeleteSelection; + pTable->m_pfnGetPoints = &QERApp_GetPoints; + pTable->m_pfnSelectedBrushCount = &QERApp_SelectedBrushCount; + pTable->m_pfnAllocateSelectedBrushHandles = &QERApp_AllocateSelectedBrushHandles; + pTable->m_pfnReleaseSelectedBrushHandles = &QERApp_ReleaseSelectedBrushHandles; + pTable->m_pfnGetSelectedBrushHandle = &QERApp_GetSelectedBrushHandle; + pTable->m_pfnActiveBrushCount = &QERApp_ActiveBrushCount; + pTable->m_pfnAllocateActiveBrushHandles = &QERApp_AllocateActiveBrushHandles; + pTable->m_pfnReleaseActiveBrushHandles = &QERApp_ReleaseActiveBrushHandles; + pTable->m_pfnGetActiveBrushHandle = &QERApp_GetActiveBrushHandle; + pTable->m_pfnTextureCount = &QERApp_TextureCount; + pTable->m_pfnGetTexture = &QERApp_GetTexture; + pTable->m_pfnGetCurrentTexture = &QERApp_GetCurrentTexture; + pTable->m_pfnSetCurrentTexture = &QERApp_SetCurrentTexture; + pTable->m_pfnGetEClassCount = &QERApp_GetEClassCount; + pTable->m_pfnGetEClass = &QERApp_GetEClass; + pTable->m_pfnResetPlugins = &QERApp_ResetPlugins; + pTable->m_pfnLoadTextureRGBA = &QERApp_LoadTextureRGBA; + pTable->m_pfnGetEntityCount = &QERApp_GetEntityCount; + pTable->m_pfnGetEntityHandle = &QERApp_GetEntityHandle; + pTable->m_pfnAllocateEpair = &QERApp_AllocateEpair; + pTable->m_pfnAllocateEntityBrushHandles = &QERApp_AllocateEntityBrushHandles; + pTable->m_pfnReleaseEntityBrushHandles = &QERApp_ReleaseEntityBrushHandles; + pTable->m_pfnGetEntityBrushHandle = &QERApp_GetEntityBrushHandle; + pTable->m_pfnCreateEntityHandle = &QERApp_CreateEntityHandle; + pTable->m_pfnCommitBrushHandleToEntity = &QERApp_CommitBrushHandleToEntity; + pTable->m_pfnCommitEntityHandleToMap = &QERApp_CommitEntityHandleToMap; + pTable->m_pfnSetScreenUpdate = &QERApp_SetScreenUpdate; + pTable->m_pfnBuildBrush2 = &QERApp_BuildBrush2; + pTable->m_pfnGetDispatchParams = &QERApp_GetDispatchParams; +// pTable->m_pfnRequestInterface = &QERApp_RequestInterface; + pTable->m_pfnError = &Error; + pTable->m_pfnLoadFile = &QERApp_LoadFile; + pTable->m_pfnExpandReletivePath = &QERApp_ExpandReletivePath; + pTable->m_pfnQE_ConvertDOSToUnixName = &QE_ConvertDOSToUnixName; + pTable->m_pfnHasShader = QERApp_HasShader; + pTable->m_pfnTexture_LoadSkin = &Texture_LoadSkin; + pTable->m_pfnGetGamePath = &QERApp_GetGamePath; + pTable->m_pfnGetQERPath = &QERApp_GetQERPath; + pTable->m_pfnGetGameFile = &QERApp_GetGameFile; + pTable->m_pfnAllocateActivePatchHandles = &QERApp_AllocateActivePatchHandles; + pTable->m_pfnAllocateSelectedPatchHandles = &QERApp_AllocateSelectedPatchHandles; + pTable->m_pfnReleasePatchHandles = &QERApp_ReleasePatchHandles; + pTable->m_pfnGetPatchData = &QERApp_GetPatchData; + pTable->m_pfnGetPatchHandle = &QERApp_GetPatchHandle; + pTable->m_pfnDeletePatch = &QERApp_DeletePatch; + pTable->m_pfnCreatePatchHandle = &QERApp_CreatePatchHandle; + pTable->m_pfnCommitPatchHandleToMap = &QERApp_CommitPatchHandleToMap; + pTable->m_pfnLoadImage = &QERApp_LoadImage; + pTable->m_pfnMessageBox = >k_MessageBox; + pTable->m_pfnFileDialog = &file_dialog; + pTable->m_pfnColorDialog = &color_dialog; + pTable->m_pfnDirDialog = &dir_dialog; + pTable->m_pfnLoadBitmap = &load_plugin_bitmap; + pTable->m_pfnProfileGetDirectory = &QERApp_ProfileGetDirectory; + pTable->m_pfnProfileSaveInt = &profile_save_int; + pTable->m_pfnProfileSaveString = &profile_save_string; + pTable->m_pfnProfileLoadInt = &profile_load_int; + pTable->m_pfnProfileLoadString = &profile_load_string; + pTable->m_pfnSysUpdateWindows = &Sys_UpdateWindows; + pTable->m_pfnSysPrintf = &Sys_Printf; + pTable->m_pfnSysFPrintf = &Sys_FPrintf; + pTable->m_pfnSysBeginWait = &Sys_BeginWait; + pTable->m_pfnSysEndWait = &Sys_EndWait; + pTable->m_pfnSys_SetTitle = &Sys_SetTitle; + pTable->m_pfnSysBeep = &Sys_Beep; + pTable->m_pfnSys_Status = &Sys_Status; + pTable->m_pfnMapFree = &Map_Free; + pTable->m_pfnMapNew = &Map_New; + pTable->m_pfnMapBuildBrushData = &Map_BuildBrushData; + pTable->m_pfnMap_IsBrushFiltered = &Map_IsBrushFiltered; + pTable->m_pfnMapStartPosition = &Map_StartPosition; + pTable->m_pfnMapRegionOff = &Map_RegionOff; + pTable->m_pfnSetBuildWindingsNoTexBuild = &Brush_SetBuildWindingsNoTexBuild; + pTable->m_pfnPointFileClear = &Pointfile_Clear; + pTable->m_pfnCSG_MakeHollow = &CSG_MakeHollow; + pTable->m_pfnRegionSpawnPoint = &Region_SpawnPoint; + pTable->m_pfnQGetTickCount = &QERApp_GetTickCount; + pTable->m_pfnGetModelCache = &GetModelCache; + pTable->m_pfnGetFileTypeRegistry = &GetFileTypeRegistry; + pTable->m_pfnReadProjectKey = &QERApp_ReadProjectKey; + pTable->m_pfnGetMapName = &QERApp_GetMapName; + pTable->m_pfnFilterAdd = &FilterCreate; + pTable->m_pfnFiltersActivate = &FiltersActivate; + + return true; + } + if (!strcmp(pAPI->major_name, SCRIPLIB_MAJOR)) + { + _QERScripLibTable *pScripLibTable = static_cast<_QERScripLibTable *>(pAPI->mpTable); + pScripLibTable->m_pfnGetToken = &GetToken; + pScripLibTable->m_pfnGetTokenExtra = &GetTokenExtra; + pScripLibTable->m_pfnToken = &QERApp_Token; + pScripLibTable->m_pfnUnGetToken = &UngetToken; + pScripLibTable->m_pfnStartTokenParsing = &StartTokenParsing; + pScripLibTable->m_pfnScriptLine = &QERApp_ScriptLine; + pScripLibTable->m_pfnTokenAvailable = &TokenAvailable; + pScripLibTable->m_pfnCOM_Parse = &COM_Parse; + pScripLibTable->m_pfnGet_COM_Token = &Get_COM_Token; + + return true; + } + if (!strcmp(pAPI->major_name, BRUSH_MAJOR)) + { + _QERBrushTable *pBrushTable = static_cast<_QERBrushTable *>(pAPI->mpTable); + pBrushTable->m_pfnBP_MessageBox = &BP_MessageBox; + pBrushTable->m_pfnBrush_AddToList = &Brush_AddToList; + pBrushTable->m_pfnBrush_Build = &Brush_Build; + pBrushTable->m_pfnBrush_Create = &Brush_Create; + pBrushTable->m_pfnBrush_Free = &Brush_Free; + pBrushTable->m_pfnBrush_Rotate = &Brush_Rotate; + pBrushTable->m_pfnBrushAlloc = &Brush_Alloc; + pBrushTable->m_pfnFace_Alloc = &Face_Alloc; + pBrushTable->m_pfnHasModel = NULL;// &HasModel; + + return true; + } + if (!strcmp(pAPI->major_name, APPSHADERS_MAJOR)) + { + _QERAppShadersTable *pShadersTable = static_cast<_QERAppShadersTable*>(pAPI->mpTable); + pShadersTable->m_pfnQTextures = QERApp_QTextures; + pShadersTable->m_pfnQTexmap = QERApp_QTexmap; + pShadersTable->m_pfnQeglobalsTexturewin = QERApp_QeglobalsTexturewin; + pShadersTable->m_pfnTexture_SetTexture = QERApp_Texture_SetTexture; + pShadersTable->m_pfnTexture_ShowInuse = Texture_ShowInuse; + pShadersTable->m_pfnBuildShaderList = &BuildShaderList; + pShadersTable->m_pfnPreloadShaders = &PreloadShaders; + + return true; + } + if (!strcmp(pAPI->major_name, QGL_MAJOR)) + { + _QERQglTable *pQglTable = static_cast<_QERQglTable *>(pAPI->mpTable); + pQglTable->m_pfn_qglAlphaFunc = qglAlphaFunc; + pQglTable->m_pfn_qglBegin = qglBegin; + pQglTable->m_pfn_qglBindTexture = qglBindTexture; + pQglTable->m_pfn_qglBlendFunc = qglBlendFunc; + pQglTable->m_pfn_qglCallList = qglCallList; + pQglTable->m_pfn_qglCallLists = qglCallLists; + pQglTable->m_pfn_qglClear = qglClear; + pQglTable->m_pfn_qglClearColor = qglClearColor; + pQglTable->m_pfn_qglClearDepth = qglClearDepth; + pQglTable->m_pfn_qglColor3f = qglColor3f; + pQglTable->m_pfn_qglColor3fv = qglColor3fv; + pQglTable->m_pfn_qglColor4f = qglColor4f; + pQglTable->m_pfn_qglColor4fv = qglColor4fv; + pQglTable->m_pfn_qglColor4ubv = qglColor4ubv; + pQglTable->m_pfn_qglColorPointer = qglColorPointer; + pQglTable->m_pfn_qglCullFace = qglCullFace; + pQglTable->m_pfn_qglDepthFunc = qglDepthFunc; + pQglTable->m_pfn_qglDepthMask = qglDepthMask; + pQglTable->m_pfn_qglDisable = qglDisable; + pQglTable->m_pfn_qglDisableClientState = qglDisableClientState; + pQglTable->m_pfn_qglDeleteLists = qglDeleteLists; + pQglTable->m_pfn_qglDeleteTextures = qglDeleteTextures; + pQglTable->m_pfn_qglDrawElements = qglDrawElements; + pQglTable->m_pfn_qglEnable = qglEnable; + pQglTable->m_pfn_qglEnableClientState = qglEnableClientState; + pQglTable->m_pfn_qglEnd = qglEnd; + pQglTable->m_pfn_qglEndList = qglEndList; + pQglTable->m_pfn_qglFogf = qglFogf; + pQglTable->m_pfn_qglFogfv = qglFogfv; + pQglTable->m_pfn_qglFogi = qglFogi; + pQglTable->m_pfn_qglGenLists = qglGenLists; + pQglTable->m_pfn_qglGenTextures = qglGenTextures; + pQglTable->m_pfn_qglGetDoublev = qglGetDoublev; + pQglTable->m_pfn_qglGetIntegerv = qglGetIntegerv; + pQglTable->m_pfn_qglHint = qglHint; + pQglTable->m_pfn_qglLightfv = qglLightfv; + pQglTable->m_pfn_qglLineStipple = qglLineStipple; + pQglTable->m_pfn_qglLineWidth = qglLineWidth; + pQglTable->m_pfn_qglListBase = qglListBase; + pQglTable->m_pfn_qglLoadIdentity = qglLoadIdentity; + pQglTable->m_pfn_qglMaterialf = qglMaterialf; + pQglTable->m_pfn_qglMaterialfv = qglMaterialfv; + pQglTable->m_pfn_qglMatrixMode = qglMatrixMode; + pQglTable->m_pfn_qglMultMatrixf = qglMultMatrixf; + pQglTable->m_pfn_qglNewList = qglNewList; + pQglTable->m_pfn_qglNormal3f = qglNormal3f; + pQglTable->m_pfn_qglNormal3fv = qglNormal3fv; + pQglTable->m_pfn_qglNormalPointer = qglNormalPointer; + pQglTable->m_pfn_qglOrtho = qglOrtho; + pQglTable->m_pfn_qglPointSize = qglPointSize; + pQglTable->m_pfn_qglPolygonMode = qglPolygonMode; + pQglTable->m_pfn_qglPopAttrib = qglPopAttrib; + pQglTable->m_pfn_qglPopMatrix = qglPopMatrix; + pQglTable->m_pfn_qglPushAttrib = qglPushAttrib; + pQglTable->m_pfn_qglPushMatrix = qglPushMatrix; + pQglTable->m_pfn_qglRasterPos3fv = qglRasterPos3fv; + pQglTable->m_pfn_qglRotated = qglRotated; + pQglTable->m_pfn_qglRotatef = qglRotatef; + pQglTable->m_pfn_qglScalef = qglScalef; + pQglTable->m_pfn_qglScissor = qglScissor; + pQglTable->m_pfn_qglShadeModel = qglShadeModel; + pQglTable->m_pfn_qglTexCoord2f = qglTexCoord2f; + pQglTable->m_pfn_qglTexCoord2fv = qglTexCoord2fv; + pQglTable->m_pfn_qglTexCoordPointer = qglTexCoordPointer; + pQglTable->m_pfn_qglTexEnvf = qglTexEnvf; + pQglTable->m_pfn_qglTexGenf = qglTexGenf; + pQglTable->m_pfn_qglTexImage1D = qglTexImage1D; + pQglTable->m_pfn_qglTexImage2D = qglTexImage2D; + pQglTable->m_pfn_qglTexParameterf = qglTexParameterf; + pQglTable->m_pfn_qglTexParameterfv = qglTexParameterfv; + pQglTable->m_pfn_qglTexParameteri = qglTexParameteri; + pQglTable->m_pfn_qglTexParameteriv = qglTexParameteriv; + pQglTable->m_pfn_qglTexSubImage1D = qglTexSubImage1D; + pQglTable->m_pfn_qglTexSubImage2D = qglTexSubImage2D; + pQglTable->m_pfn_qglTranslated = qglTranslated; + pQglTable->m_pfn_qglTranslatef = qglTranslatef; + pQglTable->m_pfn_qglVertex2f = qglVertex2f; + pQglTable->m_pfn_qglVertex3f = qglVertex3f; + pQglTable->m_pfn_qglVertex3fv = qglVertex3fv; + pQglTable->m_pfn_qglVertexPointer = qglVertexPointer; + pQglTable->m_pfn_qglViewport = qglViewport; + + pQglTable->m_pfn_QE_CheckOpenGLForErrors = &QE_CheckOpenGLForErrors; + + pQglTable->m_pfn_qgluPerspective = qgluPerspective; + pQglTable->m_pfn_qgluLookAt = qgluLookAt; + pQglTable->m_pfnHookGL2DWindow = QERApp_HookGL2DWindow; + pQglTable->m_pfnUnHookGL2DWindow = QERApp_UnHookGL2DWindow; + pQglTable->m_pfnHookGL3DWindow = QERApp_HookGL3DWindow; + pQglTable->m_pfnUnHookGL3DWindow = QERApp_UnHookGL3DWindow; + + return true; + } + if (!strcmp(pAPI->major_name, DATA_MAJOR)) + { + _QERAppDataTable *pDataTable = static_cast<_QERAppDataTable *>(pAPI->mpTable); + pDataTable->m_pfnActiveBrushes = QERApp_ActiveBrushes; + pDataTable->m_pfnSelectedBrushes = QERApp_SelectedBrushes; + pDataTable->m_pfnFilteredBrushes = QERApp_FilteredBrushes; + pDataTable->m_pfnLstSkinCache = QERApp_LstSkinCache; + + return true; + } + if (!strcmp(pAPI->major_name, PATCH_MAJOR)) + { + _QERPatchTable *pPatchTable = static_cast<_QERPatchTable *>(pAPI->mpTable); + pPatchTable->m_pfnPatch_Alloc = &Patch_Alloc; + pPatchTable->m_pfnAddBrushForPatch = &AddBrushForPatch; + pPatchTable->m_pfnMakeNewPatch = &MakeNewPatch; + + return true; + } + if (!strcmp(pAPI->major_name, ECLASSMANAGER_MAJOR)) + { + _EClassManagerTable *pEClassManTable = static_cast<_EClassManagerTable *>(pAPI->mpTable); + + pEClassManTable->m_pfnEclass_InsertAlphabetized = &Eclass_InsertAlphabetized; + pEClassManTable->m_pfnGet_Eclass_E = &Get_EClass_E; + pEClassManTable->m_pfnSet_Eclass_Found = &Set_Eclass_Found; + pEClassManTable->m_pfnGet_Parsing_Single = &Get_Parsing_Single; + pEClassManTable->m_pfnEClass_Create = &EClass_Create; + pEClassManTable->m_pfnEclass_ForName = &Eclass_ForName; + + return true; + } + if (!strcmp(pAPI->major_name, SELECTEDFACE_MAJOR)) + { + _QERSelectedFaceTable *pSelectedFaceTable = static_cast<_QERSelectedFaceTable *>(pAPI->mpTable); + + pSelectedFaceTable->m_pfnGetSelectedFaceCount = &QERApp_GetSelectedFaceCount; + pSelectedFaceTable->m_pfnGetFaceBrush = &QERApp_GetSelectedFaceBrush; + pSelectedFaceTable->m_pfnGetFace = &QERApp_GetSelectedFace; + pSelectedFaceTable->m_pfnGetFaceInfo = &QERApp_GetFaceInfo; + pSelectedFaceTable->m_pfnSetFaceInfo = &QERApp_SetFaceInfo; + pSelectedFaceTable->m_pfnGetTextureNumber = &QERApp_ISelectedFace_GetTextureNumber; + pSelectedFaceTable->m_pfnGetTextureSize = &QERApp_GetTextureSize; + pSelectedFaceTable->m_pfnSelect_SetTexture = &Select_SetTexture; + return true; + } + if (!strcmp(pAPI->major_name, APPSURFACEDIALOG_MAJOR)) + { + _QERAppSurfaceTable *pSurfDialogTable = static_cast<_QERAppSurfaceTable *>(pAPI->mpTable); + pSurfDialogTable->m_pfnOnlyPatchesSelected = &OnlyPatchesSelected; + pSurfDialogTable->m_pfnAnyPatchesSelected = &AnyPatchesSelected; + pSurfDialogTable->m_pfnGetSelectedPatch = &QERApp_GetSelectedPatch; + pSurfDialogTable->m_pfnGetTwoSelectedPatch = &QERApp_GetTwoSelectedPatch; + pSurfDialogTable->m_pfnTexMatToFakeTexCoords = &TexMatToFakeTexCoords; + pSurfDialogTable->m_pfnConvertTexMatWithQTexture = &ConvertTexMatWithQTexture; + pSurfDialogTable->m_pfnFakeTexCoordsToTexMat = &FakeTexCoordsToTexMat; + pSurfDialogTable->m_pfnPatch_ResetTexturing = &Patch_ResetTexturing; + pSurfDialogTable->m_pfnPatch_FitTexturing = &Patch_FitTexturing; + pSurfDialogTable->m_pfnPatch_NaturalizeSelected = &Patch_NaturalizeSelected; + pSurfDialogTable->m_pfnPatch_GetTextureName = &Patch_GetTextureName; + pSurfDialogTable->m_pfnQE_SingleBrush = &QE_SingleBrush; + pSurfDialogTable->m_pfnIsBrushPrimitMode = &IsBrushPrimitMode; + pSurfDialogTable->m_pfnComputeAxisBase = &ComputeAxisBase; + pSurfDialogTable->m_pfnBPMatMul = &BPMatMul; + pSurfDialogTable->m_pfnEmitBrushPrimitTextureCoordinates = &EmitBrushPrimitTextureCoordinates; + pSurfDialogTable->m_pfnQeglobalsTexturewin = &QERApp_QeglobalsTexturewin; + pSurfDialogTable->m_pfnSelect_FitTexture = &Select_FitTexture; + pSurfDialogTable->m_pfnQERApp_QeglobalsSavedinfo_SIInc = &QERApp_QeglobalsSavedinfo_SIInc; + pSurfDialogTable->m_pfnQeglobalsGetGridSize = &QERApp_QeglobalsGetGridSize; + pSurfDialogTable->m_pfnFaceList_FitTexture = &SI_FaceList_FitTexture; + pSurfDialogTable->m_pfnGetMainWindow = &SI_GetMainWindow; + pSurfDialogTable->m_pfnSetWinPos_From_Prefs = &SI_SetWinPos_from_Prefs; + pSurfDialogTable->m_pfnGetSelectedFaceCountfromBrushes = &SI_GetSelectedFaceCountfromBrushes; + pSurfDialogTable->m_pfnGetSelFacesTexdef = &SI_GetSelFacesTexdef; + pSurfDialogTable->m_pfnSetTexdef_FaceList = &SI_SetTexdef_FaceList; + + return true; + } + if (!strcmp(pAPI->major_name, UNDO_MAJOR)) + { + _QERUndoTable *pUndoTable = static_cast<_QERUndoTable *>(pAPI->mpTable); + + pUndoTable->m_pfnUndo_Start = &Undo_Start; + pUndoTable->m_pfnUndo_End = &Undo_End; + pUndoTable->m_pfnUndo_AddBrush = &Undo_AddBrush; + pUndoTable->m_pfnUndo_EndBrush = &Undo_EndBrush; + pUndoTable->m_pfnUndo_AddBrushList = &Undo_AddBrushList; + pUndoTable->m_pfnUndo_EndBrushList = &Undo_EndBrushList; + pUndoTable->m_pfnUndo_AddEntity = &Undo_AddEntity; + pUndoTable->m_pfnUndo_EndEntity = &Undo_EndEntity; + pUndoTable->m_pfnUndo_Undo = &Undo_Undo; // Nurail + pUndoTable->m_pfnUndo_Redo = &Undo_Redo; // Nurail + pUndoTable->m_pfnUndo_GetUndoId = &Undo_GetUndoId; // Nurail + pUndoTable->m_pfnUndo_UndoAvailable = &Undo_UndoAvailable; // Nurail + pUndoTable->m_pfnUndo_RedoAvailable = &Undo_RedoAvailable; // Nurail + + return true; + } + if (!strcmp(pAPI->major_name, CAMERA_MAJOR)) + { + _QERCameraTable *pCameraTable = static_cast<_QERCameraTable *>(pAPI->mpTable); + + pCameraTable->m_pfnGetCamera = &QERApp_GetCamera; + pCameraTable->m_pfnSetCamera = &QERApp_SetCamera; + pCameraTable->m_pfnGetCamWindowExtents = &QERApp_GetCamWindowExtents; + + return true; + } + if (!strcmp(pAPI->major_name, UI_MAJOR)) + { + _QERUITable *pUITable = static_cast<_QERUITable *>(pAPI->mpTable); + + pUITable->m_pfnCreateGLWindow = QERApp_CreateGLWindow; + pUITable->m_pfnHookWindow = QERApp_HookWindow; + pUITable->m_pfnUnHookWindow = QERApp_UnHookWindow; + pUITable->m_pfnGetXYWndWrapper = QERApp_GetXYWndWrapper; + pUITable->m_pfnHookListener = QERApp_HookListener; + pUITable->m_pfnUnHookListener = QERApp_UnHookListener; + + return true; + } + if (!strcmp(pAPI->major_name, UIGTK_MAJOR)) + { + _QERUIGtkTable *pUIGtkTable = static_cast<_QERUIGtkTable *>(pAPI->mpTable); + + pUIGtkTable->m_pfn_GetQeglobalsGLWidget = &QERApp_GetQeGlobalsGLWidget; + pUIGtkTable->m_pfn_glwidget_new = >k_glwidget_new; + pUIGtkTable-> m_pfn_glwidget_swap_buffers = >k_glwidget_swap_buffers; + pUIGtkTable->m_pfn_glwidget_make_current = >k_glwidget_make_current; + pUIGtkTable->m_pfn_glwidget_destroy_context = >k_glwidget_destroy_context; + pUIGtkTable->m_pfn_glwidget_create_context = >k_glwidget_create_context; +#if 0 + pUIGtkTable->m_pfn_glwidget_get_context = >k_glwidget_get_context; +#endif + + return true; + } + + return false; +} + +const char* CSynapseClientRadiant::GetInfo() +{ + return "Radiant - synapse core built " __DATE__ " " RADIANT_VERSION; +} + +const char* CSynapseClientRadiant::GetName() { + return "core"; }