#129243 - odelot - Mon May 21, 2007 12:16 am
Hi everyone... i waste my weekend studying the material around the net about ds development and some codes too. I started to code on DS last weekend and started with palib, but it was making the DSerial lib to crash some times...
so I decided to make my own window system to DS... the first thing that i needed to do was to find a way to the video ram as framebuffer for both screen and have text support...
i noticed that it is a doubt of many here, and there is a lot of question on forum. the main problem is how to setup the console from ndslib to subscreen, if we use all the memory on extended background..
So, i started to study some codes and I found the anwser on Win2DS code. He did what I was looking for.
His trick was to scroll the background on Y. As we know, the 16bit 256x256 framebuffer for sub screen use all bank C, and if we want to use another thing, like tile base background, we cant. But the DS Screen does not has 256x256 but 256x192. So there is memory that we can use. Then, if we make a little horizontal scroll in extended background (ex SUB_BG3_CY = 64 << 8) we are telling to DS no to use the begin of C banck (0x0620000) but an andress after the begin (if we use the scrolling command SUB_BG3_CY = 64 << 8, then DS will point the ext background to 0x06208000). So, now we have 0x8000 Bytes (32KB) of free space to use with tile map background and then to text.
I follow the WIN2DS example and didn't use the console from ndslib, but 2 tile maps, one for each screen, and then i update the maps to show the text that i wanted
concluding, using text with tile based background has its advantages and disadvantages. The advantages is that we dont need to change (redraw) the entire framebuffer to display or change text. The disadvantages is that you cannot show text in anywhere in the screen, but just in a 32x24 grid that map the screen, because of the definition of the tile background
the code below configures the DS memory to use ext background and tile based text on both screens, and for both it implements double buffering
hope that this helps you! Odelot
here is the link to code and to ascii tile and pallet files
(code) http://grad.icmc.usp.br/~fabiotp/dsDev/DSVideo.rar
(pic) http://grad.icmc.usp.br/~fabiotp/dsDev/dsDevExtBGwithText.jpg
so I decided to make my own window system to DS... the first thing that i needed to do was to find a way to the video ram as framebuffer for both screen and have text support...
i noticed that it is a doubt of many here, and there is a lot of question on forum. the main problem is how to setup the console from ndslib to subscreen, if we use all the memory on extended background..
So, i started to study some codes and I found the anwser on Win2DS code. He did what I was looking for.
His trick was to scroll the background on Y. As we know, the 16bit 256x256 framebuffer for sub screen use all bank C, and if we want to use another thing, like tile base background, we cant. But the DS Screen does not has 256x256 but 256x192. So there is memory that we can use. Then, if we make a little horizontal scroll in extended background (ex SUB_BG3_CY = 64 << 8) we are telling to DS no to use the begin of C banck (0x0620000) but an andress after the begin (if we use the scrolling command SUB_BG3_CY = 64 << 8, then DS will point the ext background to 0x06208000). So, now we have 0x8000 Bytes (32KB) of free space to use with tile map background and then to text.
I follow the WIN2DS example and didn't use the console from ndslib, but 2 tile maps, one for each screen, and then i update the maps to show the text that i wanted
concluding, using text with tile based background has its advantages and disadvantages. The advantages is that we dont need to change (redraw) the entire framebuffer to display or change text. The disadvantages is that you cannot show text in anywhere in the screen, but just in a 32x24 grid that map the screen, because of the definition of the tile background
the code below configures the DS memory to use ext background and tile based text on both screens, and for both it implements double buffering
hope that this helps you! Odelot
here is the link to code and to ascii tile and pallet files
(code) http://grad.icmc.usp.br/~fabiotp/dsDev/DSVideo.rar
(pic) http://grad.icmc.usp.br/~fabiotp/dsDev/dsDevExtBGwithText.jpg
Code: |
#include "../gfx/ascii.c"
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_BG0_ACTIVE | DISPLAY_BG3_ACTIVE); //initializing the sub screen with mode5 and extended backgrounds videoSetModeSub(MODE_5_2D | DISPLAY_BG0_ACTIVE | 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); vramSetBankD (VRAM_D_MAIN_BG_0x06040000); // i am not sure that i need this, but... //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 // //as we didnt tell him here to point (using BG_MAP_BASE(x) or BG_BMP_BASE(x), etc) //then it will point to 0x06000000. but we will scroll the background (BG3_CY = 64 << 8) //so it will point to 0x06008000 BG3_CR = BG_BMP16_256x256 | BG_PRIORITY(3); //same as BG3_CR, but for sub screen (0x06200000 is the adreess of //the begining of C bank) - remember that this address will change //when we make the scrolling (SUB_BG3_CY = 64 << 8), so it will point to 0x62008000 SUB_BG3_CR = BG_BMP16_256x256|BG_PRIORITY(3); //setting up scale, rotation and scroll of our extended backgrounds BG3_XDX = 1 << 8; BG3_XDY = 0; BG3_YDX = 0; BG3_YDY = 1 << 8; //our bitmap looks a bit better if we center it so scroll down (256 - 192) / 2 BG3_CX = 0; BG3_CY = 64 << 8; SUB_BG3_XDX = 1 << 8; SUB_BG3_XDY = 0; SUB_BG3_YDX = 0; SUB_BG3_YDY = 1 << 8; SUB_BG3_CX = 0; SUB_BG3_CY = 64 << 8; //setting up the background 0 from main and sub screen to use tile backgrounds //for text use (probably I need to make my own text render, as this type of text //do not apply for a windows system) BG0_CR = BG_COLOR_16 | BG_32x32 | BG_MAP_BASE(6) | BG_TILE_BASE(0);// | BG_PRIORITY(1); SUB_BG0_CR = BG_COLOR_16 | BG_32x32 | BG_MAP_BASE(6) | BG_TILE_BASE(0);// | BG_PRIORITY(0); //applying the pointers to framebuffers m_fbMainScr1=(u16*) 0x06008000;// (u16*)BG_BMP_RAM(2); //point to init of bank A, or 0x06008000 m_fbMainScr2=(u16*) 0x06028000;// (u16*)BG_BMP_RAM(10); //point to init of bank B, or 0x06028000 m_fbSubScr= (u16*) 0x06208000; //point to init of bank c, or 0x06208000 m_fbMainScr = m_fbMainScr2; //actual backbuffer is back B m_fbSubScrEmulated = (u16*)malloc (256*256*2); //just if we will use emulated double buffering for sub screen int i=0; //cleaning the vram u16* vram = (u16*)(0x06020000); while(i++ <= (256*256)) vram[i] = 0; vram = (u16*)(0x06000000); i = 0; while(i++ <= (256*256)) vram[i] = 0; //Load the text I use into character slot 0 for both screens loadText((u16*)CHAR_BASE_BLOCK(0),(u16*)BG_PALETTE); //CHAR_BASE_BLOCK(0) = 0x6000000 loadText((u16*)CHAR_BASE_BLOCK_SUB(0),(u16*)BG_PALETTE_SUB); //CHAR_BASE_BLOCK_SUB(0) = 0x6200000 //setting color to text BG_PALETTE[0]=RGB15(0,0,0); //background text color BG_PALETTE[1]=RGB15(31,31,31); //text color BG_PALETTE_SUB[0]=RGB15(0,0,0); BG_PALETTE_SUB[1] = RGB15(31, 31, 31); } //print text using tile based text on subScreen void printTextSubScrn(const char * str, int x, int y) { u16* map = (u16*)BG_MAP_RAM_SUB(6); //counting that it will not change while(*str) { if(x==32) {x=0; y++;} if(y==24) return; map[y*32+x++]=(*str)-32; str++; } } //print text using tile based text on mainScreen void printTextMainScrn(const char * str, int x, int y) { u16* map = (u16*)BG_MAP_RAM(6); //counting that it will not change while(*str) { if(x==32) {x=0; y++;} if(y==24) return; map[y*32+x++]=(*str)-32; str++; } } //copying text tile info and pallete to memory void loadText(u16 *map, u16 *palette) { dmaCopy((u16 *)asciiPal, (u16 *)palette, asciiPalLen); dmaCopy((u16 *)asciiData, (u16 *)map, asciiLen); } //swap back and front buffers of main and sub screen //can make separete swapBuffer methods to each screen //to optimizate screen refresh void swapBuffers ( ) { //mainScreen swap code 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); } //subScreen swap code //usign the emulated framebuffer memcpy (m_fbSubScr,m_fbSubScrEmulated,256*192*2 ); } //just to test - dont use coordinates that exceeds Y=192 and X=256, or you will mess if the memory void drawRectangleMainScreen (int posX, int posY, int sizeX, int sizeY, u16 color) { for (int i=posY; i<posY+sizeY; i+=1) for (int j=posX; j<posX+sizeX; j+=1) m_fbMainScr[i*256+j]= color; } //just to test - dont use coordinates that exceeds Y=192 and X=256, or you will mess if the memory void drawRectangleSubScreen (int posX, int posY, int sizeX, int sizeY, u16 color) { for (int i=posY; i<posY+sizeY; i+=1) for (int j=posX; j<posX+sizeX; j+=1) m_fbSubScrEmulated[i*256+j]= color; } //return the framebuffer to be used to subScreen //(remember to swapBuffers to refresh the DS screen) u16* getFrameBufferSubScr () { return m_fbSubScrEmulated; } //return the framebuffer to be used to mainScreen //(remember to swapBuffers to refresh the DS screen) u16* getFrameBufferMainScr () { return m_fbMainScr; } 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 [65536];//use or not use it, it is the question u16 *m_fbSubScrEmulated; //what framebuffer on main screen we are drawing bool m_drawingMainScr1; }; |