View Single Post
Old 05 March 2018, 11:57   #15
Registered User
Master484's Avatar
Join Date: Nov 2015
Location: Vaasa, Finland
Posts: 330
Yep, it's AmiBlitz I was using too, so you're right - there could be some sort of optimisation (or bug fix) it does that gives it an edge over the Blitz Basic compiler.
Or maybe the reason is the FPU code that I read some AmiBlitz commands use; maybe Newtype handling in AmiBlitz uses FPU but normal variables do not, which would explain why newtype variables are faster than normal variables?

Yep, for speed critical things I would use pointers for a current list item - it's even faster than reassigning them to a temporary variable
That's right, I tested this and pointers actually beat normal variables too in normal operations as well.

So this code...

a = 0
x = 0

 x + 1
 a + 1
until a = 10000
...Becomes slightly faster with a pointer:

a = 0
x = 0
*variable1 = x

 *variable1 + 1
 a + 1
until a = 10000
And therefore this code in my earlier post:

x = enemy(id)\x
y = enemy(id)\y

if Zone (x, y) > -1
Would be faster with something like:

*x_pointer = enemy(id)\x
*y_pointer = enemy(id)\y

if Zone (*x_pointer, *y_pointer) > -1
And now there is no need to worry about putting the values back to newtype variables, because this method directly updates them.


Here are some other code optimization ideas:

One easy way to measure speed in this program is to add "score = VPos" to the "hud" drawing routine, and then add "Gosub hud" just before the main loop VWait command. The "score" text will then tell the position of the display beam after all game logic has been done and only VWait remains. The lower the number, the faster the frame has finished.

Although this method can be somewhat inaccurate if the main loop takes several frames to finish; it only tells the beam position, not how many frames have passed. If you also want to know the amounts of frames passed, then you have to use a VBlank interrupt and put a frame counter there.

This too is quite simple to do, and the code that Daedalus posted actually shows how to do it, so you just put lines like this to your code before the main loop starts:

framecount.w = 0

SetInt 5
  framecount + 1
End SetInt
And also add "framecount = 0" after the main loop VWAIT, and now you can do a "print framecount" in the hud routine to know the amount of frames passed.

The vertical blank interrupt can also have other code in it, but don't put anything slow like Blits or lots of calculations there, because this will cause problems. But things like sprite display commands and joystick reads are OK to be put there, and this guarantees sprite movement at 50 FPS no matter how slow the game is. Although I don't think this game needs to go that far; a simple pacman game should always run at 50 FPS without relying on tricks like this.

At the routine "pillupdate", I found this structure:

If pill(pid)\state=3
 Pop If : Goto pillupdate
End if
Which I think can be replaced with just:
If pill(pid)\state=3 then pid+1
Now correct me if I am wrong, but I think that the "Pop If" always terminates the current If...End If, and so the Goto instruction after it never gets executed.

Also I tested this change and it improved speed by several scan lines. So it also seems that the Pop instruction is very slow.


Also in the "spinnerupdate" routine there are more Pop If's used in this way, in a code that seems to check if anything is inside the spinning center piece, and if so it tries to make a "Pop If:Pop For:Return" to end the routine before the spinner update happens.

But the routine doesnt seem to work, and the player can get stuck inside the spinner walls. And I tried to comment out the entire check code, and nothing changed. So it seems that the routine does nothing, because everything after the Pop If's doesnt get executed, because the "Pop If" causes an instant jump out of the current "If...End if" structure.

I actually quickly tried to fix that routine, using a more simple method to end the loop:

- I added "a=0" at the start of "spinnerupdate".
- I deleted both "Pop If" lines in the two checks that follow, and replaced them with "a=1".
- I added a line "If a=1 then Return" right before the spinner draw routine starts.

Which theoretically should have caused some change, but it didnt seem to have any effect, the spinner still moved, and player could get stuck inside it.

Also, about entering the BLITZ mode: the Blitz manual recommends that a VWAIT 250 should be used before entering BLITZ mode. This is a safety wait so that the disk drive has time to stop before BLITZ "shuts down" the operating system. Right now after loading the files the program goes to BLITZ mode right away without any waits, and this is why the disk drive motor keeps on running during the game.

Although it seems that almost no one cares about this BLITZ mode safety wait, including the official Blitz example programs.
Master484 is offline  
Page generated in 0.04208 seconds with 11 queries