2 Copyright (C) 2002 Dominic Clifton.
4 This file is part of GtkRadiant.
6 GtkRadiant is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 GtkRadiant is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GtkRadiant; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 // Sprite Model Plugin
24 // Code by Hydra aka Dominic Clifton
26 // Based on MD3Model source code by SPoG
37 It allows the user to see a graphical representation of the entity in the 3D view (maybe 2D views later) where the entity would just otherwise be a non-descriptive coloured box.
39 It is designed to be used with the entity view set to WireFrame (as the sprite images are rendered in the middle of the entity's bbox.
44 Implemented as a model module, without any ISelect stuff.
46 For an entity to use an image (instead of a model) you just update the entity defintion file so that the eclass_t's modelpath is filled in with a relative path and filename of an image file.
50 baseq3/scripts/entities.def
51 ===========================
53 \/\*QUAKED ammo_bfg (.3 .3 1) (-16 -16 -16) (16 16 16) SUSPENDED
55 -------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
56 model="sprites/powerups/ammo/bfgam.bmp"\*\/
59 valve/scripts/halflife.fgd
60 ==========================
62 @PointClass iconsprite("sprites/lightbulb.spr") base(Target, Targetname, Light) = light : "Invisible lightsource"
67 What image formats are supported ?
68 ----------------------------------
70 This module can load any image format that there is an active image module for. For q3 this would be bmp, tga and jpg. For Half-Life this would be hlw and spr.
76 - Created an inital implementation of a sprite model plugin.
77 According to the powers that be, it seems creating a model
79 It works ok, but there is no way to attach models (sprites if you will)
80 to non-fixedsize entities (like func_bombtarget)
81 Also, I can't get the alpha map stuff right so I had to invert the alpha
82 mask in the spr loader so that 0xff = not drawn pixel.
87 * make sprites always face the camera (is this done in camwindow.cpp ?)
89 * maybe add an option to scale the sprites in the prefs ?
91 * un-hack the default fall-though to "sprite" model version (see m_version)
93 * maybe convert to a new kind of class not based on model.
95 * allow sprites on non-fixedsize ents
97 * fix reversed alpha map in spr loader
99 * allow an entity to have both an .md? and a sprite model.
103 #include "spritemodel.h"
105 // =============================================================================
109 _QERFuncTable_1 __QERTABLENAME;
110 OpenGLBinding g_QglTable;
111 _QERShadersTable g_ShadersTable;
113 // =============================================================================
119 char *supportedmodelformats[] = {"spr","bmp","tga","jpg","hlw",NULL}; // NULL is list delimiter
121 static void add_model_apis(CSynapseClient& client)
124 for (ext = supportedmodelformats; *ext != NULL; ext++)
126 client.AddAPI(MODEL_MAJOR, *ext, sizeof(_QERPlugModelTable));
130 static bool model_is_supported(const char* extension)
133 for (ext = supportedmodelformats; *ext != NULL; ext++)
135 if (stricmp(extension,*ext)==0)
141 void init_filetypes()
144 for (ext = supportedmodelformats; *ext != NULL; ext++)
146 GetFileTypeRegistry()->addType(MODEL_MAJOR, filetype_t("sprite", *ext));
150 extern CSynapseServer* g_pSynapseServer;
152 class CSynapseClientModel : public CSynapseClient
155 // CSynapseClient API
156 bool RequestAPI(APIDescriptor_t *pAPI);
157 const char* GetInfo();
158 const char* GetName();
160 CSynapseClientModel() { }
161 virtual ~CSynapseClientModel() { }
165 init_filetypes(); // see todo list above.
170 CSynapseServer* g_pSynapseServer = NULL;
171 CSynapseClientModel g_SynapseClient;
173 extern "C" CSynapseClient* SYNAPSE_DLL_EXPORT Synapse_EnumerateInterfaces (const char *version, CSynapseServer *pServer)
175 if (strcmp(version, SYNAPSE_VERSION))
177 Syn_Printf("ERROR: synapse API version mismatch: should be '" SYNAPSE_VERSION "', got '%s'\n", version);
180 g_pSynapseServer = pServer;
181 g_pSynapseServer->IncRef();
182 Set_Syn_Printf(g_pSynapseServer->Get_Syn_Printf());
184 add_model_apis(g_SynapseClient); // see todo list above.
186 g_SynapseClient.AddAPI( PLUGIN_MAJOR, "sprite", sizeof( _QERPluginTable ) );
187 g_SynapseClient.AddAPI( RADIANT_MAJOR, NULL, sizeof( g_FuncTable ), SYN_REQUIRE, &g_FuncTable );
188 g_SynapseClient.AddAPI( QGL_MAJOR, NULL, sizeof( g_QglTable ), SYN_REQUIRE, &g_QglTable );
189 g_SynapseClient.AddAPI( SHADERS_MAJOR, "*", sizeof( g_ShadersTable ), SYN_REQUIRE, &g_ShadersTable );
191 return &g_SynapseClient;
194 bool CSynapseClientModel::RequestAPI(APIDescriptor_t *pAPI)
196 if (!strcmp(pAPI->major_name, MODEL_MAJOR))
198 _QERPlugModelTable* pTable= static_cast<_QERPlugModelTable*>(pAPI->mpTable);
200 if (!strcmp(pAPI->minor_name, "sprite"))
202 pTable->m_pfnLoadModel = &LoadSpriteModel;
207 Syn_Printf("ERROR: RequestAPI( '%s' ) not found in '%s'\n", pAPI->major_name, GetInfo());
213 const char* CSynapseClientModel::GetInfo()
215 return "Sprite Model module built " __DATE__ " " RADIANT_VERSION;
218 const char* CSynapseClientModel::GetName()