Introducing the Generic Platform Interface (GPI)

Overview

The GPI was developed as a porting/development tool for Noble Ape. It provides a minimalist interface between the operating system and the platform independent Noble Ape software. The GPI was the first line of attack when porting the Noble Ape Simulation and other Noble Ape software to a new platform. It provides enough basic functionality to show the look and feel of most of the Noble Ape software.

History

Noble Ape has been primarily developed on the Macintosh over the past seven years. Some of the early Noble Ape software was ported to Windows in 1997-1999 and other components have been ported to Palm in 2000. Most Noble Ape software has similarities. This makes it easy to port the software through a single generic operating system interface.

Graphics

Noble Ape software doesn't use operating system based drawing routines. All the drawing is done through off screen buffers with Noble Ape dot, line and landscape (Ocelot) functions. The decision to develop software in this way came about for two reasons.

Operating systems graphics routines, even when hardware accelerated, contain exception handling which isn't applicable for most Noble Ape software. Because most of Noble Ape's graphical output is relatively diagrammatically intensive, realtime graphics (mainly monochrome), speed is a central requirement.

Similarly, the graphics over platforms have to be reproducible and maintain the same look and feel with user interaction. The implementation of internal Noble Ape graphics means platform porting requires only copy off screen buffer to window, rather than more elaborate system specific graphics calls.

Windows and Linux

The GPI port of the Noble Ape Simulation and Planet Noble Ape to Windows was the first development test of the GPI. With a relatively straight forward interface to both the Simulation and Planet developments, the GPI produced a fast, basic port of both programs. A Linux version of the GPI was developed by Mridul P on the Noble Ape Developers' Mailing List. The combination of the GPI and Noblemake (the Noble Ape pre-compiler), allowed 1:1 development on Mac, Linux and Windows.

Structure

Aside from the Noble Ape Simulation, most of Noble Ape software operates through a single window with a basic mouse and keyboard interface. Planet Noble Ape was the first program ported through the GPI. It provide a basic test-bed for the port. The Noble Ape Simulation was quickly modified to a GPI ready version (whilst maintaining the four window Ocelot and Vector versions too).

The model initially developed for was;
initialisation
while ( event loop ){
simulation cycle
simulation draw
draw to window
simulation erase
}
close

The event loop contained mouse and keyboard calls. This model was replace with an event-loop-centric model;
initialisation
event loop
close

where event loop was;
standard events
keyboard events
simulation handle keyboard
if above requires redraw
dirty window
mouse events
simulation handle mouse
if above requires redraw
dirty window
window draw event
simulation cycle (including draw)
draw to window
simulation erase

The final option is adding an auto dirty window, if continuous simulation with drawing is required. Some programs (such as Planet Noble Ape) auto erase the off screen buffer prior to drawing to it. Thus the erase function, after drawing the contents of the off screen buffer to the window, is not needed.

The GPI can be thought of as a membrane between the operating system and platform independent software. Minor changes need to be made between operating systems on the platform independent side. For example, eight black pixels are represented by the byte value 255 on the Macintosh but are represented by the byte value 0 through Windows. This can be altered by defines and macros for erasing and pixel drawing. The example of the changes needed for Linux can be seen in /sim/gui/gui.h. Eventually this information will be pushed into the GPI.

Access Constants and Functions

To access the GPI, the platform independent must contain;

initialisation
(simulation) cycle (including draw)

With the following optional;

keyboard handling
mouse handling
(simulation) erase
close

In addition, the following platform conditions are optional;

dynamic memory handling
call to (simulation) cycle per event-loop (or roughly 30 times/second)

The GPI supports user-defined function names. This means that the functions inside the platform-independent code can be called anything. The user defines the linking function names in the GPI header file.

An example beta-GPI header is shown below;

