GLBasic forum

Codesnippets => Code Snippets => Topic started by: mrplant on 2011-Dec-21

Title: Endless Horizontal Scrolling Code
Post by: mrplant on 2011-Dec-21
Hi.

I am using the following code to scroll along a graphic image. What I have is an image that is 6144 pixels by 768 - I am using a screen resolution of 1024x768 fullscreen.
I want to have this large image shown on the screen and to slowly scroll along the screen - once it gets to the end - it loops around smoothly to the beginning again.
To make it loop smoothly - I pasted the first 1024x768 pixels of the image onto the end again. The code below does the rest. Please take a look.

Now my questions...

Although this code works - its crude and I do want to stick to this method of doing it  - i.e. as described above - but can anyone suggest a more efficient way of doing this that perhaps
is Kinder on memory usage or is faster - although this works fine - I do worry about this.. Anyone?
My code is below should anyone want to run it - comments very welcome. Thanks.



// --------------------------------- //
// Project: Testbed: Lullaby TV
// Start: Wednesday, December 20th, 2011
// IDE Version: 10


SETCURRENTDIR("Media") // go to media files

LOADSPRITE "Lullaby-6144x768.png", 0

//PLAYMUSIC "Old MacDonald.wav",TRUE // Loop Music

CONSTANT ScreenWidth = 1024
CONSTANT ScreenHeight = 768

CONSTANT GraphicWidth = 6144

GLOBAL XPos = 0

LIMITFPS 50

CLEARSCREEN RGB(0,0,0) // Set the backbuffer background colour to Black.
SHOWSCREEN // Show it.

REPEAT
   VIEWPORT XPos,0,ScreenWidth+(-XPos),ScreenHeight
   DRAWSPRITE 0,0,0
   SHOWSCREEN
   DEC (XPos)
   IF XPos < -(GraphicWidth-ScreenWidth)
      XPos = 0
   ENDIF
UNTIL FALSE


[attachment deleted by admin]
Title: Re: Endless Horizontal Scrolling Code
Post by: ampos on 2011-Dec-21
Many devices have sprite lenght limited to 1024x1024 or 2048x2048. Even most of the PCs are at 2048.

So to be safe, you have to be limited to 1024x1024.

BTW, you dont need clearscreen 0, just use clearscreen -1. Why clear the screen if it is going to be overwritten?  :P

also this will work:

Code (glbasic) Select
cleascreen -1
repeat
for x=0 to 6144-1024
   drawsprite 0,x,0
   showscreen
next
until exit=true
Title: Re: Endless Horizontal Scrolling Code
Post by: mrplant on 2011-Dec-21
Thanks for your reply.

