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.

Coding > plotting a pixel n mode 4

#10250 - Omega81 - Sun Aug 31, 2003 5:30 pm

This may sound stupid but how how do you do it? I mean I know the procedure, but I guess what I want to know is how the palatte register comes into it. When I want to plot the pixel do I send an entry from the palatte register or just a number from 0-256?
thanks
_________________
Keep it real, keep it Free, Keep it GNU

#10251 - Cyberman - Sun Aug 31, 2003 6:31 pm

I believe this is a FAQ and is probably answered all over the place but.. what the heck.
I suggest reading the documentation on the GBA. Try this for html or this for the text version. I do mean read it to not just peruse it, it won't tell you how to plot pixels (hehehe) at all though. It will tell you the structure of the GBA and answer wither 8 or 16 to plot pixels in mode 4 however.

To answer your question though 8bit pixels that means each element is a byte sized entity in VRAM. How big is a byte? A byte represents a number from 0 to 255. That kind of answers your question about the palette versus the VRAM writting doesn't it?

What you should really think about is can you write a byte to VRAM (in fact you can't). VRAM is maped as word (16 bit) entitys. So to plot a single pixel that is 8 bits into VRAM you need to do something like

Code:

void pixel_plot_4(unsigned short X, unsigned short Y, unsigned char Color)
{
  unsigned short Temp;
  unsigned short *Addr;

  // prevent out of bounds ploting
  if (X >= 240)  return;
  if (Y >= 160)  return;
  // set Addr to VRAM
  Addr = (unsigned short *) 0x6000000; // page 0 mode 4
  // add the number of lines to the address
  Addr += Y * 120;
  // count the number of words horizontally
  Addr += (X >> 1);
  // read the VRAM location
  Temp = *Addr;
  // modify the hi or low byte
  if (X & 1)
  {
    Temp &= 0x00FF;
    Temp |=  Color << 8;
  }
  else
  {
    Temp &= 0xFF00;
    Temp |= Color;
  }
  // write back the VRAM location
  *Addr = Temp;
}


for line drawing etc this can be really fast (because it's mostly manipulating pointers and playing with a temporary buffer you only write it out when.. you change the Y value or your X value is outside the range of the temp buffer (2 pixels).

Cyb

#10253 - Omega81 - Sun Aug 31, 2003 6:56 pm

thank Cyberman. I was wondering why you are multipling Y by 120 surely you mean Y*240 right?

I understand the general architecture of the GBA just wasn't sure how to deal with writing 8bit to a 16bit screen, currently, I was writeing a pixel colour to the x,y location by...

Plotpixel(x,y,((color<<8)|color));

basically converting the bit color to a 16bit color if two halves both the same value. your method is different though. I will try that and see what happens.

thanks again.
_________________
Keep it real, keep it Free, Keep it GNU

#10266 - Archeious - Mon Sep 01, 2003 3:08 am

Omega81 wrote:
thank Cyberman. I was wondering why you are multipling Y by 120 surely you mean Y*240 right?


You multiply by 120 because the screen in 120 unsigned shorts (16 bit) wide.

Omega81 wrote:
I understand the general architecture of the GBA just wasn't sure how to deal with writing 8bit to a 16bit screen, currently, I was writeing a pixel colour to the x,y location by...

Plotpixel(x,y,((color<<8)|color));

basically converting the bit color to a 16bit color if two halves both the same value. your method is different though. I will try that and see what happens.

thanks again.


By do this you are making a 120x160 screen.

#10289 - Cyberman - Mon Sep 01, 2003 7:17 pm

Omega81 wrote:
thank Cyberman. I was wondering why you are multipling Y by 120 surely you mean Y*240 right?

I understand the general architecture of the GBA just wasn't sure how to deal with writing 8bit to a 16bit screen, currently, I was writeing a pixel colour to the x,y location by...

Plotpixel(x,y,((color<<8)|color));

basically converting the bit color to a 16bit color if two halves both the same value. your method is different though. I will try that and see what happens.

thanks again.


Well as I suggested you need to read the technical documentation CAREFULLY. You are making a lot of mistakes you wouldn't be if you did. Or maybe you are posting in the wrong forum (the newbie forum might be more appropriate in other words).

First let me explain to you something called display pitch. Pitch is NOT width (don't confuse those because they are completely different). Display pitch is the number of words per horizontal line.

Mode 3 has a display pitch of 240 mode 4 has one of 120. See a pattern? :)

Hence why one multiplies by 120 instead of 240. Think of Mode 4 as 120 x 320 word screen instead of 240x160 8 bit pixels. Think in words not pixels and you will understand what is going on a lot betters. Mode 3 is 240 x 160 words same number of pixels different shape.

Your plot pixel routine I am assuming is designed for mode 3 right? You are combining the same color (1 of 256 possible ones in the palette) and storing it on the display. So basically you are ploting two pixels in mode 4 at a time? All your X and Y coordinates are going to be wrong if you do this using plot code made for mode 3. The method I gave as an example will draw an individual pixel at a given location within the 240x160 screen coordinates.

Here is why it won't work X = 239 in Mode 3 is address 0x60001DE X = 239 is the lower byte of of address 0x60000EF two completely different locations. It gets much worse as you plot down the screen as well. For example X = 239 Y = 159 is the lower byte of 0x60095FF Mode 4 in Mode 3 it is 0x6012BFE ( Note this is why one only has 16K of sprite space available in the graphics modes).

Cyb
_________________
If at first you don't succeed parachuting is NOT for you.