Tutorials

Andorra 2D Tutorials
Part 1 - Initializing Andorra 2D

Translated by Thomas Hummes

What is Andorra 2D?
Andorra 2D is a new 2D Engine for Delphi, Kylix und Freepascal/Lazarus. A 2D-Engine is used to draw graphics as fast as possible on the screen and therefore can be used for developing games. Additionally, a 2D-Engine allows creating effects, which are hard to realize with the standard Windows/Linux graphics system. Andorra 2D stands out due to the following features:

  • Usage of several graphical interfaces - DirectX or OpenGL are both possible
  • Compatibility to DelphiX - "Old" programs made with "DelphiX" can be converted to Andorra 2D without much effort.
  • 3D-Acceleration - All graphical operations are rendered using 3D-Hardware. This accelerates rendering tremendously.
  • Sprite engine - Andorra 2D includes a powerful sprite engine that simplifies game development.
  • Canvas - Andorra 2D offers a hardware-accelerated Canvas, loosely based on the Delphi Canvas.


Further information is available on the website of Andorra: http://andorra.sf.net

Download and installation

Step 1: Download
The current version of Andorra 2D is available at the website in the category "Downloads". There is also a list of all compatible versions of Delphi / Lazarus.

Step 2: Copying in the Delphi folder
Copy the "src"-folder to a destination of your choice, e.g. (C:\Program Files\Borland\BDS\4.0\lib\). Rename it to "Andorra" or a name of your choice.

Step 3: Adding the path to the library
In Delphi/Lazarus, add the new path to your library paths (usually via "Tools"->"Options"->"Library Paths").

Andorra 2D is now ready for use.

Concerning libraries: The shipped demos contain several pre-compiled libraries (AndorraDX93D.dll, etc.). These libraries were compiled using Turbo Delphi Explorer. If you use them within other Delphi versions, access violations may occur, due to changes of the internal structure of objects that are exchanged between the library and the host. To prevent this, just recompile the libraries by yourself.

Contained Units
If you want to have an overview over all available Andorra 2D units, view the documentation unit summary page:
http://andorra.sourceforge.net/docs/

Initializing Andorra 2D

Necessary preparations...
Now that you have successfully installed Andorra 2D, it is time for a test. Therefore, create a new VCL-Form Application in Delphi. I suggest that you save this new project in a folder and copy all Andorra-DLLs in to this folder.
Now you need to add several units to the uses-clause:

  • AdDraws: the core of Andorra 2D
  • AdClasses: contains types and classes, auxiliary functions and a lot of stuff you will need
  • AdTypes: contains additional types and classes

Your uses-clause will now probably look like this:

Delphi-Code:
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, AdDraws, AdClasses, AdTypes;

Now you need to declare a TAdDraw-Object. TAdDraw is the "core" of Andorra 2D. It initializes and finalizes the engine and is responsible for the drawing.
Include the following code in the public-part of your main form declaration:

Delphi-Code:
AdDraw:TAdDraw;

You now need to create an instance of this object in the OnFormCreate. Create an event handler for this event (you should know, how to do this ;-) ) an insert the following code:

Delphi-Code:
AdDraw := TAdDraw.Create(self);

This creates the new instance of TAdDraw. "self" is a reference to your main form and advises the engine to draw all graphics on the canvas of your main form. You can change this and e.g. use a panel. Then all graphics will be drawn on the panel.

Since you created this object manually, you should free it at the end. Therefore, create a new procedure for the "OnDestroy"-event of your main form and insert the following code:

Delphi-Code:
AdDraw.Free;

This finalizes the engine and frees the used memory.

Now let's get back to the Initializing. You have to connect the engine to a plugin (i.e. graphical interface like DirectX or OpenGL). Therefore, you need to set the property "DllName" of "AdDraw" to the filename of the DLL. The DirectX-Plugin is called "AndorraDX93D.dll" and the OpenGL-Plugin is called "AndorraOGL.dll". In future, other plugins may be available.

Add the following code to the OnCreate:

Delphi-Code:
AdDraw.DllName := 'AndorraDX93D.dll';

The DLL is automatically loaded when needed.


The Initializing
We want to initialize Andorra 2D. This is easily done by calling the "Initialize" function of AdDraw. If the Initializing is successful, the function return "true", otherwise you should create a error message ("Feedback to the user") and close the program.
Again, add the following code to the OnCreate:

Delphi-Code:
if AdDraw.Initialize then
begin
  // We will continue here, soon..
end
else
begin
  ShowMessage('Error while initializing Andorra 2D. Try to use another display'+
              'mode or use another video adapter.');
  halt; //<-- Completely shuts down the application