#defineGPI_WINDOW_NAME"Noble Ape"
#defineGPI_PC_APP_NAME"NobleApe"
#defineGPI_DIMENSION_X256
#defineGPI_DIMENSION_Y(256+50)
#defineGPI_INIT_FUNCTIONsim_init
#defineGPI_CYCLE_FUNCTIONsim_cycle
#defineGPI_DUAL_ENTRY_CYCLE1
#defineGPI_KEY_FUNCTIONsim_key
#defineGPI_MOUSE_FUNCTIONsim_mouse
#defineGPI_MEMORY_USED1
#defineGPI_AUTO_DIRTY1

These correspond with the following functions;

unsigned charsim_key(unsigned short num);
unsigned charsim_mouse(short px, short py);
void *sim_init(unsigned long kseed);
voidsim_cycle(unsigned char first);

The mouse and keyboard functions return 0 for no simulation cycle required or non-0 for simulation cycle required. Some keyboard or mouse routines may not require the simulation to be cycled and drawn. On the operating system side, this dirties the drawing window.

The entry value (num) for the keyboard routine is the value of the key pressed. The entry values for the mouse routine are the local co-ordinate values (px for the x-axis and py for the y-axis).

Window

The current implementation of the GPI allows for one window of any name and any size. The window's name and size are set by GPI_WINDOW_NAME, GPI_DIMENSION_X and GPI_DIMENSION_Y. In addition, the Windows version also needs an internal app name. As the example header (above) shows, this could be the window name without the spaces.

Initialisation

The initialisation function defined by GPI_INIT_FUNCTION and in the example above sim_init, takes in an unsigned long integer and returns a void pointer. The unsigned long integer is a randomising factor but equally it could be a number from a file or some user input. The returned value is the address of the off screen buffer.

Cycle and Erase

The cycle function has potentially two entry points. The first is the main simulation cycle and draw point and the second is the clean-up/erase point after the off screen buffer is drawn to the screen. When the GPI constant GPI_DUAL_ENTRY_CYCLE is set to 1, the cycle function (sim_cycle in the above example) has two entry points. One when first is 1 and the second when first is 0. The first handles the cycle/simulation code as well as the drawing to the off screen buffer. The second (when first is 0) is the clean-up/erase code for the cycle.

Some software may not require the second part of the cycle, thus it is optionally selected through the GPI_DUAL_ENTRY_CYCLE constant.

Dynamic Memory

The handling of dynamic memory changes between operating systems. Although functions like malloc and free remain relatively well supported across OS types, dynamic memory is handled differently on most OSes. Rather than guarantee ANSI memory handling, the GPI uses two calls for defining memory handling plat_new and plat_free. These contain a little more than standard malloc and free and protect against free being repeatedly called by setting the pointer to NULL before returning from plat_free. Memory management and garbage collection may be supported in later versions of the GPI.

Constant Cycling

Some applications require constant cycling, others require updates only in certain circumstances of keyboard or mouse interaction (of course menu handling also plays a role - more on that soon!). Constant cycling is defined by GPI_AUTO_DIRTY set to non-zero (aka 1).

Exit

A finalisation function is optional, but clearly necessary if dynamic memory is used (for example). If GPI_EXIT_FUNCTION is defined, then the exit function defined by GPI_EXIT_FUNCTION is called when the program exits. It is the final function called before exiting.

Noblemake

The GPI does not require Noblemake in order to work. However, because Noblemake and the GPI have been developed in tandem, there are a number of extras in Noblemake that will assist with GPI development. This information will be included with the Noblemake documentation as the Noblemake and GPI software matures.

Conclusion

This document discusses the initial implementation of the GPI. As noted through the document, a some components (such as menu handling) are not currently included. This document will be updated over the development of the GPI. It is intended that the basic functionality described in this document will be maintained.

Tom Barbalet.
First Written: 1 December 2002
Document tracked and updated in CVS


Planet Noble Ape - Noble Ape - Noble Ape Documents - the Noble Ape Simulation