1 /*--License:
2 Kyra Sprite Engine
3 Copyright Lee Thomason (Grinning Lizard Software) 2001-2005
4 www.grinninglizard.com/kyra
5 www.sourceforge.net/projects/kyra
6
7 Kyra is provided under the LGPL.
8
9 I kindly request you display a splash screen (provided in the HTML documentation)
10 to promote Kyra and acknowledge the software and everyone who has contributed to it,
11 but it is not required by the license.
12
13 --- LGPL License --
14
15 This library is free software; you can redistribute it and/or
16 modify it under the terms of the GNU Lesser General Public
17 License as published by the Free Software Foundation; either
18 version 2.1 of the License, or (at your option) any later version.
19
20 This library is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 Lesser General Public License for more details.
24
25 You should have received a copy of the GNU Lesser General Public
26 License along with this library; if not, write to the Free Software
27 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28
29 The full text of the license can be found in lgpl.txt
30 */
31
32
33
34 #include "demos.h"
35 #include <math.h>
36
37 using namespace grinliz;
38
SinWaveTest(SDL_Surface * screen)39 SinWaveTest::SinWaveTest( SDL_Surface* screen )
40 {
41 // The usual beginning: create the engine, load the dat file.
42 engine = new KrEngine( screen );
43 GLASSERT( engine );
44 engine->FillBackground( 0 );
45
46 random.SetSeed( 0 );
47
48 if ( !engine->Vault()->LoadDatFile( "space.dat" ) )
49 {
50 GLOUTPUT(( "Error loading 'space.dat'\n" ));
51 exit(100);
52 }
53
54 // Get the resource from the dat file: we use the small
55 // ship and the train ship.
56 KrSpriteResource* smallRes = engine->Vault()->GetSpriteResource( "SMALL" );
57 GLASSERT( smallRes );
58 KrSpriteResource* trainRes = engine->Vault()->GetSpriteResource( "TRAIN" );
59 GLASSERT( trainRes );
60
61 // A background starfield - same as the BEM one.
62 AddStarfield();
63
64
65 // Set up the horizontal ships.
66 int i = 0, j = 0;
67
68 for( i=0; i<MAX_HORIZONTAL_SHIP; ++i )
69 {
70 horizontal[0][i] = new KrSprite( smallRes );
71 horizontal[0][i]->SetPos( -PADDING + i * ( engine->ScreenBounds().Width() + PADDING * 2 ) / MAX_HORIZONTAL_SHIP,
72 1 * engine->ScreenBounds().Height() / 4 );
73 engine->Tree()->AddNode( 0, horizontal[0][i] );
74
75
76 horizontal[1][i] = new KrSprite( smallRes );
77 horizontal[1][i]->SetPos( -PADDING + i * ( engine->ScreenBounds().Width() + PADDING * 2 ) / MAX_HORIZONTAL_SHIP,
78 3 * engine->ScreenBounds().Height() / 4 );
79 engine->Tree()->AddNode( 0, horizontal[1][i] );
80 }
81
82
83 // Add the trains
84 memset( vertical, 0, ROWS * (MAX_CARS + 2) * sizeof( KrSprite* ) );
85 const int SPACE = 52;
86 for ( i=0; i<ROWS; ++i )
87 {
88 // Engine
89 int x = GetX( i );
90 int y = random.Rand( engine->ScreenBounds().Height() );
91 vertical[i][0] = new KrSprite( trainRes );
92 vertical[i][0]->SetAction( "ENGINE" );
93 vertical[i][0]->SetPos( x, y );
94 engine->Tree()->AddNode( 0, vertical[i][0] );
95
96 // Cars
97 for ( j=0; j<MAX_CARS; ++j )
98 {
99 KrSprite* car = new KrSprite( trainRes );
100 car->SetAction( "CAR" );
101 car->SetPos( x, y + SPACE * ( j + 1 ) );
102 engine->Tree()->AddNode( 0, car );
103 vertical[i][1+j] = car;
104 }
105
106 // Caboose
107 KrSprite* caboose = new KrSprite( trainRes );
108 caboose->SetAction( "CABOOSE" );
109 caboose->SetPos( x, y + SPACE * ( MAX_CARS + 1 ) );
110 engine->Tree()->AddNode( 0, caboose );
111 vertical[i][1+MAX_CARS] = caboose;
112 }
113 AddText( engine );
114 }
115
116
~SinWaveTest()117 SinWaveTest::~SinWaveTest()
118 {
119 delete engine;
120 }
121
122
AddStarfield()123 void SinWaveTest::AddStarfield()
124 {
125 int x, y;
126 KrTileResource* starRes = engine->Vault()->GetTileResource( "STARS" );
127 GLASSERT( starRes );
128 KrRect field = engine->ScreenBounds();
129
130 for( x = field.min.x; x <= field.max.x; x += starRes->Size() )
131 {
132 for( y = field.min.y; y <= field.max.y; y += starRes->Size() )
133 {
134 KrTile* tile = new KrTile( starRes );
135 GLASSERT( tile );
136
137 tile->SetRotation( random.Rand( 8 ) );
138 tile->SetPos( x, y );
139 engine->Tree()->AddNode( 0, tile );
140 }
141 }
142 }
143
144
CalculateScale(int _y)145 double SinWaveTest::CalculateScale( int _y )
146 {
147 const double PI = 3.1415926535897932384626433832795;
148 double y = double( _y );
149 double screenH = double( engine->ScreenBounds().Height() );
150 double thetaRadians = ( y / screenH ) * PI;
151
152 double dScale = ( cos( thetaRadians ) * 0.5 + 1.0 ) * 0.8;
153 return dScale;
154 }
155
156
CalculateTintFromScale(double scale)157 int SinWaveTest::CalculateTintFromScale( double scale )
158 {
159 const double lowPoint = ( 0.4 * 0.8 );
160 const double highPoint = ( 1.5 * 0.8 );
161
162 int tint = int ( 180.0 + ( scale - lowPoint ) / ( highPoint - lowPoint ) * 75.0 );
163 Clamp( tint, 0, 255 );
164 return tint;
165 }
166
167
168
DrawFrame()169 void SinWaveTest::DrawFrame()
170 {
171 // Move the ships (based on current depth), set the new depth,
172 // and set the scaling factor.
173 KrSprite* sprite;
174 int i, j;
175
176 // The horizontal rows of ships.
177 for( i=0; i<2; ++i )
178 {
179 for ( j=0; j<MAX_HORIZONTAL_SHIP; j++ )
180 {
181 sprite = horizontal[i][j];
182 if ( sprite )
183 {
184 double dScale = ( i == 1 ) ? 1.2 : 0.4;
185 int deltaX = ( i == 0 ) ? 2 : 3;
186
187 sprite->SetPos( sprite->X() - deltaX, sprite->Y() );
188 if ( sprite->X() < -PADDING ) sprite->SetPos( engine->ScreenBounds().Width() + PADDING, sprite->Y() );
189
190 GlFixed scale = dScale;
191 sprite->SetScale( scale, scale );
192 sprite->SetZDepth( scale.v );
193
194 KrColorTransform color;
195 int tint = CalculateTintFromScale( dScale );
196
197 color.Set( tint, 0, tint, 0, tint, 0, 255 );
198 sprite->SetColor( color );
199 }
200 }
201 }
202
203
204 // The trains.
205 for( i=0; i<ROWS; ++i )
206 {
207 for ( j=0; j<MAX_CARS + 2; j++ )
208 {
209 sprite = vertical[i][j];
210 if ( sprite )
211 {
212 int deltaY = 3;
213
214 sprite->SetPos( sprite->X(), sprite->Y() - deltaY );
215 if ( j == MAX_CARS + 1 && sprite->Y() < 0 )
216 {
217 for( int k=0; k<MAX_CARS+2; ++k )
218 {
219 vertical[i][k]->SetPos( vertical[i][k]->X(),
220 vertical[i][k]->Y() + engine->ScreenBounds().Height() * 2 );
221 }
222 }
223
224 // Recalc the scale based on the new position.
225 double dScale = CalculateScale( sprite->Y() );
226
227 GlFixed scale = dScale;
228 sprite->SetScale( scale, scale );
229 sprite->SetZDepth( scale.v );
230
231 KrColorTransform color;
232 int tint = CalculateTintFromScale( dScale );
233
234 color.Set( tint, 0, tint, 0, tint, 0, 255 );
235 sprite->SetColor( color );
236 }
237 }
238 }
239
240 engine->Draw();
241 }
242
243
GetY(int hIndex)244 int SinWaveTest::GetY( int hIndex )
245 {
246 return ( hIndex + 1 ) * engine->ScreenBounds().Height() / ( ROWS + 1 );
247 }
248
249
GetX(int vIndex)250 int SinWaveTest::GetX( int vIndex )
251 {
252 return ( vIndex + 1 ) * engine->ScreenBounds().Width() / ( ROWS + 1 );
253 }
254
255