newbie: one bg on bottom, one bg with text on top

Post Reply
radiodee1
Posts: 10
Joined: Sat Dec 05, 2009 8:50 pm

newbie: one bg on bottom, one bg with text on top

Post by radiodee1 » Sat Dec 05, 2009 9:10 pm

I'm trying to write my first libnds program. I have converted a set of tiles and displayed them on the lower (main) screen. I have written on the top screen and now I want to also display a number of the same tiles on the top screen with the text at the same time. I can get the lower display to work, and I can get text on the upper display, but cannot display tiles as well. When I mess with the various values in the code I can get colored pixels on the screen, but they don't resemble any of my tiles. They do, however, move if I change the REG_BG1HOFS_SUB and REG_BG1VOFS_SUB registers.

P.S. much of the code here was taken from other tutorials. I've tried to piece something together.

Code: Select all

//-----------------------------------------------------------
#include <nds.h>
#include <nds/arm9/background.h> // needed for REG_BG0CNT
#include <stdlib.h>
#include <stdio.h>


#include "tilesMap_bin.h"
#include "tilesTiles_bin.h"
#include "tilesPal_bin.h" 

static const int DMA_CHANNEL = 3;
static const int TILES_WIDTH = 28;
static const int TILES_HEIGHT = 16;
 
int main(void) {

	int i;
	int xoffset = 0;
	int yoffset = 0;
	int j, k;
	
	int Hmove = 3;
	int Vmove = 3;
        int scrollY = 0;
        int scrollX = 0;
  
	int displayBg1Map = 15; 
	int displayBg1Tile = 2;
	
	PrintConsole topScreen;
	
	powerOn(POWER_ALL_2D);
	
        lcdMainOnBottom(); // Place the main screen on the bottom physical screen
	
	vramSetMainBanks(VRAM_A_MAIN_BG_0x06000000,
                     VRAM_B_MAIN_BG_0x06020000,
                     VRAM_C_SUB_BG_0x06200000,
                     VRAM_D_LCD);
	
	//set video mode and map vram to the background
	videoSetMode(MODE_5_2D | DISPLAY_BG0_ACTIVE | DISPLAY_BG2_ACTIVE); 
	
	videoSetModeSub(MODE_5_2D  | DISPLAY_BG1_ACTIVE  ); 
	
	bgInit(0, BgType_Text8bpp, BgSize_T_512x512, 0, 1);
        int bgs1 = bgInitSub(1, BgType_Text8bpp, BgSize_T_512x512, displayBg1Map, displayBg1Tile); 
  
        consoleInit(&topScreen, 0,BgType_Text4bpp, BgSize_T_256x256, 31, 0, false, true);
  
	REG_BG0CNT = BG_64x64 | BG_COLOR_256 | BG_MAP_BASE(0) | BG_TILE_BASE(1);
	REG_BG1CNT_SUB = BG_64x64 | BG_COLOR_256 | BG_MAP_BASE(displayBg1Map) | BG_TILE_BASE(displayBg1Tile); 
  
	u16* mapMemory = (u16*)SCREEN_BASE_BLOCK(0); 

        u16* mapMemorySub = bgGetGfxPtr(bgs1); 
  
	dmaCopyHalfWords(DMA_CHANNEL,
                     tilesTiles_bin, 
                     (uint16 *)BG_TILE_RAM(1), 
                     tilesTiles_bin_size);
                    
        dmaCopyHalfWords(DMA_CHANNEL,
                     tilesPal_bin, 
                     (uint16 *)BG_PALETTE, 
                     tilesPal_bin_size);
  
  ///////////////////////////////////////////////////////
  
        dmaCopyHalfWords(DMA_CHANNEL,
                     tilesTiles_bin, 
                     (uint16 *)bgGetGfxPtr(bgs1), 
                     tilesTiles_bin_size);
                  

  if(1) {// turn off loop
    for (k = 0; k < 4; k ++) { // one of each of 4 maps    
      for (i = 0; i < 32; i++) { //treat each row 
        for (j = 0; j < 32; j ++ ) { // treat each entry in each row (column) 
          xoffset = j  & (TILES_WIDTH - 1);
          yoffset = i  & (TILES_HEIGHT - 1);

          mapMemory[ (32 * i) + j + (k * 32 * 32)] = TILES_HEIGHT * TILES_WIDTH; //black tile
        }      
      } 
    } 
  }


  // lay out tiles on main screen (bottom)
  for (i = 0; i < 32; i++) { //treat each row 
        for (j = 0; j < 32; j ++ ) { // treat each entry in each row (column)      
          if (j < TILES_WIDTH && i < TILES_HEIGHT) 
            mapMemory[ (32 * i) + j ] = j +( TILES_WIDTH * i);
          else mapMemory[ (32 * i) + j ] = TILES_HEIGHT * TILES_WIDTH;
        } // j block      
      }

    // show first 10 tiles on top screen. -- Doesn't work.
    for (i = 0; i < 10; i ++) {
		  mapMemorySub[i] = i;
    }
    
          consoleSelect(&topScreen);
          consoleSetWindow(&topScreen, 10,10, 32,1);

        while (1) {

          scanKeys();
      
          u16 keysPressed = keysHeld();
		if(!(keysPressed & KEY_RIGHT)) 
		{

                   scrollX -= Hmove;
		}
		if(!(keysPressed & KEY_LEFT)) 
		{

                  scrollX += Hmove;
		}
                if(!(keysPressed & KEY_UP)) 
		{

                  scrollY += Vmove;
		}
		if(!(keysPressed & KEY_DOWN)) 
		{

                  scrollY -= Vmove;
		}
		
		
		REG_BG0HOFS = scrollX;
                REG_BG0VOFS = scrollY;
		
                REG_BG1HOFS_SUB = scrollX;
                REG_BG1VOFS_SUB = scrollY;
                swiWaitForVBlank();  
    
                consoleClear();
                iprintf("hello");
    
    
  }

	return 0;
}
Last edited by radiodee1 on Mon Dec 07, 2009 1:05 pm, edited 1 time in total.

