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 > Mode7 question - again

#6527 - igorfromspb - Wed May 28, 2003 1:31 pm

Has anyone managed to finish that Pernproject Mode7 tutorial? I mean get it to switch between Mode7 and a bitmap mode to blit the sunset pic into the upper half of the screen? I know it's supposed to be very simple, it's just that I don't seem to be able to get it to run properly :-((( I either get only the lower part (mode7 floor) or only the upper part (the sunset pic) or the whole thing flickers terribly... Perhaps I'm missing the point all together. I wonder if anyone could help. Cheers.
_________________
Guns for show, knives for a pro

#6530 - Quirky - Wed May 28, 2003 2:26 pm

I've just done it... well, not added the BG but got it so there's a horizon effect. Adding the bg would be not much more effort though.

What you need to do is set the mode to a non rotate/scale mode for the first part of the screen draw, then switch to mode 2 when you want the "horizon" to start. I made this change:

Code:

void VBLANK()
{   

   REG_IF = INT_VBLANK;      
   // set the mode to mode 0...
   SetMode(MODE_0 | BG2_ENABLE);
   
   
}
void HBLANK(void)
{

    if (REG_VCOUNT == 30)
      SetMode(MODE_2 | BG2_ENABLE);

  //... rest of HBLANK code
}

#6566 - igorfromspb - Thu May 29, 2003 9:11 am

Quirky

Thanks a lot, it works! :-)
_________________
Guns for show, knives for a pro

#6568 - Link - Thu May 29, 2003 10:58 am

Quirky wrote:
I've just done it... well, not added the BG but got it so there's a horizon effect. Adding the bg would be not much more effort though.

What you need to do is set the mode to a non rotate/scale mode for the first part of the screen draw, then switch to mode 2 when you want the "horizon" to start. I made this change:

Code:

void VBLANK()
{   

   REG_IF = INT_VBLANK;      
   // set the mode to mode 0...
   SetMode(MODE_0 | BG2_ENABLE);
   
   
}
void HBLANK(void)
{

    if (REG_VCOUNT == 30)
      SetMode(MODE_2 | BG2_ENABLE);

  //... rest of HBLANK code
}



what this code does?

#6571 - Quirky - Thu May 29, 2003 12:04 pm

Pern Project tutorial read you must. Help you it will. :)

EDIT: Except in this case it probably won't help as that isn't explained on there. Oops!

That code sets the screen mode to 0 on the vblank interrupt, i.e. just after the screen has been drawn. So when the screen starts to get drawn on the next pass the mode is 0, so no "mode 7 effect" takes place.

The hblank interrupt is fired at the end of every line that is drawn. After 30 lines (vcount == 30) the mode is switched to mode 2, which is a rotation/scale mode. So from then on, the screen is drawn with the famous "mode 7 effect".

See dovoto's source code for setting up the rotation and scale effect, that code I posted was a snippet of the changes to make to get the next part working - drawing an horizon and backdrop.

#6970 - DekuTree64 - Thu Jun 05, 2003 3:27 pm

Quirky wrote:
Code:

void VBLANK()
{   

   REG_IF = INT_VBLANK;      
   // set the mode to mode 0...
   SetMode(MODE_0 | BG2_ENABLE);
   
   
}
void HBLANK(void)
{

    if (REG_VCOUNT == 30)
      SetMode(MODE_2 | BG2_ENABLE);

  //... rest of HBLANK code
}


This is kind of an old post, but I just had to ask. Wouldn't that show every other tile, with scrambled palettes and flipping, since mode 0 BGs use 16-bit tile entries and mode 2 uses 8-bit? I'd just keep an array of rot/scale reg values for each line, and leave the first 30 entries normal.

#6973 - tepples - Thu Jun 05, 2003 4:24 pm

DekuTree64 wrote:
Wouldn't [switching from mode 0 to mode 2 on vcount] show every other tile, with scrambled palettes and flipping, since mode 0 BGs use 16-bit tile entries and mode 2 uses 8-bit?

Not if you change the nametable address in BG2CNT at the same time. Something like this is what F-Zero and Super Mario Kart on the Super NES did, and it's also what Mario Kart Super Circuit does.

Quote:
I'd just keep an array of rot/scale reg values for each line, and leave the first 30 entries normal.

But then you don't get lots of layers for the background.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#17509 - bomberman - Tue Mar 09, 2004 7:20 pm

Just tried this yesterday... and I have a problem.
By using search, I found this old topic. So maybe you have a clue.

