Unit uRendering

The code of unit uRendering

unit uRendering;
{
    Copyright (c) 2011 Christopher Winward

    Licensed under the Apache License, Version 2.0 (the "License"); you may not
    use this file except in compliance with the License, as described at
    http://www.apache.org/licenses/ and http://www.pp4s.co.uk/licenses/
}
{$mode objfpc}

interface

uses
  Classes, SysUtils, sdl, sdl_gfx, uNodeClass;

type
  tColourState = (White, Green, Yellow, Red, Grey);

var
  mainSurface : pSDL_Surface;

procedure createRenderDevice;
procedure drawNode(nodeToDraw : tNode; colourState : tColourState = White);
procedure renderScene;

implementation

uses
  uGlobalVariables;

procedure createRenderDevice;
begin
  if (SDL_Init(SDL_INIT_VIDEO) <> 0) then
    begin
      writeln('Error initiliasing the video');
      readln;
      Halt;
    end;
  // Set the title bar in environments that support it.
  SDL_WM_SetCaption('Node pathfinding', nil);

  // Set Video Mode
  mainSurface := SDL_SetVideoMode(648, 400, 24, SDL_HWSURFACE);
  if (mainSurface = nil) then
    begin
      SDL_Quit;
      writeln('Error setting video mode'); readln;
      Halt;
    end;
end;

procedure drawNode(nodeToDraw : tNode; colourState : tColourState);
begin
  case colourState of //Draw a box of a given colour.
    White :  BoxColor(mainSurface, round(nodeToDraw.x), round(nodeToDraw.y), round(nodeToDraw.x) + 32,
                      round(nodeToDraw.y) + 32, $FFFFFFFF);//SDL_BlitSurface(whiteNodeSurface,nil,mainSurface,@drawRectangle);
    Green :  BoxColor(mainSurface, round(nodeToDraw.x), round(nodeToDraw.y), round(nodeToDraw.x) + 32,
                      round(nodeToDraw.y) + 32, $33FF33FF);
    Yellow : BoxColor(mainSurface, round(nodeToDraw.x), round(nodeToDraw.y), round(nodeToDraw.x) + 32,
                      round(nodeToDraw.y) + 32, $EEEE00FF);
    Red :    BoxColor(mainSurface, round(nodeToDraw.x), round(nodeToDraw.y), round(nodeToDraw.x) + 32,
                      round(nodeToDraw.y) + 32, $FF0000FF);
    Grey :   BoxColor(mainSurface, round(nodeToDraw.x), round(nodeToDraw.y), round(nodeToDraw.x) + 32,
                      round(nodeToDraw.y) + 32, $BBBBBBFF);
  end;

  //Write the node name.
  stringColor(MainSurface, round(nodeToDraw.x), round(nodeToDraw.y), PChar(nodeToDraw.name), $000000FF);
end;

procedure renderScene;
var
  count, innerCount : integer;
begin
  //I understand that some nodes are drawn multiple times - for the sake of easy coding, I have left it as this.
  //If this program was dealing with hundreds or even thousands of nodes however, I would have optimised it.

  //Draw all the nodes.
  for count := 0 to (listOfNodes.Count - 1) do
    begin
      drawNode(tNode(listOfNodes[count]));
    end;

  //Draw the explored nodes.
  for count := 0 to (exploredListTemp.Count - 1) do
    begin
      drawNode(tNode(exploredListTemp[count]), Grey);
    end;

  if (pathfoundList.Count > 0) then
    begin
      //Draw the path nodes.
      drawNode(tNode(pathfoundList[0]), Red);
      for count := 1 to (pathfoundList.Count - 2) do
        begin
          drawNode(tNode(pathfoundList[count]), Yellow);
        end;
      drawNode(tNode(pathfoundList[pathfoundList.Count - 1]), Green);
    end;

  //Draw the node connections.
  for count := 0 to (listOfNodes.Count - 2) do
    begin
      for innerCount := 0 to (tNode(listOfNodes[count]).adjacentNodes.Count - 1) do
        begin
          tempNode := tNode(tNode(listOfNodes[count]).adjacentNodes[innercount]);
          aaLineColor(mainSurface, round(tNode(listOfNodes[count]).x) + 16,
                      round(tNode(listOfNodes[count]).y) + 16,
                      round(tempNode.x) + 16, round(tempNode.y) + 16, $000000FF);
          stringColor(mainSurface, round((tNode(listOfNodes[count]).x + tempNode.x) / 2),
                      round((tNode(listOfNodes[count]).y + tempNode.y) / 2),
                      PChar(FloatToStr(tempNode.costToOtherNode(tNode(listOfNodes[count])))), $000000FF);
        end;
    end;

  if (pathfoundList.Count > 0) then
    begin
      //Draw the path taken.
      for count := 0 to (pathfoundList.Count - 2) do
        begin
          tempNode := tNode(pathfoundList[count]);
          aaLineColor(mainSurface, round(tNode(pathfoundList[count]).x) + 16,
                      round(tNode(pathfoundList[count]).y) + 16,
                      round(tNode(pathfoundList[count+1]).x) + 16,
                      round(tNode(pathfoundList[count+1]).y) + 16, $00FF00FF);
        end;
    end;

  stringColor(MainSurface, 0, 0, 'This program always tries to find a path from node A to F', $FFFFFFFF);
  stringColor(MainSurface, 0, 12, 'Press Insert to add a node, and Delete to remove one.', $FFFFFFFF);
  stringColor(MainSurface, 0, 24, 'Left clicking a node will move it, right clicking allows you to link two nodes.', $FFFFFFFF);
  stringColor(MainSurface, 0, 36, 'To link two nodes, right click and drag between the two.', $FFFFFFFF);
  stringColor(MainSurface, 0, 48, 'White nodes are unexplored, Grey have been checked but ultimately ignored.', $FFFFFFFF);
  stringColor(MainSurface, 0, 60, 'The Red node is the start, Green is the target, and Yellow are path nodes.', $FFFFFFFF);
end;

end.
Programming - a skill for life!

by Christopher Winward: U6 Age 17