Page 1 of 2

Sub graphics engine layers?

Posted: Fri Mar 27, 2009 9:21 pm
by Aethex
On the sub graphics engine, I can't seem to get the layering thing working. On the main engine, this is OK, but the lower BGs (I use bitmaps) don't even show.
These are my inits. I use mode 5 2D for both screens:

BG_MAIN[2] = bgInit (2, BgType_Bmp16, BgSize_B16_256x256, 0, 0); // 16-bit BMP
BG_MAIN[3] = bgInit (3, BgType_Bmp16, BgSize_B16_256x256, 8, 0); // 16-bit BMP
BG_SUB[2] = bgInitSub (2, BgType_Bmp16, BgSize_B16_256x256, 0, 0); // 16-bit BMP
BG_SUB[3] = bgInitSub (3, BgType_Bmp16, BgSize_B16_256x256, 8, 0); // 16-bit BMP

This is how I paint to the screen:
mbuffer[2] = RGB15 (0, 0, 0) | 1<<15;
mbuffer[3] = RGB15 (0, 31, 0) | 1<<15;
sbuffer[2] = RGB15 (0, 0, 31) | 0<<15;
sbuffer[3] = RGB15 (0, 31, 0) | 1<<15;

I know I coded it properly, because it works on the sbuffer[2] (which is the buffer to the layer 2 sub bg), but is seems like it won't even do anything about the sbuffer[3]. This is all in a for loop that cycles through each pixel in a screen.

Re: Sub graphics engine layers?

Posted: Fri Mar 27, 2009 9:46 pm
by Sylus101
How did you setup your VRAM banks? The sub engine can only have up to 128K assigned to it, when filling the visible screen on one 16 bit background, that's 96K alone.

Re: Sub graphics engine layers?

Posted: Sat Mar 28, 2009 1:13 am
by Aethex
Ummm...
VRAM_C_SUB I think. I'd imagine that 128 k is enough for bgs. Would 8bit bitmaps work with 128k?

Edit: I tried making the bgs 8bit, but to no avail. It still shows black on the bottom screen. The code to draw the pixels is the same, but perhaps it should be different when using 8bit bgs, ex. using RGB8 instead of RGB15? If so, what are the maximum values for RGB8?

Re: Sub graphics engine layers?

Posted: Sat Mar 28, 2009 4:52 am
by Sylus101
If you had 2 8 bit layers, you will have enough VRAM, but You'll have to make sure your bg init's are okay in terms of where the mapbase offset is.

The primary difference is that you'll be writing in palette position values and not direct colors. I'm not sure what RGB8 does, but what you'll be doing is filling with values from 0-255, color positions in the sub background palette.

Re: Sub graphics engine layers?

Posted: Sat Mar 28, 2009 3:27 pm
by Aethex
So how would I write to the pal in this case? And do I have to add something more to the inits in order to make it work?

Re: Sub graphics engine layers?

Posted: Sat Mar 28, 2009 10:02 pm
by Sylus101
Well, lets see. You'll have 2 bg inits something like:

Code: Select all

int sub_bg1 = bgInitSub(2, BgType_Bmp8, BgSize_B8_256x256, 0, 0); //offset by 0 * 16k makes this start at beginning of vram bank c
int sub_bg2 = bgInitSub(3, BgType_Bmp8, BgSize_B8_256x256, 4, 0); //offset by 4 * 16k makes this start at 64K of vram bank c, half way.
You will have to load some colors into the palette. Usually you would dmaCopy a palette file that was created by grit or some other program, but if you wanted to create individual colors you'd use RGB15() like you were before, but to BG_PALETTE_SUB, like

Code: Select all

BG_PALETTE_SUB[0] = RGB15(31,0,31); //Magenta, but just transparent really...
BG_PALETTE_SUB[1] = RGB15(31,0,0); //Color 1 is Red
Now the FUN part is writing 8 bit values to VRAM. You MUST write 16 bits (or 32) bits at a time. You can not just draw one pixel without some difficulty which I can get into more detail if you want. If you're filling the whole layer with one color, that's pretty easy. For the fastest way I know:

Code: Select all

dmaFillWords(((1 << 24) + (1 << 16) + (1 << 8) + 1), bgGetGfxPtr(sub_bg1), 256*192);
Makes all of layer 2 Red.

