Ejemplo n.º 1
0
KrEngine::KrEngine( SDL_Surface* _screen )
	: paintInfo( _screen )
{
	Rectangle2I bounds;
	bounds.Set( 0, 0, _screen->w - 1, _screen->h - 1 );

	Init( _screen, 1, &bounds, 0 );
}
Ejemplo n.º 2
0
Rectangle2I MapSpatialComponent::PorchPos() const
{
	Rectangle2I v;
	v.Set( 0, 0, 0, 0 );
	if ( !hasPorch ) return v;

	float yRotation = YRotation(parentChit->Rotation());
	v = CalcPorchPos(bounds.min, bounds.Width(), yRotation);
	return v;
}
Ejemplo n.º 3
0
bool PitMorph::DoSequence( TimeClock* timeClock )
{
	const float SPEED = 4.0f  * ( TERRAIN_HEIGHT / 10.0f );
	// m term in y = mx+b
	const float SLOPE = 1.0f;
	
	bool last = false;
	Lilith3D* lilith = Lilith3D::Instance();
	TerrainMesh* tmesh = lilith->GetTerrainMesh();
	float height = tmesh->Height( terrainX, terrainY ) - timeClock->CalcVelocity( SPEED );
	height = Clamp( height, TERRAIN_MIN, TERRAIN_MAX );

	// essentially the x-intecept:
	// y = mx + b, b=height
	// x = -height / m
	float radius = ( TERRAIN_MAX - height ) / SLOPE;
	int   irad = int( radius ) + 1;

	Rectangle2I bounds;
	bounds.Set( terrainX - irad, terrainY - irad, terrainX + irad, terrainY + irad );
	Rectangle2I constrain;
	constrain.Set( 0, 0, lilith3d::VERTEXSIZE-1, lilith3d::VERTEXSIZE-1 );
	bounds.DoIntersection( constrain );

	// Do the center first.
	if ( height <= altitude )
		last = true;

	if ( tmesh->Height( terrainX, terrainY ) > altitude )
	{
		tmesh->StartHeightChange();
		tmesh->SetHeight( terrainX, terrainY, height );

		for( int j=bounds.min.y; j<=bounds.max.y; ++j )
		{
			for( int i=bounds.min.x; i<=bounds.max.x; ++i )
			{
				if ( i != terrainX || j != terrainY )
				{
					float len = Length( float( terrainX-i ), float( terrainY-j ), 0.0f );
					float setHeight = len*SLOPE + height;
					if ( setHeight < tmesh->Height( i, j ) )
						tmesh->SetHeight( i, j, setHeight );
				}
			}
		}
		tmesh->EndHeightChange();
	}

	for(	Publisher< PitMorphListener >::const_iterator it = publish.begin();
			it != publish.end();
			++it )
	{
		if ( last )
			(*it)->PitDone( this, terrainX, terrainY, height );
		else
			(*it)->PitSink( this, terrainX, terrainY, height );
	}

	return last;
}
Ejemplo n.º 4
0
bool VolcanoMorph::DoSequence( TimeClock* timeClock )
{
	const float SPEED = 4.0f  * ( TERRAIN_HEIGHT / 10.0f );
	// m term in y = mx+b
	const float SLOPE = -1.3f;
	const float SMOOTH_RADIUS = 3.0f;
	bool last = false;

	Lilith3D* lilith = Lilith3D::Instance();
	TerrainMesh* tmesh = lilith->GetTerrainMesh();

	float height = tmesh->Height( terrainX, terrainY ) + timeClock->CalcVelocity( SPEED );
	height = Clamp( height, TERRAIN_MIN, TERRAIN_MAX );

	// essentially the x-intecept:
	// y = mx + b, b=height
	// x = -height / m
	float radius = -( height - TERRAIN_MIN ) / SLOPE;
	int   irad = int( radius ) + 1;

	Rectangle2I bounds;
	bounds.Set( terrainX - irad, terrainY - irad, terrainX + irad, terrainY + irad );
	Rectangle2I constrain;
	constrain.Set( 0, 0, lilith3d::VERTEXSIZE-1, lilith3d::VERTEXSIZE-1 );

	bounds.DoIntersection( constrain );

	// Do the center first.
	if ( height >= altitude )
		last = true;

	if ( tmesh->Height( terrainX, terrainY ) < altitude )
	{
		tmesh->StartHeightChange();
		tmesh->SetHeight( terrainX, terrainY, height );

		for( int j=bounds.min.y; j<=bounds.max.y; ++j )
		{
			for( int i=bounds.min.x; i<=bounds.max.x; ++i )
			{
				if ( i != terrainX || j != terrainY )
				{
					float len = Length( float( terrainX-i ), float( terrainY-j ) );
					float setHeight = len*SLOPE + height;
					
					if ( len < SMOOTH_RADIUS )
						setHeight += fuzzHeight[ (j*lilith3d::VERTEXSIZE+i) % FUZZ_SIZE ];

					if ( setHeight > tmesh->Height( i, j ) )
						tmesh->SetHeight( i, j, setHeight );
				}
			}
		}
		tmesh->EndHeightChange();
	}

	// Inform listeners of changes.
	for( Publisher< VolcanoMorphListener >::const_iterator it = publish.begin();
		 it != publish.end();
		 ++it )
	{
		if ( !last )
			(*it)->VolcanoGrow( this, terrainX, terrainY, height );
		else
			(*it)->VolcanoDone( this, terrainX, terrainY, height );
	}
	
	// And now the particles and lights!
	const float FUZZ = 4.0f;
	const float FUZZMORE = 8.0f;
	float alt = tmesh->Height( terrainX, terrainY );

	GravParticles* grav = lilith->GetGravParticles();
	TimeClock* tc = Lilith3D::GetTimeClock();

	while ( tc->Msec() > lastParticleTime )
	{
		lastParticleTime += 50;
		Vector3F loc = { (float)terrainX, (float)terrainY, alt };
		Vector3F vel = {	-FUZZ / 2 + rand.FRand( FUZZ ),	// velocity
							-FUZZ / 2 + rand.FRand( FUZZ ),
							SPEED * 1.3f };
		Color3F col = {	0.8f + rand.FRand(0.2f), 			// coloring
							0.6f + rand.FRand(0.2f), 
							0.0f };

		grav->Create( loc, vel, col,
					  GravParticles::GRAVITY,
					  1.0f,
					  GravParticles::FLAME0 );

		for( int i=0; i<3; ++i )
		{
			Vector3F vel2 = {	-FUZZMORE / 2 + rand.FRand( FUZZMORE ),
								-FUZZMORE / 2 + rand.FRand( FUZZMORE ),
								SPEED * 0.8f };
			Color3F col2 = { 1.0f, 0.0f, 0.0f };
			grav->Create( loc, vel2, col2, 
						  GravParticles::GRAVITY,
						  GravParticles::MEDIUM );
		}
	}				  
//	glowLight->SetPos( (float)terrainX, (float)terrainY, alt );
	if ( decal ) {
		decal->SetAlpha( 1.0f );
		const float FADEOUT = 0.8f * altitude;
		if ( alt > FADEOUT ) {
			decal->SetAlpha( Interpolate( FADEOUT, 1.0f, altitude, 0.0f, alt ));
		}
	}
	return last;
}
Ejemplo n.º 5
0
void KrEngine::Draw( bool updateRect, std::vector< Rectangle2I >* _rectangles )
{
	std::vector< Rectangle2I > rectArrayOnStack;

	#if defined( DRAWDEBUG_RLE ) || defined( DRAWDEBUG_BLTRECTS )
		debugFrameCounter++;
	#endif

//	GLOUTPUT( "Engine::Draw Walk\n" );
	tree->Walk();

		// We either use the passed in rectangles,
		// or the one here on the stack. Set the pointer
		// rectArray to the right thing.
	std::vector< Rectangle2I >* rectArray = ( _rectangles ) ? _rectangles : &rectArrayOnStack;
	rectArray->resize(0);
	
	if ( !paintInfo.openGL )
	{
		// Queue up the rectangles that will be used to blit to screen:

		if ( needFullScreenUpdate )
		{
			needFullScreenUpdate = false;			
			Rectangle2I rect;
			rect.Set( 0, 0, screen->w-1, screen->h-1 );
			rectArray->push_back( rect );
		}
		else
		{
			for ( int i=0; i<nWindows; ++i )
			{
				for ( int j=0; j<dirtyRectangle[i].NumRect(); ++j )
				{
					rectArray->push_back( dirtyRectangle[i].Rect(j) );
				}
			}
		}	
	}
	
	if ( paintInfo.openGL )
	{
		#ifdef KYRA_SUPPORT_OPENGL

		// OpenGL drawing
		glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		for( int j=0; j<nWindows; ++j )
		{
			if ( fillBackground[j] )
			{
				glBindTexture( GL_TEXTURE_2D, 0 );
				glColor4f( backgroundColor[j].Redf(), backgroundColor[j].Greenf(), backgroundColor[j].Bluef(), 1.0f );
				glBegin( GL_QUADS );
				{
					glVertex3i( screenBounds[j].min.x, screenBounds[j].min.y, 0 );
					glVertex3i( screenBounds[j].min.x + screenBounds[j].Width(), screenBounds[j].min.y, 0 );
					glVertex3i( screenBounds[j].min.x + screenBounds[j].Width(), screenBounds[j].min.y + screenBounds[j].Height(), 0 );
					glVertex3i( screenBounds[j].min.x, screenBounds[j].min.y + screenBounds[j].Height(), 0 );
				}
				glEnd();
			}

			bool clipping = ( screenBounds[j] != windowBounds );

			if ( clipping )
			{
				glEnable(GL_CLIP_PLANE0);
				glEnable(GL_CLIP_PLANE1);
				glEnable(GL_CLIP_PLANE2);
				glEnable(GL_CLIP_PLANE3);

				double plane0[4] = { 1.0, 0.0, 0.0, -screenBounds[j].min.x };
				double plane1[4] = { -1.0, 0.0, 0.0, (screenBounds[j].min.x + screenBounds[j].Width() ) };
				double plane2[4] = { 0.0, 1.0, 0.0, -screenBounds[j].min.y };
				double plane3[4] = { 0.0, -1.0, 0.0, (screenBounds[j].min.y + screenBounds[j].Height() ) };

				glClipPlane( GL_CLIP_PLANE0, plane0 );
				glClipPlane( GL_CLIP_PLANE1, plane1 );
				glClipPlane( GL_CLIP_PLANE2, plane2 );
				glClipPlane( GL_CLIP_PLANE3, plane3 );
			}

			tree->DrawWalk( screenBounds[j], &paintInfo, j );

			if ( clipping )
			{
				glDisable(GL_CLIP_PLANE0);
				glDisable(GL_CLIP_PLANE1);
				glDisable(GL_CLIP_PLANE2);
				glDisable(GL_CLIP_PLANE3);
			}
			dirtyRectangle[j].Clear();
		}
		UpdateScreen( 0 );
		#else
			// No openGl support, but openGl surface used
			GLASSERT( 0 );
		#endif
	}
	else
	{
		// Bitmap drawing.

		// Draw the background, if necessary. Then
		// do a draw walk for every DR.
		for( int win=0; win<nWindows; ++win  )
		{
			for( int i=0; i<dirtyRectangle[win].NumRect(); ++i )
			{
				const Rectangle2I& rect = dirtyRectangle[win].Rect( i );

				// Draw the background.
				//GLASSERT( fillBackground[j] );
				if ( fillBackground[win] )
				{
					SDL_Rect sdlrect = { rect.min.x, rect.min.y, rect.Width(), rect.Height() };
					U32 sdlColor = SDL_MapRGB( screen->format,	backgroundColor[win].c.red,
																backgroundColor[win].c.green,
																backgroundColor[win].c.blue );
					//GLASSERT( sdlColor == 0 );
					SDL_FillRect( screen, &sdlrect, sdlColor );
				}
				tree->DrawWalk( rect, &paintInfo, win );

				/*
				#ifdef DRAWDEBUG_BLTRECTS
					KrPainter painter( &paintInfo );
					painter.DrawBox( rect.xmin, rect.ymin, rect.Width(), rect.Height(), 200, 0, 0 );
				#endif
				*/
			}

			#ifdef DRAWDEBUG_BLTRECTS
				dirtyRectangle[win].DrawRects( screen );
			#endif
			dirtyRectangle[win].Clear();
		}

		// The windows and DRs have been walked. Now transfer to physical screen.
		if ( updateRect )
		{
			// Use the composite list of rectangles.
			UpdateScreen( rectArray );
		}
	}
}
Ejemplo n.º 6
0
Chit* LumosChitBag::NewBuilding(const Vector2I& pos, const char* name, int team)
{
	const ChitContext* context = Context();
	Chit* chit = NewChit();

	const GameItem& rootItem = ItemDefDB::Instance()->Get(name);
	GameItem* item = rootItem.Clone();

	// Hack...how to do this better??
	if (item->IResourceName() == "pyramid0") {
		CStr<32> str;
		str.Format("pyramid%d", random.Rand(3));
		item->SetResource(str.c_str());
	}
	if (item->IResourceName() == ISC::kiosk) {
		switch (random.Rand(4)) {
			case 0: item->SetResource("kiosk.n");	break;
			case 1: item->SetResource("kiosk.m");	break;
			case 2: item->SetResource("kiosk.s");	break;
			default:item->SetResource("kiosk.c");	break;
		}
	}

	int size = 1;
	rootItem.keyValues.Get(ISC::size, &size);
	int porch = 0;
	rootItem.keyValues.Get(ISC::porch, &porch);
	const int circuit = 0;

	// Should be pre-cleared. But recover from weird situations by clearing.
	// Note that water is a real problem.
	Rectangle2I r;
	r.Set(pos.x, pos.y, pos.x + size - 1, pos.y + size - 1);
	for (Rectangle2IIterator it(r); !it.Done(); it.Next()) {
		const WorldGrid& wg = context->worldMap->GetWorldGrid(it.Pos());
		GLASSERT(wg.IsLand());
		(void)wg;
		context->worldMap->SetRock(it.Pos().x, it.Pos().y, 0, false, 0);
		context->worldMap->SetPlant(it.Pos().x, it.Pos().y, 0, 0);
	}

	MapSpatialComponent* msc = new MapSpatialComponent();
	msc->SetBuilding(size, porch != 0, circuit);
	msc->SetBlocks((rootItem.flags & GameItem::PATH_NON_BLOCKING) ? false : true);
	chit->Add(msc);
	MapSpatialComponent::SetMapPosition(chit, pos.x, pos.y);

	chit->Add(new RenderComponent(item->ResourceName()));
	chit->Add(new HealthComponent());
	AddItem(item, chit, context->engine, team, 0);

	IString script = rootItem.keyValues.GetIString("script");
	if (!script.empty()) {
		Component* s = ComponentFactory::Factory(script.c_str(), &chitContext);
		GLASSERT(s);
		chit->Add(s);
	}

	IString proc = rootItem.keyValues.GetIString("procedural");
	if (!proc.empty()) {
		ProcRenderInfo info;
		AssignProcedural(chit->GetItem(), &info);
		chit->GetRenderComponent()->SetProcedural(0, info);
	}

	IString consumes = rootItem.keyValues.GetIString(ISC::zone);
	if (!consumes.empty()) {
		Component* s = ComponentFactory::Factory("EvalBuildingScript", &chitContext);
		GLASSERT(s);
		chit->Add(s);
	}

	IString nameGen = rootItem.keyValues.GetIString( "nameGen");
	if ( !nameGen.empty() ) {
		IString p = Context()->chitBag->NameGen(nameGen.c_str(), chit->random.Rand());
		chit->GetItem()->SetProperName( p );
	}

#if 0	// debugging
	SectorPort sp;
	sp.sector.Set( pos.x/SECTOR_SIZE, pos.y/SECTOR_SIZE );
	sp.port = 1;
	worldMap->SetRandomPort( sp );
#endif

	context->engine->particleSystem->EmitPD( ISC::constructiondone, ToWorld3F( pos ), V3F_UP, 0 );

	if (XenoAudio::Instance()) {
		Vector3F pos3 = ToWorld3F(pos);
		XenoAudio::Instance()->PlayVariation(ISC::rezWAV, random.Rand(), &pos3);
	}

	return chit;
}