Ultimate Amiga
Network Boards => AMOS Language Discussion => AMOS Factory => AMOS Professional Forum => Topic started by: adrazar on August 31, 2017, 01:36:13 PM
-
Hi,
I have a double buffered screen which I scroll using Screen Offset. The problem is that I can't seem to switch buffer AND change offset within a single vertical blank. I've tried rearranging the order of the commands, even introducing amal to do the offset (which actually worked quite well, until I tried to enforce a frame rate reduction). Then I've tried thinking instead of just experimenting, and this is what I figured would be the lay of the land:
* Screen Offset redefines what part of the bitmap is to be considered the upper left corner of the display. Calling Screen Offset in the middle of a screen rendering does not disturb the subsequent part of the current display. There are two possible reasons for this: either amos delays updating the offset-variable until next vertical blank OR the only time this variable is read is once during each vertical blank. I do not know which is true, but I have more faith in the latter.
* Screen Swap changes the bitmap starting pointer to the other buffer. Calling Screen Swap in the middle of a screen rendering will, like Screen Offset, leave the subsequent parts of the display undisturbed. Hence the bitmap starting pointer is treated the same way as the offset variable.
Now, the conclusion I draw from this is that writing
"Screen Offset N,X,Y : Screen Swap : Wait Vbl" or
"Screen Swap : Screen Offset N,X,Y : Wait Vbl"
should work equally well, but it turns out neither does. The most obvious explanation to this disagreement between theory and practice is that my reasoning is flawed or incomplete. I don't know if anyone here knows more about this stuff than I do, but here you go. :)
[A few words on the problem I'm experiencing: I'm having the player (a bob) move on top of a background scrolling at constant speed. Ideally the bob should appear fixed on the screen while the background rolls underneath, but as default the bob seems to prefer being a shaky blur instead.
I need the player object to be a bob in order to achieve a special colour-mixing effect, thus converting it to a sprite would not be the answer I seek.]
-
Screen offset should come before Screen Swap because it is supposed to affect the logical screen, though both commands really just affect the Copper list. What settings are you doing at the beginning of the code? (Particularly regarding Bob redraws and autoback.)
-
Bob Update Off, Synchro Off, Autoback 0. I use Synchro to move the bobs and Bob Clear/Bob Draw to redraw them.
-
Hmmm... That's not the culprit.
-
I have created a minimal example showing what I'm talking about (download the attatchment or type it into amos):
Bob Update Off
Screen Open 0,640,200,16,Lowres
Screen Display 0,128,50,320,200
Get Bob 1,0,0 To 16,16
Cls 0
Double Buffer : Autoback 0
Repeat
Bob 0,X+160,100,1
Bob Clear : Bob Draw
Wait 50
Screen Offset 0,X,0
Screen Swap
Wait Vbl
Add X,4,0 To 319
Until Mouse Click
The bob clearly jumps to the right. This indicates that screen swap happens first, then one frame later the offset is changed.
Screen offset should come before Screen Swap because it is supposed to affect the logical screen, though both commands really just affect the Copper list.
I know almost nothing about what a regular Copper list actually does.. What I know is that it is possible to change colours quite often during a single screen rendering by filling it with instructions manipulating "the colour registers". I guess there are other registers, but which are the relevant ones in this context?
-
This way works like a charm at 50 fps:
Screen Open 0,640,200,16,Lowres
Screen Display 0,128,50,320,200
Flash Off : Curs Off
Pen 1
Box 0,0 To 15,15
Get Bob 1,0,0 To 16,16
Cls 9
Box 0,0 To 319,199
Double Buffer : Autoback 0 : Bob Update Off
Repeat
Bob 0,160+X#,100,1
Bob Clear : Bob Draw
Screen Swap
Screen Offset 0,X,0
Wait Vbl
Inc X : X#=X#+0.5
If X=319 Then X=0
Until Mouse Click
The most important steps are:
1. Screen Swap
2. Screen Offset #,X,Y
3. Wait Vbl
Enjoy
-
Thanks Umpal, delightful to finally see a new reply :D
I have only read (not tried) your program, but think you are right it will run smoothly. After all, removing Wait 50 from my own example gives a similar result. What I still haven't figured out is why things starts acting odd from 25 fps and down, and how to fix the oddities.
Currently I'm working on what I've read about the Copper here: http://ada.evergreen.edu/~tc_nik/files/AmigaHardRefManual.pdf (http://ada.evergreen.edu/~tc_nik/files/AmigaHardRefManual.pdf). My hope is it can be used to solve this problem, but I have no regrets spending time on it even if it doesn't. ;)
-
Thanks Umpal, delightful to finally see a new reply :D
You're welcome mate.
What I still haven't figured out is why things starts acting odd from 25 fps and down, and how to fix the oddities.
Hard to say when I can't see the code (at least the main display part). If you keep the number and size of your Bobs within a reasonable limit there should be no significant drop-down fps.
My hope is it can be used to solve this problem, but I have no regrets spending time on it even if it doesn't. ;)
Very interesting documentation and surly worth of reading. However AMOS is very specific so unless you test over and over again different methods then you won't achieve any good results. But from my own experience it's possible to surprise yourself and others if one is not giving up and is looking for the best solution.
I don't know how are your skills but if they are above average I recommend you to switch to manual mode completely. I mean no Bob Clear/Draw/Update/Off and stuff. For me it's the best mode and the only way to go with AMOS. In case you wonder what I mean, I explain: I use all the time and without a single exception Screen Copy and Screen Swap. That is all I need (and in my opinion every decent programmer needs no more). It's true that it requires a lot of manual calculating and precision but only this gives me the best and satisfactory result (keeping in mind that AMOS is a high level BASIC oriented programming environment so no miracles here ;))
-
I don't know how are your skills but if they are above average I recommend you to switch to manual mode completely. I mean no Bob Clear/Draw/Update/Off and stuff. For me it's the best mode and the only way to go with AMOS. In case you wonder what I mean, I explain: I use all the time and without a single exception Screen Copy and Screen Swap.
Wow, that's something to think about! In fact I've been missing a simple way to draw and clear only a subset of the defined Bobs at a given time. I already know what my first attempt in dealing with this will be: find a way to modify the "active bitplanes" of Bobs as I wish regardless of Set Bob being uncooperative. Throwing Bobs out the window altogether is definitely another possibility I might take into consideration.
If you keep the number and size of your Bobs within a reasonable limit there should be no significant drop-down fps.
Given how the game performs so far I've more or less dismissed the possibility that it can run 50 fps on the heaviest sequences. Thus I figured the best solution would be to reduce the framerate such that it becomes constant throughout the game.
-
Wow, that's something to think about! In fact I've been missing a simple way to draw and clear only a subset of the defined Bobs at a given time. I already know what my first attempt in dealing with this will be: find a way to modify the "active bitplanes" of Bobs as I wish regardless of Set Bob being uncooperative. Throwing Bobs out the window altogether is definitely another possibility I might take into consideration.
I was having a very difficult time trying to figure out why AMOS behaved so strangely while all was 'according to the book'. Turned out that some automated function, like mentioned above, do NOT work as intended. Well, most of the time and without much expectations they DO (that's why you see from far and conclude: IT'S DEFINITELY AN AMOS PRODUCTION! ;)). But not when you're a perfectionist. I wasn't pleased with super-duper-frustrating-blinking Bobs effect suddenly coming from nowhere so I decided to switch to 'extreme' mode: the manual one ;). Since then all is finally under control. But a word of advice: Always use alongside your code a clear and logic diagram to be aware when, where and how you call Screen Copy (as whole screen as well as regions of course), Screen Swap and Wait Vbl.
Given how the game performs so far I've more or less dismissed the possibility that it can run 50 fps on the heaviest sequences. Thus I figured the best solution would be to reduce the framerate such that it becomes constant throughout the game.
I say keep it steady at 25 and you'll be a winner 8) (or keep it 20, but constant twenty and the impression will still be very positive).
-
Is it possible to examine and modify the next Copper list without turning the Copper off? It seems to me that Cop Logic only holds the previous Copper list, not the next.
-
Is it possible to examine and modify the next Copper list without turning the Copper off? It seems to me that Cop Logic only holds the previous Copper list, not the next.
I know very little about copper so I won't help (at least at this stage of my knowledge). For instance, Samurai Crow or Uncle Bruce seem to have a proper one (but I bet there are others as well). Where are you guys? :)
-
I think WinUAE has a copper list monitor but I have never used it.
Sent from my Prism II using Tapatalk
-
Ok, so it turns out I finally stumbled across the root of the problem: a call to Screen Offset NEVER changes the offset of the immediate next frame! One would have to wait an additional frame before its effect can be seen.
This loop works :D (25 fps):
Do
T=Timer
Screen Offset N,X,Y
'do stuff
If Timer-T=0 Then Wait Vbl
Screen Swap : Wait Vbl
Loop
-
If Timer-T=0 Then Wait Vbl
(...)
One would have to wait an additional frame before its effect can be seen.
This loop works :D (25 fps):
Why for the heavens would you want to slow down artificially this routine by half to 25 pfs? :o
The example I showed you above works fluently at 50 fps and the change is seen... well, normally, as one would expect. I'm lost ;D
-
I'm lost ;D
Thanks for letting me know! I think I understand what's unclear concerning both things you mention:
'do stuff
If Timer-T=0 Then Wait Vbl
Why for the heavens would you want to slow down artificially this routine by half to 25 pfs? :o
Sometimes the "do stuff" part gets done within one vertical blank. If there were no artificially added wait between this and Screen Swap, the display would in these cases suddenly update at a 50 fps rate. This is undesirable as I want the game to run at a constant frame rate, hence the wait.
The example I showed you above works fluently at 50 fps and the change is seen... well, normally, as one would expect.
Frame: Command: Offset:
1 Screen Offset 0,1,0 (0,0)
2 Screen Offset 0,2,0 (0,0)
3 Screen Offset 0,3,0 (1,0)
4 Screen Offset 0,4,0 (2,0)
5 Screen Offset 0,5,0 (3,0)
6 - (4,0)
7 - (5,0)
8 - (5,0)
This table illustrates the relation between calls to Screen Offset and what's being displayed on the screen for each of eight frames. The offset is lagging a frame behind what one would consider natural behaviour! Running 50 fps (like in the table) makes almost nothing out of this peculiarity, especially when scrolling at constant speed in one direction. But when trying to go 25 fps (like me), the change of buffer and change of offset happens on separate frames if this is not taken into account. A nasty shaking results. And of course it never occured to me that something like THIS could be the reason! That is, until I suddenly had a stroke of luck... :)
The program that put me on the right track was based on your example (most notably the Box):
Screen Open 0,640,200,16,Lowres
Screen Display 0,128,50,320,200
Flash Off : Curs Off : Cls 0
Box 0,0 To 319,199
Double Buffer : Autoback 0
For X=0 to 320
Plot X,1
Screen Offset 0,X,0
Screen Swap : Wait Vbl
Next X
Isn't that point a litte far to the right... ???
-
(...) I want the game to run at a constant frame rate, hence the wait.
That explains everything (in this matter ;)). Well, eager to see your final product! Keep up the good work mate.
-
@adrazar
Were you ever able to get this working? I'm running into the same problem where screen offset seems to happen too late. Did you ever find a solution?
-
Were you ever able to get this working? I'm running into the same problem where screen offset seems to happen too late. Did you ever find a solution?
Well yes.. The solution I presented wasn't 100% consistent after all, still some frames would not have Screen Swap and Screen Offset happen simultaneously. Anyway, it was close enough to perfect for me to settle with it that way, at least for the time being.
But the story didn't really end there, though :P
A few months later I somehow discovered that the reason Screen Offset scrolls the screen without more ado is because of Auto View.. So I tried disabling it with Auto View Off and call View manually instead, and just like that: all the scrolling problems were gone!
It's bothered me a bit that I haven't shared this info here before, so thanks for asking! ;)
-
Awesome! Did you have to call View in the game loop? Thanks!
-
Did you have to call View in the game loop?
That's right, Screen Offset won't scroll the screen unless it's coupled with a View instruction inside the game loop.
It was hard to understand the usage of View because the manual is a bit vague there. So to clarify: it updates the screen according to the changes made by Screen Open, Screen To Front/Back, Screen Hide/Show, Screen Display, Screen Offset (and Rainbow). None of these will do anything with the display until View is called at some later point in the program.
-
Argh, I just can't seem to get this right. There is always a noticeable flicker when the view is changed. Even when I try to get it to change the view in the VBL interval, the flicker persists. Maybe the view calculations need more time than a VBL? Here is my loop, constructive criticism is welcome:
Auto View Off
Double Buffer
Autoback 0
Do
' All my calculations here
Bob Clear
Screen Offset 0,X,0
Bob Draw
Wait Vbl
Screen Swap
View
Loop
-
If View generates the Copper lists, maybe it should be done before the Wait Vbl? Just a suggestion....
-
Thanks SamuraiCrow. I just tried your suggestion. It didn't work, there is still a skip. And the bobs appear "fuzzy" also--like I'm seeing both buffers at the same time.
-
I notice two things that might cause problems :P
It seems Bob Update is still On, which means that Bob Update (= Bob Clear, Bob Draw and Screen Swap in one go) is executed every VBL. I always turn it off before using Bob Clear/Bob Draw.
The second thing is that Wait Vbl should normally come after Screen Swap (because the buffers aren't actually swapped before the next VBL). I agree with SamuraiCrow that also View should be done before Wait Vbl (because the Copper list swapping mechanism works similarly, I think).