Esempio n. 1
0
void BemGame::AddFloor()
{
	int i, j, x, y;
	KrResource* resource = engine->Vault()->GetResource( KYRATAG_SPRITE, BEM_ROOM | BEM_FLOOR );
	GLASSERT( resource );
	KrSpriteResource* spriteRes = resource->ToSpriteResource();
	GLASSERT( spriteRes );

	// The map is backwards. It is reference [y][x] and is upside
	// down to boot. *sigh*
	for( i=0; i<MAPX; i++ )
	{
		for( j=0; j<MAPY; j++ )
		{
			if ( GetMap( i, j ) == FLOOR )
			{
				KrSprite* sprite = new KrSprite( spriteRes );
				isoMath->TileToScreen( i, j, 0, &x, &y );
				sprite->SetPos( x, y );

				sprite->SetActionRotated( "NONE", ((i+j)%4) * 90 );

				// So much for abstraction.
				if ( ( j == 2 || j == 9 ) &&
					 ( i == 4 || i == 7 ) )
					sprite->SetFrame( 1 );
				else
					sprite->SetFrame( 0 );
				engine->Tree()->AddNode( floorTree, sprite );
			}
		}
	}
}
Esempio n. 2
0
void EdStateMovie::ZoomOut()
{
	GlFixed scale = movieNode->XScale();
	if ( scale.v > GlFixed_1 / 4 )
	{
		scale /= 2;
		movieNode->SetScale( scale, scale );


		KrImNode* image = shared->Engine()->Tree()->FindNodeById( 0 );
		GLASSERT( image );
		KrSprite* sprite = image->ToSprite();
		GLASSERT( sprite );

		shared->Engine()->Tree()->Walk();

		//int x = sprite->CompositeXForm(0).x.ToInt();
		//int y = sprite->CompositeXForm(0).y.ToInt();
		KrRect screen = shared->Engine()->ScreenBounds();
		GlFixed scale = movieNode->XScale();
		GlFixed inverse = GlFixed( 1 ) / scale;

		sprite->SetPos( (inverse * screen.Width()).ToInt() / 2, (inverse*screen.Height()).ToInt()/2 );
	}
}
Esempio n. 3
0
KrCollisionMap* KrSpriteResource::GetCollisionMap( KrImage* state/*, int window*/ )
{
	GLASSERT( state && state->ToSprite() );
	KrSprite* sprite = state->ToSprite();
	GLASSERT( sprite->SpriteResource() == this );

	if ( state->XScale( /*window*/ ) != 1 || state->YScale( /*window*/ ) != 1 )
	{
		if ( !IsScaleCached( state->CompositeXForm( /*window*/ ).xScale,
							 state->CompositeXForm( /*window*/ ).yScale ) )
		{
			// For sprites, only cached scales can be used!
			/*#ifdef DEBUG
			GLOUTPUT( "ERROR: Collision only allowed with cahed sprites!\n" );
			GLOUTPUT( "SpriteResource '%s' for Action '%s' Frame %d scale %f, %f\n",
					  ResourceName().c_str(),
					  sprite->GetAction()->Name().c_str(),
					  sprite->Frame(),
					  state->CompositeXForm( window ).xScale.ToDouble(),
					  state->CompositeXForm( window ).xScale.ToDouble() );
			#endif*/
			GLASSERT( 0 );
			return 0;
		}
	}
	KrAction* action = sprite->GetAction();
	return action->GetCollisionMap( state->CompositeXForm( /*window*/ ).xScale,
									state->CompositeXForm( /*window*/ ).yScale,
									sprite->Frame() );
}
Esempio n. 4
0
void EdStateMovie::StateOpening()
{
	movieNode = new KrImNode();
	shared->Engine()->Tree()->AddNode( shared->ImNode(), movieNode );

	// Create the action, put it in a sprite resource.
	KrAction* movieAction = shared->CreateAnimationAction();
	if ( movieAction )
	{
		spriteResource = new KrSpriteResource(	"AlignerSprite" );
		spriteResource->AddAction( movieAction );

		numFrames = spriteResource->GetActionByIndex( 0 )->NumFrames();
	
		KrSprite* sprite = new KrSprite( spriteResource );
		sprite->SetFrame( 0 );
		sprite->SetNodeId( 0 );

		KrRect rect = shared->Engine()->ScreenBounds();
		sprite->SetPos( rect.Width()  / 2,
						rect.Height() / 2 );
		shared->Engine()->Tree()->AddNode( movieNode, sprite );
	}	
	shared->ConsoleNode()->SetVisible( false );	
	shared->SetInfoBox( false );
}
Esempio n. 5
0
void
Puzzle::setSolutionBrickWithIdx(const Brick* const b, unsigned int idx)
{
    if(bbc::debug) std::cerr << "Puzzle::setSolutionBrickWithIdx(" << b << "," << idx << "," << b->getSprite()->NodeId() << ")\n";

	assert(idx < m_width*m_height );

	KrSprite* s = b->getSprite();
	if( s )
	{
		if( !m_solution_tree ) {
			m_solution_tree = new KrImNode;
			assert(Brainblast::instance()->engine()->Tree());
			Brainblast::instance()->engine()->Tree()->AddNode(0, m_solution_tree);
			m_solution_tree->SetZDepth(SOLZ);
		}
		KrSprite* sprite = s->Clone()->ToSprite(); 
		Brick* nb = new Brick(sprite,b->id());
		Brainblast::instance()->engine()->Tree()->AddNode(m_solution_tree, sprite);
		int xspace = m_rect.w/m_width;
		int yspace = m_rect.h/m_height;
		nb->setPos(m_rect.x + (idx%m_width)*xspace+xspace/2,
				   m_rect.y + (idx/m_width)*yspace+yspace/2);
		m_solution[idx] = nb;
		m_total_solution_bricks++;
	}
}
Esempio n. 6
0
PyObject *
_wrap_sprite_num_frame (PyObject *self, PyObject *args)
{
	   PyObject *py_r;
	   
	   if (!PyArg_ParseTuple (args, "O:frame", &py_r)) return NULL;
	   GLASSERT (py_r && py_r != Py_None);
	   
	   KrSprite *r = AS_PTR (KrSprite, py_r);
	   GLASSERT (r);
	   
	   int frame = r->NumFrames();

	   return PyInt_FromLong (frame);
}
Esempio n. 7
0
PyObject *
_wrap_sprite_do_step (PyObject *self, PyObject *args)
{
	   PyObject *py_r;

	   if (!PyArg_ParseTuple (args, "O:do_step", &py_r)) return NULL;
	   GLASSERT (py_r && py_r != Py_None);
	   
	   KrSprite *r = AS_PTR (KrSprite, py_r);
	   GLASSERT (r);
	   
	   r->DoStep();

	   RETURN_NONE
}
Esempio n. 8
0
PyObject *
_wrap_sprite_set_frame (PyObject *self, PyObject *args)
{
	   PyObject *py_r;
	   int       frame;
	   
	   if (!PyArg_ParseTuple (args, "Oi:set_frame", &py_r, &frame)) return NULL;
	   GLASSERT (py_r && py_r != Py_None);
	   
	   KrSprite *r = AS_PTR (KrSprite, py_r);
	   GLASSERT (r);
	   
	   r->SetFrame(frame);

	   RETURN_NONE
}
Esempio n. 9
0
PyObject *
_wrap_sprite_get_action (PyObject *self, PyObject *args)
{
	   PyObject *py_r;
	   
	   if (!PyArg_ParseTuple (args, "O:get_action", &py_r)) return NULL;
	   GLASSERT (py_r && py_r != Py_None);
	   
	   KrSprite *r = AS_PTR (KrSprite, py_r);
	   GLASSERT (r);
	   
	   KrAction *action = r->GetAction();
	   GLASSERT (action);
	   
	   return PyCObject_FromVoidPtr (action, NULL);
}
Esempio n. 10
0
PyObject *
_wrap_sprite_set_action (PyObject *self, PyObject *args)
{
	   PyObject *py_r;
	   char     *action;
	   
	   if (!PyArg_ParseTuple (args, "Os:set_action", &py_r, &action)) return NULL;
	   GLASSERT (py_r && py_r != Py_None);
	   GLASSERT (action);
	   
	   KrSprite *r = AS_PTR (KrSprite, py_r);
	   GLASSERT (r);
	   
	   r->SetAction(action);

	   RETURN_NONE
}
Esempio n. 11
0
PyObject *
_wrap_sprite_set_action_rotated (PyObject *self, PyObject *args)
{
	   PyObject *py_r;
	   char     *action;
	   int       degrees;
	   
	   if (!PyArg_ParseTuple (args, "Osi:set_action_rotated", &py_r, &action, &degrees)) return NULL;
	   GLASSERT (py_r && py_r != Py_None);
	   GLASSERT (action);
	   
	   KrSprite *r = AS_PTR (KrSprite, py_r);
	   GLASSERT (r);

	   r->SetActionRotated (action, degrees);

	   RETURN_NONE
}
Esempio n. 12
0
PyObject *
_wrap_sprite_del (PyObject *self, PyObject *args)
{
	   PyObject *py_r;

	   if (!PyArg_ParseTuple (args, "O:del", &py_r)) return NULL;

	   KrSprite *r = AS_PTR (KrSprite, py_r);
	   GLASSERT (r);

	   if (r->GetUserData() != KrSprite_TYPE) {
			 RETURN_NONE;
	   }

	   delete r;
	   
	   RETURN_1;
}
Esempio n. 13
0
PyObject *
_wrap_sprite_new (PyObject *self, PyObject *args)
{
	   PyObject *py_r;
	   
	   if (!PyArg_ParseTuple (args, "O:new", &py_r)) return NULL;
	   GLASSERT (py_r && py_r != Py_None);

	   KrSpriteResource *r = AS_PTR (KrSpriteResource, py_r);
	   GLASSERT (r);

	   KrSprite *s = new KrSprite (r);
	   GLASSERT (s);

	   s->SetUserData (KrSprite_TYPE);
	   
	   return PyCObject_FromVoidPtr (s, NULL);
}
Esempio n. 14
0
PyObject *
_wrap_sprite_get_bounding_box (PyObject *self, PyObject *args)
{
	   PyObject *py_e;
	   int       window;
	   
	   if (!PyArg_ParseTuple (args, "Oi:get_bounding_box", &py_e, &window)) return NULL;

	   KrSprite *e = AS_PTR (KrSprite, py_e);
	   GLASSERT (e);
	   
	   KrRect rect;
	   e->GetBoundingBox(&rect, window);

	   PyObject *t = PyTuple_New (4);
	   PyTuple_SetItem (t, 0, PyInt_FromLong (rect.xmin));
	   PyTuple_SetItem (t, 1, PyInt_FromLong (rect.ymin));
	   PyTuple_SetItem (t, 2, PyInt_FromLong (rect.xmax));
	   PyTuple_SetItem (t, 3, PyInt_FromLong (rect.ymax));

	   return t;
}
Esempio n. 15
0
TileTest::TileTest( SDL_Surface* _screen )
{
	drawn = false;
	screen = _screen;
	engine = new KrEngine( screen );
	//GLOUTPUT( "TileTest::TileTest\n" );
	engine->Validate();	// check validity

	int i, j;

	// Classes to hold other objects:
	engine->Vault()->LoadDatFile( "standardtest.dat" );

	KrTileResource* noAlphaRes = engine->Vault()->GetTileResource( "NOALPHA" );
	KrTileResource* alphaRes = engine->Vault()->GetTileResource( "ALPHA" );
	GLASSERT( noAlphaRes && alphaRes );

	// Transforms:
	KrColorTransform alphaCForm;
	alphaCForm.SetAlpha( 255 * 70 / 100 );

	KrColorTransform redCForm;
	redCForm.SetRed( 255 * 50 / 100, 127 );

	KrColorTransform blueCForm;
	blueCForm.SetBlue( 255 * 50 / 100, 127 );

	KrColorTransform greenAlphaCForm;
	greenAlphaCForm.SetGreen( 255 * 50 / 100, 127 );
	greenAlphaCForm.SetAlpha( 255 * 70 / 100 );

	KrColorTransform blueAlphaCForm;
	blueAlphaCForm.SetBlue( 255 * 50 / 100, 127 );
	blueAlphaCForm.SetAlpha( 255 * 70 / 100 );

	// Containers:
	KrImNode* c0 = new KrImNode;	// background
	KrImNode* c1 = new KrImNode;	// tiles
 	KrImNode* c2 = new KrImNode;	// canvas

	engine->Tree()->AddNode( 0, c0 );
	engine->Tree()->AddNode( c0, c1 );
	engine->Tree()->AddNode( c0, c2 );

	c1->SetPos(   0,   0 );
	c2->SetPos(	420,   0 );
	c1->SetZDepth( 1 );
	c2->SetZDepth( 1 );

	// ---------- Background ----------- //
	KrSpriteResource* backSpriteRes = engine->Vault()->GetSpriteResource( "BACKGROUND" );
	GLASSERT( backSpriteRes );
	KrAction* action = backSpriteRes->GetActionByIndex( 0 );
	GLASSERT( action );
	const KrRle& rle = action->Frame( 0 );

	for ( i=0; i <= (screen->w) / rle.Width(); i++ )
	{
		for ( j=0; j <= (screen->h) / rle.Height(); j++ )
		{
			KrSprite* sprite = new KrSprite( backSpriteRes );
			sprite->SetPos( i*rle.Width(), j*rle.Height() );
			GLASSERT( sprite );
			engine->Tree()->AddNode( c0, sprite );
		}
	}

	// ---------- The "no alpha" tile.
	// no transform:
	for ( i=0; i<8; i++ )
	{
		noAlpha[i][0] = new KrTile( noAlphaRes );
		noAlpha[i][0]->SetPos( i*noAlpha[i][0]->Size(), 0 );
		noAlpha[i][0]->SetRotation( i );
		GLASSERT( noAlpha );
		engine->Tree()->AddNode( c1, noAlpha[i][0] );
	}

	// alpha:
	for ( i=0; i<8; i++ )
	{
		noAlpha[i][1] = new KrTile( noAlphaRes );
		noAlpha[i][1]->SetColor( alphaCForm );
		noAlpha[i][1]->SetPos( i*noAlpha[i][1]->Size(), 1*noAlpha[i][1]->Size() );
		noAlpha[i][1]->SetRotation( i );
		GLASSERT( noAlpha[i][1] );
		engine->Tree()->AddNode( c1, noAlpha[i][1] );
	}

	// red:
	for ( i=0; i<8; i++ )
	{
		noAlpha[i][2] = new KrTile( noAlphaRes );
		noAlpha[i][2]->SetColor( redCForm );
		noAlpha[i][2]->SetPos( i*noAlpha[i][2]->Size(), 2*noAlpha[i][2]->Size() );
		noAlpha[i][2]->SetRotation( i );
		GLASSERT( noAlpha[i][2] );
		engine->Tree()->AddNode( c1, noAlpha[i][2] );
	}

	// combination:
	for ( i=0; i<8; i++ )
	{
		noAlpha[i][3] = new KrTile( noAlphaRes );
		noAlpha[i][3]->SetColor( blueAlphaCForm );
		noAlpha[i][3]->SetPos( i*noAlpha[i][3]->Size(), 3*noAlpha[i][3]->Size() );
		noAlpha[i][3]->SetRotation( i );
		GLASSERT( noAlpha );
		engine->Tree()->AddNode( c1, noAlpha[i][3] );
	}

	// ---------- The "alpha" tile.
	// no transform:
	for ( i=0; i<8; i++ )
	{
// 		i=6;
		alpha[i][0] = new KrTile( alphaRes );
		alpha[i][0]->SetPos( i*alpha[i][0]->Size(), 4*alpha[i][0]->Size() );
		alpha[i][0]->SetRotation( i );
		GLASSERT( alpha[i][0] );
		engine->Tree()->AddNode( c1, alpha[i][0] );
	}

	// alpha:
	for ( i=0; i<8; i++ )
	{
		alpha[i][1] = new KrTile( alphaRes );
		alpha[i][1]->SetColor( alphaCForm );
		alpha[i][1]->SetPos( i*alpha[i][1]->Size(), 5*alpha[i][1]->Size() );
		alpha[i][1]->SetRotation( i );
		GLASSERT( alpha[i][1] );
		engine->Tree()->AddNode( c1, alpha[i][1] );
	}

	// red:
	for ( i=0; i<8; i++ )
	{
		alpha[i][2] = new KrTile( alphaRes );
		alpha[i][2]->SetColor( redCForm );
		alpha[i][2]->SetPos( i*alpha[i][2]->Size(), 6*alpha[i][2]->Size() );
		alpha[i][2]->SetRotation( i );
		GLASSERT( alpha[i][2] );
		engine->Tree()->AddNode( c1, alpha[i][2] );
	}

	// combination:
	for ( i=0; i<8; i++ )
	{
		alpha[i][3] = new KrTile( alphaRes );
		alpha[i][3]->SetColor( blueAlphaCForm );
		alpha[i][3]->SetPos( i*alpha[i][3]->Size(), 7*alpha[i][3]->Size() );
		alpha[i][3]->SetRotation( i );
		GLASSERT( alpha[i][3] );
		engine->Tree()->AddNode( c1, alpha[i][3] );
	}

	// ----------- A canvas ----------------- //
	KrCanvasResource* canvasResource = new KrCanvasResource( "mycanvas",
															 50, 50,
															 true );
	engine->Vault()->AddResource( canvasResource );
	KrRGBA* pixels = canvasResource->Pixels();
	KrRGBA color;
	for( i=0; i<canvasResource->Width(); i++ )
	{
		for( j=0; j<canvasResource->Height(); j++ )
		{
			color.c.red = i*4 + 50;
			color.c.green = j*4 + 50;
			color.c.blue = 0;
			color.c.alpha = 255 - i;
			pixels[ j*canvasResource->Width() + i ] = color;
		}
		// Put in a diagonal line:
		color.Set( 0, 0, 255 );
		pixels[ i*canvasResource->Width() + i ] = color;
	}

	const int NUMCANVASDIV2 = NUMCANVAS / 2;
	for ( i=0; i<NUMCANVASDIV2; i++ )
	{
		GlFixed sx;
		GlFixed sy;

		// The left canvas:
		canvas[i*2] = new KrCanvas( canvasResource );

		engine->Tree()->AddNode( c2, canvas[i*2] );
		canvas[i*2]->SetPos( 0, i * canvas[i*2]->Height() * 3 / 2 );
		sx.v = GlFixed_1 * (i+1) / 3;
		sy.v = GlFixed_1 * (i+1) / 3;

		canvas[i*2]->SetScale( sx, sy );

		// The right canvas:
		canvas[i*2+1] = new KrCanvas( canvasResource );
		engine->Tree()->AddNode( c2, canvas[i*2+1] );

		canvas[i*2+1]->SetPos( 100, i * canvas[i*2+1]->Height() * 3 / 2 );
		sx.v = GlFixed_1 * (NUMCANVASDIV2 + 1 - i) / 3;
		sy.v = GlFixed_1 * (i+1) / 3;

		canvas[i*2+1]->SetScale( sx, sy );
	}
}
Esempio n. 16
0
void EdStateMovie::FrameTick()
{
	KrImNode* image = shared->Engine()->Tree()->FindNodeById( 0 );
	GLASSERT( image );
	KrSprite* sprite = image->ToSprite();
	GLASSERT( sprite );

	sprite->DoStep();

	int x = sprite->CompositeXForm(0).x.ToInt();
	int y = sprite->CompositeXForm(0).y.ToInt();
	KrRect screen = shared->Engine()->ScreenBounds();
	GlFixed scale = movieNode->XScale();
	GlFixed inverse = GlFixed( 1 ) / scale;

	if ( x < 0 )
		sprite->SetPos( (inverse * screen.Width()).ToInt(), sprite->Y() );
	if ( x > screen.Width() )
		sprite->SetPos( 0, sprite->Y() );
	if ( y < 0 )
		sprite->SetPos( sprite->X(), (inverse*screen.Height()).ToInt() );
	if ( y > screen.Height() )
		sprite->SetPos( sprite->X(), 0 );
}
Esempio n. 17
0
ScalingTest::ScalingTest( SDL_Surface* screen )
{
	int i, j;
	//KrMatrix2 xForm;
	state = BOTH;

	//
	// Create the engine, load the dat files, get the resource.
	//
	engine = new KrEngine( screen );
	GLASSERT( engine );

	if ( !engine->Vault()->LoadDatFile( "space.dat" ) )
	{
		GLOUTPUT(( "Error loading 'space.dat'\n" ));
		exit(100);
	}

	fontVault = new KrResourceVault();
	if ( !fontVault->LoadDatFile( "font.dat" ) )
	{
		GLOUTPUT(( "Error loading 'font.dat'\n" ));
		exit(100);
	}

	KrSpriteResource* shipRes = engine->Vault()->GetSpriteResource( "MED" );
	GLASSERT( shipRes );
	KrSpriteResource* smallShipRes = engine->Vault()->GetSpriteResource( "SMALL" );
	GLASSERT( smallShipRes );
	KrFontResource*	fontConsole = fontVault->GetFontResource( "CONSOLE" );
	GLASSERT( fontConsole );

	KrRGBA white, red;
	white.Set( 255, 255, 255 );
	red.Set( 255, 0, 0 );

	AddBackground();

	// A group of travelling ships.
	travellingShip = new KrSprite( shipRes );
	travellingShip->SetAction( "BODY" );
	travellingShip->SetPos( 500, 390 );
	engine->Tree()->AddNode( 0, travellingShip );

	for ( i=0; i<4; ++i )
	{
		KrSprite* escort = new KrSprite( smallShipRes );
		escort->SetPos( 10 + i*30, -55 + i*30 );
		engine->Tree()->AddNode( travellingShip, escort );
	}

	travelText = new KrTextBox( fontConsole, 300, 300, 1 );
	engine->Tree()->AddNode( travellingShip, travelText );
	travelText->SetPos( -60, 30 );
	travelText->SetTextChar( "sin wave motion", 0 );



	//
	// Zoom 3 canvases to compare. The canvas are set up by drawing
	// a sprite to a canvas.
	//
	int hotx, hoty;
	KrCanvasResource* canvasRes = shipRes->CreateCanvasResource( "BODY", 0, &hotx, &hoty );
	GLASSERT( canvasRes );
	GLASSERT( canvasRes->Alpha() );
	engine->Vault()->AddResource( canvasRes );

	for( i=0; i<canvasRes->Width(); ++i )
	{
		for( j=0; j<canvasRes->Height(); ++j )
		{
			KrRGBA* pixel = canvasRes->Pixels() + j*canvasRes->Width() + i;
			if ( pixel->c.alpha )
				pixel->c.alpha = i * 256 / canvasRes->Width();
		}
	}

	for( i=0; i<3; ++i )
	{
		canvas[i] = new KrCanvas( canvasRes );
		canvas[i]->SetPos( 50 + i * 200, 170 );
		engine->Tree()->AddNode( 0, canvas[i] );
	}
	canvas[0]->SetQuality( KrQualityFast );
	canvas[1]->SetQuality( KrQualityLinear );
	canvas[2]->SetQuality( KrQualityAdaptive );


	// A sprite that scales in the upper left.
	// A resource to mark the center of the sprite.
	KrBoxResource* centerRes = new KrBoxResource( "Center",
												  5, 5,
												  &red, 1,
												  KrBoxResource::CROSSHAIR );
	engine->Vault()->AddResource( centerRes );

	// The ship that scales in the upper left
	ship = new KrSprite( shipRes );
	ship->SetAction( "BODY" );
	ship->SetPos( SHIPX, SHIPY );
	engine->Tree()->AddNode( 0, ship );


	// Center marker of the sprite
	center = new KrBox( centerRes );
	engine->Tree()->AddNode( 0, center );
	center->SetPos( SHIPX, SHIPY );

	// Some text info.
	textBox = new KrTextBox( fontConsole, 1024, 1024, 0 );
	textBox->SetPos( 10, 10 );
	engine->Tree()->AddNode( 0, textBox );

	scaleX.v = GlFixed_1 - GlFixed_1 / 8;
	scaleY.v = GlFixed_1 - GlFixed_1 / 8;
	AddText( engine );
}
Esempio n. 18
0
int main( int argc, char *argv[] )
{
	// code_d A random number generator.
	Random random;

	SDL_Surface* screen;

	const SDL_version* sdlVersion = SDL_Linked_Version();
	if ( sdlVersion->minor < 2 )
	{
		printf( "SDL version must be at least 1.2.0" );
		exit( 254 );
	}

	/* Initialize the SDL library */
	if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_NOPARACHUTE) < 0 ) {
		printf( "Couldn't initialize SDL: %s\n",SDL_GetError());
		exit(255);
	}

	/* Create a display for the image */
	screen = SDL_SetVideoMode( SCREENX, SCREENY, 0, SDL_SWSURFACE );
	if ( screen == NULL ) {
		exit(3);
	}

	KrEngine* engine = new KrEngine( screen );
	engine->Draw();

	// Load the dat file.
	// The dat file was carefully created in the sprite
	// editor. Loading allows us access to the 
	// MAGE, PARTICLE, and CARPET.
	if ( !engine->Vault()->LoadDatFile( "tutorial1.dat" ) )
	{
		printf( "Error loading the tutorial dat file\n" );
		exit( 255 );
	}

	// Get the CARPET resource
	KrSpriteResource* carpetRes = engine->Vault()->GetSpriteResource( TUT1_CARPET );
	GLASSERT( carpetRes );

	// Create the carpet sprite and add it to the tree
	KrSprite* carpet = new KrSprite( carpetRes );
	carpet->SetPos( SCREENX, SCREENY / 2 );
	engine->Tree()->AddNode( 0, carpet );
	// Get the MAGE resource, create the mage.
	KrSpriteResource* mageRes = engine->Vault()->GetSpriteResource( TUT1_MAGE );
	GLASSERT( mageRes );
	KrSprite* mage = new KrSprite( mageRes );

	// Add the Mage as a child of the carpet.
	engine->Tree()->AddNode( carpet, mage );
	SDL_Event event;
	bool done = false;

	// Start timing!
	SDL_SetTimer( TIMER_INTERVAL, TimerCallback );

	while( !done && SDL_WaitEvent(&event) )
	{
		if ( event.type == SDL_QUIT )
			break;

		switch(event.type)
		{
			case SDL_KEYDOWN:
			{
				done = true;
			}
			break;

			case SDL_TIMER_EVENT:
			{
				// code_d Walk the list and move the particles
				// Move the carpet.
				carpet->DoStep();
				if ( carpet->X() < 0 )
				{
					carpet->SetPos( SCREENX, carpet->Y() );
				}
				engine->Draw();
			}
			break;

			default:
				break;
		}

	}

	delete engine;

	SDL_Quit();	
	return 0;
}