By this stage you should have a rudimentary understanding of how the Pandora Engine is structured, so it's time to look at an example program before we dive into the more technical side of the system. We're going to start with an example that goes through the process of opening a window and printing a line of text inside of it. There are two ways that we can achieve this - the first using Athene + DML, the second is to write it entirely using the Pandora Engine. Both examples are good 'shell programs' for you to use in writing your own software.
If you're using the Pandora Engine to write programs within Athene, the most realistic option for writing a Hello World program is to use DML. While we're going to show you how to write a Hello World executable in the next part of this section, for the amount of time it takes to write the same thing in DML, a script will normally be the preferred option. Here goes:
<dml type="program"> <window title="Hello World" insideborder insideheight="100" insidewidth="180"> <render x="[owner.leftmargin]" y="[owner.topmargin]" xoffset="[owner.rightmargin]" yoffset="[owner.bottommargin]" colour="#ffffff"> <text align="center" string="Hello World" colour="#000000"/> </render> </window> </dml>
DML is designed for interface construction, which makes it ideal for simple programs like this. For more complex applications, we would typically design the entire interface in DML and then code the more complex parts using C.
For the purposes of this part of the manual we will not discuss the intricacies of DML, but you can refer to the DML Whitepaper if you need further information on how DML works.
Writing a Pandora based executable from scratch is a fairly straight-forward affair and does not require a great deal of startup code. The following code illustrates how a program will normally go through the process of opening a window, setting up a connection with the desktop and then interpreting system messages in a message loop. When the user clicks on the window's close gadget, the program ends. Here's the code:
#include <pandora/system/all.h> #include <pandora/graphics/all.h> STRING ProgName = "Hello World"; STRING ProgAuthor = "Rocklyte Systems"; STRING ProgDate = "December 2003"; STRING ProgCopyright = "Copyright Rocklyte Systems (c) 2001-2003. All rights reserved."; LONG ProgDebug = 0; FLOAT ProgKernelVersion = 3.3; extern struct KernelBase *KernelBase; ERROR msghandler(struct Message *); OBJECTID glWindowID; ERROR program(void) { struct Render *render; OBJECTPTR window, text; OBJECTID render_id; LONG topmargin, bottommargin, rightmargin, leftmargin; /*** Open a window ***/ if (CreateObject(ID_WINDOW, NULL, &window, &glWindowID, FID_Title|TSTRING, ProgName, FID_InsideBorder|TLONG, TRUE, FID_InsideWidth|TLONG, 150, FID_InsideHeight|TLONG, 50, FID_Icon|TSTRING, "nature/flower", TAGEND) IS ERR_Okay) { /*** Get the window margins ***/ GetFields(window, FID_LeftMargin|TLONG, &leftmargin, FID_TopMargin|TLONG, &topmargin, FID_BottomMargin|TLONG, &bottommargin, FID_RightMargin|TLONG, &rightmargin, TAGEND); ReleaseObject(window); /*** Create a render area for drawing graphics ***/ if (CreateObject(ID_RENDER, NULL, &render, &render_id, FID_Owner|TLONG, glWindowID, FID_XCoord|TLONG, leftmargin, FID_YCoord|TLONG, topmargin, FID_XOffset|TLONG, rightmargin, FID_YOffset|TLONG, bottommargin, FID_Colour|TSTRING, "#ffffff", TAGEND) IS ERR_Okay) { /*** Create the Hello World text ***/ CreateObject(ID_TEXT, NULL, &text, NULL, FID_Owner|TLONG, render_id, FID_String|TSTRING, "Hello World", FID_Align|TLONG, ALIGN_CENTER, FID_Face|TSTRING, "Helvete:16", FID_Colour|TSTRING, "#000000", TAGEND); /*** Show the render object inside the window ***/ Action(AC_Show, render, NULL); ReleaseObject(render); /*** Show our window ***/ ActionMsg(AC_Show, glWindowID, NULL); /*** Set our message handler and put the task to sleep ***/ SetResource(RES_MESSAGEHANDLER, (LARGE)&msghandler); ProcessMessages(NULL, MF_WAIT); } } return(ERR_Okay); } /* This routine will kill our program if the window that we created ** is closed by the user. */ ERROR msghandler(struct Message *Message) { if (Message->Type IS MSGID_QUIT) return(ERR_Terminate); return(ERR_Failed); /* Return failure if message unrecognised */ }
Please note that if you need exact detail on the functionality of this program, you can click on the hyperlinks to read the function documentation. Step-by-step, this is an overview of how the program works:
That's all there is to it. We recommend reading the documentation on the Window, Render and Text classes and then modifying this program by changing the field parameters that are passed to each object. Please click here for the source code and makefile for this program. This is the only working example of an executable program in this manual, so if you want to see more, please refer to the source code that is provided with the Pandora Engine to learn more from other programs.
Next: Object Management In Depth