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 > weird bitmap bg behaviour at CX=0

#127569 - mml - Thu May 03, 2007 10:05 am

This has got me stumped.

So I've got a 512x256x8 bitmap background on BG3 in mode 5 on the main screen (wrapping enabled), a basic console on the sub screen, to which I'm printing current x/y co-ordinates so I can keep track of where I am, and a couple of keys set up in my game loop so I can scroll it around.

Everything is working cleanly, except that at BG3_CX=0, the background renders weirdly. Instead of just rendering the "left" half of the image as you'd expect, it renders it, and then on what apppears to be odd scanlines only, it helpfully goes ahead and renders the "right" half too.

As soon as I scroll left or right, it renders correctly at the correct position in the bitmap; if I scroll back to CX=0 it garbles it again. What confuses me the most, though, is that at CX=(512<<8) and CX=(-512<<8) it renders correctly!

I'm testing using no$gba at present (haven't yet got the bits to test on actual hardware), however I would assume that if this was an emulator bug someone would've tickled it long before me and it'd be either fixed or documented all over forums.

Thereby I can only conclude that I'm doing something tragically wrong somewhere, but I can't for the life of me work out what -- the fact that it renders correctly at the wrapped equivalents of 0 suggest that I'm not crapping all over the memory somewhere by mistake (or poor maths), or setting the background size wrong, etc; but I can't think what else I could be doing that might cause this.

Anyone come across this before, or at least have some idea what's happening here?

(Yeah, I know (now) that I'd be better off using tiled backgrounds for what I'm doing at the moment, but I'd like to at least figure out what I'm doing wrong with the bitmap first so I don't make similar mistakes down the track...)

#127575 - Lick - Thu May 03, 2007 11:30 am

Tip: try it on hardware first. Emulators work, but not well enough to ignore hardware.
_________________
http://licklick.wordpress.com

#127576 - mml - Thu May 03, 2007 11:39 am

That goes without saying; but until I have means to get it onto my hardware I'm stuck making do as well as I can. (Which also goes without saying, so I might's well've not posted this comment. :P)

#127577 - Lick - Thu May 03, 2007 11:41 am

Hehe. You do have the rotation variables set up correctly right?
_________________
http://licklick.wordpress.com

#127579 - mml - Thu May 03, 2007 11:58 am

I believe so -- that it works correctly for other values of CX suggests it, anyway.

During setup, I initialise like this:

Code:

    BG3_XDX = 1 << 8; /* scale x */
    BG3_XDY = 0; /* rotation x */
    BG3_YDX = 0; /* rotation y */
    BG3_YDY = 1 << 8; /* scale y */
    BG3_CX = 0; /* translation x */
    BG3_CY = 0; /* translation y */
...
    bg_pos.x = bg_pos.y = 0;


... where bg_pos is:

Code:

    typedef struct s_s32vect {
        s32 x;
        s32 y;
    } s32vect;
...
    s32vect bg_pos;



In the game loop, I increment or decrement bg_pos.x appropriately depending on keysHeld(), then update CX like this:

Code:

        BG3_CX = bg_pos.x << 8;
        BG3_CY = bg_pos.y << 8;


(I don't touch bg_pos.y beyond initialising it to zero -- didn't get as far as adding vertical scrolling before this problem bit me, and I've been trying to fix the problem ever since, rather than adding more onto the code...)

Seems right as far as I can tell, but I'm new to DS (and never touched a GBA) so "as far as I can tell" doesn't count for a lot.

#127581 - OOPMan - Thu May 03, 2007 12:29 pm

Try it in some other emus as well...
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#127585 - Lick - Thu May 03, 2007 12:46 pm

That code seems fine to me, except for the fact that:
Quote:
4000020h - BG2PA - BG2 Rotation/Scaling Parameter A (alias dx) (W)
4000022h - BG2PB - BG2 Rotation/Scaling Parameter B (alias dmx) (W)
4000024h - BG2PC - BG2 Rotation/Scaling Parameter C (alias dy) (W)
4000026h - BG2PD - BG2 Rotation/Scaling Parameter D (alias dmy) (W)


Bit Expl.
0-7 Fractional portion (8 bits)
8-14 Integer portion (7 bits)
15 Sign (1 bit)

So it's actually s8 (char)-sized and not s32. But this wouldn't matter enough to create your glitch. I could test-drive on real hardware for you.
_________________
http://licklick.wordpress.com

#127586 - mml - Thu May 03, 2007 1:08 pm

Are we talking about the same registers? My choice of 32 bits there was based on these definitions from the libnds headers (although they seem to behave signedly):

Code:
./nds/arm9/video.h:#define BG3_CX         (*(vuint32*)0x04000038)
./nds/arm9/video.h:#define BG3_CY         (*(vuint32*)0x0400003C)


The rotation/scale ones are defined as 16 bits though...:

Code:
./nds/arm9/video.h:#define BG3_XDX        (*(vuint16*)0x04000030)
./nds/arm9/video.h:#define BG3_XDY        (*(vuint16*)0x04000032)
./nds/arm9/video.h:#define BG3_YDX        (*(vuint16*)0x04000034)
./nds/arm9/video.h:#define BG3_YDY        (*(vuint16*)0x04000036)


The addresses are different, but you seem to have pasted definitions for BG2 rather than BG3 -- in any case though, libnds defines BG2_CX and BG2_CY as vuint32*'s as well.

#127592 - Lick - Thu May 03, 2007 1:49 pm

Ah, my mistake. I was confusing it with the rotation regs.
_________________
http://licklick.wordpress.com

#127956 - mml - Sun May 06, 2007 11:20 pm

I'm still curious what's going on here, but I forked the code the other day to play around with tiles and physics and haven't been back. Thanks anyway, though. Will come back to this if I need actually need a bitmap background for something, I guess.