Not to make assumptions, but if you're wondering why all the (1 << 24) + (1 << 16) + (1 << 8) + 1 stuff... I have to tell what color I want in each 8 bit slot of a 32 bit value... Not a bad spot to maybe have a little macro similar to RGB15 but would define a 32 bit value instead of a 15 bit one.

Hope this helps and doesn't totally confuse things.

Re: Sub graphics engine layers?

Posted: Sat Mar 28, 2009 10:51 pm
by Aethex
But lets say that I want to draw only some pixels. Would I use dmaCopyWords, and use bgGetGfxPtr(sub_bg1) , where i is the location of the pixel?

Oh, and why are the locations of the pixels off? The whole screen seems to be colored, even if I colored fewer than 256 by 192 pixels.

Code: Select all

for (i = 0; i < 256 * 100; i++) {
		sbuffer[2][i] = 2;
	}
or

Code: Select all

dmaFillWords (0, sbuffer[2], 256 * 100);

Re: Sub graphics engine layers?

Posted: Sat Mar 28, 2009 11:19 pm
by Sylus101
Well, give me more specifics. If you're down to the pixel level there's one answer... if you're saying maybe the top half or left half of the screen that's another answer...

Re: Sub graphics engine layers?

Posted: Sat Mar 28, 2009 11:21 pm
by Aethex
Well, how would it be done pixel-level?

EDIT: Specifics:

Code: Select all

BG_PALETTE_SUB[0] = RGB15(5,5,5); // Gray
	BG_PALETTE_SUB[1] = RGB15(31,0,0) | 0<<15; // Red, should be transparent?
	BG_PALETTE_SUB[2] = RGB15(31,15,0); // Orange
	
	for (i = 0; i < 256 * 192; i++) {
		sbuffer[2][i] = 1; // Red
		sbuffer[3][i] = 2; // Orange
	}
The problem is that this gives me evenly-spaced black-and-orange stripes, instead of painting the whole screen

I'm really confused now.

Re: Sub graphics engine layers?

Posted: Sun Mar 29, 2009 4:10 am
by Sylus101
I wish I had some stock code... but sadly I don't.

Okay, lets say we just have 1 8 bit background on the sub screen, mapped to the start of VRAM_C. There is a macro ready to use called BG_GFX_SUB as a location to write to, and it could also be used as an array to access certain points. Lets say I want to make just the point where x = 15 and y = 32 the color Red. You've already got color 1 in the palette red and no that is not transparent. Color 0 is always transparent. It actually does not matter at all what color you assign to palette color 0, it's never displayed.

Okay, so to check a specific point you can access the background memory like this:

Code: Select all

BG_GFX_SUB[(x >> 1) + (y << 7)]
So if I do BG_GFX_SUB[(15 >> 1) + (32 << 7)] = 1, an odd thing will happen. What you'll end up with is a red pixel at 14, 32 instead of 15,32. But why?

Well, the reason is that BG_GFX_SUB is a 16 bit pointer to the VRAM location for Sub screen backgrounds, and in 8bit mode there are 2 pixel colors stored in each 16 bit register location. 16 bit backgrounds are 10 times easier because you write a direct color to BG_GFX_SUB[x + (y << 8)] and bam, you've got your exact pixel the color you want.

Okay, so back to 8 bit bgs, basically you have an even (lower byte), and odd value (upper byte) in each 16 bit field.

I'm actually a bit short on time to give the rest of this right now, but I'm hoping maybe this puts you on the right track. Without anymore code:

1. Read in the value from BG_GFX_SUB[(x >> 1) + (y << 7)] first (assign it to some temporary u16 variable).
u16 temp = BG_GFX_SUB[(x >> 1) + (y << 7)];
2. Split that up into it's 2 pixel colors, the lower will be the even value, the upper will be the odd.
u8 even = temp&255;
u8 odd = temp >> 8;
3. Depending on if your x value is odd or even... replace the appropriate even or odd variable with the color of your choice.
odd = 1;
4. Put it back together...
temp = even + (odd << 8);
BG_GFX_SUB[(x >> 1) + (y << 7)] = temp;

I'll have to test that to be totally sure I got the right, as I'm in a bit of a hurry... hope that explains it a bit.