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 ){
123 for ( ext = supportedmodelformats; *ext != NULL; ext++ )
125 client.AddAPI( MODEL_MAJOR, *ext, sizeof( _QERPlugModelTable ) );
129 static bool model_is_supported( const char* extension ){
131 for ( ext = supportedmodelformats; *ext != NULL; ext++ )
133 if ( stricmp( extension,*ext ) == 0 ) {
140 void init_filetypes(){
142 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
153 // CSynapseClient API
154 bool RequestAPI( APIDescriptor_t *pAPI );
155 const char* GetInfo();
156 const char* GetName();
158 CSynapseClientModel() { }
159 virtual ~CSynapseClientModel() { }
162 init_filetypes(); // see todo list above.
167 CSynapseServer* g_pSynapseServer = NULL;
168 CSynapseClientModel g_SynapseClient;
170 extern "C" CSynapseClient * SYNAPSE_DLL_EXPORT Synapse_EnumerateInterfaces( const char *version, CSynapseServer *pServer ){
171 if ( strcmp( version, SYNAPSE_VERSION ) ) {
172 Syn_Printf( "ERROR: synapse API version mismatch: should be '" SYNAPSE_VERSION "', got '%s'\n", version );
175 g_pSynapseServer = pServer;
176 g_pSynapseServer->IncRef();
177 Set_Syn_Printf( g_pSynapseServer->Get_Syn_Printf() );
179 add_model_apis( g_SynapseClient ); // see todo list above.
181 g_SynapseClient.AddAPI( PLUGIN_MAJOR, "sprite", sizeof( _QERPluginTable ) );
182 g_SynapseClient.AddAPI( RADIANT_MAJOR, NULL, sizeof( g_FuncTable ), SYN_REQUIRE, &g_FuncTable );
183 g_SynapseClient.AddAPI( QGL_MAJOR, NULL, sizeof( g_QglTable ), SYN_REQUIRE, &g_QglTable );
184 g_SynapseClient.AddAPI( SHADERS_MAJOR, "*", sizeof( g_ShadersTable ), SYN_REQUIRE, &g_ShadersTable );
186 return &g_SynapseClient;
189 bool CSynapseClientModel::RequestAPI( APIDescriptor_t *pAPI ){
190 if ( !strcmp( pAPI->major_name, MODEL_MAJOR ) ) {
191 _QERPlugModelTable* pTable = static_cast<_QERPlugModelTable*>( pAPI->mpTable );
193 if ( !strcmp( pAPI->minor_name, "sprite" ) ) {
194 pTable->m_pfnLoadModel = &LoadSpriteModel;
199 Syn_Printf( "ERROR: RequestAPI( '%s' ) not found in '%s'\n", pAPI->major_name, GetInfo() );
203 const char* CSynapseClientModel::GetInfo(){
204 return "Sprite Model module built " __DATE__ " " RADIANT_VERSION;
207 const char* CSynapseClientModel::GetName(){