I switch from mode 2 to mode 0 on an hblank interrupt at line 151. That works fine in the emul, and that works almost fine on the hardware :(
I see correctly what I should see in both modes except the first three lines (152 to 154) are completely blank and belong neither to mode 2 nor mode 0...

Did you experience that on the hardware ???

Thanks for your help.

#17512 - poslundc - Tue Mar 09, 2004 7:38 pm

Yeah, that sounds pretty much like what I experienced. Switching modes during VDraw generally causes a couple of scanlines of garbage.

Although from what tepples has informed us, it may be possible to obscure the effect with a text background that isn't affected by the mode change (eg. BGs 0 and 1 when going between modes 1 and 2). Since Mode 2 doesn't have any text backgrounds, though, I don't know how you would manage this.

Dan.

#17525 - bomberman - Tue Mar 09, 2004 10:16 pm

It's what I feared... I'll have to handle my status bar through sprites :(
It would have been very practical to use a text background. I'll keep searching for a while and should I find something, I'll post it.

#17531 - Miked0801 - Tue Mar 09, 2004 11:05 pm

You can mode switch from 0 to 1 w/o garbage. We've done this on previous games.

#17540 - bomberman - Wed Mar 10, 2004 12:24 am

but that's it... the only combination.
I absolutely need mode 2 for my game :(

thanks anyway.

btw, what is the explanation behind this behaviour ? I spoke to pros, they were not aware of it, and I am even more surprised that it can work for some combination(s?) of modes...

#17543 - Miked0801 - Wed Mar 10, 2004 12:52 am

You sure? I don't see why mode 0 to mode 2 couldn't work - or 2 to 0. It's just a matter of timing in your hblanks.

#17546 - bomberman - Wed Mar 10, 2004 1:16 am

[post edited]

f..k

if you read this post forget about it... doesn't work :O(

Mike, I will try between mode with text background as stated above just to ensure my code is right.
I can send you the bins and relevant code if you want. This is insane...

#17552 - poslundc - Wed Mar 10, 2004 3:44 am

Miked0801 wrote:
You sure? I don't see why mode 0 to mode 2 couldn't work - or 2 to 0. It's just a matter of timing in your hblanks.


It's been my experience that meddling with REG_DISPCNT mid-draw causes a couple of scanlines of garbage, at least wherever the actual display is affected (eg. turning backgrounds on and off). I've only seen it happen on hardware.

Dan.

#17567 - bomberman - Wed Mar 10, 2004 9:32 am

and it's not a pleasant experience :O)

Today I use mode2(BG2+BG3) and I switch back and forth to mode0(BG0). If it is a matter of switching background on and off, I can try to switch from mode2(BG2+BG3) to mode0(BG2) since I have the full VBlank to come back to mode 2 and switch on both backgrounds.

Maybe I was not clear...

#17571 - Cearn - Wed Mar 10, 2004 1:40 pm

Just FYI, the PERN mode 7 is horribly blocky at close range (high VCount and/or low altitude) There is a very simple way of getting rid of that. See
http://user.chem.tue.nl/jakvijn/tonc/mode7.htm#demo for pictures of PERN's mode 7 (fig 7a), one based on Shaun Southerns demo (fig7c) and one that's somewhere in between (fig7b). The code for all three of these is given a little lateron in the page.
Unfortunately I can only test on emu. If hardware gives you trouble with this code then forget I mentioned anything.

#17584 - Miked0801 - Wed Mar 10, 2004 7:01 pm

Ok, I just went and double checked to make sure I was correct and yes, we are switching on an hblank from mode 0 to mode 1 w/o any garbage (on hardware or emu). Are you waiting to make sure that you are indeed within an hblank period when switching and also making sure that your HDMA interrupt is not running before or while the switch is occuring? It does work, we have a game on the way to publishing that uses it.

#17654 - bomberman - Thu Mar 11, 2004 11:33 pm

YYYYYEEEEEEEEESSSSSSSSSSSSS !!!!!!!!!!!

I got it after several hours of experiment and juggle with those damn registers. And yes Mike, I was timing correctly ! I never doubted in my code ;o)
Here is what I tried...

Originally, I was displaying mode 2 (BG2+BG3) until line 151. Then from here, I would switch to mode 0 (BG0). I had those first three lines which were blank. But when switching back to mode 2, no blank lines (because in the mean time, we were in the VBlank which lasts for 68 lines).
I then tried to make the contrary. Display first eight lines with mode 0 and then switch to mode 2 for the remaining of the screen. I still had three missing lines when entering mode 2.
I thought that maybe the fact of enabling/disabling background is not something GBA likes. I don't know why it would be like this but it was worth a try.
So instead of switching to mode 0 (BG0), I tried to switch to mode 0 (BG2). And guess what ? It worked. I terminated by testing mode 0 (BG1) which doesn't work and mode 0 (BG3) which works. I could also test with mode 1 and combinations of BG 0, 1 and 2, but I feel what would be the results.
This implies, as tepples says, to modify not only the display register during the HBlank, but also the background register to point to the correct map/char blocks.

If someone could explain me why the graphics processor is inactive when enabling or disabling backgrounds during the display of three lines, I would be more than obliged !

Dan, can you confirm if you were in a configuration like I was and Mike could you confirm that you keep the same BG when you switch mode ?
Hey Dan, you can restart doing what you wanted to do...

Luckily I test on hardware quite frequently :O)

#17655 - Miked0801 - Fri Mar 12, 2004 12:09 am

Not sure what you mean by keeping same BG.

#17660 - poslundc - Fri Mar 12, 2004 12:54 am

bomberman wrote:
Dan, can you confirm if you were in a configuration like I was and Mike could you confirm that you keep the same BG when you switch mode ?


I can't confirm much; it was a long time ago that I was trying to do the mode-switch thing. I forget if I was switching modes or toggling BGs on and off (or perhaps both). Anyway, my general advice to anyone else planning on venturing down this road is to be wary of what you do with REG_DISPCNT during HBlanks, and make sure to test on hardware early and often.

Dan.

#17676 - bomberman - Fri Mar 12, 2004 9:55 am

@Mike

I was referring to BG numbers. In mode 2, I have BG2 and BG3 as active. On HBlank, I only activated mode 0 with BG0. It's where GBA has problems.
If I activate mode 0 but with BG2 active (or BG3) which was already active, then it's fine. Just make sure that the BG that you want to display was already displayed in the previous mode before HBlank.
In short it seems that GBA has no problems switching modes in a HBlank (after all even twenty years old 8bits computers do that), but activating a BG takes time, approximately three scanlines (obviously longer than a HBlank).

@Dan
I can only repeat the same advice. Several and frequent test on hardware are mandatory !

#17692 - Miked0801 - Fri Mar 12, 2004 6:58 pm

Ok, we already have all 4 planes active above the line, below, we only ohave 3 as that's the max that the mode supports - so that stays within your theory.

#17799 - bomberman - Sun Mar 14, 2004 10:08 pm

Mike, make the test, you will see this is more than a theory ;)

