Background Problems

Post Reply
Swifty
Posts: 1
Joined: Sat Sep 17, 2011 2:18 am

Background Problems

Post by Swifty » Sat Sep 17, 2011 3:32 am

I recently upgraded my game after a very long time, and I've found that my backgrounds aren't showing any more. The sprites are all showing up fine, but the backgrounds are all completely black. I've changed the references from vramSetMainBanks/vramRestoreMainBanks to vramSetPrimaryBanks/vramRestorePrimaryBanks.

I'm at a loss as to what has happened. Anyone care to point out where I've done something stupid?

Code: Select all

#include <nds.h>
#include <string>
using std::string; //to use C++ strings
#include <stdio.h>
#include <string.h>

int backgrounds[2][4]; //[main?] [layer]
void loadBgTiles(int bg, const char* path);
void loadBgMap(bool main, int bg, bool extended,const char* path);
void loadBgPal(bool main,int bg, const char* path);
void loadBgMap256x256(int bg, u8* buffer, int size);
void loadBgMapNotER(int bg, u8* buffer, int size);

void loadBg(bool main, int number, int mapBase, int tileBase, const char* name, BgSize size){
	string path = name;
	path = "bg/" + path + ".map.bin";
	if(main){
		if(number < 2){
			backgrounds[main][number] = bgInit(number, BgType_Text8bpp, size, mapBase, tileBase);
		}
		else{
			backgrounds[main][number] = bgInit(number, BgType_ExRotation, size, mapBase/2, tileBase);
		}
	}
	else{
		backgrounds[main][number] = bgInitSub(number, BgType_Text8bpp, BgSize_T_512x512, mapBase, tileBase);
	}
	bgHide(backgrounds[main][number]);
	bool rotScale = false;
	if(main && number>1){
		rotScale = true;
	}
	loadBgMap(rotScale, backgrounds[main][number], size == BgSize_ER_512x512,  path.c_str());
	path = name;
	path = "bg/" + path + ".img.bin";
	loadBgTiles(backgrounds[main][number], path.c_str());
	path = name;
	path = "bg/" + path + ".pal.bin";
	loadBgPal(main, number, path.c_str());
	bgShow(backgrounds[main][number]);
}

void loadBg(bool main, int number, int tileMapBase, const char* name, BgSize size){
	loadBg(main, number, tileMapBase, tileMapBase, name, size);
}

void loadBg(bool main, int number, int mapBase, int tileBase, const char* name){
	BgSize size = BgSize_T_512x512;
	if(main && number >= 2){
		size = BgSize_ER_512x512;
	}
	loadBg(main, number, mapBase, tileBase, name, size);
}

void loadBg(bool main, int number, int tileMapBase, const char* name){
	BgSize size = BgSize_T_512x512;
	if(main && number >= 2){
		size = BgSize_ER_512x512;
	}
	loadBg(main, number, tileMapBase, tileMapBase, name, size);
}

void loadBgTiles(int bg, const char* path){
	int i, size;
	u8* buffer;
	FILE* gfx;
	gfx = fopen(path, "rb");
	if(gfx != NULL) {
		fseek(gfx, 0, SEEK_END);
		size = ftell(gfx); 
		fseek(gfx, 0, SEEK_SET);
		
		buffer = new u8[size];
		
		i = 0;
		while(i < size) {
			fread(&buffer[i], 1, 1, gfx);
			i++;
		}
		memcpy(	  bgGetGfxPtr(bg), /* Our address for main
											background 3 */
				buffer, /* This variable is generated for us by
									grit. */
				 size); /* This length (in bytes) is generated
											from grit. */
		delete[] buffer;
		fclose(gfx);
	}else{
		iprintf("File NULL");
	}
}

void loadBgMap(bool main, int bg, bool extended, const char* path){
	FILE* gfx;
	int i, size;
	u8* buffer;
	gfx = fopen(path, "rb");
	if(gfx != NULL) {
		fseek(gfx, 0, SEEK_END);
		size = ftell(gfx); 
		fseek(gfx, 0, SEEK_SET);
		
		buffer = new u8[size];
		
		i = 0;
		while(i < size) {
			fread(&buffer[i], 1, 1, gfx);
			i++;
		}
		if((size>4095 && extended ) || !main ){
			memcpy(	  bgGetMapPtr(bg),	//Our address for background
							buffer,		//This variable is generated for us by
											// grit.
							 size);		// This length (in bytes) 
		}else{
			if(extended){
				loadBgMap256x256(bg, buffer, size);
			}else{
				loadBgMapNotER(bg, buffer, size);
			}
		}
		delete[] buffer;
		fclose(gfx);
	}else{
		iprintf("File NULL");
	}
}

