using System;
using System.Collections;
using Microsoft.DirectX.DirectDraw;
using Global;
using Global.GlobalClass;
using System.Drawing;
namespace KillerInstinct.DirectX{
public class DrawClass
{
public Clipper Clip = null;
public Surface Front = null;
public Surface Back = null;
public Device Draw = null;
public DrawClass(System.Windows.Forms.Control window)
{
try
{
Draw = new Device();
Draw.SetCooperativeLevel(window, CooperativeLevelFlags.FullscreenExclusive);
Draw.SetDisplayMode(global.options.SCR_WIDTH, global.options.SCR_HEIGHT, global.options.SCR_DEPTH, 0, false);
SurfaceDescription description = new SurfaceDescription();
description.SurfaceCaps.Flip = description.SurfaceCaps.Complex = description.SurfaceCaps.PrimarySurface = true;
description.BackBufferCount = CONST.BACKBUFFER_COUNT;
Front = new Surface(description, Draw);
Clip = new Clipper(Draw);
Clip.Window = window;
Front.Clipper = Clip;
SurfaceCaps caps = new SurfaceCaps();
caps.BackBuffer = true;
Back = Front.GetAttachedSurface(caps);
DrawInfoTextBox("Initializing DrawClass...", Color.White);
}
catch (Exception)
{
FreeDirectDraw();
}
}
public void FreeDirectDraw()
{
if (Draw != null)
{
Draw.Dispose();
Draw = null;
}
}
public bool CheckOnScreen(Rectangle frame)
{
if (frame.X + frame.Width > global.options.SCR_WIDTH ||
frame.X <= 0 ||
frame.Y + frame.Height > global.options.SCR_HEIGHT ||
frame.Y <= 0)
return false;
return true;
}
// overloaded version of DrawBox that accepts
public void DrawBox(Rectangle rect, Color borderColor)
{
DrawBox(rect.X, rect.Y, rect.Width, rect.Height, borderColor, Color.Empty);
}
// overloaded version of DrawBox that uses Color.Empty for fill color
public void DrawBox(int x, int y, int width, int height, Color borderColor)
{
DrawBox(x, y, width, height, borderColor, Color.Empty);
}
// draws a box with specified border color and fill color
public void DrawBox(int x, int y, int width, int height, Color borderColor, Color fillColor)
{
Draw3dBox(x, y, width, height, borderColor, Color.Empty, fillColor);
}
// draws a box, that is y/x portion is different color than height/width (to allow cheap windows shadow effect)
public void Draw3dBox(int x, int y, int width, int height, Color borderColor1, Color borderColor2, Color fillColor)
{
if (CheckOnScreen(new Rectangle(x+1, y+1, width-1, height-1)))
{
try
{
// if a fill color was specified, use it
System.Drawing.Rectangle rect = new Rectangle(x, y, width, height);
// set the fill color
Back.ColorFill(rect, fillColor);
Back.FillColor = fillColor;
// set the border color
Back.ForeColor = borderColor1;
Back.DrawBox(x, y, x+width, y+height);
// draw y/x half of box
/*Back.DrawLine(x, y, width, y); // -----
Back.DrawLine(x, y, x, height); // |
// if second border color, ues it
if (borderColor2 != Color.Empty)
Back.ForeColor = borderColor2;
// draw height/width half of box
Back.DrawLine(width, y, width, height); // |
Back.DrawLine(x, height, width, height); // _____*/
}
catch (Exception e)
{
global.dbg.Out(Debug.ERR, "DrawClass.Draw3dBox exception, xy=[" + x + "," + y + "] width=[" + width + "] height=[" + height + "] bColor1=[" + borderColor1 + "] bColor2=[" + borderColor2 + "] fColor=[" + fillColor + "]");
global.dbg.Out(Debug.ERR, "DrawClass.Draw3dBox exception: " + e);
throw new Exception("Draw3dBox", e);
}
}
}
// draws a circle
public void DrawCircle(int x, int y, int radius, Color borderColor)
{
//TODO: check point in circle
if (CheckOnScreen(new Rectangle(x-radius/2, y-radius/2, radius, radius)))
{
try
{
// set the border color
Back.ForeColor = borderColor;
Back.DrawCircle(x, y, radius);
}
catch (Exception e)
{
global.dbg.Out(Debug.ERR, "DrawClass.DrawCircle exception, x=[" + x + "] y=[" + y + "] rad=[" + radius + "] bColor=[" + borderColor + "]");
global.dbg.Out(Debug.ERR, "DrawClass.DrawCircle exception: " + e);
throw new Exception("DrawCircle", e);
}
}
}
// draws a line
public void DrawLine(int x1, int y1, int x2, int y2, Color lineColor)
{
try
{
// set the line color
Back.ForeColor = lineColor;
Back.DrawLine(x1, y1, x2, y2);
}
catch (Exception e)
{
global.dbg.Out(Debug.ERR, "DrawClass.DrawLine exception, x1=[" + x1 + "] y1=[" + y1 + "] x2=[" + x2 + "] y2=[" + y2 + "] color=[" + lineColor + "]");
global.dbg.Out(Debug.ERR, "DrawClass.DrawLine exception: " + e);
throw new Exception("DrawLine", e);
}
}
// writes text
public void DrawText(int x, int y, string text, Color c)
{
try
{
Back.ForeColor = c;
Back.DrawText(x, y, text, false);
}
catch (Exception e)
{
global.dbg.Out(Debug.ERR, "DrawClass.DrawText exception, x=[" + x + "] y=[" + y + "] text=[" + text + "] color=[" + c + "]");
global.dbg.Out(Debug.ERR, "DrawClass.DrawText exception: " + e);
throw new Exception("DrawText", e);
}
}
// SPECIAL DRAWING FUNCTIONS FOR START-UP INFO SCREEN
private const int INFOTEXT_X = 5;
private const int INFOTEXT_START_Y = 10;
private const int INFOTEXT_OFFSET = 15;
private const int INFOTEXT_LINECOUNT = 20; // max INFO TEXT lines to display on-screen
private ArrayList infoTextList = new ArrayList();
private int initStartTime = System.Environment.TickCount;
//public void DrawTextBox(int x, int y, Color boxColor, Color textColor, Frame frame, Color frameColor
public void DrawInfoTextBox(string text, Color textColor)
{
if (Back != null)
{
if (infoTextList == null)
{
global.dbg.Out(Debug.DBG2, "DrawTextBox creating new ArrayList.");
infoTextList = new ArrayList();
}
// if we have too many messages...
if (infoTextList.Count > INFOTEXT_LINECOUNT)
{
global.dbg.Out(Debug.DBG2, "DrawTextBox erasing first element.");
// move all strings up one positon in the array to make room for new INFO TEXT item
for (int i=1; i<infoTextList.Count; ++i)
infoTextList[i-1] = infoTextList[i];
}
// insert "time since last call" + the new message at position 0
infoTextList.Add("[" + (System.Environment.TickCount-initStartTime) + "ms] " + text);
global.dbg.Out(Debug.DBG2, "DrawTextBox adding: " + "[" + (System.Environment.TickCount-initStartTime) + "ms] " + text);
// make background black
DrawBox(0,0,global.options.SCR_WIDTH,global.options.SCR_HEIGHT, Color.Black, Color.Black);
// go through list and draw all INFO TEXT messages
int infoTextY = INFOTEXT_START_Y;
for (int i=0; i < infoTextList.Count; ++i)
{
DrawText(INFOTEXT_X, infoTextY, (string)infoTextList[i], textColor);
infoTextY += INFOTEXT_OFFSET;
}
// draw everything to screen
Front.Draw(Back, DrawFlags.DoNotWait);
}
else
{
global.dbg.Out(Debug.DBG1, "DrawTextBox trying to use a NULL Back buffer!");
}
}
}
}
|