#19941 - bomberman - Wed Apr 28, 2004 3:32 pm

Sorry to get this thread out of the limbs but I have the explanation now...
but for those who followed it, they might be interested
If you have a look at the Of....al Ni....do Do.........on, it is said when it come to DISPSTAT, bits 8 to 12, that it is immediate to turn a background OFF, but it takes exactly three scan lines to turn a background ON !!!

I had estimated the blank to three lines on my tiny screen if you look above. Not bad :O)
So either I keep the solution I ended with (reusing the same BG but changing the map/tile blocks, which is a quick enough thing to do during a HBlank) or I do like this: still change the mode at line 151 but also at line 148 reactivating BG0.

Hope it helps !

#19952 - dagamer34 - Wed Apr 28, 2004 9:46 pm

bomberman wrote:

Of....al Ni....do Do.........on


I wonder what this means...
_________________
Little kids and Playstation 2's don't mix. :(

#19953 - niltsair - Wed Apr 28, 2004 9:57 pm

For 150$, I'll take an 'E' :) There are 23!!!!

My guess Official Nintendo Documention :)
_________________
-Inside every large program is a small program struggling to get out. (Hoare's Law of Large Programs)
-The man who can smile when things go wrong has thought of someone he can blame it on. (Nixon's Theorem)

#19955 - dagamer34 - Wed Apr 28, 2004 10:10 pm

I was being funny.

I'll take an 'I' for $200, anyway.
_________________
Little kids and Playstation 2's don't mix. :(

#19980 - gladius - Thu Apr 29, 2004 4:45 am

The solution I used in my racer demo (was posted on gbadev a loooong time ago, http://members.fortunecity.com/infinityhq/projects/gba.html) was to load the information I needed for the two horizon backgrounds, and the mode7 map part into VRAM first.

Once all that was loaded up, at the vblank, set up mode 2, with bg 2 and 3 showing the horizon, and set up a VCOUNT interrupt at line 31.

The VCOUNT at line 31 turns on a H-blank interrupt, the H-blank interrupt then sets up the HDMA, and changes bg 2 and 3 to be the ones used for the mode 7 ground. It then enables a VCOUNT interrupt at line 161 and turns the h-blank interrupt off.

The VCOUNT interrupt at 161 simply disables the HDMA and reenables line coincidence for line 31, and the cycle of life repeats :).[/url]