void loadBgMapNotER(int bg, u8* buffer, int size){
//----------------------------
	u16* map = (u16*)bgGetMapPtr(bg); 
				//draw top half 
	for(int iy = 0; iy < 32; iy++){ 
		//first the left half 
		memcpy(map+(iy*32), buffer+(iy*128), 64); 
		 
		//then the right half 
		memcpy(map + (32 + iy) * 32, buffer + iy * 128 + 64, 32 * 2); 
	} 
	 
	//map += 32 * 32 * 2; 
	 
	//draw bottom half 
	for(int iy = 0; iy < 32; iy++){ 
		//copy one line at a time 
		//first the left half 
		memcpy(map+((iy+64)*32), buffer+((iy+32)*128), 64); 
		 
		//then the right half 
		memcpy(map+((iy+96)*32), buffer+((iy+32)*128)+64, 64); 
	}
//----------------------------------	
}

void loadBgMap256x256(int bg, u8* buffer, int size){
	u16* map = (u16*)bgGetMapPtr(bg);
	for(int iy = 0; iy < 32; iy++){
		memcpy(map+(iy*64), buffer+(iy*64), 64);
	}
}
void loadBgPal(bool main, int number, const char* path){
	FILE* gfx;
	int i, size;
	u8* buffer;
	gfx = fopen(path, "rb");
	if(gfx != NULL) {
		fseek(gfx, 0, SEEK_END);
		size = ftell(gfx); 
		fseek(gfx, 0, SEEK_SET);
		
		buffer = new u8[size];
		
		i = 0;
		while(i < size) {
			fread(&buffer[i], 1, 1, gfx);
			i++;
		}
		if(main){
			vramSetBankE(VRAM_E_LCD);
			memcpy(VRAM_E_EXT_PALETTE[number*16], /* screen palette*/
							buffer, size);
			vramSetBankE(VRAM_E_BG_EXT_PALETTE);
			switch(number){
				case 3:
					REG_BG3CNT |= BG_PALETTE_SLOT3;
					break;
				case 2:
					REG_BG2CNT |= BG_PALETTE_SLOT2;
					break;
				case 1:
					REG_BG1CNT |= BG_PALETTE_SLOT1;
					break;
				case 0:
					REG_BG0CNT |= BG_PALETTE_SLOT0;
					break;
			}
		}else{
			vramSetBankH(VRAM_H_LCD);
			memcpy(VRAM_H_EXT_PALETTE[number*16], /* screen palette*/
							buffer, size);
			vramSetBankH(VRAM_H_SUB_BG_EXT_PALETTE);
			switch(number){
				case 3:
					REG_BG3CNT_SUB |= BG_PALETTE_SLOT3;
					break;
				case 2:
					REG_BG2CNT_SUB |= BG_PALETTE_SLOT2;
					break;
				case 1:
					REG_BG1CNT_SUB |= BG_PALETTE_SLOT1;
					break;
				case 0:
					REG_BG0CNT_SUB |= BG_PALETTE_SLOT0;
					break;
			}
			REG_DISPCNT_SUB |= DISPLAY_BG_EXT_PALETTE; /*Tell the sub screen to use
							extended palettes for the backgrounds*/
		}
		delete[] buffer;
		fclose(gfx);
	}else{
		iprintf("File NULL");
	}
}

void loadFont(char* name, ConsoleFont target){
//First the tiles
	string path = name;
	path = "font/"+path+".img.bin";
	int i, size;
	u16* buffer;
	FILE* gfx;
	gfx = fopen(path.c_str(), "rb");
	if(gfx != NULL) {
		fseek(gfx, 0, SEEK_END);
		size = ftell(gfx); 
		fseek(gfx, 0, SEEK_SET);
		
		buffer = (u16*)malloc(size);
		
		i = 0;
		while(i < size) {
			fread(&buffer[i], 1, 1, gfx);
			i++;
		}
		memcpy(	target.gfx, /* Font's tiles */
				buffer, /* This variable is generated for us by
								   * grit. */
				 size); /* This length (in bytes) is generated
									   from the file read. */
		free(buffer); 
		fclose(gfx);
	}else{
		iprintf("File NULL");
	}
//Then the palette
	path = name;
	path = "font/"+path+".pal.bin";
	gfx = fopen(path.c_str(), "rb");
	if(gfx != NULL) {
		fseek(gfx, 0, SEEK_END);
		size = ftell(gfx); 
		fseek(gfx, 0, SEEK_SET);
		
		buffer = (u16*)malloc(size);
		
		i = 0;
		while(i < size) {
			fread(&buffer[i], 1, 1, gfx);
			i++;
		}
		memcpy(	target.pal, /* Font's tiles */
				buffer, /* This variable is generated for us by
									grit. */
				 size); /* This length (in bytes) is generated
										from the file read. */
		target.numColors =  size / 2;
		free(buffer); 
		fclose(gfx);
	}else{
		iprintf("File NULL");
	}
	target.numChars = 95;
	target.bpp = 4;
	target.asciiOffset = 32;
	target.convertSingleColor = false;
}

