gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > question regarding paletted 8bit background mode - Answered

#135902 - mr_munk - Fri Jul 27, 2007 9:26 am

Hi,

I have adapted the example code from a tutorial to display an 8bit paletted image. I want to use the image data as a LUT and as an initial test, I am attempting to copy the pixel data from the LUT to the screenbuffer using a for loop, however the resultant image drawn to the screen appears to skip every second line... Can someone help me understand why this is happening?

Here is an image of the screen:

[Images not permitted - Click here to view it]

I think that the LUT contains the correct data because I can DMAcopy the data from the LUT array to the screen successfully; here is a screenshot of the image displayed correctly on screen:

[Images not permitted - Click here to view it]

Here are the relevant parts of my code:

Code:
#include "sob3_bin.h" //shadow of the beast raw images 192x256x256 8bit
#include "master_bin.h"//palette
...
//load sob3 image into main memory
u8* sob3img = new u8[sob3_bin_size];
dmaCopy(sob3_bin, sob3img, sob3_bin_size);
...
//point our video buffer to the start of bitmap background video
u16* video_buffer_main = (u16*)BG_BMP_RAM(0);
   
//set video mode to mode 5 with background 3 enabled
videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE);   
   
//map vram a to start of main background graphics memory
vramSetBankA(VRAM_A_MAIN_BG_0x06000000);

//set control registers
//initialize the background
BG3_CR = BG_BMP8_256x256 | BG_BMP_BASE(0);
   
BG3_XDY = 0;
BG3_XDX = 1 << 8;
BG3_YDX = 0;
BG3_YDY = 1 << 8;
...
dmaCopy(master_bin, BG_PALETTE, 256*2); //load the palette into palette main memory

//*copy* img 3 to main screen cr mapped memory - doesn't work
for(i = 0; i < 256 * 256; i++)
{
   video_buffer_main[i] = sob3img[i];
   iprintf("mem add vb[%d]: %X \n", i, &video_buffer_main[i]);
}


In 16bit mode the image draws correctly, although the paletted colours are all wrong. (does 16bit mode support a palette?)

I have been trying to solve this problem for myself but have made little progress in 3 days, I would welcome any information.


Last edited by mr_munk on Fri Jul 27, 2007 12:58 pm; edited 1 time in total

#135908 - Dwedit - Fri Jul 27, 2007 10:19 am

You are writing 8 bits of data into a 16 bit slot. The upper 8 bits are all zero, hence your black horizontal stripes every other pixel.

I suggest you just memcpy the data directly into video memory instead of doing the (incorrect) 8>16 bit expansion you are currently doing.
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."

#135912 - mr_munk - Fri Jul 27, 2007 11:29 am

Thanks, I suspected something similar to this, what I don't understand is why the memory slots are 16bit? I assumed (although I could well be wrong) that setting the BG3 control register to 8bit would make it read the slots in 8bit blocks ?

Eventually I want to use the pixel data as a LUT so I can calculate offsets on a per pixel basis and warp the image, the solution (I think) that you are suggesting is a good one - writing the warped data to a buffer and then memcopying it to the background memory - thanks for that :) However I also want to develop my understanding better - can anyone help me to understand why the memory slots are inherantly 16bit ? Is it because the CR is 16bit and the memory is mapped to the CR ?

#135914 - elhobbs - Fri Jul 27, 2007 11:49 am

you must do 16bit writes to vram regardless of the background mode. that is a just how the hardware works. dmaCopy is your best/fastest option.

#135916 - mr_munk - Fri Jul 27, 2007 12:57 pm

Thanks :D

#135926 - Dwedit - Fri Jul 27, 2007 2:33 pm

mr_munk wrote:
Thanks, I suspected something similar to this, what I don't understand is why the memory slots are 16bit? I assumed (although I could well be wrong) that setting the BG3 control register to 8bit would make it read the slots in 8bit blocks ?

Eventually I want to use the pixel data as a LUT so I can calculate offsets on a per pixel basis and warp the image, the solution (I think) that you are suggesting is a good one - writing the warped data to a buffer and then memcopying it to the background memory - thanks for that :) However I also want to develop my understanding better - can anyone help me to understand why the memory slots are inherantly 16bit ? Is it because the CR is 16bit and the memory is mapped to the CR ?

In your case, you were doing 16 bit writes because you had declared "u16* video_buffer_main". If you had used u8* instead, you would be doing 8 bit writes. It just so happens that the video hardware does not like 8-bit writes, it causes the byte to be written to both halves of a 16 bit word.
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."