Horizontal Scroll not showing all background image
Moderator: Stef
Horizontal Scroll not showing all background image
I'm learning about scrolling, just made some simple scrolls and found that not all background images are showing at all.
Just using files bga.png and bgb.png from Sample/Sprite example (both 640px wide).
I write px in bga.png to check where is cut, and happens around 500px (pls see attached).
I think I made all well...
...
VDP_setScreenWidth320();
VDP_setPalette(PAL1, bga_image.palette->data);
ind = TILE_USERINDEX;
VDP_drawImageEx(PLAN_A, &bga_image, TILE_ATTR_FULL(PAL1, FALSE, FALSE, FALSE, ind), 0, 0, FALSE, TRUE);
ind += bgb_image.tileset->numTile;
...
VDP_setScrollingMode(HSCROLL_PLANE, VSCROLL_PLANE);
...
VDP_setHorizontalScroll(PLAN_A, offset_H_PlanoA); //offset_H_PlanoA increase when hit LEFT of RIGHT
Take note same happens with PLAN_B and bgb image
Just using files bga.png and bgb.png from Sample/Sprite example (both 640px wide).
I write px in bga.png to check where is cut, and happens around 500px (pls see attached).
I think I made all well...
...
VDP_setScreenWidth320();
VDP_setPalette(PAL1, bga_image.palette->data);
ind = TILE_USERINDEX;
VDP_drawImageEx(PLAN_A, &bga_image, TILE_ATTR_FULL(PAL1, FALSE, FALSE, FALSE, ind), 0, 0, FALSE, TRUE);
ind += bgb_image.tileset->numTile;
...
VDP_setScrollingMode(HSCROLL_PLANE, VSCROLL_PLANE);
...
VDP_setHorizontalScroll(PLAN_A, offset_H_PlanoA); //offset_H_PlanoA increase when hit LEFT of RIGHT
Take note same happens with PLAN_B and bgb image
- Attachments
-
- scroll problem.PNG (130.52 KiB) Viewed 15253 times
-
- bga.png (4.4 KiB) Viewed 15253 times
-
- Very interested
- Posts: 118
- Joined: Mon Feb 19, 2018 7:31 pm
Re: Horizontal Scroll not showing all background image
Maybe it is rescomp's optimization.
Look your .res file.
0 / NONE = no optimisation (each tile is unique)
1 / ALL = find duplicate and flipped tile (default)
2 / DUPLICATE = find duplicate tile only
https://github.com/Stephane-D/SGDK/blob ... escomp.txt
Look your .res file.
0 / NONE = no optimisation (each tile is unique)
1 / ALL = find duplicate and flipped tile (default)
2 / DUPLICATE = find duplicate tile only
https://github.com/Stephane-D/SGDK/blob ... escomp.txt
Re: Horizontal Scroll not showing all background image
This is my .res
IMAGE bgb_image "gfx/bgb.png" NONE
IMAGE bga_image "gfx/bga.png" NONE
Tried also
IMAGE bgb_image "gfx/bgb.png" BEST
IMAGE bga_image "gfx/bga.png" BEST
No changes at all
IMAGE bgb_image "gfx/bgb.png" NONE
IMAGE bga_image "gfx/bga.png" NONE
Tried also
IMAGE bgb_image "gfx/bgb.png" BEST
IMAGE bga_image "gfx/bga.png" BEST
No changes at all
-
- Very interested
- Posts: 118
- Joined: Mon Feb 19, 2018 7:31 pm
Re: Horizontal Scroll not showing all background image
Try with another NONE
name, img_file, compression, mapopt
name, img_file, compression, mapopt
Code: Select all
IMAGE bgb_image "gfx/bgb.png" NONE NONE
IMAGE bga_image "gfx/bga.png" NONE NONE
Re: Horizontal Scroll not showing all background image
The tilemap is 512px wide. You need to draw in new tiles on the sides as you scroll it.
Sik is pronounced as "seek", not as "sick".
Re: Horizontal Scroll not showing all background image
This is not working properly, lot of artifacts.cloudstrifer wrote: ↑Tue Oct 01, 2019 3:50 amTry with another NONE
name, img_file, compression, mapopt
Code: Select all
IMAGE bgb_image "gfx/bgb.png" NONE NONE IMAGE bga_image "gfx/bga.png" NONE NONE
Yes, I think this is the problem.
I saw "[TUTO] How to make a scrolling ?" thread, but maybe a little hard for me.
If you know about another simple tutorial, it will be wellcome.
Re: Horizontal Scroll not showing all background image
Hi again, I'm afraid I saw lot of threads but no success at all.
Ok so by default with SGDK we have 512 pixels wide, that is, 64 tiles (from 0 to 63).
Question. bga.png is 640px wide. Where are the last 640-512=128px (16 tiles)? (from 64 to 79)
Are they still in memory somewhere?
I tried to use VDP_setMapEx() but not sure how to use it. I want to add tiles row 64 to memory, as scroll moves from left to right, after that add row 65 and so until 79... and then start again in 0. But no matter how I do, VDP_setMapEx() paints with 'nothing', all I see is background.
plan = PLAN_A // ok
map = bga_image.map // is this ok????
TILE_ATTR_FULL(...) // ok
x= 64;
y=0;
xm= ??
ym= ??
wm= ??
hm= ??
Not sure what to put in xm,ym,wm,hm... ?
Ok so by default with SGDK we have 512 pixels wide, that is, 64 tiles (from 0 to 63).
Question. bga.png is 640px wide. Where are the last 640-512=128px (16 tiles)? (from 64 to 79)
Are they still in memory somewhere?
I tried to use VDP_setMapEx() but not sure how to use it. I want to add tiles row 64 to memory, as scroll moves from left to right, after that add row 65 and so until 79... and then start again in 0. But no matter how I do, VDP_setMapEx() paints with 'nothing', all I see is background.
Code: Select all
VDP_setMapEx( plan, map, TILE_ATTR_FULL(....), x,y, xm, ym, wm, hm)
map = bga_image.map // is this ok????
TILE_ATTR_FULL(...) // ok
x= 64;
y=0;
xm= ??
ym= ??
wm= ??
hm= ??
Not sure what to put in xm,ym,wm,hm... ?
Re: Horizontal Scroll not showing all background image
I'm going to attempt to explain. I'll try to simplify as much. I'll only concentrate on horizontal scrolling. Assuming NTSC mode 320x224.
In the VDP_setMapEx function, you can think of the x and y parameters as the PLAN TILE SPACE. So by default, SGDK assigns 64 tiles wide and 32 tiles high. With that in mind, you can set it by getting the modulo as x % 64 or y % 32, so that if it exceeds it will "wrap around". Or you could also do x & 63 or y & 31 so that it only gets the significant bits (since both are always power of two).
xm and ym you can think as the MAP TILE SPACE. It's what the position in the tilemap you want to get information from. So if you created a map using IMAGE, you divide the image's width and height by 8, and you get the number of tiles per horizontal and vertical respectively. The SGDK Map structure has w, h vallues which corresponds to the tilemap's horizontal and vertical number of tiles.
wm and hm are the number of columns and row you want to copy. If you only want to copy the right/left edge, then wm, hm would be something like 1, 28. Means 1 tile wide, 28 tiles high (28 * 8 = 224 pixels NTSC mode height). VDP_setMapEx might be ok to "paint" the whole screen by settings hm,wm to 40,28, but do that only when initially positioning the map. Succeeding paints should only paint the edges. In most cases that's enough unless you have a scroll speed higher the 8 pixels (in which case you paint 2 tiles wide).
Now, all this must be tied with your camera. VDP_setHorizontalScroll basically sets your "camera" by offsetting the PLAN with the given value. But think of the CAMERA in WORLD PIXEL SPACE. You have to convert you camera coordinates into MAP TILE SPACE and PLAN TILE SPACE. You could do that by first dividing the camera value by 8 (or shifting by 3, like CamX >> 3). Don't forget to get the modulo "% 64" or get the significant bits "& 63" to keep it within PLAN TILE SPACE for the x parameter. For xm, keep as is.
So, if you have CamX and CamY as camera position (which represents the upperleft corner of your CAMERA), then CamX >> 3 will return you the leftmost part of your camera, while (CamX >> 3) + 39 would be the rightmost, though I suggest painting at (CamX >> 3) + 40 instead to avoid seeing "unpainted" edge.
Then when setting the camera values, it should be:
VDP_setHorizontalScroll(plan, -CamX);
VDP_setVerticalScroll(plan, CamY);
Note that CamX is negated.
I hope this gets you started. There are many other points, like optimization, 8-way scrolling, "negative" coordinates, and using FX32 for camera. But those can come later once you figured out basic scrolling. I'm pretty sure I missed something, or have something wrong. And nothing gets more replies than a wrong answer
In the VDP_setMapEx function, you can think of the x and y parameters as the PLAN TILE SPACE. So by default, SGDK assigns 64 tiles wide and 32 tiles high. With that in mind, you can set it by getting the modulo as x % 64 or y % 32, so that if it exceeds it will "wrap around". Or you could also do x & 63 or y & 31 so that it only gets the significant bits (since both are always power of two).
xm and ym you can think as the MAP TILE SPACE. It's what the position in the tilemap you want to get information from. So if you created a map using IMAGE, you divide the image's width and height by 8, and you get the number of tiles per horizontal and vertical respectively. The SGDK Map structure has w, h vallues which corresponds to the tilemap's horizontal and vertical number of tiles.
wm and hm are the number of columns and row you want to copy. If you only want to copy the right/left edge, then wm, hm would be something like 1, 28. Means 1 tile wide, 28 tiles high (28 * 8 = 224 pixels NTSC mode height). VDP_setMapEx might be ok to "paint" the whole screen by settings hm,wm to 40,28, but do that only when initially positioning the map. Succeeding paints should only paint the edges. In most cases that's enough unless you have a scroll speed higher the 8 pixels (in which case you paint 2 tiles wide).
Now, all this must be tied with your camera. VDP_setHorizontalScroll basically sets your "camera" by offsetting the PLAN with the given value. But think of the CAMERA in WORLD PIXEL SPACE. You have to convert you camera coordinates into MAP TILE SPACE and PLAN TILE SPACE. You could do that by first dividing the camera value by 8 (or shifting by 3, like CamX >> 3). Don't forget to get the modulo "% 64" or get the significant bits "& 63" to keep it within PLAN TILE SPACE for the x parameter. For xm, keep as is.
So, if you have CamX and CamY as camera position (which represents the upperleft corner of your CAMERA), then CamX >> 3 will return you the leftmost part of your camera, while (CamX >> 3) + 39 would be the rightmost, though I suggest painting at (CamX >> 3) + 40 instead to avoid seeing "unpainted" edge.
Then when setting the camera values, it should be:
VDP_setHorizontalScroll(plan, -CamX);
VDP_setVerticalScroll(plan, CamY);
Note that CamX is negated.
I hope this gets you started. There are many other points, like optimization, 8-way scrolling, "negative" coordinates, and using FX32 for camera. But those can come later once you figured out basic scrolling. I'm pretty sure I missed something, or have something wrong. And nothing gets more replies than a wrong answer
Re: Horizontal Scroll not showing all background image
Awesome, best explanation ever!!
Thanks a lot, I will try again, have a nice day
Thanks a lot, I will try again, have a nice day
Re: Horizontal Scroll not showing all background image
Still having problems with scroll. Let's work simple. Horizontal scroll only (from left to right). 320x224px. Only 1 plane. No sprites.
I'm using sonic background from SGDK sample folder but I add px position (see background's bottom)
As you can see this image have 640x224px, then 80x28 tiles. In BLUE part to be scroll, in purple zone not to be showed when scrolling as exceeds memory zone for scroll. That's the reason 500px mark (bottom image) and palm is cut (pls see first post).
So this is what I have now:
Sure it's wrong but.. why?
At the beginning, plan_A is painted with VDP_drawImageEx(). That's right.
Then in main loop, I use VDP_setHorizontalScroll(PLAN_A, offset); to move 1 px the image to the left.
After 8 movements, 1 tile is moved, then at this moment tile 0, rolls in memory from left part to right part, and becomes 63 tile.
That's the reason I tried to use
VDP_setMapEx(PLAN_A, mi_map, TILE_ATTR_FULL(PAL0, FALSE, FALSE, FALSE, ind_tileset), 63, 0, 64+cont, 0, 1, 28);
to paint in tile 63 (PLAN TILE SPACE) the right tile column (tile 64 in MAP TILE SPACE).
For some reason I get scroll and 1 colum changing at tile 63... not sure why XD
Pls see
https://prnt.sc/phvscg
I'm using sonic background from SGDK sample folder but I add px position (see background's bottom)
As you can see this image have 640x224px, then 80x28 tiles. In BLUE part to be scroll, in purple zone not to be showed when scrolling as exceeds memory zone for scroll. That's the reason 500px mark (bottom image) and palm is cut (pls see first post).
So this is what I have now:
Code: Select all
[..]
u16 ind_tileset;
s16 offset;
int main()
{
SYS_disableInts();
offset =0;
VDP_setScreenWidth320();
//backgrounds
VDP_setPalette(PAL0, fondo1.palette->data);
ind_tileset = TILE_USERINDEX;
VDP_drawImageEx(PLAN_A, &fondo1, TILE_ATTR_FULL(PAL0, FALSE, FALSE, FALSE, ind), 0, 0, FALSE, TRUE);
ind_tileset += fondo1.tileset->numTile;
// load image tileset with DMA, decompress before using
VDP_loadTileSet(fondo1.tileset, ind_tileset, TRUE);
Map *mi_map = unpackMap(fondo1.map, NULL);
SYS_enableInts();
int i = 0;
int cont = 0;
while(TRUE)
{
VDP_setHorizontalScroll(PLAN_A, offset);
SPR_update();
VDP_waitVSync();
if(i>7) //only every 8
{
i = 0;
VDP_setMapEx(PLAN_A, mi_map, TILE_ATTR_FULL(PAL0, FALSE, FALSE, FALSE, ind_tileset), 63, 0, 64+cont, 0, 1, 28);
cont++; if(cont>16) cont = -64; // 80 tiles - 64 = 16 tiles
}
offset--; i++;
}
return 0;
}
Sure it's wrong but.. why?
At the beginning, plan_A is painted with VDP_drawImageEx(). That's right.
Then in main loop, I use VDP_setHorizontalScroll(PLAN_A, offset); to move 1 px the image to the left.
After 8 movements, 1 tile is moved, then at this moment tile 0, rolls in memory from left part to right part, and becomes 63 tile.
That's the reason I tried to use
VDP_setMapEx(PLAN_A, mi_map, TILE_ATTR_FULL(PAL0, FALSE, FALSE, FALSE, ind_tileset), 63, 0, 64+cont, 0, 1, 28);
to paint in tile 63 (PLAN TILE SPACE) the right tile column (tile 64 in MAP TILE SPACE).
For some reason I get scroll and 1 colum changing at tile 63... not sure why XD
Pls see
https://prnt.sc/phvscg
Re: Horizontal Scroll not showing all background image
You are hardcoding the 63 into VDP_setMapEx. You shouldn't. It should be based on the offset converted into PLAN SPACE.
Same goes for the 64+cont part, which should be also be based on the offset converted into TILEMAP SPACE.
Also, note that you are subtracting your offset as you're supposed to go right? That can work, just remember to convert your sign when computing TILE and PLANE SPACE. For me, I prefer it to be positive as you go right, then just apply the negated value to VDP_setHorizontalScroll. Same goes for the vertical offset, I prefer it to be positive as I go down, but no need to change sign in VDP_setVerticalScroll.
Same goes for the 64+cont part, which should be also be based on the offset converted into TILEMAP SPACE.
Also, note that you are subtracting your offset as you're supposed to go right? That can work, just remember to convert your sign when computing TILE and PLANE SPACE. For me, I prefer it to be positive as you go right, then just apply the negated value to VDP_setHorizontalScroll. Same goes for the vertical offset, I prefer it to be positive as I go down, but no need to change sign in VDP_setVerticalScroll.
Re: Horizontal Scroll not showing all background image
If scrolling is still troubling you, I've altered the SGDK's "Sprite" example to do basic scrolling. (see attachment, scrolling.zip)
Made the playfield wider (1280px wide) to see the effect. Also, removed the BEST compression for the tilemaps, as VDP_setMapEx is slower when decompressing data (too slow for Sonic speed).
There's a pre-built "rom.bin" if you have issues building this.
Look for "danibus" in main.c for the comments.
Made the playfield wider (1280px wide) to see the effect. Also, removed the BEST compression for the tilemaps, as VDP_setMapEx is slower when decompressing data (too slow for Sonic speed).
There's a pre-built "rom.bin" if you have issues building this.
Look for "danibus" in main.c for the comments.
- Attachments
-
- scrolling.zip
- (219.93 KiB) Downloaded 382 times
Re: Horizontal Scroll not showing all background image
Thanks a lot @hotrodxhotrodx wrote: ↑Sat Oct 12, 2019 12:28 pmIf scrolling is still troubling you, I've altered the SGDK's "Sprite" example to do basic scrolling. (see attachment, scrolling.zip)
Made the playfield wider (1280px wide) to see the effect. Also, removed the BEST compression for the tilemaps, as VDP_setMapEx is slower when decompressing data (too slow for Sonic speed).
There's a pre-built "rom.bin" if you have issues building this.
Look for "danibus" in main.c for the comments.
Re: Horizontal Scroll not showing all background image
I'm fighting with scroll code again, it's working but there is a small problem
320x224px, horizontal scroll from right to left, using an image with size 1024x224px
The problem is that I can see when tiles are being updated, just when left tile colum is going to dissapear at the left part, it's updated and then moves away.
this is the code:
320x224px, horizontal scroll from right to left, using an image with size 1024x224px
The problem is that I can see when tiles are being updated, just when left tile colum is going to dissapear at the left part, it's updated and then moves away.
this is the code:
Code: Select all
[...]
VDP_drawImageEx(PLAN_B, &bgd_image, TILE_ATTR_FULL(PAL2, FALSE, FALSE, FALSE, ind), 0, 0, FALSE, TRUE);
ind += bgd_image.tileset->numTile;
VDP_setScrollingMode(HSCROLL_PLANE ,VSCROLL_PLANE);
s16 offset=512; //PIXELS from 0 to 1023px
s16 offsetTILES = 0; //TILES, from 0 to 63 tiles
while(TRUE) //main Loop
{
//here some sprite and control stuff
[...]
VDP_waitVSync();
//now scrolling part
VDP_setHorizontalScroll(PLAN_B, -offset);
offsetTILES = offset>>3 % 127;
if(offset>1023){ offset = 0; offsetTILES = 0;}
VDP_setMapEx(PLAN_B, bgd_image.map, TILE_ATTR_FULL(PAL2, FALSE, FALSE, FALSE, TILE_USERINDEX),offsetTILES, 0, offsetTILES, 0, 1, 28);
offset++;
}
[...]
-
- Very interested
- Posts: 2984
- Joined: Fri Aug 17, 2007 9:33 pm
Re: Horizontal Scroll not showing all background image
This line...
Did you mean to do
Remember that % is above >> in precedence. Or did you really want this
% is mod, so % 127 gives 0 to 126. Bitwise AND is also below >> in precedence.
Code: Select all
offsetTILES = offset>>3 % 127;
Code: Select all
offsetTILES = (offset>>3) % 127;
Code: Select all
offsetTILES = offset>>3 & 127;