void setBlackFade(){
	REG_BLDCNT_SUB = BLEND_SRC_SPRITE | BLEND_SRC_BG0 | BLEND_SRC_BG1 | BLEND_SRC_BG2 | BLEND_SRC_BG3 | BLEND_FADE_BLACK;
	REG_BLDCNT = BLEND_SRC_SPRITE | BLEND_SRC_BG0 | BLEND_SRC_BG1 | BLEND_SRC_BG2 | BLEND_SRC_BG3 |BLEND_FADE_BLACK;
	REG_BLDY_SUB = 16;
	REG_BLDY = 16;
}

void fadeBoth(){
	REG_BLDCNT_SUB = BLEND_SRC_SPRITE | BLEND_SRC_BG0 | BLEND_SRC_BG1 | BLEND_SRC_BG2 | BLEND_SRC_BG3 | BLEND_FADE_BLACK;
	REG_BLDCNT = BLEND_SRC_SPRITE | BLEND_SRC_BG0 | BLEND_SRC_BG1 | BLEND_SRC_BG2 | BLEND_SRC_BG3 | BLEND_FADE_BLACK;
	for(int dark = 0; dark<=32;dark++){
		REG_BLDY_SUB = dark>>1;
		REG_BLDY = dark>>1;
		swiWaitForVBlank();
	}
}

void unFadeBoth(){
	REG_BLDCNT_SUB = BLEND_SRC_SPRITE | BLEND_SRC_BG0 | BLEND_SRC_BG1 | BLEND_SRC_BG2 | BLEND_SRC_BG3 | BLEND_FADE_BLACK;
	REG_BLDCNT = BLEND_SRC_SPRITE | BLEND_SRC_BG0 | BLEND_SRC_BG1 | BLEND_SRC_BG2 | BLEND_SRC_BG3 | BLEND_FADE_BLACK;
	for(int dark = 32; dark>=0;dark--){
		REG_BLDY_SUB = dark>>1;
		REG_BLDY = dark>>1;
		swiWaitForVBlank();
	}
}

void whiteFadeBoth(){
	REG_BLDCNT_SUB = BLEND_SRC_SPRITE | BLEND_SRC_BG0 | BLEND_SRC_BG1 | BLEND_SRC_BG2 | BLEND_SRC_BG3 | BLEND_FADE_WHITE;
	REG_BLDCNT = BLEND_SRC_SPRITE | BLEND_SRC_BG0 | BLEND_SRC_BG1 | BLEND_SRC_BG2 | BLEND_SRC_BG3 | BLEND_FADE_WHITE;
	for(int dark = 0; dark<=32;dark++){
		REG_BLDY_SUB = dark>>1;
		REG_BLDY = dark>>1;
		swiWaitForVBlank();
	}
}

void unWhiteFadeBoth(){
	REG_BLDCNT_SUB = BLEND_SRC_SPRITE | BLEND_SRC_BG0 | BLEND_SRC_BG1 | BLEND_SRC_BG2 | BLEND_SRC_BG3 | BLEND_FADE_WHITE;
	REG_BLDCNT = BLEND_SRC_SPRITE | BLEND_SRC_BG0 | BLEND_SRC_BG1 | BLEND_SRC_BG2 | BLEND_SRC_BG3 | BLEND_FADE_WHITE;
	for(int dark = 32; dark>=0;dark--){
		REG_BLDY_SUB = dark>>1;
		REG_BLDY = dark>>1;
		swiWaitForVBlank();
	}
}

WinterMute
Site Admin
Posts: 2060
Joined: Tue Aug 09, 2005 3:21 am
Location: UK
Contact:

Re: Background Problems

Post by WinterMute » Sun Sep 18, 2011 1:30 pm

I don't see the code in here that uses vramSetPrimaryBanks/vramRestorePrimaryBanks which might help a bit.

A while ago I let someone talk me into having a default vram configuration before main is called which may potentially be interfering with your VRAM setup. That code does this :-

Code: Select all

//---------------------------------------------------------------------------------
u32 __attribute__((weak)) vramDefault() {
//---------------------------------------------------------------------------------

	// map all VRAM banks to lcdc mode
	VRAM_CR = 0x80808080;
	VRAM_E_CR = 0x80;
	VRAM_F_CR = 0x80;
	VRAM_G_CR = 0x80;
	VRAM_H_CR = 0x80;
	VRAM_I_CR = 0x80;

	dmaFillWords(0, BG_PALETTE, (2*1024));	// clear main and sub palette
	dmaFillWords(0, OAM, 2*1024);			// clear main and sub OAM
	dmaFillWords(0, VRAM, 656*1024);		// clear all VRAM


	return vramSetPrimaryBanks(VRAM_A_MAIN_BG, VRAM_B_MAIN_SPRITE, VRAM_C_SUB_BG, VRAM_D_SUB_SPRITE);
}
You can override this function in your own code by providing your own vramDefault function with C linkage - if that fixes your issue then I might need to rethink the merits of providing a default VRAM configuration.

Apart from that I'm not really sure what the problem might be.
Help keep devkitPro toolchains free, Donate today

Personal Blog

Post Reply

Who is online

Users browsing this forum: No registered users and 7 guests