Using SGDK's VDP_setHorizontalScroll()

For anything related to VDP (plane, color, sprite, tiles)

Moderators: BigEvilCorporation, Mask of Destiny

Post Reply
djcouchycouch
Very interested
Posts: 710
Joined: Sat Feb 18, 2012 2:44 am

Using SGDK's VDP_setHorizontalScroll()

Post by djcouchycouch » Sun Feb 19, 2012 2:59 pm

I have a few basic questions about VDP_setHorizontalScroll() as I'm not sure what kind of behaviour I should be expecting. I've seen other threads about the topic but I still haven't been able to wrap my head around it.

- To confirm: If I want to scroll the whole background layer as one big piece, as opposed to line-by-line, would I just call VDP_setHorizontalScroll(APANE, 0, myScrollValue) ? I've tried this and it appears like it works that way.

- If I wanted to scroll a background layer line-by-line, don't I just call VDP_setHorizontalScroll for each line with their own scrolling value?

- Is the number of scrollable lines dependant on the height of the background layer or the height of the screen?

- When is the best time to call VDP_setHorizontalScroll? I've seen examples where its set during HBLANK, some not. In my own code, I'm calling it in a while loop in the main function.

- Somewhat related, when is the best time to update game code? Like my question above, I'm not sure if I should be doing game logic in a while loop in my main function or if I should be doing it in a blanking callback function.

Thanks!
DJCC.

hiperbou
Newbie
Posts: 6
Joined: Sun Aug 12, 2012 1:43 pm

Post by hiperbou » Sun Aug 12, 2012 1:46 pm

Hello, sorry for writing on an old post.
I'm very interested in the questions you have made. Did you made any research or find the answers by yourself?

djcouchycouch
Very interested
Posts: 710
Joined: Sat Feb 18, 2012 2:44 am

Post by djcouchycouch » Sun Aug 12, 2012 9:26 pm

Hi!

Here's what I figured out.

If you want any kind of scrolling other than the whole background, you have to set the scrolling mode. For example, in my code I have:

Code: Select all

void SetScrollMode()
{
    // register 0x0b sets the scroll mode
    // first two bits sets the horizontal scroll mode (whole layer mode (0x00), tile row mode(0x02), or per-line mode(0x03))
    // third bit (0 or 1) sets the vertical scroll mode (whole layer mode or column mode)

    VDP_setReg(0x0b, 0x03); 
}

This sets the scroll mode to per-line. This means every line has a scroll value.


So when calling:

Code: Select all

void VDP_setHorizontalScroll(u16 plan, u16 line, u16 value);
you can pass one scroll value per line.

It might be too slow because you're calling a function for every value for every line. I wrote a helper function that takes an array instead.

Code: Select all

void VDP_setHorizontalScrollLines(u16 plan, u16* lines, u16 value)
{
    vu16 *pw;
    vu32 *pl;
    u16 addr;

    /* Point to vdp port */
    pw = (u16 *) GFX_DATA_PORT;
    pl = (u32 *) GFX_CTRL_PORT;

    addr = HSCRL;
    if (plan == BPLAN) addr += 2;

    VDP_setAutoInc(4);
    *pl = GFX_WRITE_VRAM_ADDR(addr);

    u16* tempLines = lines;

    u16 loop = 224;
    while(loop--)
    {
        *pw = *tempLines;
        tempLines++;
    }
}

Each line is in "screen" space. That means it only affects the line scroll for every visible line on screen. It won't affect any lines outside of the screen. You'll see what I mean if you mess around with the values.


If you're using per-tile scrolling, as opposed to per line, you need to call void VDP_setHorizontalScroll(u16 plan, u16 line, u16 value) but for every 8th line. So something like:

VDP_setHorizontalScroll(APLAN, 0, value); // first tile row
VDP_setHorizontalScroll(APLAN, 8, value); // second tile row
VDP_setHorizontalScroll(APLAN, 16, value); // third tile row
VDP_setHorizontalScroll(APLAN, 24, value); // fourth tile row

And, in Goplanes, I call those scrolling functions during VBlank.

I hope that gets you unstuck.

DJCC.

hiperbou
Newbie
Posts: 6
Joined: Sun Aug 12, 2012 1:43 pm

Post by hiperbou » Sun Aug 12, 2012 10:26 pm

Thanks for your answers, I hope it could be useful to anyone searching information about this in the future.
In addition to what you said:
- Is the number of scrollable lines dependant on the height of the background layer or the height of the screen?
As it seems, there will be 224 or 240 scrollable lines (NTSC or PAL)
- Somewhat related, when is the best time to update game code? Like my question above, I'm not sure if I should be doing game logic in a while loop in my main function or if I should be doing it in a blanking callback function.
I'm doing this on my game loop.

I've also made a custom function to update the scroll both vertically and horizontally using per-line scroll mode. But I'll give a try to the variation you have made.
Thanks!

Stef
Very interested
Posts: 3131
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Post by Stef » Mon Aug 13, 2012 8:28 pm

djcouchycouch wrote: ...
This sets the scroll mode to per-line. This means every line has a scroll value.


So when calling:

Code: Select all

void VDP_setHorizontalScroll(u16 plan, u16 line, u16 value);
you can pass one scroll value per line.

It might be too slow because you're calling a function for every value for every line. I wrote a helper function that takes an array instead.
...
Indeed =) I will methods in the next version so you could set all H scroll on a single call as your helper version. Same stuff goes for vscroll ;)

Post Reply