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 > OAM is screwing me.

#174835 - relminator - Fri Jul 23, 2010 7:52 am

Oam gets flipped?

I've just implemented my oamfont(font are rendered via oam) since my sub screen font needs are not that much and I needed the speed.

However an artifact shows on one of the text printed on the sub screen and the weird thing is that it only shows on start up. I'm pretty sure it's the oam trying to screw me because I've implemented the same font system using the gl interface and it worked like a charm. I've been trying to find out the bug to no avail for hours now.

My eyes are not that fast to discern but I think the oam gets flipped.

Code:

/******************************************************************************
*******************************************************************************

   Space Impakto DS
   relminator
   http://rel.betterwebber.com


   Coamfont class


*******************************************************************************
******************************************************************************/

#include <nds.h>
#include "Coamfont.h"



/******************************************************************************



******************************************************************************/
void Coamfont::init(OamState *_oam,u8 *_gfx, int _width, int _height, SpriteSize _size, int _max_chars)
{
   active_chars = 0;
   oam = _oam;
   
   if (_max_chars > MAX_FONT_SPRITES)
      _max_chars = MAX_FONT_SPRITES;
   
   gfx = _gfx;
   max_chars = _max_chars;
   width = _width;
   height = _height;
   tile_mem_size = width * height;
   
   fonts[0].create (oam, width, height, _size, SpriteColorFormat_256Color, true, true);
   fonts[0].active = false;
   
   for (int i = 1; i < max_chars; i++)
   {
      fonts[i].create (oam, width, height, _size, SpriteColorFormat_256Color, true);
      fonts[i].active = false;
   }

}

/******************************************************************************



******************************************************************************/
void Coamfont::clear()
{
   active_chars = 0;
   for (int i = 0; i < max_chars; i++)
   {
      fonts[i].active = false;
   }

}

/******************************************************************************



******************************************************************************/
void Coamfont::print(int x, int y, const char *text)
{

   unsigned char font_char;
   
   while(*text)
   {
      font_char = (*(unsigned char*)text++) - 32;
      if (font_char)   // don't print space
      {
         for (int i = 0; i < max_chars; i++)
         {
            if (!fonts[i].active)
            {
               dmaCopy(gfx + (tile_mem_size*font_char) , fonts[i].gfx, tile_mem_size);
               fonts[i].active = true;
               fonts[i].x = x;
               fonts[i].y = y;
               fonts[i].update_oam();
               active_chars++;
               break;
            }
         }
      }
      x += width;
   }
   
}

/******************************************************************************



******************************************************************************/
void Coamfont::print(int x, int y, int value)
{

   
   sprintf(str,"%i",value);
   
   print(x, y, str);
   
}

/******************************************************************************



******************************************************************************/
void Coamfont::print(int x, int y, const char *text, int value)
{

   strcpy(str, text);
   sprintf(str2,"%i",value);
   strcat(str, str2);
   
   print(x, y, str);
   
}

/******************************************************************************



******************************************************************************/
void Coamfont::print_centered(int x, int y, const char *text)
{

   unsigned char font_char;
   int total_width = 0;
   
   total_width = width * strlen(text);
   
   x = (SCREEN_WIDTH - total_width) / 2;
   
   
   while(*text)
   {
      font_char = (*(unsigned char*)text++) - 32;
      if (font_char)   // don't print space
      {
         for (int i = 0; i < max_chars; i++)
         {
            if (!fonts[i].active)
            {
               dmaCopy(gfx + (tile_mem_size*font_char) , fonts[i].gfx, tile_mem_size);
               fonts[i].active = true;
               fonts[i].x = x;
               fonts[i].y = y;
               fonts[i].update_oam();
               active_chars++;
               break;
            }
         }
      }
      x += width;
   }
   
}

/******************************************************************************



******************************************************************************/
void Coamfont::print_score(int x, int y, int value, const char *filler, int length)
{

   sprintf(str2,"%i",value);
   int value_len = strlen(str2);
   
   if (length < value_len)
      length = value_len;
      
   int new_length = length - value_len;
   
   for (int i=0; i < new_length; i++)
   {
      str[i]=*filler;
   }
   
   //str[new_length]='\0';         // not needed
   
   char *p_str = &str[new_length];
 
   strcpy(p_str, str2);
   
   print(x, y, str);
   
}

/******************************************************************************



******************************************************************************/
void Coamfont::print_spaced(int x, int y, const char *text, int x_space, s32 x_offset, s32 y_offset)
{

   unsigned char font_char;
   s32 spacing = x_space << 12;
   s32 y_spacing = 0;
   s32 _x = x << 12;
   s32 _y = y << 12;
   s32 _x_space = x_space << 12;
   
   while(*text)
   {
      font_char = (*(unsigned char*)text++) - 32;
      if (font_char)   // don't print space
      {
         for (int i = 0; i < max_chars; i++)
         {
            if (!fonts[i].active)
            {
               dmaCopy(gfx + (tile_mem_size*font_char) , fonts[i].gfx, tile_mem_size);
               fonts[i].active = true;
               fonts[i].x = _x >> 12;
               fonts[i].y = _y >> 12;
               fonts[i].update_oam();
               active_chars++;
               break;
            }
         }
      }
      
      y_spacing += y_offset;
      
      spacing += x_offset;
      _x_space = spacing;
      
      _x += ((width<<12) + _x_space);
      _y += (y_spacing);
   }
   
}

/******************************************************************************



******************************************************************************/
void Coamfont::print_vertical(int x, int y, const char *text)
{

   unsigned char font_char;
   
   while(*text)
   {
      font_char = (*(unsigned char*)text++) - 32;
      if (font_char)   // don't print space
      {
         for (int i = 0; i < max_chars; i++)
         {
            if (!fonts[i].active)
            {
               dmaCopy(gfx + (tile_mem_size*font_char) , fonts[i].gfx, tile_mem_size);
               fonts[i].active = true;
               fonts[i].x = x;
               fonts[i].y = y;
               fonts[i].update_oam();
               active_chars++;
               break;
            }
         }
      }
      y += height;
   }
   
}





Anyways here's the full source and binary:
(Look at the moving "ANYATECH" text at the bottom.)

http://rel.betterwebber.com/junk.php?id=111


And for the glfont routine that works perfectly:

http://rel.betterwebber.com/junk.php?id=110


Thanks in advance!
_________________
http://rel.betterwebber.com

#174837 - Dwedit - Fri Jul 23, 2010 10:11 am

Are you writing to OAM outside of vblank time?
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."

#174838 - relminator - Fri Jul 23, 2010 10:14 am

Dwedit wrote:
Are you writing to OAM outside of vblank time?


Before.

1. Print via oam (write to oam)
2. vblank
3. oamUpdate()
_________________
http://rel.betterwebber.com