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++) {
125 client.AddAPI(MODEL_MAJOR, *ext, sizeof(_QERPlugModelTable));
129 static bool model_is_supported(const char *extension)
132 for (ext = supportedmodelformats; *ext != NULL; ext++) {
133 if (stricmp(extension, *ext) == 0) {
140 void init_filetypes()
143 for (ext = supportedmodelformats; *ext != NULL; ext++) {
144 GetFileTypeRegistry()->addType(MODEL_MAJOR, filetype_t("sprite", *ext));
148 extern CSynapseServer *g_pSynapseServer;
150 class CSynapseClientModel : public CSynapseClient {
152 // CSynapseClient API
153 bool RequestAPI(APIDescriptor_t *pAPI);
155 const char *GetInfo();
157 const char *GetName();
159 CSynapseClientModel()
162 virtual ~CSynapseClientModel()
167 init_filetypes(); // see todo list above.
172 CSynapseServer *g_pSynapseServer = NULL;
173 CSynapseClientModel g_SynapseClient;
175 extern "C" CSynapseClient *SYNAPSE_DLL_EXPORT
177 Synapse_EnumerateInterfaces(const char *version, CSynapseServer *pServer)
179 if (strcmp(version, SYNAPSE_VERSION)) {
180 Syn_Printf("ERROR: synapse API version mismatch: should be '"
182 "', got '%s'\n", version );
185 g_pSynapseServer = pServer;
186 g_pSynapseServer->IncRef();
187 Set_Syn_Printf(g_pSynapseServer->Get_Syn_Printf());
189 add_model_apis(g_SynapseClient); // see todo list above.
191 g_SynapseClient.AddAPI(PLUGIN_MAJOR, "sprite", sizeof(_QERPluginTable));
192 g_SynapseClient.AddAPI(RADIANT_MAJOR, NULL, sizeof(g_FuncTable), SYN_REQUIRE, &g_FuncTable);
193 g_SynapseClient.AddAPI(QGL_MAJOR, NULL, sizeof(g_QglTable), SYN_REQUIRE, &g_QglTable);
194 g_SynapseClient.AddAPI(SHADERS_MAJOR, "*", sizeof(g_ShadersTable), SYN_REQUIRE, &g_ShadersTable);
196 return &g_SynapseClient;
199 bool CSynapseClientModel::RequestAPI(APIDescriptor_t *pAPI)
201 if (!strcmp(pAPI->major_name, MODEL_MAJOR)) {
202 _QERPlugModelTable *pTable = static_cast<_QERPlugModelTable *>( pAPI->mpTable );
204 if (!strcmp(pAPI->minor_name, "sprite")) {
205 pTable->m_pfnLoadModel = &LoadSpriteModel;
210 Syn_Printf("ERROR: RequestAPI( '%s' ) not found in '%s'\n", pAPI->major_name, GetInfo());
216 const char *CSynapseClientModel::GetInfo()
218 return "Sprite Model module built " __DATE__ " "
222 const char *CSynapseClientModel::GetName()