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.
Using SGDK's VDP_setHorizontalScroll()
Moderators: BigEvilCorporation, Mask of Destiny
-
- Very interested
- Posts: 710
- Joined: Sat Feb 18, 2012 2:44 am
-
- Very interested
- Posts: 710
- Joined: Sat Feb 18, 2012 2:44 am
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:
This sets the scroll mode to per-line. This means every line has a scroll value.
So when calling: 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.
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.
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);
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.
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:
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!
In addition to what you said:
As it seems, there will be 224 or 240 scrollable lines (NTSC or PAL)- Is the number of scrollable lines dependant on the height of the background layer or the height of the screen?
I'm doing this on my game loop.- 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'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!
-
- Very interested
- Posts: 3131
- Joined: Thu Nov 30, 2006 9:46 pm
- Location: France - Sevres
- Contact:
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 vscrolldjcouchycouch wrote: ...
This sets the scroll mode to per-line. This means every line has a scroll value.
So when calling:you can pass one scroll value per line.Code: Select all
void VDP_setHorizontalScroll(u16 plan, u16 line, u16 value);
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.
...