Search the web
Sign In
New User? Sign Up
gbadev
? Already a member? Sign in to Yahoo!

Yahoo! Groups Tips

Did you know...
Message search is now enhanced, find messages faster. Take it for a spin.

Best of Y! Groups

   Check them out and nominate your group.
Having problems with message search? Fill out this form to ensure your group is one of the first to be migrated to the new message search system.

Messages

  Messages Help
Advanced
Long discussion of screen basics (was re: Sprite in mode 4)   Message List  
Reply | Forward Message #10736 of 15019 |
For those of you who know how the screen works, this isn't gonna tell you
anything new. However, I'm prone to idiot errors; could someone check this,
and make sure it's correct? Also, could someone answer my question about
S/R Bitmaps, and make sure I'm not forgetting something in the
what's-needed-to-display-a-sprite list?

> What are the relations between modes and sprites? I
> was also playing with the "sprite" demo, and once I
> changed modes, it stopped working. What are the basics
> to show a sprite? What is the best tutorial around?

First, the basics: there is 96k of RAM for video (hereafter VRAM). It's
chopped up differently for the sprite-and-background modes (hereafter Sprite
modes) than it is for the direct pixel access modes (hereafter Bitmap
modes). Of the six modes, the first three (0, 1, 2) are sprite modes, and
the last three (3, 4, 5) are bitmap modes. Switching sprite modes changes
what kind of backgrounds you get; switching bitmap modes changes how the
bitmap RAM is interpreted (8 or 15 bit, with or without z-buffer, fullscreen
or partial screen).

All modes have sprites, but the amount of VRAM given to sprites changes.
In the sprite modes, 32k of VRAM is given to the sprites (this 32k starts at
VRAM + 0x10000h, or 0x6010000h.) The OAM breaks this space up into 2^10
chunks (numbered 0 to 1023), giving you that 10-bit index for which tile in
Obj Attr 2.

The remaining space is given to the "maps" - the arrays of which tile is
being given to which square on a given background - and the tiles for the
backgrounds. Because background sizes shift, you can demarcate where each
background begins and ends. Also, you can demarcate where the tiles for the
backgrounds begin. Of that 64k, at most 32k can be taken by the map data
(the tile layout), meaning that at least 32k is guaranteed to be space for
background tiles.

In the sprite modes, shifting modes changes which backgrounds behave in
what way. Mode 0 is the easiest: it's four normal backgrounds. Nice and
simple. Normal backgrounds can do the typical stuff: flip tiles in their
map, use 4- or 8-bit tiles, etc. All four backgrounds may be turned on
(0,1,2,3). However, in any of these modes, you may turn any BG off at any
time. (In modes 1-5, certain BGs *must* be turned off, but you are never
forced to have any of them on.)

Mode 1 is a little more complex. You have two normal backgrounds (bg 0
and 1), and one background which does Scaling and Rotation (bg 2). Scaling
and rotation backgrounds don't H/V flip tiles, and they can only use 8-bit
tile faces, but in exchange for that loss of control, you get to spin them
and zoom them to your heart's content. In mode 1, BG3 must be turned off.

Mode 2 is a pair of scaling and rotation backgrounds, and no normal
backgrounds. Mode 2 has BG2 and 3 on, and 0 and 1 off.

