#175593 - SchmendrickSchmuck - Sun Jan 02, 2011 2:53 pm
I'm new to libnds (coming from PAlib...), and I need some help with backgrounds. I have read most of the tutorials, but none that I could find fit my question. For solely educational reasons, I would like to have the following layer setup:
Top layer 0: Text
Layer 1: 8bit drawable bg
Layer 2: 3D graphics
Layer 3: Tiled bg
I am not usually one for asking ready written code, but in this case I believe that this is the best way to help me understand the system and make up my own background layer setups. All I'm asking for is a simple main() with this layer setup, as well as some pixel plotting on the 8bit bg. I'd very much appreciate it if someone would take the time to help me out (or point me to a tutorial that discusses it). Thanks in advance.
Last edited by SchmendrickSchmuck on Sat Feb 05, 2011 4:12 pm; edited 4 times in total
#175594 - Dwedit - Sun Jan 02, 2011 6:15 pm
3D graphics must be on hardware layer #0, but the layers are re-arrangeable, so you can put the hardware layers in any priority order you want.
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."
#175596 - SchmendrickSchmuck - Sun Jan 02, 2011 11:39 pm
I was aware of that, but I'm unsure how exactly to achieve this.
This piece of code comes after initializing openGL: (using 16bit instead of 8bit for testing purposes)
Code: |
vramSetBankB(VRAM_B_MAIN_BG_0x06000000);
bgInit(3, BgType_Bmp16, BgSize_B16_256x256, 0,0);
bgSetPriority(0, 2);
bgSetPriority(3, 0); |
After that I test it by filling the screen with green:
Code: |
for(int i = 0; i < 256 * 192; i++)
VRAM_B[i] = RGB15(0, 31, 0); |
But I don't see anything. Am I missing anything?
Last edited by SchmendrickSchmuck on Mon Jan 03, 2011 12:15 am; edited 1 time in total
#175597 - DiscoStew - Mon Jan 03, 2011 12:15 am
If you're gonna use an 8-bit background, then you will need to set up a palette for it, which require setting up another VRAM bank for that. You then write the color values to the palette, and write the index to each palette color via a value between 0 and 255 inclusive to the other bank, which you have set up as the B bank. Because vram writes don't like 8-bit values, you'll have to write in 2 index values at a time.
But, if you want to write the colors directly with no palette, then use a 16-bit background instead.
_________________
DS - It's all about DiscoStew
#175598 - SchmendrickSchmuck - Mon Jan 03, 2011 12:20 am
Thanks DiscoStew, I figured I needed a palette for 8bit which I don't have ready at the moment, so I changed to 16 bit and updated my post. I also tried hiding the 3D layer in case it would hide the layers below it, but to no avail. Is there a specific video mode I need for 8bit or something? Currently I'm using mode5_3D.
#175600 - sverx - Mon Jan 03, 2011 12:11 pm
Mode 5 3D (or Mode 3 3D) is ok. So you could have:
BG0: 3D
BG1: Text (or Tiled BG)
BG2: Tiled BG (or Text)
BG3: Bitmapped BG
and you'll rearrange the order using the BG_PRIORITY(n) where 0>=n>=3, lower values are in front.
#175601 - SchmendrickSchmuck - Mon Jan 03, 2011 12:37 pm
Sverx,
That is exactly what I am trying to accomplish, but what I'm doing doesn't seem to work. Below is my entire init code, along with an explanation of what I'm trying to do with every line.
Code: |
vramSetBankA(VRAM_A_TEXTURE); // VRAM A for 3D textures
videoSetMode(MODE_5_3D); // Init video
consoleDemoInit(); // Init text on sub screen
init_gl_screen(); // Init GL on main screen, code is direct copy of examples
vramSetBankB(VRAM_B_MAIN_BG); // VRAM B for bitmap memory
int gfxbg = bgInit(3, BgType_Bmp16, BgSize_B16_256x256, 0,0); // Init bmp bg on layer 3
bgSetPriority(0, 2); // Set 3D layer on layer 2
bgSetPriority(3, 0); // Set bitmap layer on top
bgHide(0); // Hide 3D layer just in case
u16* buffer = (u16*)bgGetGfxPtr(gfxbg);
for(int i = 0; i < 256 * 192; i++)
buffer[i] = RGB15(0, 31, 0); // Fill up screen with green
// Result remains a black screen |
I changed part of the code to be the same as some of the bitmap examples, but I still end up with a black screen.
#175603 - sverx - Mon Jan 03, 2011 2:39 pm
Code: |
buffer[i] = RGB15(0, 31, 0) | 0x8000; // Fill up screen with green |
16 bits bitmap have an alpha bit that you need to set to actually show the pixel...
#175605 - SchmendrickSchmuck - Mon Jan 03, 2011 4:51 pm
That got me excited for a bit (excuse the pun), but no dice. Anything else it might be? Maybe something outside of the piece of code I posted that could be messing things up?
#175606 - sverx - Mon Jan 03, 2011 5:22 pm
maybe you've still got other layers active on top of this one? Hide the others as well. Then no other idea. Try debugging with DeSmuME...
#175607 - SchmendrickSchmuck - Mon Jan 03, 2011 6:02 pm
I looked at some stuff in DeSmuME, and the only layers I have as visible are layer 0 (3D) and layer 3 (bitmap). There the screen shows as black too.
My full code (I took out EVERYTHING else, so this might as well be directly inside main()):
Code: |
vramSetBankA(VRAM_A_TEXTURE);
videoSetMode(MODE_5_3D);
consoleDemoInit();
vramSetBankB(VRAM_B_MAIN_BG); // VRAM B for bitmap memory
int gfxbg = bgInit(3, BgType_Bmp16, BgSize_B16_256x256, 0,0); // Init bmp bg on layer 3
bgSetPriority(0, 2); // Set 3D layer on layer 2
bgSetPriority(3, 0); // Set bitmap layer on top
buffer = (u16*)bgGetGfxPtr(gfxbg);
for(int i = 0; i < 256 * 96; i++)
buffer[i] = RGB15(0, 31, 0) | 0x8000; // Fill up screen with green
while(1);
// Result remains a black screen |
I changed 192 to 96 to fill half the screen instead.
EDIT:
I have found a solution: Changing the B bank to A made it work, but why can't I use bank B for bitmap layers? And if it is possible, how can I do this?
#175611 - sverx - Tue Jan 04, 2011 11:58 am
Oh, right, I didn't notice that.
VRAM_B_MAIN_BG is a synonym of VRAM_B_MAIN_BG_0x06020000, so it's 'the second bank' for BGs.
You shoud use VRAM_B_MAIN_BG_0x06000000 instead.
I made a web page, a while ago, with all these. It's in Italian but I guess it's understandable anyway: list of all the modes for all the VRAM banks explained
#175612 - SchmendrickSchmuck - Tue Jan 04, 2011 12:25 pm
Thanks sverx, that seemed to do the trick. I thought MAIN_BG was always the same as the 0x06000000 address, but I see that that's not the case for banks B, C and D. Thanks again!
EDIT:
I need some more help concerning backgrounds. I'm trying to add a scrolling tiled background to my game, but all I get is garbage. My initializing code:
Code: |
videoSetMode(MODE_5_3D);
videoSetModeSub(MODE_5_2D);
vramSetBankA(VRAM_A_TEXTURE); // Sprite/3D textures
vramSetBankC(VRAM_C_SUB_BG); // Sub bg text
Init3D(); // Initializes 3D engine
vramSetBankE(VRAM_E_MAIN_BG); // Main bg text/8bit bg. Bank E size == 64kb, enough for 8bit * 256 * 192 + text layer
consoleInit(&topScreen, LAYER_MAIN_TEXT, BgType_Text4bpp, BgSize_T_256x256, 3, 0, true, true); // Map base of 3 (8bit bg = 256 * 192 * 8bit = 48kb = 3 * 16kb)
consoleInit(&bottomScreen, LAYER_SUB_TEXT, BgType_Text4bpp, BgSize_T_256x256, 2, 0, false, true); // Map base of 2 (?)
consoleClear();
consoleSelect(&topScreen);
consoleClear();
vramSetBankB(VRAM_B_MAIN_BG);
offset_x = offset_y = 0;
scroll_x = 0;
scroll_y = 0;
bg = bgInit(2, BgType_Text8bpp, BgSize_T_512x256, 4, 0);
dmaCopy(TextBackgroundsTiles, bgGetGfxPtr(bg), sizeof(TextBackgroundsTiles));
dmaCopy(TextBackgroundsPal, BG_PALETTE, sizeof(TextBackgroundsPal));
bgTileMap = (u16*)bgGetMapPtr(bg);
for(int iy = 0; iy < screenHeight; iy++)
dmaCopy(&Layer1024x1024Map[iy * mapWidth], &bgTileMap[iy * bgWidth], screenWidth * 2);
tex = LoadTexture((void*)gg_pcx, 128, 128, 0);
bgSetPriority(LAYER_MAIN_TEXT, 0);
bgSetPriority(LAYER_MAIN_3D, 2);
bgSetPriority(2, 1);
|
Then in the main game loop (mostly taken from bg scrolling example):
Code: |
u16* bgLeftHalf = bgTileMap;
u16* bgRightHalf = bgTileMap + 32 * 32;
movingHorizontal = false;
movingVertical = false;
if(IsKeyDown(KEY_LEFT))
{
offset_x = scroll_x / 8 - 1;
scroll_x--;
if(scroll_x < 0)
scroll_x = 0;
else
movingHorizontal = true;
}
else if(IsKeyDown(KEY_RIGHT))
{
offset_x = scroll_x / 8 + screenWidth;
scroll_x++;
if(scroll_x >= (mapWidth - screenWidth) * tileWidth)
scroll_x = (mapWidth - screenWidth) * tileWidth - 1;
else
movingHorizontal = true;
}
if(IsKeyDown(KEY_UP))
{
offset_y = scroll_y / 8 - 1;
scroll_y--;
if(scroll_y < 0)
scroll_y = 0;
else
movingVertical = true;
}
else if(IsKeyDown(KEY_DOWN))
{
offset_y = scroll_y / 8 + screenHeight;
scroll_y++;
if(scroll_y >= (mapHeight - screenHeight) * tileWidth)
scroll_y = (mapHeight - screenHeight) * tileWidth - 1;
else
movingVertical = true;
}
if(movingHorizontal)
{
u16* bgTemp = ((offset_x & 63) >= bgWidth) ? bgRightHalf : bgLeftHalf;
for(int iy = scroll_y / 8 - 1 ; iy < scroll_y / 8 + screenHeight + 1; iy++)
{
bgTemp[(offset_x & (bgWidth - 1)) + (iy & (bgHeight - 1)) * 32] =
Layer1024x1024Map[offset_x + iy * mapWidth];
}
}
if(movingVertical)
{
for(int ix = scroll_x / 8 - 1 ; ix < scroll_x / 8 + screenWidth + 1; ix++)
{
u16* bgTemp = ((ix & 63) >= bgWidth) ? bgRightHalf : bgLeftHalf;
bgTemp[(ix & (bgWidth - 1)) + (offset_y & (bgHeight - 1))* 32] =
Layer1024x1024Map[ix + offset_y * mapWidth];
}
}
bgSetScroll(bg, scroll_x, scroll_y);
bgUpdate();
|
I am using the tile files from the example: #include <TextBackgrounds.h>
Result: http://img191.imageshack.us/img191/9898/screeniey.png
Any help would be appreciated