#region Copyright
/*
--------------------------------------------------------------------------------
This source file is part of Xenocide
by Project Xenocide Team
For the latest info on Xenocide, see http://www.projectxenocide.com/
This work is licensed under the Creative Commons
Attribution-NonCommercial-ShareAlike 2.5 License.
To view a copy of this license, visit
http://creativecommons.org/licenses/by-nc-sa/2.5/
or send a letter to Creative Commons, 543 Howard Street, 5th Floor,
San Francisco, California, 94105, USA.
--------------------------------------------------------------------------------
*/
/*
* @file BuildTimes.cs
* @date Created: 2007/04/30
* @author File creator: dteviot
* @author Credits: none
*/
#endregion
#region Using Statements
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using ProjectXenocide.Model.Geoscape.Outposts;
#endregion
namespace ProjectXenocide.UI.Scenes.Facility
{
///
/// Overlay for facilities, giving build time remaining
///
class BuildTimes
{
///
/// Constructor
///
/// The facilities in the base
public BuildTimes(Floorplan floorplan)
{
this.floorplan = floorplan;
}
///
/// Load/create the graphic resources needed by the build time quads
///
/// content manager that fetches the content
/// the display
public void LoadContent(ContentManager content, GraphicsDevice device)
{
texture = content.Load(@"Content\Textures\OutpostLayout\BuildTimes");
InitializeMesh();
if (0 < meshVertices.Length)
{
constructVertexBuffer(device);
constructIndexBuffer(device);
basicEffectVertexDeclaration = new VertexDeclaration(
device, VertexPositionTexture.VertexElements);
}
}
///
/// Consturct mesh holding set of quads holding build times
///
private void InitializeMesh()
{
int numQuads = CountNumQuadsNeeded();
meshVertices = new VertexPositionTexture[numQuads * 4];
meshIndices = new short[numQuads * 6];
int count = 0;
foreach (FacilityHandle handle in floorplan.Facilities)
{
if (handle.IsUnderConstruction)
{
AddQuadToMesh(handle, count);
++count;
}
}
}
///
/// Set up a BasicEffect for drawing the build time remaining quads
///
/// effect to use to draw the quads
public void ConfigureEffect(BasicEffect effect)
{
effect.LightingEnabled = false;
effect.DiffuseColor = new Vector3(1.0f, 1.0f, 1.0f);
effect.Alpha = 0.5f;
effect.Texture = texture;
effect.TextureEnabled = true;
}
///
/// Draw the build times on the device
///
/// Device to render the build times to
/// effect to use to draw the build times
public void Draw(GraphicsDevice device, BasicEffect effect)
{
if (0 < meshVertices.Length)
{
device.VertexDeclaration = basicEffectVertexDeclaration;
device.Vertices[0].SetSource(
vertexBuffer, 0, VertexPositionTexture.SizeInBytes);
device.Indices = indexBuffer;
effect.Begin();
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Begin();
device.DrawIndexedPrimitives(
PrimitiveType.TriangleList,
0,
0,
meshVertices.Length,
0,
meshIndices.Length / 3
);
pass.End();
}
effect.End();
}
}
///
/// Add the polys (needed for this facility) to the mesh
///
/// Facility to provide a build time for
/// Where to put the polys in the mesh
private void AddQuadToMesh(FacilityHandle handle, int quadNum)
{
// compute position in scene for quad
float left = (floorplan.CellsWide * -0.5f) + handle.X + (handle.FacilityInfo.XSize * 0.5f) - 0.5f;
float top = (floorplan.CellsHigh * -0.5f) + handle.Y + (handle.FacilityInfo.YSize * 0.5f) - 0.5f;
float height = 0.5f;
Vector3 topLeft = new Vector3(left, height, top);
Vector3 topRight = new Vector3(left + 1.0f, height, top);
Vector3 bottomLeft = new Vector3(left, height, top + 1.0f);
Vector3 bottomRight = new Vector3(left + 1.0f, height, top + 1.0f);
// constants for BuildTime texture map
const int texturesPerRow = 7; // Bitmap has 7 textures per row
const float bitmapPixelLength = 256.0f; // Bitmap is 256 x 256
const int texturePixelLength = 35; // each texture is 35 pixels high and wide
const float textureLength = texturePixelLength / bitmapPixelLength;
// figure out texture for quad
int textureIndex = (int)Math.Ceiling(handle.TimeToBuild / 86400.0) - 1;
Debug.Assert(textureIndex <= 49);
float texTop = (texturePixelLength + 1) * (textureIndex / texturesPerRow) / bitmapPixelLength;
float texLeft = (texturePixelLength + 1) * (textureIndex % texturesPerRow) / bitmapPixelLength;
Vector2 textureTopLeft = new Vector2(texLeft, texTop);
Vector2 textureTopRight = new Vector2(texLeft + textureLength, texTop);
Vector2 textureBottomLeft = new Vector2(texLeft, texTop + textureLength);
Vector2 textureBottomRight = new Vector2(texLeft + textureLength, texTop + textureLength);
// Add vertices to Mesh
int vIndex = quadNum * 4;
meshVertices[vIndex] = new VertexPositionTexture(topLeft, textureTopLeft);
meshVertices[vIndex + 1] = new VertexPositionTexture(bottomLeft, textureBottomLeft);
meshVertices[vIndex + 2] = new VertexPositionTexture(topRight, textureTopRight);
meshVertices[vIndex + 3] = new VertexPositionTexture(bottomRight, textureBottomRight);
// Add vertices to Mesh
int iIndex = quadNum * 6;
meshIndices[iIndex] = (short)(vIndex);
meshIndices[iIndex + 1] = (short)(vIndex + 2);
meshIndices[iIndex + 2] = (short)(vIndex + 1);
meshIndices[iIndex + 3] = (short)(vIndex + 2);
meshIndices[iIndex + 4] = (short)(vIndex + 3);
meshIndices[iIndex + 5] = (short)(vIndex + 1);
}
///
/// Figure out the number of quads (holding build time) we need to draw
///
/// Number of quads
private int CountNumQuadsNeeded()
{
int count = 0;
foreach (FacilityHandle handle in floorplan.Facilities)
{
if (handle.IsUnderConstruction)
{
++count;
}
}
return count;
}
///
/// construct a vertex buffer that can be used to draw the quads
///
private void constructVertexBuffer(GraphicsDevice device)
{
vertexBuffer = new VertexBuffer(
device,
VertexPositionTexture.SizeInBytes * meshVertices.Length,
BufferUsage.None
);
vertexBuffer.SetData(meshVertices);
}
///
/// construct the triangle list that can be used to draw the quads.
///
private void constructIndexBuffer(GraphicsDevice device)
{
indexBuffer = new IndexBuffer(
device,
sizeof(short) * meshIndices.Length,
BufferUsage.None,
IndexElementSize.SixteenBits
);
indexBuffer.SetData(meshIndices);
}
#region Fields
private Texture2D texture;
private VertexDeclaration basicEffectVertexDeclaration;
private VertexPositionTexture[] meshVertices;
private short[] meshIndices;
private VertexBuffer vertexBuffer;
private IndexBuffer indexBuffer;
///
/// The facilities in the base
///
private Floorplan floorplan;
#endregion Fields
}
}