BBC BASIC for Windows
« Darts »

Welcome Guest. Please Login or Register.
Apr 5th, 2018, 11:08pm



ATTENTION MEMBERS: Conforums will be closing it doors and discontinuing its service on April 15, 2018.
Ad-Free has been deactivated. Outstanding Ad-Free credits will be reimbursed to respective payment methods.

If you require a dump of the post on your message board, please come to the support board and request it.


Thank you Conforums members.

BBC BASIC for Windows Resources
Online BBC BASIC for Windows documentation
BBC BASIC for Windows Beginners' Tutorial
BBC BASIC Home Page
BBC BASIC on Rosetta Code
BBC BASIC discussion group
BBC BASIC for Windows Programmers' Reference

« Previous Topic | Next Topic »
Pages: 1  Notify Send Topic Print
 thread  Author  Topic: Darts  (Read 565 times)
David Williams
Developer

member is offline

Avatar

meh


PM

Gender: Male
Posts: 452
xx Darts
« Thread started on: Nov 24th, 2015, 8:13pm »

Just a precursor to something I'm doing in ARM BBC BASIC. Not having hardware accelerated FP maths operations may mean having to resort to (mostly) fixed-point arithmetic and/or lookup tables.

Code:
      *FLOAT 64

      MODE 10 : OFF

      ScrW% = @vdu%!208
      ScrH% = @vdu%!212

      NumObjs% = 20

      DIM X( NumObjs%-1 ), Y( NumObjs%-1 )
      DIM VelX( NumObjs%-1 ), VelY( NumObjs%-1 )
      DIM Cx%( NumObjs%-1 ), Cy%( NumObjs%-1 )
      DIM Chg%( NumObjs%-1 ), ChgStart%( NumObjs%-1 )

      FOR I% = 0 TO NumObjs%-1
        X(I%) = RND(ScrW%)-1
        Y(I%) = RND(ScrH%)-1
        ChgStart%(I%) = 100 + RND(200)
      NEXT I%

      Chg%() = 0

      *REFRESH OFF

      REPEAT
  
        CLS
  
        FOR I% = 0 TO NumObjs%-1
    
          IF Chg%(I%) = 0 THEN
            Chg%(I%) = ChgStart%(I%)
            Cx%(I%) = 32 + RND(ScrW% - 2*32)
            Cy%(I%) = 32 + RND(ScrH% - 2*32)
          ELSE
            Chg%(I%) -= 1
          ENDIF
    
          Dx = X(I%) - Cx%(I%)
          Dy = Y(I%) - Cy%(I%)
          L = 0.15 / SQR(Dx^2 + Dy^2)
          VelX(I%) -= Dx * L
          VelY(I%) -= Dy * L
    
          angle = FNatan2( VelY(I%), VelX(I%) )
    
          X% = X(I%)
          Y% = Y(I%)
          x1% = X% + 8*COS(angle - PI/2)
          y1% = Y% + 8*SIN(angle - PI/2)
          x2% = X% + 24*COS(angle)
          y2% = Y% + 24*SIN(angle)
          x3% = X% + 8*COS(angle + PI/2)
          y3% = Y% + 8*SIN(angle + PI/2)
    
          GCOL 1 + (I% MOD 15)
          MOVE 2*x1%, 2*y1%
          MOVE 2*x3%, 2*y3%
          PLOT 85, 2*x2%, 2*y2%
    
          IF ABS(VelX(I%)) > 4.0 THEN VelX(I%) = 4.0*SGN(VelX(I%))
          IF ABS(VelY(I%)) > 4.0 THEN VelY(I%) = 4.0*SGN(VelY(I%))
    
          X(I%) += VelX(I%)
          Y(I%) += VelY(I%)
    
        NEXT I%
  
        *REFRESH
        WAIT 1
  
      UNTIL FALSE
      END

      DEF FNatan2(y,x) : ON ERROR LOCAL = SGN(y)*PI/2
      IF x>0 THEN = ATN(y/x) ELSE IF y>0 THEN = ATN(y/x)+PI ELSE = ATN(y/x)-PI
 


User IP Logged

dfeugey
Guest
xx Re: Darts
« Reply #1 on: Nov 25th, 2015, 06:28am »

Cool.

Nota : FP maths could be possible in BBC Basic, but there are some hesitations from developers, since you must open a FP context for BBC Basic (that implies some slowdowns when calling system APIs). I suggested to get both versions, integer and VFP.

So work in progress...
User IP Logged

DDRM
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM

Gender: Male
Posts: 321
xx Re: Darts
« Reply #2 on: Nov 25th, 2015, 3:00pm »

Hi David,

Cute - but they crash into each other! Surely there should be a collision avoidance routine? grin

If you want more speed how about:

doubling your ScrW% and ScrH% (and all consequent positions and velocities etc), which would allow you to remove several doublings in your inmost loop

Moving some of the array additions etc outside the inner loop: so for example you could add VelX() to X(), and equivalently for Y() and Chg%(). If you had arrays for Dx and Dy you could do the same with those, and also with the VelX and VelY assignments. I believe whole-array calculations are much faster than doing them all individually.

Not sure how much, if any of that would translate to ARM basic, though - I can't remember if you have array arithmetic there, and as I recall barrel-shifting is free, at least in assembler, so maybe if you did the doubling as shifts that is also very fast.