end;

First steps done. If everything compiles successfully and no error message is generated, Andorra 2D will run. But there is nothing to see...

Yeah, a black window
One more time some explanations:
Games need to update the screen a lot of times per second. This is usually done with a loop like this (pseudo-code):

Delphi-Code:
repeat
  Do_Calculations;
  Render;
  if PressESC then abort := true;
until abort;
Close;

Unfortunately, this method causes the CPU to run at 100% (not suitable for Laptops). Furthermore, the same game will run at different speed on different computers (we can easily manage this - explained in the next tutorial).
Another method would be to use the TTimer. We would use a small interval and use the OnTimer-Event for calculating and rendering.

Unfortunately, this also will not work properly. The Timer-Messages have a low priority and therefore, the OnTimer-event is fired 50 times per second at most.

Nevertheless, we will again have a closer look to the first proposal. You may ask, where to put this loop in a VCL-Application. Then Answer is: Nowhere. Every VCL-Application has an internal loop, comparable to this:

Delphi-Code:
while not Application.Terminated do
begin
  Application.ProcessMessages;
  if Done = false then Application.OnIdle; // not exactly, but easier to understand
end;

During each loop, a function named "OnIdle" is called. We can easily use this function for our code.

Insert into the public-part of the main forms declaration:

Delphi-Code:
procedure Idle(Sender:TObject; var Done:boolean);

And now include the following code:

Delphi-Code:
procedure TForm1.Idle(Sender: TObject; var Done: boolean);
begin
  if AdDraw.CanDraw then // Only continue, if drawing is possible
  begin
    // we’ll continue here soon
  end;
 
  Done := false; // Important, otherwise the function will not be called in every loop
end;

And now enter the following line in the "OnCreate"-event where "We will continue here, soon..." was written:

Delphi-Code:
Application.OnIdle := Idle; 

This links the "OnIdle"-Event to our self-defined function.
This Idle-function is now the core of our game. All calculations and drawing operations are called here. Therefore, we need the following code in the Idle-function:

Delphi-Code:
AdDraw.ClearSurface(clBlack); // Fill the surface with black color

AdDraw.BeginScene;
// Here you need to perform all drawing operations later
AdDraw.EndScene;

AdDraw.Flip; // Draws you result on the screen. Otherwise, you would not see anything

One more thing concerning AdDraw.Flip: You may have noticed that the Delphi-canvas flickers, if several graphical operations are performed. This would also happen to Andorra 2D if there would not be a "trick": Internally, two canvases are used alternating. If the drawing is finished, the result is drawn on the screen and the other canvas is used for drawing the next frame (the switch is done by AdDraw.Flip). This concept is called "Double Buffering". If you want to know more, there is a good article at Wikipedia.

But let's get back to Delphi: Compile and run the program: If everything went fine, you should see a black window. All done.

The Code
For reference, the complete source code of this tutorial:

Delphi-Code:
unit Form1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, AdDraws, AdClasses, AdTypes;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    AdDraw:TAdDraw;
    procedure Idle(Sender:TObject;var Done:boolean);
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  AdDraw := TAdDraw.Create(self);
  AdDraw.DllName := 'AndorraDX93D.dll';
  if AdDraw.Initialize then
  begin
    Application.OnIdle := Idle;
  end
  else
  begin
    ShowMessage('Error while initializing Andorra 2D. Try to use another display'+
                'mode or another video adapter.');
    halt;
  end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  AdDraw.Free;
end;

procedure TForm1.Idle(Sender: TObject; var Done: boolean);
begin
  if AdDraw.CanDraw then
  begin
    AdDraw.ClearSurface(clBlack);

    AdDraw.BeginScene;
    //Your code here
    AdDraw.EndScene;
   
    AdDraw.Flip;
  end;
  Done := false;
end;

end.

Conclusion
The first step towards 2D-Rendering with 3D-acceleration is done. But to be honest: For a simple black window, no Andorra 2D is needed. Therefore, the next tutorial is about:

  • How to draw an image
  • How to move the image at constant speed
  • How to draw in fullscreen mode

After all, this tutorial got quite large. This is a result of the detailed explanations. In the following tutorials, we will expect a little bit more (especially concerning Delphi) and will increase speed a little bit.

Copyright and License
(c) by Andreas Stöckel, January 2008
(c) of the english translation by Thomas Hummes, January 2008

The content of this tutorial is released under the GNU Free Documentation License.


This page was generated with the help of the following PHP-Scripts: GeSHi a free PHP Syntax highlighter and StringParser_BBCode a free BBCode Parser.