I suspect the modulo operations you're using become slower and slower as #univclock increases. There is no "divide" or "multiply" instruction on the machine, and so the cost of those operations changes as values get larger.
If you compile with the --jlp switch, it'll use an external hardware accelerator. (This accelerator is built into the LTO Flash cartridge, and supported in jzIntv. It's also available on my JLP cartridge boards.)
Alternately, if you have values that just increment modulo some value, you're better off dedicating some small 8 bit variables to those values and doing an explicit increment and test.
That is, rather than writing:
(#univclock % (7-dificulty))
Have some other variable that increments 0 .. 6-dificulty. For example, if I called it 'diff_phase': (Short for "difficulty phase'.)
diff_phase = diff_phase + 1
if diff_phase = (7-dificulty) then diff_phase = 0
This one will also get slower and slower and slower:
I'd replace that with, say, "move_phase" (short for movement phase):
move_phase = move_phase + 1
if move_phase = 3 then move_phase = 0
Some of the modulos may be OK. I believe IntyBASIC will replace modulo with a bitwise AND if you're computing modulo a power of 2. So %8 ends up being the same as AND 7. You can double check by looking at the compiler output. Your BASIC source code will be interlisted with the corresponding assembly, making it easy to find what your code expands into.
Other minor things:
is better written as
It might not be obvious from the generated assembly, but the latter is much faster. The RAND%3 generates a loop that repeatedly subtracts 3 from the random seed. That could iterate many, many times. The RAND(3) calls "qs_mpy8". That performs multiplication via the quarter square method, and takes ~50 cycles. Compared to the repeated subtract method, it's actually much faster.
; x = RAND%3
; y = RAND(3)
This comment also applies to your other calls to RAND.
You also need to be a little careful with RAND: RAND only updates once per frame. If you need distinct random numbers, use RANDOM() instead. The range on both is limited 0..255, so if you need larger random numbers, you need to do something different. (At first, I thought you might have an issue in chooseObject, but on closer inspection, you don't.)
This sets all the array values to 0. I suspect you did not want to /100 here. You do the right thing in determinelevel, so I suspect this is stale code?
percentage(0) = 48/100
percentage(1) = 23/100
percentage(2) = 23/100
percentage(3) = 4/100
percentage(4) = 2/100
If you make the percentages cumulative, you can avoid the awkward math in chooseObject. That is, you could do something like this:
percentage = 48
percentage = 23 + percentage
percentage = 23 + percentage
percentage = 4 + percentage
percentage = 2 + percentage
Then your chooseObject routine can avoid all that addition:
chance = RANDOM(percentage(4))
if chance < percentage(0) then 'nothing chances
chance = 0
elseif chance < percentage(1) then 'rock chances
chance = 1
elseif chance < percentage(2) then 'coin chances
chance = 2
elseif chance < percentage(3) then 'apple chances
chance = 3
else 'Random powerup
chance = RANDOM(3) + 4 'Powerup
I'm not sure 'percentage' is a great name for that variable. cum_obj_weight (cumulative object weight) is perhaps more descriptive.
If you can make the weights always sum to 128 or 256, you can make this even more efficient by eliminating percentage(4) and replacing RANDOM(percentage(4)) with RANDOM(256). The computation for that is more efficient. Basically, you'll just scale all your weights upwards by 2.56, and round creatively so they sum to 256.
Try tweaking those things, and see where you end up. :-)
Edited by intvnut, Sun Dec 17, 2017 4:19 PM.