Now, in the bitmap modes, only 16k is given to tile faces. The OAM
doesn't change how it orders tiles; rather, you just start putting tiles in
at the halfway point (which is VRAM + 0x14000h, or 0x6014000h). In the OAM,
just point to sprite number 512 and up when setting TileID (which is
equivalent to pretending to having 512 entries and just leaving bit 9 on, or
pretending to have 512 entries and ORing by something #defined to 512.)

That leaves 80k of space in the bitmap modes, which is allotted to the
bitmap buffer. The hardware considers BG2 to be the bitmap (don't ask me
why); in all bitmap modes, BG2 is the only BG which may be on. I believe
turning BG2 off in a bitmap mode turns the actual bitmap off, but I've never
tried it, so I'm not certain. Someone on IRC told me that the bitmaps took
scaling and rotation parameters correctly, but I've never tried it, so I
don't know if that's true (could someone give a definitive answer on this,
please?)

In mode 3, the bitmap buffer is read as a single array of (240*160)
halfwords (16 bits). Each of those entries is interpreted as a pixel in BGR
order, giving the bottom 5 bits to the Red value, the next 5 to Green, the
next 5 to Blue, and discarding the top bit. This means that, in mode 3, you
can get away with just writing an RGB value to the correct location in an
array (shown below) and it will just set a pixel. Mode 3 is the mode
obvious mode to computer programmers, IMHO. Remember that you do still get
sprites, but that the amount of VRAM allotted to keeping faces is halved
(enough for 512 4-bit or 256 8-bit tiles, IIRC).

In mode 4, the buffer is instead interpreted as an array of 8-bit
entries. Since each entry (that is, each pixel) takes half as much space in
VRAM, you have enough memory for two screens; in fact, that's exactly how it
works. The 80k is broken up into two full screens' worth of data, called
Z-Buffer 0 and Z-Buffer 1 (many people omit the Z.) If you're familiar with
Z-Buffers or Double Buffering, you should be nodding your head about now.
If not, read on.

There's a bit in DISPCNT (I think it's bit 4, but I'm too lazy to check)
that sets which of those two chunks is being used to paint the screen. The
reason one wants this is because it's helpful for drawing smoothly, if your
draw routines won't finish in the space of a single screen draw cycle. If
you've ever seen the screen draws that get diagonal lines chopping across
the middle, that's the effect we're trying to avoid: that comes from being
halfway done drawing when the screen gets updated. What you do instead is
to draw to the buffer which isn't being used, and then flip the screen to
use that buffer (one bit set doesn't take long at all) when you know the
screen isn't in the middle of drawing. That's what double buffering is:
drawing offscreen and instantly popping your changes into place.

That's so useful, in fact, that mode 5 does it, too. Mode 5 is an odd
mode that you don't see used terribly often. It's a 15-bit color mode with
Z-Buffers. "But ... there isn't that much VRAM", you say? Right: Mode 5
only uses part of the screen. Specifically, it's 160x128, in the middle of
the screen. I don't know if there's a way to stretch it to fit the screen -
I don't use mode 5 at all. I believe that it's intended for full-color fast
paint to screen, suggesting things like movie playback, etc. However, as
every good programmer knows, it's really for whatever interesting crap you
can make it do. <grins>

-------------------------------

Regarding sprites and what you need to do to turn them on:

1) The sprite layer must be enabled (DISPCNT bit 12=on)

2) You need to have an onscreen sprite which is not set to DblSize,
S/R on (setting both effectively hides the sprite)

3) The sprite needs to be pointing at a valid tile, and the tile
needs to have tile data (they start transparent)

4) Screen display must be enabled (AKA Forced Blank, or LCDC; this
is DISPCNT bit 7, and it must be set to *off* - setting the bit forces the
screen to all-white)

5) Set the palettes, so that your sprites aren't solid black

6) If you're in a bitmap mode (mode 3,4,5), you must remember that
sprites start at 512, not 0

7) You must not use my graphics (so ugly they'll break your screen,
natch)

8) Your gameboy must be on, and it must have a program loaded (a
cart, or multiboot)

-------------------------------

Anyhoo, I think that that about covers the basics of screen usage. I didn't
really cover much about map usage ('cause I don't want to type anymore), and
I didn't explain anything about 1D/2D sprite tile layout (someone else can
do that, I'm not in the mood). But it should work. Also, I promised to
show an example of drawing to a mode 3 screen, so here goes:

(This uses macros. Macros are bad for reasons whose explanations are
outside of the scope of this posting. Macros are also very fast, but then
again, so are inline functions, which aren't bad at all.)

I did not test this code. But I think it ought to work, unless I did
something stupid.

-------------------------------

typedef volatile unsigned char vu8;
typedef volatile unsigned short int vu16;

#define DispStat 0x4000004
#define DispCnt 0x4000000
#define Mode3 3
#define BG2_On 0x0400
#define tPutPixel(usex, usey, usecolor) *(vu16 *)(VRAM
+((((vu8)(usey)*240)+(vu8)(usex))*2))=(vu16)(usecolor)

void setmode3() { // Bad: function does more than it should, but is good
enough for an example
*(vu16 *)DispCnt = Mode3 | BG2_On; // Turn on BG2 and set to screen mode
3
*(vu16 *)DispStat = 0; // Turn off LCDC with a shotgun
}

int main() { // main *must* return an int - void is against standard!
vu8 i, j, hang;
vu16 zcolor;

setmode3(); // Prepare the screen and turn it on

for (color=0; zcolor<32768; zcolor++) { // For each possible 15-bit color
do
for (j=0; j<160; j++) { // for each screen row do
for (i=0; i<240; i++) { // for each scren column do
tPutPixel(i,j,zcolor); // draw the pixel at (i,j) in color zcolor
}
}
}

while (1) {
++hang; hang=0; // Gee, I wonder. Maybe this hangs the app?
}

return 0; // proper form!
}


_________________________________________________________
Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com





Sun Mar 31, 2002 12:54 am

johnisaheadcase
Online Now Online Now
Send Email Send Email

Forward
Message #10736 of 15019 |
Expand Messages Author Sort by Date

For those of you who know how the screen works, this isn't gonna tell you anything new. However, I'm prone to idiot errors; could someone check this, and make...
John Q. Pretentious
johnisaheadcase
Online Now Send Email
Apr 2, 2002
8:16 pm
Advanced

Copyright © 2009 Yahoo! Inc. All rights reserved.
Privacy Policy - Terms of Service - Guidelines - Help