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 > Doubts on sub screen about double buffering

#129126 - odelot - Sat May 19, 2007 6:28 am

Hi,

I am new on DS developement...

i want to map the main and the sub screen on extended backgrounds with 16 bits to use as framebuffer..

I saw that in main screen i have a lot of possible banks to use, but in the sub screen i just have the bank C.. is it correct?? So i cant have 2 framebuffers on sub screen and just change the SUB_BGx_CR to point to it, as i can do with main screen???

the other doubt is if I can use text with extended background, running on mode 5, in both of screens???

EDIT <add doubt>: can I use others banks to use more memory on sub screen, like use the memory after 0x06220000 (end of C back for BG)??? how i say that in SUB_BGx_CR???

thanks in advance

#129144 - tepples - Sat May 19, 2007 4:40 pm

If you can't double buffer a 16-bit full-screen bitmap on the sub screen, you might want to use a second buffer in main RAM and then copy it in using HDMA. But I wonder whether you are in fact using the most efficient method of doing what you want to do. What are you going to be putting on each screen?
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#129149 - odelot - Sat May 19, 2007 6:21 pm

i will do a windows system...

i tried to put a framebuffer on memory but when i try it on emulator it gives a (rom crash error)...

i just be sad that i cant use the text provided by ndslib on both screen using them with extended background...

well here is my code... i dont know if it is 100% right but it works ;-) wish that it help someone

Code:
//Coded by Odelot - (Brazil) - 19/05/2007 - DSVideo.h
#ifndef __DSVIDEO_H
#define __DSVIDEO_H

#include <nds.h>

class DSVideo
{
public:
   void init ()
   {
      //initialing this variable that will help us with the swapBuffers of double buffering of main screen
      m_drawingMainScr1=true;

      //initializing the main screen with mode5 and extended backgrounds
      videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE);   
      //initializing the sub screen with mode5 and extended backgrounds
      videoSetModeSub(MODE_5_2D  |  DISPLAY_BG3_ACTIVE);   

      //initializing the bank A, B and C. Note that C bank is set to be used in sub screen
      vramSetBankA (VRAM_A_MAIN_BG_0x06000000);
      vramSetBankB (VRAM_B_MAIN_BG_0x06020000);
      vramSetBankC (VRAM_C_SUB_BG_0x06200000);
      
      //BG3_CR (main screen) is a complicated register... it has a lot of information.
      //what we need to know is that, with OR operation, we make it, and it
      //will works like a pointer for what the DS need to show on background (BG)
      //layer, in case, the Background 3 that we enabled on videoSetMode
      BG3_CR = BG_BMP16_256x256 | BG_BMP_BASE(0)  |  BG_PRIORITY(3); 

      //here we have data about scale, rotation, etc
      //about the background... i dont know how to use
      //it yet, and i didn need it yet too
      BG3_XDX = 0;
      BG3_XDY = 1 << 8;
      BG3_YDY = 0;
      BG3_YDX = 1 << 8;

      //same as BG3_CR, but for sub screen (0x06200000 is the adreess of
      //the begining of C bank)
      SUB_BG3_CR = BG_BMP16_256x256 | 0x06200000|  BG_PRIORITY(3);


      //same as BG3_XDX etc...
      SUB_BG3_XDX = 0;
      SUB_BG3_XDY = 1 << 8;
      SUB_BG3_YDY = 0;
      SUB_BG3_YDX = 1 << 8;

      //applying the pointers to framebuffers
      m_fbMainScr1= (u16*)BG_BMP_RAM(0); //point to init of bank A, or 0x06000000
      m_fbMainScr2= (u16*)BG_BMP_RAM(8); //point to init of bank B, or 0x06020000
      m_fbSubScr= (u16*) 0x06200000; //point to init of bank c, or 0x06200000
      m_fbMainScr = m_fbMainScr2; //actual framebuffer is back B

      int i=0;
      //paint the screens with blue color (just to test.. there is a fast way to do this)
      for(i = 0; i < 256 * 256; i++)
         m_fbMainScr1[i] = RGB15(0,0,31) | BIT(15);
      for(i = 0; i < 256 * 256; i++)
         m_fbMainScr2[i] = RGB15(0,0,31) | BIT(15);
      for(i = 0; i < 256 * 256; i++)
         m_fbSubScr[i] = RGB15(0,0,31) | BIT(15);

   }

   void swapBuffers ( )
   {
      m_drawingMainScr1=!m_drawingMainScr1;
      if (m_drawingMainScr1)
      {
            //changing the back buffer pointer
         m_fbMainScr=m_fbMainScr2;
         //if we are drawing now main screen 1, so here we are updating the DS pointer to it
         BG3_CR = BG_BMP16_256x256 | BG_BMP_BASE(0)  |  BG_PRIORITY(3); 
      }
      else
      {   
         m_fbMainScr=m_fbMainScr1;
         BG3_CR = BG_BMP16_256x256 | BG_BMP_BASE(8)  |  BG_PRIORITY(3);
      }
      //if you'd like to use the virtual framebuffer for the sub screen, copy it here
      

   }


    //just to test
   void drawRectangleMainScreen (int posX, int posY, int sizeX, int sizeY, u16 color)
   {
      //handle out of limits rectangle

      for (int i=posX; i<posX+sizeX; i+=1)
         for (int j=posY; j<posY+sizeY; j+=1)
            m_fbMainScr[i*256+j]= color;

   }

private:
   //main screen framebuffer  #1
   u16* m_fbMainScr1;

   //main screen framebuffer  #2
   u16* m_fbMainScr2;

   //main screen framebuffer actual
   u16* m_fbMainScr;

   //sub screen framebuffer
   u16* m_fbSubScr;

   //emulated sub screen framebuffer  (it is crashing the rom ? )
   //u16 m_fbSubScrEmulated [256*256];//use or not use it, it is the question

   bool m_drawingMainScr1;

};


#endif

#129514 - jespa - Wed May 23, 2007 10:58 am

Hi,

I has been tested your code and works fine one my "iris" emulator.
But I founded an incomplete code in your init video and swap screens.

You have to wait VBlank before to swap the screens. The code that is absent I show it now,


void DSVideo::init(void)
{

irqInit();
irqSet(IRQ_VBLANK, 0);

....
}

void DSvideo::SwapBuffers(void)
{

swiWaitForVBlank();

....


}

I hope that I have helped you in some thing.

#129533 - odelot - Wed May 23, 2007 4:14 pm

hi.. thanks.. i am glad that some one tested the code and gave a feedback

I had put this code to wait de vblank interrupt outside the DSVideo class, that?s way it isnt there.. but is a good idea to put inside the DSVideo.. thanks..

one guy said that we can do double buffering on sub screen in hardware with sprites (like the do to make 3D on both screen)... i won't try right know (if someone wants to updates this code with this, feel free to make it), but probably i will try it son (one week or two)

ah, I updated this code, and put tile based char to use to write text on both screen and tile based keyboard on both screen too... and to save memory i put the both tile information in one tile bank and used two maps and two pallets to represent them.. (here is the example with just the tile based chars working http://forum.gbadev.org/viewtopic.php?t=13253)

if you want, i can upload it... but i need to finish yet the stylus event and the keyboard test to give the keys events from keyboard