radiodee1
Posts: 10
Joined: Sat Dec 05, 2009 8:50 pm

Re: newbie: one bg on bottom, one bg with text on top

Post by radiodee1 » Mon Dec 07, 2009 12:59 pm

I didn't mean for the last post to come out looking the way it did. The code is sometimes unreadable because of the spacing, but I didn't know it was going to look that way when I originally posted it.

So, there's obviously a lot I don't understand. Maybe someone can answer just a few simple questions, though.

1.) is it even possible to have console text and a working bg on one of the engines?
2.) if it is possible, can you do this on the sub engine, or do you have to do it on the main engine?

I could probably ask other questions, but I won't now.

StevenH
Posts: 133
Joined: Sun Feb 22, 2009 7:59 pm

Re: newbie: one bg on bottom, one bg with text on top

Post by StevenH » Tue Dec 08, 2009 12:43 am

1) Yes it's possible, but you will have to use some very careful memory management depending on the type of image you are wanting to use.

2) Both can do it, just be aware that the sub engine is not as powerful as the main engine, so you will not be able to do exactly the same on the two screens.

IIRC there's an example that shows how this works.

radiodee1
Posts: 10
Joined: Sat Dec 05, 2009 8:50 pm

Re: newbie: one bg on bottom, one bg with text on top

Post by radiodee1 » Tue Dec 08, 2009 5:05 pm

OK. I have some questions that don't relate to console output.

I was under the impression that map and tile bases started at 0x6000000. Is this regardless of what VRAM banks you have activated?

If you activate VRAM_C as a SUB background (VRAM_C_SUB_BG_0x06200000) and you want to put a tile set and a map into that area (which I think is do-able) and you already have banks A and B activated, and you want to know the bases for your tileset and your map, do you start numbering over from zero? (assuming that you're working with the sub engine or maybe because you're working with a new VRAM bank...) Or do you continue your numbering from the first things that you were working on in bank A + B. Maybe put a different way, do you continue numbering from 0x6000000 or do you start over?

Yjerkle
Posts: 3
Joined: Wed Jan 13, 2010 12:29 am

Re: newbie: one bg on bottom, one bg with text on top

Post by Yjerkle » Wed Jan 13, 2010 12:40 am

Tile and map bases for the main engine start at 0x6000000. Tile and map bases for the sub engine start at 0x06200000. These two addresses are fixed regardless of what banks are mapped into those places.

If, for example, you've got banks A, B and D set as consecutive main bg, and C as sub bg, then you'll address the memory in A, B and D with one continuous set of base numbers, starting with base 0 at the beginning of A (0x6000000) and continuing through B and D, and you'll address C with a another set, starting with base 0 at the beginning of C (0x06200000) and continuing only to the end of C.

radiodee1
Posts: 10
Joined: Sat Dec 05, 2009 8:50 pm

Re: newbie: one bg on bottom, one bg with text on top

Post by radiodee1 » Wed Jan 13, 2010 2:42 pm

Thank you, that's very helpful.

Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 0 guests