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 > MODE_5_2D color questions - trying to plot pixels

#88704 - Onions - Wed Jun 21, 2006 3:21 am

I wanted to use the framebuffer mode for both screens, but found out only 1 screen can be used at a time. So I then (after searching these forums) found out that MODE_5_2D is the next best thing. The thing is, it won't read my converted image files and only seems to take what I believe is hexidecimal (such as 0xFFFF - however, it will not show the color red... or aka 0x00FF, which I find bizarre).

So what do I have to do to be able to read outputted files from gfx2gba that I'm currently using to convert my bmps?
Must I use a palatte? Because I'm currently not, nor do I know how. My code can be found below (very simple start up code that I needed to to get right before moving on). If anyone wants to edit it so it can read my bitmap array, I'd appreciate it.

Code:

#include <nds.h>
#include "..\graphics\FreakyHead.raw.c"

int main(void)
{
   powerON(POWER_ALL);
   
   videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE);
   vramSetBankA(VRAM_A_MAIN_BG);
   BG3_CR = BG_BMP16_256x256;
   BG3_XDX = 1 << 8;
   BG3_XDY = 0;
   BG3_YDX = 0;
   BG3_YDY = 1 << 8;
   BG3_CX = 0;
   BG3_CY = 0;

   videoSetModeSub(MODE_5_2D | DISPLAY_BG3_ACTIVE);
   vramSetBankC(VRAM_C_SUB_BG);
   SUB_BG3_CR = BG_BMP16_256x256;
   SUB_BG3_XDX = 1 << 8;
   SUB_BG3_XDY = 0;
   SUB_BG3_YDX = 0;
   SUB_BG3_YDY = 1 << 8;
   SUB_BG3_CX = 0;
   SUB_BG3_CY = 0;

   for(int y = 50; y < 100; y++)
      for(int x = 50; x < 100; x++)
         BG_GFX[y * SCREEN_WIDTH + x] = FreakyHead_Bitmap[y * SCREEN_WIDTH + x];


   return 0;
}

#88705 - tepples - Wed Jun 21, 2006 4:04 am

Onions wrote:
I wanted to use the framebuffer mode for both screens, but found out only 1 screen can be used at a time. So I then (after searching these forums) found out that MODE_5_2D is the next best thing. The thing is, it won't read my converted image files and only seems to take what I believe is hexidecimal (such as 0xFFFF - however, it will not show the color red... or aka 0x00FF, which I find bizarre).

Remember that Nintendo DS colors are RGBA with binary alpha. The GBA didn't use the alpha bit, so GBA-oriented image conversion tools generally leave it turned off, but you'll have to turn it on for all pixels that you want to show up.
Code:
FEDCBA98 76543210
|||||||| ||||||||
|||||||| |||+++++- Red intensity
||||||++-+++------ Green intensity
|+++++------------ Blue intensity
+----------------- 0: skip drawing this pixel

So the proper code for red is 10000000 00011111, or 0x801F.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#88707 - Onions - Wed Jun 21, 2006 4:56 am

Okay, that did work. Thanks very much.

My only problem now is finding a converter than can read each pixel in my bmp and output it's color to a code similar to the above.

Is there one out there - a graphics converter made specifically for the DS like this? If not... well, I don't know how to make one personally. I could possibly get the color data from a bitmap image, but I have no idea on how to convert that to the format the DS seems to be using.

Any help in this is greatly appreciated. I'd like to move on but have been stuck on this for a few days.
I had something working on the GBA, by the way, and am currently trying to port it over to the DS.

#88708 - tepples - Wed Jun 21, 2006 5:04 am

This won't be as fast as a native solution, but something like this (untested) code will work until you find or write a suitable PC app:
Code:
void memcpy_opaque_alpha(u32 *restrict dst, const u32 *restrict src, int len) {
  for(;
      len > 0;
      len -= 4, dst++, src++) {
    *dst = *src | 0x80008000;
  }
}

void memcpy_magicpink_alpha(u16 *restrict dst, u16 *restrict src, int len) {
  for(;
      len > 0;
      len -= 2, dst++, src++) {
    u32 srcPx = *src;
    *dst = (srcPx == RGB5(31, 0, 31)) ? srcPx : srcPx | 0x8000;
  }
}

Use memcpy_opaque_alpha() if you want the GBA behavior. Use memcpy_magicpink_alpha() if you want to send sprites behind the magenta background.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#88709 - Onions - Wed Jun 21, 2006 5:15 am

I've written this new code incorporating what you mentioned, but I must be doing something wrong...

Code:

#include <nds.h>
#include "..\graphics\FreakyHead.raw.c"

void memcpy_opaque_alpha(u32 *dst, u32 *src, int len);
u32 image[38400];

int main(void)
{
   powerON(POWER_ALL);

   videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE);
   vramSetBankA(VRAM_A_MAIN_BG);
   BG3_CR = BG_BMP16_256x256;
   BG3_XDX = 1 << 8;
   BG3_XDY = 0;
   BG3_YDX = 0;
   BG3_YDY = 1 << 8;
   BG3_CX = 0;
   BG3_CY = 0;

   videoSetModeSub(MODE_5_2D | DISPLAY_BG3_ACTIVE);
   vramSetBankC(VRAM_C_SUB_BG);
   SUB_BG3_CR = BG_BMP16_256x256;
   SUB_BG3_XDX = 1 << 8;
   SUB_BG3_XDY = 0;
   SUB_BG3_YDX = 0;
   SUB_BG3_YDY = 1 << 8;
   SUB_BG3_CX = 0;
   SUB_BG3_CY = 0;

   memcpy_opaque_alpha(image, FreakyHead_Bitmap, 38400);

   for(int y = 50; y < 100; y++)
      for(int x = 50; x < 100; x++)
         BG_GFX[y * SCREEN_WIDTH + x] = image[y * SCREEN_WIDTH + x];


   return 0;
}

void memcpy_opaque_alpha(u32 *dst, u32 *src, int len)
{
  for(; len > 0; len -= 4, dst++, src++)
    *dst = *src | 0x80008000; 
}


It compiles but I get a black screen.

#89025 - Onions - Thu Jun 22, 2006 9:02 pm

Well, I've gotten an image to correctly display on screen, my problem now is trying to switch between screen buffers, which I can't seem to do in the mode I'm in.

How would I go about doing this with the setup below...

Code:

videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE);
vramSetBankA(VRAM_A_MAIN_BG);


To then write to the screen, I'd have to use...
Code:

BG_GFX[]


Thing is, unlike MODE_FB0 that I was using with VRAM_A_LCD, I can't simply switch drawing to the screen. For example, I could choose to write to either VRAM_A[], or VRAM_B[], and then switch vramSetMode() to either VRAM_FB0 or VRAM_FB1 to show the different buffers.
However, the mode I'm using now doesn't seem to have all these options - mainly, there's only one BG_GFX and nothing like BG_GFX_A or BG_GFX_B, or anything to distinguish the two.

So how can I switch between buffers? Currently I
m seeing scan lines, although using dmaCopy() has sped it up a little.

Thanks to any that can help.

EDIT: It seems I might have figured it out, although I'll have to look into it further to be sure.

#97184 - tarake - Tue Aug 08, 2006 12:07 pm

Why I use similar to all of this topic so I can plot pixel but only on emulator "DeSmuME" and "ides" not on hardware(flashme with super card).

(I can run any example homebrew application on my hardware)

#97213 - omaremad - Tue Aug 08, 2006 5:23 pm

for bitmap gfx use jpeg it proides very good compression and its easy to use find the gba jpeg source at doubles tutorial 10