1 /*
2      PLIB - A Suite of Portable Game Libraries
3      Copyright (C) 1998,2002  Steve Baker
4 
5      This library is free software; you can redistribute it and/or
6      modify it under the terms of the GNU Library General Public
7      License as published by the Free Software Foundation; either
8      version 2 of the License, or (at your option) any later version.
9 
10      This library is distributed in the hope that it will be useful,
11      but WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      Library General Public License for more details.
14 
15      You should have received a copy of the GNU Library General Public
16      License along with this library; if not, write to the Free Software
17      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18 
19      For further information visit http://plib.sourceforge.net
20 
21 */
22 
23 #include "ssg.h"
24 #include "ssgAux.h"
25 
26 #define EMBER_SCALE  3.0f
27 
_ssgaFireParticleCreate(ssgaParticleSystem * ps,int idx,ssgaParticle * p)28 void _ssgaFireParticleCreate ( ssgaParticleSystem *ps,
29                                int idx, ssgaParticle *p )
30 {
31   ((ssgaFire *) ps) -> createParticle ( idx, p ) ;
32 }
33 
34 
35 
_ssgaFireParticleUpdate(float,ssgaParticleSystem * ps,int idx,ssgaParticle * p)36 void _ssgaFireParticleUpdate ( float, ssgaParticleSystem *ps,
37                                int idx, ssgaParticle *p )
38 {
39   ((ssgaFire *) ps) -> updateParticle ( idx, p ) ;
40 }
41 
42 
43 
44 
reInit()45 void ssgaFire::reInit ()
46 {
47   setCreationRate ( (float)(getNumParticles()) / max_ttl ) ;
48 
49   delete colourTable ;
50   delete sizeTable   ;
51 
52   tableSize = (int)( 10.0f * max_ttl ) ;
53 
54   colourTable = new float [ tableSize * 4 ] ;
55   sizeTable   = new float [ tableSize     ] ;
56 
57   sgCopyVec4 ( & colourTable [ 0 ], hot_colour ) ;
58   sizeTable [ 0 ] = start_size ;
59 
60   for ( int i = 1 ; i < tableSize ; i++ )
61   {
62     sizeTable [ i ] = sizeTable [ i-1 ] * 1.06f ;
63 
64     if ( sizeTable [ i ] >= 1.5 ) sizeTable [ i ] = 1.5 ;
65 
66     sgScaleVec3 ( & colourTable [   i  * 4 ],
67 		  & colourTable [ (i-1)* 4 ], 0.90f ) ;
68 
69     colourTable [ i * 4 + 3 ] = 1.0f ;
70   }
71 }
72 
73 
createParticle(int idx,ssgaParticle * p)74 void ssgaFire::createParticle ( int idx, ssgaParticle *p )
75 {
76   float xx = (float)(rand()%1000)/500.0f * radius - radius ;
77   float yy = (float)sqrt ( radius * radius - xx * xx ) ;
78 
79   yy = (float)(rand()%1000)/500.0f * yy - yy ;
80 
81   p -> time_to_live = max_ttl ;
82   p -> size = sizeTable [ 0 ] ;
83 
84   sgCopyVec4 ( p -> col, & colourTable [ 0 ] ) ;
85 
86   if ( (idx & 3) != 0 )
87   {
88     sgSetVec3 ( p -> pos, xx, yy, -p->size ) ;
89     sgSetVec3 ( p -> vel, 0, 0, upward_speed ) ;
90   }
91   else
92   {
93     p->size *= EMBER_SCALE ;
94 
95     sgSetVec3 ( p -> pos, xx, yy, 0.0f ) ;
96     sgSetVec3 ( p -> vel, 0, 0, 0 ) ;
97   }
98 
99   sgSetVec3 ( p -> acc, 0, 0, 0 ) ;
100 }
101 
102 
103 
104 
updateParticle(int idx,ssgaParticle * p)105 void ssgaFire::updateParticle ( int idx, ssgaParticle *p )
106 {
107   int tick = (int)( ( max_ttl - p->time_to_live ) * 10.0f ) ;
108 
109   if ( tick >= tableSize )
110   {
111     p->time_to_live = 0.0f ;
112     return ;
113   }
114 
115   if ( (idx & 3) != 0 )
116     p -> size = sizeTable [ tick ] ;
117   else
118     p -> size = sizeTable [ tick ] * EMBER_SCALE ;
119 
120   sgCopyVec4 ( p -> col, & colourTable [ tick * 4 ] ) ;
121 }
122 
123 
124 static ssgSimpleState *fireState   = NULL ;
125 static ssgTexture     *fireTexture = NULL ;
126 static bool            isfogged    = true ;
preFireDraw(ssgEntity *)127 static int preFireDraw ( ssgEntity * )
128 {
129   isfogged = ( glIsEnabled ( GL_FOG ) == GL_TRUE ) ;
130 
131   if ( isfogged )
132     glDisable ( GL_FOG ) ;
133 
134   glBlendFunc ( GL_ONE, GL_ONE ) ;
135   return TRUE ;
136 }
137 
138 
postFireDraw(ssgEntity *)139 static int postFireDraw ( ssgEntity * )
140 {
141   glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
142 
143   if ( isfogged )
144     glEnable ( GL_FOG ) ;
145 
146   return TRUE ;
147 }
148 
ssgaFire(int num,float _radius,float height,float speed)149 ssgaFire::ssgaFire ( int num,
150                      float _radius,
151                      float height,
152                      float speed )
153             : ssgaParticleSystem ( num/2,
154                                   0, 0,             // <== Don't Change this!!
155                                   TRUE, 1.0f, height * 2.0f,
156                                   _ssgaFireParticleCreate,
157                                   _ssgaFireParticleUpdate )
158 {
159   radius = _radius ;
160   upward_speed = speed ;
161   start_size = 0.6f ;
162 
163   if ( fireState == NULL )
164   {
165     /*
166       The texture constructor deletes the texture from
167       main memory after it's finished with it!!  YIKES!!
168     */
169 
170     unsigned char *t = new unsigned char [ 32 * 32 ] ;
171     memcpy ( t, _ssgaGetFireTexture(), 32 * 32 ) ;
172 
173     fireTexture = new ssgTexture ( "NONE", t, 32, 32, 1 ) ;
174 
175     fireState = new ssgSimpleState () ;
176     fireState -> setTexture        ( fireTexture ) ;
177     fireState -> setTranslucent    () ;
178     fireState -> enable            ( GL_TEXTURE_2D ) ;
179     fireState -> enable            ( GL_BLEND ) ;
180     fireState -> disable           ( GL_LIGHTING ) ;
181     fireState -> ref () ;
182   }
183 
184 
185   tableSize   = 0 ;
186   colourTable = NULL ;
187   sizeTable   = NULL ;
188 
189   sgSetVec4 ( hot_colour, 1.0f, 0.2f, 0.1f, 1.0f ) ;
190 
191   setHeight ( height ) ;  /* Forces a reInit */
192 
193   setState    ( fireState ) ;
194   setCallback ( SSG_CALLBACK_PREDRAW , preFireDraw  ) ;
195   setCallback ( SSG_CALLBACK_POSTDRAW, postFireDraw ) ;
196   update ( 2.0f * max_ttl / (float)(getNumParticles()) ) ;
197 }
198 
update(float t)199 void ssgaFire::update ( float t )
200 {
201   ssgaParticleSystem::update ( t ) ;
202 }
203 
204 
205 unsigned char *_ssgaGetFireTexture () ;
206 
207 
~ssgaFire()208 ssgaFire::~ssgaFire ()
209 {
210   tableSize   = 0 ;
211   delete [] colourTable ;
212   delete [] sizeTable   ;
213 }
214 
215 
216 
217 
218 static unsigned char fuzzyBlob [] =
219 {
220   0,0,0,0,0,0,0,0,0,0,0,0,1,3,4,5,5,4,3,1,0,0,0,0,0,0,0,0,0,0,0,0,
221   0,0,0,0,0,0,0,0,0,1,5,9,14,17,19,20,20,20,17,14,10,5,1,0,0,0,0,0,0,0,0,0,
222   0,0,0,0,0,0,0,1,5,12,19,25,29,33,35,36,37,36,33,30,25,20,13,6,1,0,0,0,0,0,0,0,
223   0,0,0,0,0,0,2,10,19,27,34,40,45,48,51,52,53,51,49,45,40,35,28,20,11,3,0,0,0,0,0,0,
224   0,0,0,0,0,4,13,23,33,41,48,55,60,64,67,69,69,67,65,61,56,49,42,34,25,15,5,0,0,0,0,0,
225   0,0,0,0,4,14,26,36,46,55,63,70,75,80,83,85,85,83,80,76,70,64,56,47,37,27,16,5,0,0,0,0,
226   0,0,0,2,13,26,37,48,59,68,77,84,91,95,99,101,101,99,96,91,85,78,69,60,50,39,27,15,3,0,0,0,
227   0,0,1,10,23,36,48,60,71,81,90,99,105,111,115,117,117,115,111,106,100,92,82,72,61,50,38,25,12,1,0,0,
228   0,0,5,19,33,46,59,71,83,94,104,113,120,126,130,133,133,131,127,121,114,105,95,84,72,60,47,34,21,7,0,0,
229   0,1,12,27,41,55,68,81,94,105,116,126,134,141,146,149,149,147,142,135,127,118,107,95,83,70,56,43,29,14,2,0,
230   0,5,19,34,48,63,77,90,104,116,128,139,148,156,162,165,165,162,157,149,140,129,118,105,92,78,64,50,36,21,6,0,
231   0,9,25,40,55,70,84,99,113,126,139,151,161,170,177,181,181,178,171,163,152,140,128,114,100,86,72,57,42,27,11,0,
232   1,14,29,45,60,75,91,105,120,134,148,161,173,184,192,196,197,193,185,175,163,150,136,122,107,92,77,62,47,31,16,2,
233   3,17,33,48,64,80,95,111,126,141,156,170,184,196,206,212,212,207,197,185,172,158,143,128,113,97,82,66,50,35,19,4,
234   4,19,35,51,67,83,99,115,130,146,162,177,192,206,219,227,228,220,208,194,179,163,148,132,117,101,85,69,53,37,21,5,
235   5,20,36,52,69,85,101,117,133,149,165,181,196,212,227,241,242,229,214,198,182,167,151,135,119,103,87,71,54,38,22,6,
236   5,20,37,53,69,85,101,117,133,149,165,181,197,212,228,242,243,230,214,199,183,167,151,135,119,103,87,71,55,39,22,6,
237   4,20,36,51,67,83,99,115,131,147,162,178,193,207,220,229,230,221,209,194,179,164,148,133,117,101,85,69,53,38,22,6,
238   3,17,33,49,65,80,96,111,127,142,157,171,185,197,208,214,214,209,199,187,173,159,144,129,113,98,82,67,51,35,19,4,
239   1,14,30,45,61,76,91,106,121,135,149,163,175,185,194,198,199,194,187,176,164,151,137,123,108,93,78,63,47,32,16,2,
240   0,10,25,40,56,70,85,100,114,127,140,152,163,172,179,182,183,179,173,164,154,142,129,115,101,87,72,57,42,27,12,1,
241   0,5,20,35,49,64,78,92,105,118,129,140,150,158,163,167,167,164,159,151,142,131,119,106,93,79,65,51,36,22,7,0,
242   0,1,13,28,42,56,69,82,95,107,118,128,136,143,148,151,151,148,144,137,129,119,108,96,84,71,57,44,30,15,2,0,
243   0,0,6,20,34,47,60,72,84,95,105,114,122,128,132,135,135,133,129,123,115,106,96,85,74,61,49,35,22,8,0,0,
244   0,0,1,11,25,37,50,61,72,83,92,100,107,113,117,119,119,117,113,108,101,93,84,74,63,51,39,26,13,2,0,0,
245   0,0,0,3,15,27,39,50,60,70,78,86,92,97,101,103,103,101,98,93,87,79,71,61,51,40,28,16,4,0,0,0,
246   0,0,0,0,5,16,27,38,47,56,64,72,77,82,85,87,87,85,82,78,72,65,57,49,39,28,17,6,0,0,0,0,
247   0,0,0,0,0,5,15,25,34,43,50,57,62,66,69,71,71,69,67,63,57,51,44,35,26,16,6,0,0,0,0,0,
248   0,0,0,0,0,0,3,12,21,29,36,42,47,50,53,54,55,53,51,47,42,36,30,22,13,4,0,0,0,0,0,0,
249   0,0,0,0,0,0,0,1,7,14,21,27,31,35,37,38,39,38,35,32,27,22,15,8,2,0,0,0,0,0,0,0,
250   0,0,0,0,0,0,0,0,0,2,6,11,16,19,21,22,22,22,19,16,12,7,2,0,0,0,0,0,0,0,0,0,
251   0,0,0,0,0,0,0,0,0,0,0,0,2,4,5,6,6,6,4,2,1,0,0,0,0,0,0,0,0,0,0,0
252 } ;
253 
254 
_ssgaGetFireTexture()255 unsigned char *_ssgaGetFireTexture () { return fuzzyBlob ; }
256 
257