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 > Works on emulator but not on a real hardware [solved]

#117389 - Zubrow - Sun Feb 04, 2007 4:44 pm

Here's my noob problem: I'm learning nds coding, to begin I'm trying to display a basic sprite on the main screen and make it move with the sub screen.

My code looks like this
Main.cpp:
Code:

void OnIrq(void)
{   
  if(REG_IF & IRQ_VBLANK)
  {
    VBLANK_INTR_WAIT_FLAGS |= IRQ_VBLANK;
    REG_IF |= IRQ_VBLANK;
  }
}

int main(void)
{
  irqInit();
  irqSet(IRQ_VBLANK, OnIrq);

  powerON(POWER_ALL_2D);
  videoSetMode(MODE_3_2D|DISPLAY_SPR_ACTIVE|DISPLAY_SPR_1D|DISPLAY_SPR_1D_LAYOUT);
  vramSetBankA(VRAM_A_MAIN_SPRITE);

  for (int i = 0; i < 128; ++i)
  {
    sSpriteEntry* pSprite = reinterpret_cast<sSpriteEntry*>(reinterpret_cast<u8*>(OAM) + i * sizeof (sSpriteEntry));
    pSprite->attribute[0] = ATTR0_DISABLED;
  }

  for (int i = 0; i < 128; ++i)
  {
    sSpriteEntry* pSprite = reinterpret_cast<sSpriteEntry*>(reinterpret_cast<u8*>(OAM_SUB) + i * sizeof (sSpriteEntry));
    pSprite->attribute[0] = ATTR0_DISABLED;
  }

  swiCopy(ProphetTiles, SPRITE_GFX, ProphetTilesLen);
  swiCopy(ProphetPal, SPRITE_PALETTE, ProphetPalLen);

  CSprite Prophet1(ATTR0_COLOR_256|ATTR0_SQUARE|(SCREEN_WIDTH >> 1) - 96, ATTR1_SIZE_64|(SCREEN_HEIGHT >> 1), 0|ATTR2_ALPHA(1));
  CSprite Prophet2(ATTR0_COLOR_256|ATTR0_SQUARE|(SCREEN_WIDTH >> 1) - 32, ATTR1_SIZE_64|(SCREEN_HEIGHT >> 1), 128|ATTR2_ALPHA(1));

  Prophet1.Update();
  Prophet2.Update();

  touchPosition tp;

  for (;;)
  {
    tp = touchReadXY();
    if (tp.x != 0 && tp.y != 0)
    {
      Prophet1.GoTo(tp.px, tp.py);
      Prophet2.GoTo(tp.px, tp.py+64);
      Prophet1.Update();
      Prophet2.Update();
    }
  }

  return 0;
}


I use my own class to handle sprite

Sprite.cpp: (ripped)
Code:

CSprite::CSprite(u16 Attr0, u16 Attr1, u16 Attr2)
{
  m_SpriteEntry.attribute[0] = Attr0;
  m_SpriteEntry.attribute[1] = Attr1;
  m_SpriteEntry.attribute[2] = Attr2;

  m_SpriteRotation.hdx = 256;
  m_SpriteRotation.hdy = 0;
  m_SpriteRotation.vdx = 0;
  m_SpriteRotation.vdy = 256;

  static u16 Id;
  m_SpriteId = Id++;
}

void CSprite::Update(void)
{
  dmaCopy(&m_SpriteEntry, OAM + ((sizeof (sSpriteEntry) >> 1) * m_SpriteId), sizeof (sSpriteEntry));
}


That's work with many emulator (like Dualis), but I get a black screen on my NDS ( I use a M3 Simply to run my code ).
So what's wrong with my code ?

Thanks.


Last edited by Zubrow on Mon Feb 05, 2007 10:26 am; edited 1 time in total

#117391 - tepples - Sun Feb 04, 2007 4:53 pm

I can't see the content of SPRITE_PALETTE, but I can tell you that Dualis has a bug. At one point in the development of LOCKJAW DS, I found that if sprites are turned on, the backdrop in Dualis uses color 0 from the sprite palette instead of (correct) color 0 from the background palette. The text wouldn't show up. Copying background color 0 into sprite color 0 fixed this.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#117422 - Zubrow - Sun Feb 04, 2007 8:41 pm

Thanks for your reply, here's the content of the palette
Code:

const unsigned short ProphetPal[256]=
{
   0x7C1F,0x654D,0x2890,0x1E3A,0x5B3B,0x1486,0x2E56,0x7FBD,
   0x1065,0x1C64,0x40C7,0x1935,0x0421,0x0421,0x0421,0x0421,
   0x0840,0x0842,0x0842,0x0842,0x0842,0x0842,0x0842,0x0842,
   0x0C63,0x0C63,0x0C63,0x0C63,0x0C63,0x0C63,0x0C63,0x0C63,
   0x1084,0x1084,0x1084,0x1084,0x1084,0x1084,0x1084,0x1084,
   0x14A5,0x14A5,0x14A5,0x14A5,0x14A5,0x14A5,0x14A5,0x14A5,
   0x18C6,0x18C6,0x18C6,0x18C6,0x18C6,0x18C6,0x18C6,0x18C6,
   0x1CE7,0x1CE7,0x1CE7,0x1CE7,0x1CE7,0x1CE7,0x1CE7,0x1CE7,
...
};


I tried with many emulators and I get this.
My problem is that I have a black screen on my real NDS, I guess I forgot something with OAM.

#117425 - tepples - Sun Feb 04, 2007 8:55 pm

Have you got a similar program to work in GBA mode?
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#117448 - Quirky - Sun Feb 04, 2007 10:21 pm

I had similar problems with sprites, you may need a DC_Flush before copying to OAM. My own Sprite update does this:
Code:
void Sprite::update() const
{
  if (!valid()) return;
  SpriteEntry * oam = (SpriteEntry*)m_OAM;
  DC_FlushRange(&s_sprites[m_screen][m_index],sizeof(SpriteEntry));
  dmaCopy(&s_sprites[m_screen][m_index], &oam[m_index], sizeof(SpriteEntry));
}

#117455 - Zubrow - Sun Feb 04, 2007 10:53 pm

tepples wrote:
Have you got a similar program to work in GBA mode?

No, I have a slot1 linker, so I can't run homebrew in GBA mode.

Quirky: I added DC_FlushAll() in my update routine, but it still doesn't work.

Thanks for your advise.

#117458 - Mighty Max - Sun Feb 04, 2007 11:07 pm

You are declaring CProphet and thus the sprite data within the main() routine, causing it to be created in Stack. The stack is exclusively accessible by the arm9 (DTCM). Afaik DMA does not work for this memory.
_________________
GBAMP Multiboot

#117515 - Zubrow - Mon Feb 05, 2007 7:42 am

Mighty Max wrote:
You are declaring CProphet and thus the sprite data within the main() routine, causing it to be created in Stack. The stack is exclusively accessible by the arm9 (DTCM). Afaik DMA does not work for this memory.

You're right, I changed the dmaCopy to swiCopy and now it works just like a charm. Thanks a lot! You solve my problem.