To build a cross-platform C-based extensible low-level library for building games. The library should be extensible, allowing anyone to plug in additional features, through layering on top of the API, external systems, or new internal functionality.
In general, AllegroPro should attempt to promote the use of available hardware features. It should do this in four ways. One, discourage the use of software by making the hardware path the one that is easiest to use. Two, make it explicit which features that hardware exposes and allow the user great latitude in selecting which hardware implementations and features to use based on this. Three, expose to the user the specific limitations of each hardware driver in terms of overall functionality, thus allowing the user to know when performing an operation may produce low-performance results. Four, creating objects that use software interfaces should be through an API that looks at least somewhat different from the regular, hardware path; thus making it obvious when an object is software and when it is hardware.
Specifically, the library should provide for the following:
AllegroPro's functionality is divided into 4 Tiers. Each Tier builds on the functionality of the previous Tiers.
Tier 1 is know as the Core functionality. It contains functionality that has no dependence on any other features.
The Core of AllegroPro has the following subsystems associated with it:
These systems have few hooks for the user to override functionality or provide their own featureset. These are designed to be fundamental subsystems that are the building blocks of other Tiers. As such, the Core will not be available as a separate download from Tier 2.
Tier 2 functionality is know as the Base functionality. Base functionality is divided into 4 components. These are the components that make up the Base system are:
Each component can have one or more drivers registered with AllegroPro. A driver that is registered means that AllegroPro is aware of its existence and can find it when the user asks for a driver with certain features.
A driver represents an interface into a particular piece of hardware, through a particular output device, if the driver provides output capabilities. For example, a window in a windowing-OS environment is a particular output device. In order to render to multiple windows, multiple drivers must be created, with each driver having a separate window. For components that do not have output devices, such as the input component, creating one driver is sufficient. For components where it makes sense for only one driver to be in existence, the driver object will not be exposed to the user. The API for these components will allow for the creation and destruction of said drivers only.
While each system has control over the mechanisms to create drivers, each one should provide for a simple means of autodetecting a reasonable driver with only the bare minimum of parameters. Also, each driver should be named, and the user should be able to create a driver by name.
Drivers are used to create other objects that represent hardware resources. Operations can be performed on these objects to produce various hardware-based effects.
In general, objects created in one driver cannot be used by objects created from another. However, there is the possibility for two drivers of the same type, or even two different driver types, to share drivers. To do this, there is an API function that checks to see if the drivers can share objects. If they can, then it will inform the drivers that they should share objects. From that point on, any objects created in one driver can be used in another. <Not sure if this is a terribly useful feature>.
The user can register drivers at any time. This registration process adds them to the list of known drivers that AllegroPro will search when looking for a driver with certain capabilities. However, most drivers should automatically register themselves, and standard drivers that ship with AllegroPro will do so. As such, manual registration will be rarely needed. Drivers cannot be activated without first registering them. Registration can happen at any time.
Drivers can have optional functionality. However, for each component, the driver must provide some minimum set of functionality. Also, for each optional piece of functionality, there must be some API for querying if that functionality is available.
The particulars of each component's design, as well as the functionality of planned drivers, is specified in that component's section.
It is the responsibility of the graphics driver to create a window on windowing OS's, if the user does not override this.
However, other drivers, in particular the sound drivers, may require a window in order to function. This allows the OS to know when to allow a sound driver access to shared resources and when to disallow it based on the state of this window. Because of this, one or more graphics drivers must be activated before any other drivers have been created.
However, it is possible to override the creation of a window handle. Also, it is possible for the user to create multiple graphics drivers for multiple windows. In these cases, the user can do one of two things.
The user can specify a particular graphics driver, that has a window (fullscreen drivers have a window), that should be considered the "main" window. If the user doesn't pick one, then the system will use the first graphics driver that was created by the user. If that driver is destroyed, then AllegroPro will only destroy the window itself when all other drivers that rely upon this window are destroyed.
The other way is for the user to specify, through an OS-specific interface, a particular window to use as the primary window for non-graphics drivers.
In any case, whether it is through a graphics driver or a user-defined window, the window will be referred to as the main window. In general, the main window should be created and set early in the lifetime of the program, and not changed.
One of the primary purposes of having the driver model at all is to allow the user to install plugin drivers that register themselves with Allegro. By doing so, one can easily add a driver to existing code, and even have existing code use it.
In theory, the idea is that AllegroPro could scan a specific directory for drivers, as well as having an API for scanning user-specified directories.
Note that this does not necessitate that AllegroPro not ship with drivers, or that drivers that come with AllegroPro have to be separate .dll/.so files. Standard drivers can be integrated directly into the base system.
Tier 2 Base functionality is the first section of truly useable AllegroPro functionality. It provides the basic features that 2D game developers need. Components will not be available separately; there will be one Base download that contains all of the components as well as the Tier 1 system.
Tier 3 functionality consists also of extensible, driver-based, components. However, because most of these systems are not interfacing with hardware, calling them drivers is a misnomer. They should simply be components. These components should be easier for the user to extend, for the user is more likely to extend these than to build Tier 2 drivers. These components are the following:
Tier 3 components will be available as separate downloads, as well as a full down of all Tier 1-3 functionality.
There will be an official C++ wrapper around all AllegroPro features up through Tier 3. Thus using AllegroPro++ will mean that all Tier 1-3 functionality is available. This helps prevent having to write multiple wrappers for each level.
AllegroPro++ is designed to be as opaque an abstraction as possible. In theory, the user of the wrapper never needs to be aware of a C API.
Tier 4 consists of plugins that the user may or may not wish to use. These will not be available as a single download; they are always separate. These are features that either have a dependency on lots of other components (the GUI and the Resource Manager), or they are simply useful adjuncts that do not really mesh with the rest of AllegroPro (the vector math library). Tier 4 consists of the following:
AllegroPro Base Design Justification
AllegroPro will be an object-based API, written in C. This means that most objects created by AllegroPro will not be actual objects that the user can use. Instead, they will be some form of handle that the user can call API functions on. Objects are not created or destroyed with malloc/free operations. Instead, they are allocated and deallocated with various API calls.
Such an API provides for the ability to fully, opaquely, encapsulate the API in a C++ interface (re: AllegroPro++). Mixing the C and C++ API's is not advisable.
Any function that produces a significant error that requires explanation will use the AllegroPro Error Mechanism to publish a string version of that error. This will require drivers to also provide errors.
While the API's are not yet finalized, or close to it, a sanity check on how the user will use features is important. As such, we have a sanity check for blitting a single bitmap from starting. Other sanity checks will be added for other systems that may inspire concerns.
The AllegroPro API's implementations will utilize the given conventions.