gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > Our PALib alternative

#141271 - Corsix - Sun Sep 23, 2007 6:22 pm

Overview:
A group discussed and implemented high level library for simplifying DS development.

Aims:
1. It should provide an interface to the DS hardware, which could also be implemented as an interface to PC hardware, thus allowing for debugging to be done in a full IDE on a PC (be able to run on the pc or ds by changing a target)
2. Be heavily documented (doxygen?)
3. ?

To get people started, an incomplete abstraction of the 2D cores:
Code:
//! A 2D rendering core
/*!
   The DS has two rendering cores, called the main core and the sub core. Either core can render to
   either screen. The main core has more modes of operation, and has more options for assigning VRAM
   to it.
   \sa getMain2DCore()
   \sa getSub2DCore()
*/
class I2DCore
{
public:
   //! Possible modes of operation
   enum eModes
   {
      M_Mode0, //!< Text, Text, Text    , Text
      M_Mode3, //!< Text, Text, Text    , Extended
      M_Mode1, //!< Text, Text, Text    , Rotation
      M_Mode4, //!< Text, Text, Rotation, Extended
      M_Mode2, //!< Text, Text, Rotation, Rotation
      M_Mode5, //!< Text, Text, Extended, Extended
      M_FrameBuffer_VRAMA, //!< Direct RGB16 rendering via VRAM bank A
   };

   //! Sets the core to operate in one of the preset modes
   /*!
      The main 2D core supports all modes, however the sub core only supports modes 0-5.

      \param eNewMode Mode to operate in
      \return true if the mode was set, false if the core does not support the specified mode
   */
   virtual bool setMode(eModes eNewMode) = 0;

   //! Areas of the core that can have memory assigned to them
   enum eMemoryDestinations
   {
      MD_Background,
      MD_Sprites,
      MD_BackgroundExtendedPalettes,
      MD_SpriteExtendedPalettes,
   };

   //! Assigns one of the VRAM banks to serve as memory for the core
   /*!
      A 2D core contains very little built-in memory, therefore VRAM must be assigned to it.

      \param eMemoryDestination Where to assign the memory to
      \param eVRamBank The VRAM bank to assign
      \return true if the VRAM bank could be mapped to the destination, false if it is not possible
   */
   virtual bool assignVRAMBank(eMemoryDestinations eMemoryDestination, eVRamBanks eVRamBank) = 0;

   //! Gets one of the 4 background layers
   /*!
      When the core is in mode 0 through 5, then it has 4 background layers, numbered 0 through 3.
      Background 3 is drawn at the back, and background 0 at the front.
      \param iIndex Index of the background to get (0 through 3, inclusive)
      \return Pointer to the background layer, or NULL if the index was not valid, or the current
         mode does not have background layers
   */
   virtual IBackground* getBackground(u16 iIndex) const = 0;

   //! Gets the builtin core palette for the background layers
   /*!
      If extended background palettes are not used, then the core has a single 256 entry palette
      for the 4 background layers.
   */
   virtual palette_t* getPrimaryBackgroundPalette() const = 0;

   //! Gets the builtin core palette for sprites
   /*!
      If extended sprite palettes are not used, then the core has a single 256 entry palette
      for all of the sprites.
   */
   virtual palette_t* getPrimarySpritePalette() const = 0;
};

//! Gets the main 2D rendering core
I2DCore* getMain2DCore();

//! Gets the sub 2D rendering core
I2DCore* getSub2DCore();


Post your abstractions of DS features, improve/discuss/comment on other people's abstractions, etc.


Last edited by Corsix on Sun Sep 23, 2007 7:16 pm; edited 1 time in total

#141274 - Peter - Sun Sep 23, 2007 7:13 pm

Corsix wrote:
1. It should provide an interface to the DS hardware, which could also be implemented as an interface to PC hardware, thus allowing for debugging to be done in a full IDE on a PC (be able to run on the pc or ds by changing a target)

Well, everything else is counterproductive anyway :)

Corsix wrote:

2. Be heavily documented (doxygen?)

I found doxygen to be an excellent documentation system.

Corsix wrote:

To get people started, an incomplete abstraction of the 2D cores:

Personally I'm rather scared of virtual functions on platforms like the NDS, since those need an extra table-lookup before they can be called. It doesn't matter for methods which aren't called often, but when performance is an issue, using virtual functions isn't the first choice.

Corsix wrote:

Code:

class I2DCore
{
   virtual bool setMode(eModes eNewMode) const = 0;
}


In my opinion this method shoudn't be const, as it seem to set/modify something in the core.
_________________
Kind Regards,
Peter

#141277 - Corsix - Sun Sep 23, 2007 7:22 pm

Whoops, that shouldn't have been const.

Ultimately, there must be a tradeoff between speed and ease of use. If you want really fast, then you code in assembler using raw libnds. Are there faster ways than virtual methods for providing suitable abstraction?

#141287 - Peter - Sun Sep 23, 2007 8:31 pm

Corsix wrote:
Are there faster ways than virtual methods for providing suitable abstraction?

I guess it depends why you actually want to use virtual methods. If you only want to provide a base-set of methods, you can also just have two implementations of the class.

That's how I made it. I have a class for NDS and one for Win32, both feature the same set of base-methods and have the same name and there is no need to derive from it.

For example the NDS class:
Code:

class I2DCore
{
public:
   // base-set of functions
   bool setMode(eModes eNewMode) const;
   bool assignVRAMBank(eMemoryDestinations eMemoryDestination, eVRamBanks eVRamBank);

private:
   // nds specific functions
};


The Win32 class:
Code:

class I2DCore
{
public:
   // base-set of functions
   bool setMode(eModes eNewMode) const;
   bool assignVRAMBank(eMemoryDestinations eMemoryDestination, eVRamBanks eVRamBank);

private:
   // win32 specific functions
};

If this means a lot of duplicated code, it's probably not the best solution.

However, in my particular case the win32 class is using direct3d and the nds class something totally different, so the method implementations have no commonness at all and this is the reason why I chose this approach instead of virtual methods.
_________________
Kind Regards,
Peter