Problem testing PrintConsole

Post Reply
Sylus101
Posts: 179
Joined: Wed Dec 24, 2008 5:08 am

Problem testing PrintConsole

Post by Sylus101 » Fri Jan 02, 2009 12:20 am

I was successfully able to get an 8bit background on layer 2 with some transparency spots showing a 16 bit background on layer 3 underneath. Once I figured out how to set the mapbase offset correctly (at least I'm pretty sure I did) so that one would load into BANK A and the other into BANK B things seemed fine.

Now, I've removed the 8bit layer and am trying to put a print Console on a layer above the 16 bit one, 0 in this case. There are a handful of problems, but I think I'm close. EDIT - I have looked at the post a little bit down from here and tried to use it as a reference since it's pretty much the same scenario (I'm using 2 VRAM banks though...) but it didn't help much...

1. If I put up text before loading the background's graphics, that text is not shown.

2. Text displayed afterward shows up, but there are artifact characters elsewhere on the screen.

3. Clearing the console (Pressing and releasing A button) and trying to display more text results in a blue horizontal bar across
the top of the screen and more text is displayed successfully. The other artifacts are gone. I've had varying results as I've tried to get the right
mapbase and tilebase values. If I understand correctly... I need to get those into VRAM_B, so the mapbase must be 64 or higher and the tilebase 8 or higher. Outputting the gfx location (as long as I'm doing even that part right) seems to verify my assumption, but still... the results aren't quite right.

4. Here's the code as it stands. The only compiler warning is the output of bgGetGfxPtr(topScreen.bgId) which it says is a u16 ** when it expects an unsigned int. I couldn't seem to get that to cast down right... but it still shows outputs what I expect to see.

Code: Select all

#include <nds.h>
#include <stdio.h>
#include "spriteinfo.h"
#include "test1_bin.h"

int main(void) {
	//---------------------------------------------------------------------------------
	
	int i = 0;
	
	int width = 16, length = 16, frame = 0, max_frame = 2;
	
	int sp2x = 120, sp2y = 80;
	
	u8 lcdswapped = 0;
	
	touchPosition touch;

	videoSetMode(MODE_5_2D);

	videoSetModeSub(MODE_0_2D);

	vramSetBankA(VRAM_A_MAIN_BG);
	vramSetBankB(VRAM_B_MAIN_BG);
	vramSetBankD(VRAM_D_SUB_SPRITE);
	
	// 16 bit background on layer 3 using VRAM A
	int bg3id = bgInit(3, BgType_Bmp16, BgSize_B16_256x256, 0, 0);
	
	// Print console on layer 0, mapbase should be 64*2k = 128 and at 0x06020000
	// tilebase is at 9 * 16k = 144, should be offset enough from mapbase and in VRAMB... I think...
	PrintConsole topScreen = *consoleInit(0, 0, BgType_Text4bpp, BgSize_T_256x256, 64, 9, true);
	consoleSelect(&topScreen);
	
	oamInit(&oamSub, SpriteMapping_1D_128, false);

	u16* gfxSub = oamAllocateGfx(&oamSub, SpriteSize_16x16, SpriteColorFormat_256Color);
	
	u16* gfxSub2 = oamAllocateGfx(&oamSub, SpriteSize_16x16, SpriteColorFormat_256Color);
	
	for(i = 0; i < 4; i++) SPRITE_PALETTE_SUB[i] = face_Pal[i]-32768;
	
       //This text is not seen
	iprintf("\tsometest\n");
	
	DC_FlushAll();
	dmaCopyWords(3, face_Sprite + length*width*frame, gfxSub, 256);
	dmaCopyWords(3, face_Sprite + length*width*frame, gfxSub2, 256);
	dmaCopyWords(3, test1_bin, bgGetGfxPtr(bg3id), test1_bin_size);
	
	oamSet(&oamSub, 1, sp2x, sp2y, 0, 0, SpriteSize_16x16, SpriteColorFormat_256Color, gfxSub2, -1, false, false);
	
	iprintf("\n\n\tHello DS dev'rs\n");
	iprintf("\twww.drunkencoders.com\n");
	iprintf("\twww.devkitpro.org\n");
	iprintf("\tprint console bgId\n\tgfx are at: 0x%x", bgGetGfxPtr(topScreen.bgId));

	while(1) {

		scanKeys();

		if(keysHeld() & KEY_TOUCH){
			touchRead(&touch);
		}
			
		if(keysUp() & KEY_A){
			frame++;
			if(frame > max_frame) frame = 0;
			DC_FlushRange(face_Sprite + length*width*frame, 256);
			dmaCopyWords(3, face_Sprite + length*width*frame, gfxSub, 256);
			consoleClear();
                        iprintf("\n\n\tHello DS dev'rs\n");
			iprintf("\twww.drunkencoders.com\n");
			iprintf("\twww.devkitpro.org\n");
		}
		
		if(keysHeld() & KEY_RIGHT)
			sp2x++;
		if(keysHeld() & KEY_LEFT)
			sp2x--;
		if(keysHeld() & KEY_UP)
			sp2y--;
		if(keysHeld() & KEY_DOWN)
			sp2y++;
			
		if(keysUp() & KEY_L){
			lcdSwap();
			if(lcdswapped)lcdswapped = 1; else lcdswapped = 0;
		}
		
		oamSet(&oamSub, 
			0, 
			touch.px, 
			touch.py, 
			0, 
			0,
			SpriteSize_16x16, 
			SpriteColorFormat_256Color, 
			gfxSub, 
			-1, 
			false, 
			false);
			
		oamSet(&oamSub, 
			1, 
			sp2x, 
			sp2y, 
			0, 
			0,
			SpriteSize_16x16, 
			SpriteColorFormat_256Color, 
			gfxSub2, 
			-1, 
			false, 
			false);

		swiWaitForVBlank();

		oamUpdate(&oamSub);
	}

	return 0;
}
-Sylus "Not Stylus..." McFrederickson

Come visit my web site.

dovoto
Developer
Posts: 43
Joined: Fri Aug 12, 2005 10:01 pm
Contact:

Re: Problem testing PrintConsole

Post by dovoto » Sat Jan 03, 2009 2:59 pm

Maximum map base is 31, maps must come in the first 64 K of background memory on the DS.

try:
print console
map base 0
gfx base 1

bmp layer
map base 2 (map base is used as a 16 K offset by bitmap layers)

Sylus101
Posts: 179
Joined: Wed Dec 24, 2008 5:08 am

Re: Problem testing PrintConsole

Post by Sylus101 » Sat Jan 03, 2009 7:19 pm

I've had a long edited response that I haven't had a chance to post but now it looks like I have 2 solutions. Your suggestion worked fine, thanks a bunch and believe it or not, I'm sure I understand how that worked. I've got 128k available in VRAM A. Putting the console's map at 0 and tiles at 1 makes spots 0-15 available for gfx and 16-31 for the map and 32-127 will be for the bmp graphics. So that puts everything in VRAM A. Good to know too that a map must occur in the first 64k of a bank.

Let's just assume for some reason I need the extra 32k in VRAM A for something else and I want to just move the console's graphics to the beginning of VRAM bank B. I kept going back to the solution in the post by yrro a few weeks ago with the same issue, and I actually came up with something that worked. Adding DISPLAY_SCREEN_BASE(2) to VideoSetMode and adding topScreen.fontBgMap = BG_MAP_RAM(4 + 64); did the trick.

I'm rather confused, though, why this worked... I'm really wishing I could see more of the code behind bgInit and consoleInit at this point. I'm reading through video.h, background.h, console.h, and the gbatek spec page trying desperately to better understand how this is working under the hood. I think I'm getting there, particularly how the DISPCNT registers work and are being set by the libnds macros, but how the BGxCNT ones I'm struggling with, particularly setting where in RAM where a map and tiles are located.

It just feels like this 2nd solution required too much compensation for it to work. In my mind the DISPLAY_SCREEN_BASE change should have been enough, providing the 128k vram offset for the map data, but even then... I don't understand how that knew which BG layer I was working with? What if I wanted to put another tiled bg on Layer 1 using more memory from Bank B or even Bank C?

Code: Select all

#include <nds.h>
#include <stdio.h>
#include "spriteinfo.h"
#include "test1_bin.h"

int main(void) {
	//---------------------------------------------------------------------------------
	
	int i = 0;
	
	int width = 16, length = 16, frame = 0, max_frame = 2;
	
	int sp2x = 120, sp2y = 80;
	
	u8 lcdswapped = 0;
	
	touchPosition touch;

	videoSetMode(MODE_5_2D | DISPLAY_SCREEN_BASE(2));

	videoSetModeSub(MODE_0_2D);

	vramSetBankA(VRAM_A_MAIN_BG);
	vramSetBankB(VRAM_B_MAIN_BG);
	vramSetBankD(VRAM_D_SUB_SPRITE);
	
	// 16 bit background on layer 3 using VRAM A
	int bg3id = bgInit(3, BgType_Bmp16, BgSize_B16_256x256, 0, 0);
	
	// Print console on layer 0, mapbase should be 4*2k = 8k
	// tilebase is at 8 * 16k = 128k and at the start of VRAM BANK B
        PrintConsole topScreen = *consoleInit(0, 0, BgType_Text4bpp, BgSize_T_256x256, 4, 8, true);
        topScreen.fontBgMap = BG_MAP_RAM(4 + 64);
	consoleSelect(&topScreen);
	
	oamInit(&oamSub, SpriteMapping_1D_128, false);

	u16* gfxSub = oamAllocateGfx(&oamSub, SpriteSize_16x16, SpriteColorFormat_256Color);
	
	u16* gfxSub2 = oamAllocateGfx(&oamSub, SpriteSize_16x16, SpriteColorFormat_256Color);
	
	for(i = 0; i < 4; i++) SPRITE_PALETTE_SUB[i] = face_Pal[i]-32768;
	
       //This text is not seen
	iprintf("\tsometest\n");
	
	DC_FlushAll();
	dmaCopyWords(3, face_Sprite + length*width*frame, gfxSub, 256);
	dmaCopyWords(3, face_Sprite + length*width*frame, gfxSub2, 256);
	dmaCopyWords(3, test1_bin, bgGetGfxPtr(bg3id), test1_bin_size);
	
	oamSet(&oamSub, 1, sp2x, sp2y, 0, 0, SpriteSize_16x16, SpriteColorFormat_256Color, gfxSub2, -1, false, false);
	
	iprintf("\n\n\tHello DS dev'rs\n");
	iprintf("\twww.drunkencoders.com\n");
	iprintf("\twww.devkitpro.org\n");
	iprintf("\tprint console bgId\n\tgfx are at: 0x%x", bgGetGfxPtr(topScreen.bgId));

	while(1) {

		scanKeys();

		if(keysHeld() & KEY_TOUCH){
			touchRead(&touch);
		}
			
		if(keysUp() & KEY_A){
			frame++;
			if(frame > max_frame) frame = 0;
			DC_FlushRange(face_Sprite + length*width*frame, 256);
			dmaCopyWords(3, face_Sprite + length*width*frame, gfxSub, 256);
			consoleClear();
                        iprintf("\n\n\tHello DS dev'rs\n");
			iprintf("\twww.drunkencoders.com\n");
			iprintf("\twww.devkitpro.org\n");
		}
		
		if(keysHeld() & KEY_RIGHT)
			sp2x++;
		if(keysHeld() & KEY_LEFT)
			sp2x--;
		if(keysHeld() & KEY_UP)
			sp2y--;
		if(keysHeld() & KEY_DOWN)
			sp2y++;
			
		if(keysUp() & KEY_L){
			lcdSwap();
			if(lcdswapped)lcdswapped = 1; else lcdswapped = 0;
		}
		
		oamSet(&oamSub, 
			0, 
			touch.px, 
			touch.py, 
			0, 
			0,
			SpriteSize_16x16, 
			SpriteColorFormat_256Color, 
			gfxSub, 
			-1, 
			false, 
			false);
			
		oamSet(&oamSub, 
			1, 
			sp2x, 
			sp2y, 
			0, 
			0,
			SpriteSize_16x16, 
			SpriteColorFormat_256Color, 
			gfxSub2, 
			-1, 
			false, 
			false);

		swiWaitForVBlank();

		oamUpdate(&oamSub);
	}

	return 0;
}
-Sylus "Not Stylus..." McFrederickson

Come visit my web site.

dovoto
Developer
Posts: 43
Joined: Fri Aug 12, 2005 10:01 pm
Contact:

Re: Problem testing PrintConsole

Post by dovoto » Sun Jan 04, 2009 4:01 pm

I always seem to forget about the base offsets in display control. I am in the middle of a move but will take a look and see if i can clear that up tonight.

Sylus101
Posts: 179
Joined: Wed Dec 24, 2008 5:08 am

Re: Problem testing PrintConsole

Post by Sylus101 » Sun Jan 04, 2009 11:45 pm

Yea, moving sucks.

I tried to research the DISPLAY_SCREEN_BASE and DISPLAY_CHAR_BASE settings a bit and am having trouble finding much information. My main confusion is that when these are used does it offset in all 4 background registers where the DS will look for map and tile graphics? If so, wouldn't have setting DISPLAY_SCREEN_BASE(2) have messed up where my 16 bit bg graphics were found? On second thought... since there isn't a map and just tile data I suppose that's why. Now if it'd been a tiled bg... I would have had to compensate for it as well, correct?

I guess where my main confusion is that I wasn't clear on what restrictions there are with where tile and map data could be stored. I was initially getting the impression I could pretty much point anything to any starting point in any VRAM Bank as long as it had been initialized. A bit naive, I'm realizing.

EDIT - Would I be correct (or at least close) in saying, that all Background graphics per engine (tiled and bmp) must fit (or would "start" be a better word?) within a 256k block of adjacent and initialized VRAM Banks? Same for maps but a 64k block (and that 64k block needs to be at the start of a VRAM Bank?)?
-Sylus "Not Stylus..." McFrederickson

Come visit my web site.

Post Reply

Who is online

Users browsing this forum: Google [Bot] and 6 guests