Scrolling screen sometimes becomes jerky

Previous topic - Next topic

Ozden79

Hello There,

I'm prototyping a new game with GLBasic which I'm new as well  =D. I saw an interesting behavior and would like to ask whether I'm doing anything wrong.

In my sample, I'm simply scrolling a screen which is constructed by 16x16 pixel blocks. The whole screen size is 480x320. I call a routine inside the main while-wend loop and the FPS is limited to 60. I only draw the blocks which are inside the view. While scrolling, I sometimes see a loss in the smoothness of the scroll. The actual routine which does the drawing is this :

Code (glbasic) Select

SUB Draw_Level:
LOCAL Block$
LOCAL Block
LOCAL DrawX
LOCAL DrawY

FOR i=0 TO LEN(LevelData$) -1
FOR j=0 TO LEN(LevelData$[i]) -1
Block$ = MID$(LevelData$[i],j,1)
Block = ASC(Block$)
Block = Block -65

DrawX = j*16 - IG_CurrentX
DrawY = i*16 - IG_CurrentY

IF Block > 0 AND DrawX >=-16 AND DrawY >=-16 AND DrawX < Screen_X AND DrawY < Screen_Y
DRAWANIM 0,Block,DrawX,DrawY
ENDIF

NEXT
NEXT

SHOWSCREEN


ENDSUB


Is there anything I'm not aware of about the timing of redrawing? I though "SHOWSCREEN" is handling everything for having a steady 60 FPS as I specified (I also think my routine shouldn't take that much time that will cause a skip on a frame).

By the way, I test it on a windows 7 machine which has 256 mb GPU and core duo cpu...

Thanks in advance...

Ãâ€"zden
 

Hemlos

Im not really sure why it wouldnt be smooth, however, here are some things to keep in mind and try out..

1. Assuming this function is compatible with your machine...
Check the actual FPS with a function, place this right before SHOWSCREEN:

PRINT FPS(),10,10

Code (glbasic) Select

FUNCTION FPS:
// Updates a stable FPS Value, Every One Second Interval:
// Usage: MyFpsValue=FPS()

STATIC TimeBuffer , FrameCount , FPSVALUE
LOCAL FrameTime

FrameTime = GETTIMER();
TimeBuffer = TimeBuffer + FrameTime;
FrameCount = FrameCount + 1;

IF TimeBuffer >= 1000.0;
TimeBuffer = TimeBuffer - 1000.0;
FPSVALUE = FrameCount;
FrameCount = 0;
ENDIF

RETURN FPSVALUE

ENDFUNCTION


2. You should try to keep the arrays (which determine the loop sizes) as small as possible.
Embedding loops within loops can slow things in some situations, especially if the loops are large and have too many processes in them.

Bing ChatGpt is pretty smart :O

MrTAToad

I would use LIMITFPS -1 instead of LIMITFPS 60

Your draw_level function could do with being a bit more efficient - constantly dealing with strings and converting them to ASCII values is rather time comsuming - do any conversion in your loading system, and preferably use integers.

It might also be worth slipping 
Code (glbasic) Select
IF Block > 0 AND DrawX >=-16 AND DrawY >=-16 AND DrawX < Screen_X AND DrawY < Screen_Y into two seperate parts - that way if there is an invalid coordinate or value the chances of only dealing with half the IF statement increases.



Ozden79

Hello There,

Thanks for both of your answers :

Hemlos : I'm loading the level data, which is blocks consisting of 16x16 images into an array. The first level of the array is simply the rows and the second level is a simple string which contains the whole row. I actually see one improvement in here that to loop only visible area of the level instead of whole data but other than that, I don't think I can constraint the loops further.

MrTAToad : If I set the FPS to -1, all my timing (which depends on passed frames), becomes corrupt. For example, even in the splash screen, I wait for 60 frames in order to fade out the image. I think that's a bad practice and I should always use passed time instead? Also about the if block, doesn't it check each comparison starting from the first and if any of it is not correct, it skips the rest? This was the habit in C# that I use daily and if it's not the same, I should split the checks as you suggested.

Thanks for both of your anwers, I'll check further to see what I can do about this...

Actually, I just did increase the FPS to 120 and it works quite well in this refresh rate as well. This is clearly not something that my code delays the screen refresh. Maybe "jerky" does not express what I mean very well (Excuse me, I'm not a native English person) and maybe this will explain things better, I see rare skips on scrolling, which means it's smooth most of the time and rarely I see a skip on scrolling. This might something normal as well or I might be a bit sceptical  =D so I just wanted to be sure that whether this is normal or not.

Thanks again...

Ãâ€"zden

MrTAToad

#4
You should be using an independent processor speed timing system for all movements...

Quotestarting from the first and if any of it is not correct, it skips the rest?
It could if the compiler is intelligent enough to do so...

yaKC

Ozden79, if the scrolling is smooth with the occasional stutter/jump could it be that you have the game locked at 60 fps and your monitor refresh is set to 70 fps or some other than 60 fps value?

It sounds like when you run an old emulated PAL system with a game requiring 50 fps update on a monitor at 60 or 70 fps refresh whereby it's smooth with the occasional stutter... just a thought :) good luck

Moru

Yes, that monitor refresh is my guess to. Is there some way of syncing the refresh-rate to the monitor in window mode? Most other games I have seen can't do this but for full-screen mode it should be possible, right?

Hemlos

Oz, which platform (and hardware) is this software being designed for?

Because VSYNC  is typically hardware independant, and requires the owner to decide which mode to use(ie. 60hz 70hz 80hz, "No Sync"), you should be timing your movements with a timer as opposed to frame count. This will help regulate all routines, independant of hardware profiles.
Bing ChatGpt is pretty smart :O

Ozden79

Hi,

Moru : I use a laptop which has a 60hz screen refresh rate, so this shouldn't be the problem.

Hemlos : It'll be run on IPhone but I do my tests on Windows 7 for now and the screen res is 480x320 like in IPhone. As you said, I'll replace my framecount logic with a time based one, this was an old habbit like counting scanlines on C64  :).

Anyway, I wont't bother further with this for now as I'm sure it's something simple and can be checked later. Thanks to everybody who has spent time and answered my question...

Ãâ€"zden