The SGADE Documentation

the SGADE The Socrates Gameboy Advance Development Engine

The SGADE is a development library for the Nintendo Gameboy Advance. It's free for all uses and is distributed without guarantees. For more information visit the SGADE page.


Main Page   Modules   Data Structures   File List   Data Fields   Globals   Related Pages  

The SGADE Documentation

Version 1.02 dev D This text comes from the Socrates.h file.

Introduction to the Documentation

The documentation for the SGADE is divided into several parts. You are now reading the largest section. It contains a complete reference to all code, and some background information on the SGADE development philosophy and codestyle. Other information can be found in the FAQ and the the tutorials. These can be found on the SGADE website.

Before you start using the SGADE I strongly suggest reading all information below. After that I would browse this reference for a bit, and then take a go through the tutorials.

Philosophy

I believe in object and component oriented programming. However, unlike some people, I also believe that one can use any coding paradigm in any language. I don't need C++ or Java to use OOP, and I could do functional programming in assembly. Some languages might be better suited for some paradigms, but some languages are also better suited for some platforms. This is the reason I chose C over C++ for Gameboy Advance development.

I can see the merits in using C++ for a GBA project, but only for advanced management systems. If, for example, I had to write a strategy game for the GBA, I would probably use C++ constructs to manage units and resources. But for Socrates, C gave me all I ever needed. Object oriented programming without the memory overhead and performance drawbacks of C++.

If anyone wants to discuss this with me, and wants to tell me C++ can be just as fast, I'd love a discussion. But not until you've read Scott Meyer's books: Effective C++ and More Effective C++.

So, I would be using C. How then is OOP reflected in my C coding? Two things are important here. This pointers and singletons.

This pointers are used whenever a function acts upon an object. In C++ all methods belonging to a class receive an implicit (hidden) this pointer. Whenever you invoke a method on a class like this:

        object.Method();

What C++ actually does is this:

        Method( &object );

So all we have to do to emulate an object oriented class-method-like system is provide the this pointer ourselves. What better than using a short example. Take a look at the following C++ code.

        // Define the class
        class SoClass
        {
            // Attributes;
            int m_Attribute;

            // Methods;
            void Method1( void );
            void Method2( int a_Argument );
            int  Method3( void );
        }

        // Declare an instance;
        SoClass object

        // Use the class
        object.Method1();
        object.Method2( 10 );
        int i = object.Method3();

This would be written in C (the SGADE) as follows:

        // Define the structure
        typedef struct 
        {
            // Attributes;
            int attribute;
        } SoClass;

        // Define the methods;
        void SoClassMethod1( SoClass* a_This );
        void SoClassMethod2( SoClass* a_This, int a_Argument );
        int  SoClassMethod3( SoClass* a_This );

        // Declare an instance;
        SoClass object

        // Use the class
        SoClassMethod1( &object );
        SoClassMethod2( &object, 10 );
        int i = SoClassMethod3( &object );

Once you realize there is actually no difference between the above C++ and C code, nothing stops you from doing OOP in C. It is true that the often called 'true' OOP concepts like polymorphism and inheritance require more complicated constructs, but most of it can be solved using clever casting and function pointers.

What about singletons then? Well, targeting the Gameboy Advance, it turns out that a lot of classes are often instantiated only once. A good example is an interrupt manager or a mode 4 renderer. All methods belonging to such an object will always receive the same this pointer. This would be nonsense ofcourse, and therefore we treat these objects as singletons. In the SGADE a singleton is a group of global functions without this pointers. But we treat those as methods belonging to and acting upon a single object and not as seperate functions. Consider the following functions:

        void SoMode4RendererEnable( void );
        void SoMode4RendererFlip( void );
        void SoMode4RendererClear( void );
            ....

All of these functions act upon a global fictional object called SoMode4Renderer. There is no SoMode4Renderer type, but the object is there. You will never see it, but just remember that whenever you use a singleton.

C, as opposed to C++, has no build in information hiding facilities. Every attribute of a structure is public (for the compiler). However, you should always treat all members of every structure as private. Use the supplied methods to act upon these structures.

There is a single exception to this. The SoVector3 and SoVector2 structures (because of their simplicity) have public members. Every other structure has only private members. These are marked as 'For Internal Use Only'. Treat them that way.

Code Style

I use a fairly strict coding style. Uniform and consistent coding improves readability. I use the following rules for coding.

The following piece of code gives some examples. Note that the large blocks of comments are normally done by using the / * and * / (without the spaces) comment style, but I can't use these here as this code example is itself embedded in a comment (yes this HTML is generated from a source file, see the next section on Doxygen for more information).

        // A global variable.
        u32 g_GlobalVariable;

        // A static variable.
        static u32 s_StaticVariable;

        // --------------------------------------------------------------------
        //
        //  \brief  A global function.
        //  \param  a_Argument1         First argument of the function
        //  \param  a_Argument2         First argument of the function
        //  
        //  \return  The first argument added to the second argument.
        //  
        //  This function does blah blah blah
        //            blah blah blah
        //                  blah blah blah
        //  
        // --------------------------------------------------------------------
        u32 SoGlobalFunction( u32 a_Argument1, u32 a_Argument2 )
        {
            // A local variable.
            u32 localVariable;

            // Do the calculation
            localVariable = a_Argument1 + a_Argument2;

            // Done;
            return localVariable;
        }
        // --------------------------------------------------------------------
    
        // --------------------------------------------------------------------
        //
        //  \brief This structure represents blah blah;
        //
        //  This structure can be used to do blah blah blah blah...
        //
        // --------------------------------------------------------------------
        typedef struct
        {
            u32 m_MemberAttribute1;     // Attribute that is for blah....
            u32 m_MemberAttribute2;     // Attribute that is for bleh...
        
        } SoSomeStructure
        // --------------------------------------------------------------------

        // --------------------------------------------------------------------
        // 
        //  \brief  Method belonging to the SoSomeStructure class
        //  
        //  \param  a_This  This pointer
        //
        //  This function does blah blah blah blah...
        //
        // --------------------------------------------------------------------
        void SoSomeStructureMethod( SoSomeStructure* a_This )
        {
            // Acces the member of the given this pointer.
            a_This->m_MemberAttribute = 10;
        }
        // --------------------------------------------------------------------

Just look at the above example and some of the SGADE code and you'll soon see the consistency and particular coding practices I use to improve development.

On Doxygen Source Commenting

Doxygen is a tool that extracts comments from source code and creates documentation in HTML, Latex, or other formats. The very words you are reading now (if you are reading this documentation in HTML format) have been extraced by Doxygen.

More information on Doxygen can be found on its website at http://www.doxygen.org I'll give some short tips and advice that might help when you start browsing the SGADE source code.

Doxygen parses the sourcecode and uses the source surrounding comments to get information about this code. You can add certain tags to the comments to give Doxygen information about what you mean with the code following the comments.

A Doxygen compatible source comment can be given in the following ways:

Inside a comment the following tags are used as special commands. Each tag is prefixed by a \ (backslash).

There might be some more tags in the source I have forgotten here. But most of the time these will explain themselves.

Where to from here

Now that you have read something about the philosophy and coding style of the SGADE you know what to expect when using the SGADE. I suggest you start by browsing this reference, especially the modules section at the top of this page. After that, browse through some of the code and try some tutorials.


Copyright 2002 by the SGADE authors. See SoLicense.h or Visit the SGADE page for more information.