The Clearscreen command was an oversight I copied/pasted from my previous project  :-[

Given the size of the graphic file - and this content is just a test - I'd like to have non repeating elements so scrolling parallax layer style prob isn't what I want...

How can I then handle an image of this size - given that its 6000 plus pixels across and I want to display a fullscreen segment of that (1024x768) each frame..

I can't seem to find commands to cut out a rectangles area from a larger graphic image and show that...

I suppose what I am asking is what is the best approach to take to do this?

thanks again.

Title: Re: Endless Horizontal Scrolling Code
Post by: Moru on 2011-Dec-21
Get a tilemap editor. Can't say much else without seeing the picture you want to display...
Title: Re: Endless Horizontal Scrolling Code
Post by: Slydog on 2011-Dec-21
You would split your 6144 wide image into 6 (or 3) smaller images.
I'm not sure what platform you are targeting, but if it's PC then you should be good at 2048 wide images.

Then to scroll it you need to determine which two images (of the 3, if they are 2048 wide) you need displayed currently.
To draw the portion of the two images you want, use POLYVECTORs and specify the x, y for each corner vertice of the source image.

Here's something I whipped up (NOT tested) to show you what I mean.
I used my Poly_Draw() function, and TXyXy TYPE to make things simple.

Code (glbasic) Select
TYPE TXyXy
x1%
y1%
x2%
y2%

FUNCTION Set: x1%, y1%, x2%, y2%
self.x1 = x1
self.y1 = y1
self.x2 = x2
self.y2 = y2
ENDFUNCTION
ENDTYPE

CONSTANT ScreenWidth% = 1024
CONSTANT ScreenHeight% = 768
CONSTANT GraphicWidth% = 2048
CONSTANT BackgroundSprites% = 3
CONSTANT BackgroundWidth% = 2048 * 3 // GraphicWidth * BackgroundSprites

GLOBAL sp_background%[]
DIM sp_background[BackgroundSprites]
LOCAL xPos%=0
LOCAL x1%=0 // x Position where the two sprites are joined
LOCAL sp_current% // Current sprite we're working with
LOCAL xy_screen AS TXyXy // Screen x,y TL and BR corner locations
LOCAL xy_sprite AS TXyXy // Sprite x,y TL and BR corner locations

// Load the three images into the 3 sprites IDs
sp_background[0] = GENSPRITE
LOADSPRITE "Lullaby-1.png", sp_background[0]
sp_background[1] = GENSPRITE
LOADSPRITE "Lullaby-2.png", sp_background[1]
sp_background[2] = GENSPRITE
LOADSPRITE "Lullaby-3.png", sp_background[2]

// +---+------+
// |B1 |B2    |
// |   |      |
// +---+------+
// 0  x1     ScreenWidth

REPEAT
x1 = GraphicWidth - MOD(xPos, GraphicWidth)
sp_current = xPos / GraphicWidth // Will be either 0, 1, or 2

// Draw left background sprite
xy_screen.Set(0, 0, x1, ScreenHeight)
xy_sprite.Set(GraphicWidth-x1, 0, GraphicWidth, GraphicHeight)
STARTPOLY sp_current
Poly_Draw(xy_screen, xy_sprite, RGB(255,255,255))
ENDPOLY

// Draw right background sprite
INC sp_current // Use next background sprite
IF sp_current > BackgroundSprites THEN sp_current = 0  // Cycle to first background sprite when at end
xy_screen.Set(x1+1, 0, ScreenWidth, ScreenHeight)
xy_sprite.Set(0, 0, ScreenWidth-x1, GraphicHeight)
STARTPOLY sp_current
Poly_Draw(xy_screen, xy_sprite, RGB(255,255,255))
ENDPOLY

INC xPos
IF xPos > (BackgroundWidth - ScreenWidth) THEN xPos = 0
UNTIL FALSE

// (uv1) 0___2
//       |  /|
//       | / |
//       |/__|
//       1   3 (uv2)
// xy :: Top-Left and Bottom-Right screen location
// uv :: Top-Left and Bottom-Right texture location
FUNCTION Poly_Draw: xy AS TXyXy, uv AS TXyXy, colour%
POLYNEWSTRIP
POLYVECTOR xy.x1, xy.y1, uv.x1, uv.y1, colour // TL
POLYVECTOR xy.x1, xy.y2, uv.x1, uv.y2, colour // BL
POLYVECTOR xy.x2, xy.y1, uv.x2, uv.y1, colour // TR
POLYVECTOR xy.x2, xy.y2, uv.x2, uv.y2, colour // BR
ENDFUNCTION
Title: Re: Endless Horizontal Scrolling Code
Post by: mrplant on 2011-Dec-22
Hi thanks.

I will check this new way out and report back..

My target device is probably going to be the iPad in landscape mode 1024x768 - what is the maximum safe size to use for that platform just out of interest - anyone know?
Title: Re: Endless Horizontal Scrolling Code
Post by: mrplant on 2011-Dec-22
This code is simpler and does work... but as I originally discovered when writing my version - it scrolls the background the wrong direction left to right instead of right to left

cleascreen -1
repeat
for x=0 to 6144-1024
   drawsprite 0,x,0
   showscreen
next
until exit=true
Title: Re: Endless Horizontal Scrolling Code
Post by: Slydog on 2011-Dec-22
I think to just reverse the direction, change the last two lines in the loop to:

Code (glbasic) Select
DEC xPos
IF xPos < 0 THEN xPos = (BackgroundWidth - ScreenWidth)  // -1 : May need the '-1' at the end if flickers when at end
Title: Re: Endless Horizontal Scrolling Code
Post by: mrplant on 2011-Dec-23
Thanks Slydog - I haven't actually looked at your example code yet but it looks interesting - about to check it out now thanks.

I was still playing about with my own code - on the iPad it is stretching the aspect ratio for some weird reason I can't figure out - perhaps as the texture size is too big??

anyway-  about to test your solution out..

thanks.
Title: Re: Endless Horizontal Scrolling Code
Post by: chve on 2011-Dec-24
I should do something so:

Code (glbasic) Select

// --------------------------------- //
// Project: Testbed: Lullaby TV
// Start: Wednesday, December 20th, 2011
// IDE Version: 10.209


SETCURRENTDIR("Media") // go to media files

LOADSPRITE "Lullaby-6144x768.png",  map

//PLAYMUSIC "Old MacDonald.wav",TRUE // Loop Music

CONSTANT ScreenWidth = 1024
CONSTANT ScreenHeight = 768

CONSTANT GraphicWidth = 6144

GLOBAL map, exit

GLOBAL speedH, speedW, imgX, scrW, imgWide, imgY, scrH, imgHeight
GLOBAL worldX, worldY ,MundoX, MundoY


GETSPRITESIZE map, imgWide, imgHeight

scrW=imgWide ; scrH= imgHeight


imgX=0 ;imgY=0 ; speedW=1


LIMITFPS 50

SHOWSCREEN // Show it.

CLEARSCREEN -1
REPEAT
imgX=imgX-speedW ; IF (imgX+scrW)<0 THEN imgX=imgX+scrW

MundoX = MOD (worldX,imgWide) ;MundoX = -imgX ; IF worldX < 0 THEN MundoX = imgX - imgWide
DRAWSPRITE map, imgX, imgY
DRAWSPRITE map, imgX, imgY+scrH
    DRAWSPRITE map, imgX+scrW, imgY
DRAWSPRITE map, imgX+scrW, imgY+scrH

SHOWSCREEN
UNTIL exit=TRUE

Title: Re: Endless Horizontal Scrolling Code
Post by: mrplant on 2011-Dec-27
Hi Slydog.

I have been trying to compile your code but get this error.
Could you possibly run attached file with your code and work out what I have done wrong?
Graphics are cut into 2048 by 768 sizes like you mentioned..

thanks

This is the error I get when compiling for windows.

*** Configuration: WIN32 ***
precompiling:
GPC - GLBasic Precompiler V.10.104 SN:1d5d2793 - 3D, NET
Wordcount:50 commands
compiling:
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp0.cpp: In function `int __GLBASIC__::__MainGameSub_()':
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp0.cpp:130: error: `x1' was not declared in this scope
*** FATAL ERROR - Please post this output in the forum
_______________________________________
*** Finished ***

[attachment deleted by admin]
Title: Re: Endless Horizontal Scrolling Code
Post by: Kitty Hello on 2012-Jan-02
oh! bug.

Either move the TYPE declaration below the "main" function, or don't use the same parameter name "x1" in the Set function as well as a LOCAL in "main". So sorry.
Title: Re: Endless Horizontal Scrolling Code
Post by: mrplant on 2012-Jan-02
thanks
Title: Re: Endless Horizontal Scrolling Code
Post by: mrplant on 2012-Jan-03
go code to compile but it locked up machine. I don't know the first thing about polyvectors so I added  a show screen command to main loop and it didn't crash this time!
All it showed though was a scrolling in outline sort of like a moving pyramid single line - no graphic content just outline.. then another pyramid outline, followed by another..
Anyone?
Way over my head now... ;-(
Title: Re: Endless Horizontal Scrolling Code
Post by: Slydog on 2012-Jan-03
Sorry, I've been away all Christmas week.
I ran the code and see there were a few bugs.  (ha, I guess I should have tested it!)

I've fixed them as far as I can see, and it now scrolls continuously and smoothly.
See the attached project.

Oh, for testing, I put a red line at the bottom of the 2nd graphic (and a yellow on the 3rd) to help see where the scroll position is at.

You can switch the direction with the new 'direction' variable.  (-1 for reverse)
You can set the scroll speed with the new 'speed' variable.  (I guess these could be combined into one variable using a negative speed for the reverse direction!)

I'm not 100% sure this is pixel perfect yet.
It may skip the 1st or last pixel in the graphic, and/or overlap the joining pics by a pixel.
More testing would be needed. (ie. I would start and end each graphic file with a one pixel wide line, each file with a different colour, see if you notice both lines where the split is).

[Update] I fixed a bug with detecting the end (or start, depending on scroll direction) of the last/first image.
It looked like it was working, but it happens that the 1st half of the 1st image and 2nd half of the last image were identical so it appeared to connect back to back.

[attachment deleted by admin]
Title: Re: Endless Horizontal Scrolling Code
Post by: mrplant on 2012-Jan-04
Hi Slydog..

A fantastic routine you have written there. It runs great on PC. Mac and iPad!

I added some iOS auto rotation code for iPad and it handles it all great.

Seems much more stable than my original Objective-C and first GLBasic version.

The iPad seems able to handle the 2048 pixel wide images no problem, glad to report.

Well, iPad 2 anyway - still to test on an iPad1.

Incidentally, I added a 6 pixel high vertical coloured line at both edges of each section and did the same in a different colour at the edges of the 2nd section etc.

The good news is I took screenshots and zoomed in and the pixels met perfectly, meaning your routine seems to be joining up perfectly!

I wish I understood more about what Polyvector is doing.

I'll get there..

Regards

Mr Plant.
Title: Re: Endless Horizontal Scrolling Code
Post by: Slydog on 2012-Jan-06
Great!  It seems together perfectly!  (or appears to!)
But, I found a bug when it checks xPos for the start/end, it was one screen width off.
I updated the .zip file in my previous post.

It just so happens that the 1st and 3rd image have the same picture if you overlapped them one screen width.
The original yellow line should have scrolled out of view (when direction=1), but instead it suddenly skips to the 1st image, but was unnoticable as it was the same graphic.

Here's the udpated section:
Code (glbasic) Select
IF direction = 1
IF xPos >= BackgroundWidth THEN xPos = 0
ELSE
IF xPos < 0 THEN xPos = BackgroundWidth - 1
ENDIF
Title: Re: Endless Horizontal Scrolling Code
Post by: mrplant on 2012-Jan-08
Thanks again Slydog..

I hadn't noticed that but glad you found and fixed it - ran your code and its flying by very nicely and smoothly and all your test lines line up perfectly..

Ps. Where is best place to learn all about Polyvector and its use? Manual doesn't go into it in detail and I can guess why!

Why is it so much better than Drawsprite etc? I am taking it the answer is because it is a low level accelerated OpenGL feature?

Thanks again.

mr p.