If your reference point was the tip of the arrow you could cut down the number of SIN and COS calculations by one set each time. Would multiplying by 8 be achieved more quickly using a left shift?

Can FNatan2 generate an error other than if x=0? Would dealing with that specific case (or maybe x<1E-12) be faster than setting up a local error handler on each call? If you do that, is it quicker to leave it inline, rather than having the overhead of a function call and return?

Best wishes,

D
User IP Logged

David Williams
Developer

member is offline

Avatar

meh


PM

Gender: Male
Posts: 452
xx Re: Darts
« Reply #3 on: Nov 25th, 2015, 5:33pm »

on Nov 25th, 2015, 3:00pm, DDRM wrote:
Hi David,

Cute - but they crash into each other! Surely there should be a collision avoidance routine? grin


That would be much more interesting (both to watch and to code!). But the application in mind is just a 'Space Invaders' game, featuring some fairly dumb aliens that follow random paths. It's unlikely that I'll have time to finish the project in any case.


Quote:
If you want more speed how about:

doubling your ScrW% and ScrH% (and all consequent positions and velocities etc), which would allow you to remove several doublings in your inmost loop


Certainly a worthwhile optimisation to make under ARM BBC BASIC running on a system typically some 3 times slower than an average laptop PC. I've never liked BBC BASIC's use of 'virtual coordinates', even though I understand the rationale behind them.

Quote:
Moving some of the array additions etc outside the inner loop: so for example you could add VelX() to X(), and equivalently for Y() and Chg%(). If you had arrays for Dx and Dy you could do the same with those, and also with the VelX and VelY assignments. I believe whole-array calculations are much faster than doing them all individually.


Yes, you're right - I completely forgot about those (I've used them several times in the past).

Quote:
Not sure how much, if any of that would translate to ARM basic, though - I can't remember if you have array arithmetic there, and as I recall barrel-shifting is free, at least in assembler, so maybe if you did the doubling as shifts that is also very fast.


The project is 99% BASIC (the 1% asm comes from the need to prepare hundreds of sprite transparency masks in a fraction of a second, rather than 20-or-so seconds it takes in BASIC).

Quote:
If your reference point was the tip of the arrow you could cut down the number of SIN and COS calculations by one set each time. Would multiplying by 8 be achieved more quickly using a left shift?


Can avoid SIN/COS calculations by using lookup tables (often necessary with ARM BASIC).

In ARM BASIC (and probably BB4W), there's practically nothing in it whether using multiplication operator ( * ) or left shift ( << ). In fact, in a quick test I just did, using * was fractionally faster. Assembly language is a different matter of course (although I'd be surprised if the MUL instruction on modern ARMs is as expensive as it used to be).

Quote:
Can FNatan2 generate an error other than if x=0? Would dealing with that specific case (or maybe x<1E-12) be faster than setting up a local error handler on each call?


Yes, that's what I did with the ARM BASIC experimental version.

Quote:
If you do that, is it quicker to leave it inline, rather than having the overhead of a function call and return?


Yes, that's an obvious (and important) optimisation to make. If one desires a consistent high frame rate (60 fps, say), then saving clock cycles helps. Just pointing out that the 'Darts' program was just a graphical demo, rather than an exercise in efficient code (although I'm glad you reminded me of the array arithmetic ops). There's several other optimisations that can be made (including removing superfluous brackets, which the ARM BASIC cruncher/optimiser utility StrongBS does anyway, among many other useful tweaks). Employing lookup tables for trig functions (including inverse tangent) would speed things up hugely in the case of ARM BASIC (but not necessarily BB4W). Furthermore, using lookup tables of fixed-point integers obviously gives an even greater performance boost, although it can get fiddly, and one needs to keep an eye on the inevitable loss of precision.


David.
--
User IP Logged

David Williams
Developer

member is offline

Avatar

meh


PM

Gender: Male
Posts: 452
xx Re: Darts
« Reply #4 on: Nov 25th, 2015, 6:57pm »

Randomly generated 'alien' sprites flying along random paths!

http://www.proggies.uk/bb4w/randomaliens.zip

30 sprites are generated.

The Zip folder includes the EXE and BBC source listing (purely for inspection; the source won't run without GFXLIB2).

One task would be to ensure the aliens spin around smoothly, rather than 'snapping' into position (currently, the angle is strictly the direction of motion, with no angular inertia).

An ARM BASIC version would use pre-rotated sprite frames (and no translucent shadows!).


David.
--
User IP Logged

David Williams
Developer

member is offline

Avatar

meh


PM

Gender: Male
Posts: 452
xx Re: Darts
« Reply #5 on: Nov 26th, 2015, 6:26pm »

on Nov 25th, 2015, 06:28am, dfeugey wrote:
Cool.

Nota : FP maths could be possible in BBC Basic, but there are some hesitations from developers, since you must open a FP context for BBC Basic (that implies some slowdowns when calling system APIs). I suggested to get both versions, integer and VFP.


Here's an ARM BBC BASIC version of the demo (runs well on a Raspberry Pi 2):

http://www.proggies.uk/riscos/basic/RndAliensX

It's crunched with !StrongBS for performance. Set file type to BASIC (&FFB).


David.
--

http://www.proggies.uk
User IP Logged

Pages: 1  Notify Send Topic Print
« Previous Topic | Next Topic »

| |

This forum powered for FREE by Conforums ©
Terms of Service | Privacy Policy | Conforums Support | Parental Controls