pedgarcia Posted April 17, 2020 Share Posted April 17, 2020 Hi all, I've been playing with Action! and created this small program where a little ship travels from left to right on screen. The ship is made of 3x5 pixels with the following shape: X X XX X X And this is the program: byte WAIT_SYNC=$D40A, VCOUNT=$D40B proc plotShip(byte x,y,c) color=c plot(x+1,y) plot(x+1,y+1) plot(x+2,y) plot(x+1,y-1) plot(x,y-2) plot(x,y+2) return proc eraseShip(byte x,y,c) color=c plot(x-1,y-2) plot(x,y-1) plot(x-1,y+2) plot(x,y+1) plot(x,y) return proc main() card i,r,J graphics(7+16) setcolor(4,0,0) ;black background setcolor(0,4,8) ;pink setcolor(1,7,8) ;lt.blue for i=2 to 150 do plotShip(i,40,1) ;DRAW do until vcount&128 od eraseShip(i,40,0) ;ERASE od ; pause for i=0 to 32767 do od return What I noticed is that if I remove the line waiting for VCOUNT in the main loop, the ship travels with the correct shape but flickering a lot. I was expecting the flickering because I am drawing and erasing the ship in the same loop even considering my erase function is intended to erase the trace the ship would "leave" behind. Then I thought I would add the VCOUNT loop to wait for the vertical line would reach the end of the screen to then erase the ship. My assumption was that I'd draw in one frame, and erase in the other, and that would make the animation smoother. (As I write this I feel I am wrong ) . Anyways, what I see on screen is indeed less flickering but the animation is more "jittery" and leaving a small trace, as if the ship is twice as wide. What I am missing here? Is there a better way to do something similar (without using PMG) as my idea is to illustrate the basic built-in graphic functions in action. Thanks Quote Link to comment Share on other sites More sharing options...
Rybags Posted April 17, 2020 Share Posted April 17, 2020 (edited) The OS plot routine is slow regardless of language in use. Finding a VCount sweet spot might be possible but likely not work for the full screen range, be inconsistent PAL/NTSC and maybe be speed inconsistent as well. One thing that can help (sort of) is keep "old x/y" then plot "new x/y" then immediately erase "old" (but first test that new is different to old) The tradeoff is you might then have a trail rather than flicker. Or better idea - just use a custom plot routine. Without too much effort a table-based plot routine should be 2-3 times quicker than the OS one. Edited April 17, 2020 by Rybags Quote Link to comment Share on other sites More sharing options...
R0ger Posted April 17, 2020 Share Posted April 17, 2020 Well here clearly something like player is being drawn. Using bitmap graphics or PMG is way to do it. Certainly not lines, and certainly not OS lines. Quote Link to comment Share on other sites More sharing options...
Preppie Posted April 17, 2020 Share Posted April 17, 2020 (edited) I don't know Action but in Fastbasic putting the pause before the plotship instead of between plotship and eraseship works better. for x=2 to 150 pause 0 exec draw_ship exec erase_ship next Edited April 17, 2020 by Preppie Quote Link to comment Share on other sites More sharing options...
Wrathchild Posted April 17, 2020 Share Posted April 17, 2020 6 minutes ago, Preppie said: putting the pause before the plotship That doesn't make sense as the ship is then erased for the greater proportion of time, there would be little sense in drawing it. Quote Link to comment Share on other sites More sharing options...
Preppie Posted April 17, 2020 Share Posted April 17, 2020 He's drawing the new ship then erasing the old ship, if you pause between this then you end up with two ships in view (hence the trail). Quote Link to comment Share on other sites More sharing options...
Wrathchild Posted April 17, 2020 Share Posted April 17, 2020 No he's not, the loop draws at xpos of I and then waits and then erases at I and then I is incremented, then repeat. The pause is in-between the draw and erase and so only one ship is view, he just considered about a trail (which would occur if you incremented I before the erase and then draw at the same I) As others have already covered, the slowness of the plot function is more than likely causing either screen tearing or flicking (e.g. if the time to erase & draw is exceeding 1 frame) Quote Link to comment Share on other sites More sharing options...
Preppie Posted April 17, 2020 Share Posted April 17, 2020 7 minutes ago, Wrathchild said: No he's not, the loop draws at xpos of I and then waits and then erases at I and then I is incremented, then repeat. The pause is in-between the draw and erase and so only one ship is view, he just considered about a trail (which would occur if you incremented I before the erase and then draw at the same I) As others have already covered, the slowness of the plot function is more than likely causing either screen tearing or flicking (e.g. if the time to erase & draw is exceeding 1 frame) If this was the case he could draw and erase with the same procedure by just changing the color as the coordinates would be the same. But the coordinates in the erase proc are not the coords of the ship that has just been drawn, but are of the previously drawn ship. Quote Link to comment Share on other sites More sharing options...
Wrathchild Posted April 17, 2020 Share Posted April 17, 2020 Sorry Preppie, how was I blind to that Indeed, there only needs to be the plotShip and not the eraseShip function and just call plotShip with color zero to erase Quote Link to comment Share on other sites More sharing options...
Preppie Posted April 17, 2020 Share Posted April 17, 2020 No problem Confused me a little to start with. Why is there 2 procs? Why does the erase proc have 5 plots and the draw proc have 6 plots? Quote Link to comment Share on other sites More sharing options...
pedgarcia Posted April 17, 2020 Author Share Posted April 17, 2020 (edited) To answer the questions about the two functions. At first I was using the plot one calling twice, one with color 0, but then the results were not good, so I created the eraseShip plotting over the trail the ship would leave behind (therefore 5 points instead of 6). Again, this are just experiences and not suitable for a game, for example Based on all the comments, looks like the OS plot routines are very slow and it would be hard to get better results while using them. Is it possible using fast plot functions to plot everything in one single frame? Is the do until vcount&128 od making any difference there at all, or just make it run slower? Thanks again Edited April 17, 2020 by pedgarcia typos and more explanations. Quote Link to comment Share on other sites More sharing options...
Preppie Posted April 17, 2020 Share Posted April 17, 2020 (edited) it's already fast enough to do it in one frame if this is all you want to do, but doing much more would be difficult. I tried to do 2 ships in FastBasic and ended up with flicker. Even with one ship In FastBasic if you set Y to less than 38 then you start to get problems as there's not enough time to draw the ship. The more you need to draw the lower down on the screen you'll need to put it. Action may move things along a bit faster, but ultimatly you're restricted by the slow OS plot/draw functions. Edited April 17, 2020 by Preppie Quote Link to comment Share on other sites More sharing options...
pedgarcia Posted April 20, 2020 Author Share Posted April 20, 2020 That makes totally sense. My intention was to illustrate the basic graphic capabilities, but maybe I should try something else instead. Or simplify it to the point where it makes sense to someone that knows nothing (almost like me:) ) Thanks again for all the input! Quote Link to comment Share on other sites More sharing options...
Rybags Posted April 21, 2020 Share Posted April 21, 2020 Given that it's Action and fairly fast, you could probably do your own softsprite routine (even if it's just for a single dot) Quote Link to comment Share on other sites More sharing options...
pedgarcia Posted April 26, 2020 Author Share Posted April 26, 2020 What is the theory behind soft sprites ? I would guess: 1 - save area where sprite will be placed 2 - Place sprite ORd with background When it moves: 3 - restore saved background done in #1 4 - Repeat Am I in the right track? Thanks Quote Link to comment Share on other sites More sharing options...
Rybags Posted April 26, 2020 Share Posted April 26, 2020 Close - before 2 you perform AND with background which masks out the area the softsprite will appear at, an OR only operation could see target pixel 01 ORed with old pixel 10 giving value 11. An alternate is XOR softsprites where the sprite is simply XORed with the background. The restore occurs when you XOR back. Advantage of more speed but disadvantage that weird colours can result. Quote Link to comment Share on other sites More sharing options...
pedgarcia Posted April 26, 2020 Author Share Posted April 26, 2020 Thanks Rybags! I will give it a try Cheers Quote Link to comment Share on other sites More sharing options...
NRV Posted April 26, 2020 Share Posted April 26, 2020 More than that, if you have more than one software sprite: - first "erase" all previous/old sprites in the screen - then draw all new sprites ..repeat Erasing means restoring the background and it can be done in different ways, for example: - if you background is empty, you just put 0's in the old sprite position. - or you could have a copy of the background in memory and just copy the area touched by the sprite from there. - or use some other logic to restore the background, like when using background "tiles".. Drawing can also be done in different ways, some of them faster but prone to more visual artifacts: - just storing the sprite data on the screen without masking or caring for the sprite "borders" against the background. - doing an OR or XOR/EOR of the sprite bytes against the background. - doing the "proper" method of having a sprite mask (different than the sprite data) to AND against the background (basically cutting a hole with the shape of the sprite in the background), and then ORing the sprite data against the background. Then there is the problem with rotating the sprite bits inside a byte, because the graphic modes use 8, 4 or 2 pixels per byte. This can be done in real time (slow) or having the rotations pre-calculated in memory (faster, but using a lot more memory). All this is for graphic modes. Char based software sprites are a little more complex. 2 Quote Link to comment Share on other sites More sharing options...
ac.tomo Posted April 26, 2020 Share Posted April 26, 2020 (edited) There's a method to stop 'tearing' or 'flickering' that a lot of programmers use in Demo's and have done for years, what you do is to create 2 DM's (Display Memories) and whilst 1 is being displayed do the plotting and unplotting, or screen clearing in the non-displaying DM, then switch to engage this DM, and then you clear and plot the image you want in the other DM and when done then switch that DM in etc.. OK? EDIT: Another good way, I'm not sure if it has already been mentioned, but all you have to do is re-PLOT your image and just delete the one byte/or end depending on which way the image moves; if the image moves right PLOT it and erase the left bytes etc. Edited April 26, 2020 by ac.tomo 2 Quote Link to comment Share on other sites More sharing options...
pedgarcia Posted April 29, 2020 Author Share Posted April 29, 2020 Great info! I think I am a bit far from be able to achieve that, but I am going to try something similar for the little ship in my sample. Cheers Quote Link to comment Share on other sites More sharing options...
ac.tomo Posted April 29, 2020 Share Posted April 29, 2020 If I'm right, its: LOOP POKE DM-LSB, 1st LSB POKE DM-MSB, 1st MSB POKE 88, 2nd LSB POKE 89, 2nd MSB plot, clear or whatever, then; POKE DM-LSB, 2nd LSB POKE DM-MSB, 2nd MSB POKE 88, 1st LSB POKE 89, 1st MSB then plot, clear etc.. then LOOP If your using strings use 2 strings for the 2 DM addresses. LSB and MSB are obtained by: DIM DM1$(1024), DM2$(1024) D1=ADR(DM1$) MSB1=INT(D1/256) LSB1= D1-(256*MSB1) D2=ADR(DM2$) MSB2=INT(D2/256) LSB2=D2-(256*MSB2) then; DL=PEEK(560)+256*PEEK(561) DM address: POKE DL+4, LSB1 or LSB2 POKE DL+5, MSB1 or MSB2 Hope that's understandable. 1 Quote Link to comment Share on other sites More sharing options...
pedgarcia Posted May 4, 2020 Author Share Posted May 4, 2020 Not sure if I understand what the pokes are doing. Can you explain please? Thanks Quote Link to comment Share on other sites More sharing options...
ac.tomo Posted May 4, 2020 Share Posted May 4, 2020 (edited) 15 hours ago, pedgarcia said: Not sure if I understand what the pokes are doing. Can you explain please? Thanks I'm not exactly sure what you want me to explain; the DM's, LSB's and MSB's are basically variables. The DM variable points to the Display Memory (which is found at bytes 4 and 5 into the Display List), locations 88 and 89 point to the top-left corner of your graphics 0 screen, in this case you will have 2 Graphics 0 displays, ideally you would protect some RAM but I'll explain that when you get to grips with this. Edited May 4, 2020 by ac.tomo Quote Link to comment Share on other sites More sharing options...
pedgarcia Posted May 8, 2020 Author Share Posted May 8, 2020 Hi, ac.tomo I think I understand now. You are swapping the animation in two "pages". Is that so? Paulo Quote Link to comment Share on other sites More sharing options...
ac.tomo Posted November 22, 2020 Share Posted November 22, 2020 On 5/8/2020 at 2:16 AM, pedgarcia said: Hi, ac.tomo I think I understand now. You are swapping the animation in two "pages". Is that so? Paulo 2 different screens yes. 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.