BBC BASIC for Windows
« Yet another starfield »

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



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: Yet another starfield  (Read 1550 times)
David Williams
Developer

member is offline

Avatar

meh


PM

Gender: Male
Posts: 452
xx Yet another starfield
« Thread started on: Mar 21st, 2015, 11:20am »

I've been doing a lot of stuff with BASIC V on RISC OS, and will be making a BASIC demo for the Raspberry Pi 2 (just for fun, of course). Anyway, here's a BB4W version of the 'starfield' program I wrote this morning. The BASIC V version is pretty optimal (I've completely unrolled the loop in that version), but the code below is probably not optimal w.r.t. BB4W.

As an aside, I'm amazed (and disappointed) that we're in the second decade of the 21st Century, and ARM BBC BASIC still doesn't natively support structures. I can only guess (because I haven't looked into it) that there must be something fundamental within the interpreter which makes implementing BB4W-like structures difficult or impossible. Lack of support for structures has made my recent attempt to port 'Space Rocks' to RISC OS much more painful than it needed to be.

Code:
      *ESC OFF

      MODE 8 : OFF

      ON ERROR PROCerror

      ORIGIN 640, 512

      MaxZ% = 500
      MinZ% = 30

      N% = 500
      DIM X%(N%-1), Y%(N%-1), Z%(N%-1)

      REM Define initial star positions:
      FOR I% = 0 TO N%-1
        X%(I%) = RND(1280)-640-1
        Y%(I%) = RND(1024)-512-1
        Z%(I%) = RND(MaxZ%-MinZ%) + MinZ% - 1
      NEXT I%

      REM Colour table:
      DIM C%(MaxZ%)
      FOR I% = 0 TO MaxZ%
        C%(I%) = 255 * (1 - I%/MaxZ%)
      NEXT I%

      REM Division table:
      DIM D%(MaxZ%)
      FOR I% = 1 TO MaxZ%
        D%(I%) = MaxZ%/I% * 65536
      NEXT I%

      M% = MinZ%

      GCOL 1

      *REFRESH OFF

      REPEAT
        CLS
        FOR I% = 0 TO N%-1
          Z%=Z%(I%)
          U%=D%(Z%)
          V%=D%(Z%-9)
          C%=C%(Z%)
          COLOUR 1,C%,C%,C%
          LINE X%(I%)*U%>>16, Y%(I%)*U%>>16, X%(I%)*V%>>16, Y%(I%)*V%>>16
          IF Z% > M% THEN
            Z%(I%) -= 5
          ELSE
            X%(I%) = RND(1280)-640-1
            Y%(I%) = RND(1024)-512-1
            Z%(I%) = MaxZ%
          ENDIF
        NEXT
        *REFRESH
        SYS "Sleep", 1
      UNTIL FALSE
      END

      DEF PROCerror
      OSCLI "REFRESH ON" : CLS : ON : VDU 7
      REPORT : PRINT " at line "; ERL;
      REPEAT UNTIL INKEY(1)=0
      ENDPROC 

« Last Edit: Mar 21st, 2015, 11:56am by David Williams » User IP Logged

rtr2
Guest
xx Re: Yet another starfield
« Reply #1 on: Mar 21st, 2015, 11:57am »

on Mar 21st, 2015, 11:20am, David Williams wrote:
I can only guess (because I haven't looked into it) that there must be something fundamental within the interpreter which makes implementing BB4W-like structures difficult or impossible.

I very much doubt it. If the internal organisation of ARM BASIC is anything like BB4W (and I bet it is: the way the CALL statement works pretty much mandates the way 'variables' are handled) I would guess that supporting structures would be fairly straightforward.

As implemented in BB4W each structure needs an 8-byte 'descriptor', and as ARM BASIC 6 has 8-byte floats (doubles) the underlying mechanisms for dealing with a datatype of that size must already be there. Indeed if I was trying to add the feature I might even use an 8-byte float as a temporary alias for a structure so as not to have to write too much code all in one go.

My assessment is that there are unlikely to be significant technical hurdles, but that there is simply nobody with the understanding and motivation to do it. Given that the source of ARM BASIC is available that is indeed a sad state of affairs.

When, some years ago, I was unwise enough to raise this subject on a RISC OS forum the reaction was that the indirection operators provided an entirely adequate substitute for structures. My attempts to argue otherwise were shot down in flames of course. sad

Richard.
User IP Logged

David Williams
Developer

member is offline

Avatar

meh


PM

Gender: Male
Posts: 452
xx Re: Yet another starfield
« Reply #2 on: Mar 21st, 2015, 12:07pm »

This looks quite nice, IMHO (you couldn't do this easily and efficiently with BASIC V):

Code:
     *ESC OFF

      MODE 8 : OFF

      ON ERROR PROCerror

      ORIGIN 640, 512

      MaxZ% = 500
      MinZ% = 50

      N% = 400
      DIM X%(N%-1), Y%(N%-1), Z%(N%-1)

      REM Define initial star positions:
      R% = RND(-123456789)
      FOR I% = 0 TO N%-1
        X%(I%) = RND(1280)-640-1
        Y%(I%) = RND(1024)-512-1
        Z%(I%) = RND(MaxZ%-MinZ%) + MinZ% - 1
      NEXT I%

      REM Colour table:
      DIM C%(MaxZ%)
      FOR I% = 0 TO MaxZ%
        C%(I%) = 255 * (1 - I%/MaxZ%)
      NEXT I%

      REM Division table:
      DIM D%(MaxZ%)
      FOR I% = 1 TO MaxZ%
        D%(I%) = MaxZ%/I% * 65536
      NEXT I%

      REM Line thickness table:
      DIM T%(MaxZ%)
      FOR I% = 1 TO MaxZ%
        T%(I%) = 1 + 9 * (1 - I%/MaxZ%)^2
      NEXT I%

      M% = MinZ%

      GCOL 1

      *REFRESH OFF

      REPEAT
        CLS
        FOR I% = 0 TO N%-1
          Z%=Z%(I%)
          U%=D%(Z%)
          V%=D%(Z%-15)
          C%=C%(Z%)
          COLOUR 1,C%,C%,C%
          @vdu%!248=T%(Z%)
          LINE X%(I%)*U%>>16, Y%(I%)*U%>>16, X%(I%)*V%>>16, Y%(I%)*V%>>16
          IF Z% > M% THEN
            Z%(I%) -= 8
          ELSE
            X%(I%) = RND(1280)-640-1
            Y%(I%) = RND(1024)-512-1
            Z%(I%) = MaxZ%
          ENDIF
        NEXT
        *REFRESH
        SYS "Sleep", 1
      UNTIL FALSE
      END

      DEF PROCerror
      OSCLI "REFRESH ON" : CLS : ON : VDU 7
      REPORT : PRINT " at line "; ERL;
      REPEAT UNTIL INKEY(1)=0
      ENDPROC
 
User IP Logged

rtr2
Guest
xx Re: Yet another starfield
« Reply #3 on: Mar 21st, 2015, 12:54pm »

on Mar 21st, 2015, 12:07pm, David Williams wrote:
This looks quite nice, IMHO (you couldn't do this easily and efficiently with BASIC V)

I would have slightly preferred VDU 23,23... over @vdu%!248 simply to keep it slightly 'purer', although that would almost certainly slow it down. The only obvious compensating speed-up would be to evaluate X%(I%) and Y%(I%) only once rather than twice - but even then I can't be sure there would be a net benefit:

Code:
          X%=X%(I%)
          Y%=Y%(I%)
          VDU 23,23,T%(Z%)|
          LINE X%*U%>>16, Y%*U%>>16, X%*V%>>16, Y%*V%>>16 

Richard.
User IP Logged

David Williams
Developer

member is offline

Avatar

meh


PM

Gender: Male
Posts: 452
xx Re: Yet another starfield
« Reply #4 on: Mar 21st, 2015, 1:13pm »

on Mar 21st, 2015, 12:54pm, g4bau wrote:
The only obvious compensating speed-up would be to evaluate X%(I%) and Y%(I%) only once rather than twice - but even then I can't be sure there would be a net benefit:


Thanks. It's certainly something worth checking with the BASIC V version because the Raspberry Pi 2 is a slower system than most low-end PCs (although currently I'm using RPCEmu), and every clock cycle counts.


David.
--
User IP Logged

David Williams
Developer

member is offline

Avatar

meh


PM

Gender: Male
Posts: 452
xx Re: Yet another starfield
« Reply #5 on: Apr 2nd, 2015, 5:20pm »

Here's another conversion from ARM BBC BASIC V (which is rather disingenuous of me because I developed most of it with BB4W!).

60 fps on a Raspberry Pi 2, which I think is quite impressive considering the relatively slow processor, and that each of the 495 points that define the outlines is subject to an 'unaccelerated' floating point divide and several multiplies (a lot of work for dear old BASIC V), and all the graphics are drawn by the OS.

If the perspective transform(s), which probably requires thousands of clock cycles per frame, can be offloaded to a matrix (and I believe it can!), then a performance boost will ensue. Probably.

Code:
REM Rotating Raspberry Pi logo
REM Converted to BB4W from ARM BBC BASIC V original

*ESC OFF
PROCFixWndSz
MODE 8:OFF
ON ERROR PROCerror
ORIGIN 640,512

RESTORE
totalPts%=0
FOR L%=0 TO 13
  READ N%
  READ fillX%,fillY%
  READ x0%,y0%:totalPts%+=1
  FOR I% = 1 TO N%-1
    READ X%,Y%:totalPts%+=1
  NEXT I%
NEXT L%

totalPts%+=14

RESTORE
minX%=1E9
maxX%=-1E9
minY%=1E9
maxY%=-1E9
DIM p(totalPts%-1,2),q(totalPts%-1,2),m(2,2)
P%=0
FOR L%=0 TO 13
  READ N%,fillX%,fillY%
  FOR I% = 0 TO N%-1
    READ X%,Y%
    IF X%<minX% THEN minX%=X%
    IF X%>maxX% THEN maxX%=X%
    IF Y%<minY% THEN minY%=Y%
    IF Y%>maxY% THEN maxY%=Y%
    p(P%,0)=X%
    p(P%,1)=Y%
    P% += 1
  NEXT I%
NEXT L%

FOR I%=1 TO 14
  READ p(P%,0),p(P%,1)
  P%+=1
NEXT I%

FOR I%=0 TO totalPts%-1
  p(I%,0)-=minX%+(maxX%-minX%)DIV2
  p(I%,1)-=minY%+(maxY%-minY%)DIV2
NEXT I%

REM Rotation angles
A=0 : B=0 : C=0
frame%=0
frameRate%=0
T%=0
TIME=0

COLOUR 1,32,32,32 : REM interior fill colour
COLOUR 2,64,64,64 : REM outer outline colour
COLOUR 3,&BC,&11,&42 : REM berry colour (sort of fuscha?)
COLOUR 4,&BC DIV 2,&11 DIV 2,&42 DIV 2 : REM berry outline colour
COLOUR 5,20,220,40 : REM leaf colour
COLOUR 6,20,30,100 : REM background colour
COLOUR 134
GCOL 134

k=600

*REFRESH OFF

REPEAT
  CLS
  sA=SIN(A)
  cA=COS(A)
  sB=SIN(B)
  cB=COS(B)
  sC=SIN(C)
  cC=COS(C)
  m()=(cB*cC), -cB*sC, sB,  cA*sC+sA*sB*cC, cA*cC-sA*sB*sC, -sA*cB, sA*sC-cA*sB*cC, sA*cC+cA*sB*sC, cA*cB
  q()=p().m()
  s=650+150*SIN(TIME/150)*COS(TIME/70)
  
  REM path 0:
  GCOL 2
  z0=s/(q(0,2)+k)
  MOVE q(0,0)*z0,q(0,1)*z0
  FOR I%=1 TO 134
    z=s/(q(I%,2)+k)
    DRAW q(I%,0)*z,q(I%,1)*z
  NEXT
  DRAW q(0,0)*z0,q(0,1)*z0
  
  GCOL 4
  
  REM path 1:
  z0=s/(q(135,2)+k)
  MOVE q(135,0)*z0,q(135,1)*z0
  FOR I%=136 TO 158
    z=s/(q(I%,2)+k)
    DRAW q(I%,0)*z,q(I%,1)*z
  NEXT
  DRAW q(135,0)*z0,q(135,1)*z0
  
  REM path 2:
  z0=s/(q(159,2)+k)
  MOVE q(159,0)*z0,q(159,1)*z0
  FOR I%=160 TO 179
    z=s/(q(I%,2)+k)
    DRAW q(I%,0)*z,q(I%,1)*z
  NEXT
  DRAW q(159,0)*z0,q(159,1)*z0
  
  REM path 3:
  z0=s/(q(180,2)+k)
  MOVE q(180,0)*z0,q(180,1)*z0
  FOR I%=181 TO 202
    z=s/(q(I%,2)+k)
    DRAW q(I%,0)*z,q(I%,1)*z
  NEXT
  DRAW q(180,0)*z0,q(180,1)*z0
  
  REM path 4:
  z0=s/(q(203,2)+k)
  MOVE q(203,0)*z0,q(203,1)*z0
  FOR I%=204 TO 223
    z=s/(q(I%,2)+k)
    DRAW q(I%,0)*z,q(I%,1)*z
  NEXT
  DRAW q(203,0)*z0,q(203,1)*z0
  
  REM path 5:
  z0=s/(q(224,2)+k)
  MOVE q(224,0)*z0,q(224,1)*z0
  FOR I%=225 TO 244
    z=s/(q(I%,2)+k)
    DRAW q(I%,0)*z,q(I%,1)*z
  NEXT
  DRAW q(224,0)*z0,q(224,1)*z0
  
  REM path 6:
  z0=s/(q(245,2)+k)
  MOVE q(245,0)*z0,q(245,1)*z0
  FOR I%=246 TO 270
    z=s/(q(I%,2)+k)
    DRAW q(I%,0)*z,q(I%,1)*z
  NEXT
  DRAW q(245,0)*z0,q(245,1)*z0
  
  REM path 7:
  z0=s/(q(271,2)+k)
  MOVE q(271,0)*z0,q(271,1)*z0
  FOR I%=272 TO 299
    z=s/(q(I%,2)+k)
    DRAW q(I%,0)*z,q(I%,1)*z
  NEXT
  DRAW q(271,0)*z0,q(271,1)*z0
  
  REM path 8:
  z0=s/(q(300,2)+k)
  MOVE q(300,0)*z0,q(300,1)*z0
  FOR I%=301 TO 321
    z=s/(q(I%,2)+k)
    DRAW q(I%,0)*z,q(I%,1)*z
  NEXT
  DRAW q(300,0)*z0,q(300,1)*z0
  
  REM path 9:
  z0=s/(q(322,2)+k)
  MOVE q(322,0)*z0,q(322,1)*z0
  FOR I%=323 TO 341
    z=s/(q(I%,2)+k)
    DRAW q(I%,0)*z,q(I%,1)*z
  NEXT
  DRAW q(322,0)*z0,q(322,1)*z0
  
  REM path 10:
  z0=s/(q(342,2)+k)
  MOVE q(342,0)*z0,q(342,1)*z0
  FOR I%=343 TO 364
    z=s/(q(I%,2)+k)
    DRAW q(I%,0)*z,q(I%,1)*z
  NEXT
  DRAW q(342,0)*z0,q(342,1)*z0
  
  REM path 11:
  z0=s/(q(365,2)+k)
  MOVE q(365,0)*z0,q(365,1)*z0
  FOR I%=366 TO 386
    z=s/(q(I%,2)+k)
    DRAW q(I%,0)*z,q(I%,1)*z
  NEXT
  DRAW q(365,0)*z0,q(365,1)*z0
  
  REM path 12:
  z0=s/(q(387,2)+k)
  MOVE q(387,0)*z0,q(387,1)*z0
  FOR I%=388 TO 434
    z=s/(q(I%,2)+k)
    DRAW q(I%,0)*z,q(I%,1)*z
  NEXT
  DRAW q(387,0)*z0,q(387,1)*z0
  
  REM path 13:
  z0=s/(q(435,2)+k)
  MOVE q(435,0)*z0,q(435,1)*z0
  FOR I%=436 TO 480
    z=s/(q(I%,2)+k)
    DRAW q(I%,0)*z,q(I%,1)*z
  NEXT
  DRAW q(435,0)*z0,q(435,1)*z0
  
  REM fill points
  z=s/(q(481,2)+k)
  GCOL 1 : FILL q(481,0)*z,q(481,1)*z
  
  GCOL 3
  FOR I%=482 TO 492
    z=s/(q(I%,2)+k)
    FILL q(I%,0)*z,q(I%,1)*z
  NEXT
  
  GCOL 5
  FOR I%=493 TO 494
    z=s/(q(I%,2)+k)
    FILL q(I%,0)*z,q(I%,1)*z
  NEXT
  
  A=0.9*SIN(TIME/140)
  B=0.9*COS(TIME/70 + 0.45)
  C=3*SIN(TIME/100)*COS(TIME/200)
  
  PRINT TAB(2,1); frameRate%; " fps"
  frame% += 1
  IF TIME >= T%+100 THEN frameRate%=frame% : frame%=0 : T%=TIME
  
  *REFRESH
  SYS "Sleep", 1
UNTIL FALSE
END

DEF PROCFixWndSz
LOCAL W%
SYS"GetWindowLong",@hwnd%,-16 TO W%
SYS"SetWindowLong",@hwnd%,-16,W% ANDNOT&40000 ANDNOT&10000
ENDPROC

DEF PROCerror
*REFRESH ON
CLS : ON : VDU 7
PRINT '" " + REPORT$ + " at line "; ERL;
REPEAT UNTIL INKEY(1)=0
ENDPROC

DATA 135,0,0
DATA 282,628,292,652,302,667,318,681,328,681,336,690,348,694,355,693,366,698,374,699
DATA 380,696,389,701,398,702,408,698,422,701,433,697,446,696,455,691,467,690,477,687
DATA 484,680,497,680,506,673,508,663,504,654,509,644,508,634,503,628,504,618,497,605
DATA 496,594,486,581,484,569,469,556,465,545,450,537,444,529,428,520,446,508,462,492
DATA 474,473,480,455,483,434,484,421,488,413,500,404,513,388,523,371,529,354,531,336
DATA 530,316,524,295,517,281,505,265,500,244,493,226,490,209,484,192,470,169,449,149
DATA 424,135,398,118,381,108,363,101,339,81,319,71,299,65,285,65,265,65,242,71
DATA 220,83,204,98,175,111,154,123,137,135,103,158,86,178,76,201,72,213,70,223
DATA 59,262,54,271,41,288,34,310,32,329,33,351,40,372,50,389,61,401,76,413
DATA 79,423,81,444,86,465,92,480,102,491,113,503,133,520,121,526,114,536,102,541
DATA 95,549,94,556,84,563,78,573,77,581,68,589,66,597,67,604,61,611,58,618
DATA 60,629,56,636,54,643,57,654,56,666,59,676,68,679,77,679,86,687,98,690
DATA 107,690,117,695,129,696,140,701,156,698,168,702,181,698,194,699,207,693,221,693
DATA 234,683,246,681,256,673,267,659,275,646
DATA 24,0,0
DATA 284,152,302,152,323,148,339,143,347,138,352,131,352,123,347,115,337,105,324,96
DATA 310,88,296,84,283,82,273,82,260,85,247,90,233,97,222,105,213,116,209,126
DATA 215,134,227,141,241,147,263,151
DATA 21,0,0
DATA 140,266,163,250,179,233,191,212,197,191,198,172,195,160,185,151,174,148,160,149
DATA 141,154,124,165,109,180,99,194,94,208,90,225,89,243,92,256,100,268,113,272
DATA 126,271
DATA 23,0,0
DATA 282,308,303,306,321,299,336,287,348,272,354,258,356,241,354,222,347,205,337,192
DATA 322,182,307,174,290,171,271,172,251,178,232,190,217,209,210,232,211,253,217,271
DATA 227,284,241,296,258,304
DATA 21,0,0
DATA 381,238,396,254,411,268,430,279,446,282,459,278,467,266,471,253,472,238,471,218
DATA 466,200,457,184,443,169,424,155,407,148,390,146,375,149,363,159,360,175,362,196
DATA 370,217
DATA 21,0,0
DATA 94,400,101,396,106,387,108,371,108,356,107,337,104,321,101,310,95,292,88,280
DATA 80,275,72,278,63,289,56,303,52,317,51,333,52,349,55,360,63,374,70,384
DATA 82,394
DATA 26,0,0
DATA 207,441,227,438,243,431,256,419,264,405,268,387,268,369,264,351,257,335,247,321
DATA 235,309,221,301,206,295,191,292,174,294,157,301,144,312,135,327,130,343,128,361
DATA 132,380,138,395,147,408,158,421,171,430,187,437
DATA 29,0,0
DATA 332,440,348,445,365,444,380,440,395,432,405,424,414,415,422,403,430,388,433,373
DATA 434,357,433,341,428,329,421,317,409,306,393,299,378,296,361,298,344,303,328,313
DATA 315,325,307,337,301,351,296,367,295,380,295,395,300,411,307,422,318,433
DATA 22,0,0
DATA 467,401,478,394,488,384,496,372,502,359,505,347,506,336,505,321,502,309,498,297
DATA 491,286,482,277,473,278,465,288,459,302,454,319,450,342,449,359,449,370,450,383
DATA 453,394,459,401
DATA 20,0,0
DATA 169,510,181,511,192,511,201,509,204,503,197,493,180,475,159,456,137,438,121,427
DATA 109,421,102,421,99,425,99,433,101,450,106,466,115,480,128,493,144,503,157,508
DATA 23,0,0
DATA 286,524,303,521,319,514,334,505,344,493,348,481,346,470,338,460,327,453,311,448
DATA 293,445,275,446,257,448,243,452,231,458,220,468,215,478,216,490,224,501,235,510
DATA 247,517,259,521,272,524
DATA 22,0,0
DATA 374,509,386,509,399,506,411,502,423,496,434,487,443,476,450,463,455,448,457,435
DATA 457,424,456,419,450,418,434,425,417,438,398,453,379,470,367,482,357,495,352,503
DATA 354,507,363,509
DATA 48,0,0
DATA 237,565,232,552,221,540,208,532,191,527,175,525,155,525,164,530,144,534,129,539
DATA 140,544,122,549,109,557,120,559,93,577,104,578,84,597,93,598,74,620,87,620
DATA 77,631,70,640,82,642,72,665,99,664,94,674,103,675,126,671,121,681,148,675
DATA 142,686,173,676,167,686,194,673,193,683,214,669,214,679,235,659,239,667,257,646
DATA 268,620,268,602,264,591,258,583,246,575,202,606,136,637,198,599
DATA 46,0,0
DATA 318,575,304,585,296,599,295,614,301,634,313,654,326,667,330,659,349,680,352,669
DATA 372,684,373,673,396,687,393,677,421,685,415,676,445,679,439,672,471,674,466,666
DATA 492,664,483,642,496,641,488,631,479,621,489,620,482,609,472,598,481,598,462,579
DATA 472,578,460,568,445,559,455,556,427,544,434,539,403,532,408,525,388,524,365,528
DATA 347,537,334,548,328,564,361,596,429,637,357,603

REM fill points:
DATA 282,550
DATA 282,116
DATA 140,206
DATA 282,238
DATA 418,206
DATA 78,340
DATA 196,364
DATA 370,364
DATA 478,340
DATA 142,470
DATA 282,484
DATA 416,470
DATA 160,580
DATA 400,580
 
« Last Edit: Apr 2nd, 2015, 5:23pm by David Williams » User IP Logged

rtr2
Guest
xx Re: Yet another starfield
« Reply #6 on: Apr 2nd, 2015, 10:18pm »

on Apr 2nd, 2015, 5:20pm, David Williams wrote:
Here's another conversion from ARM BBC BASIC V (which is rather disingenuous of me because I developed most of it with BB4W!).

That's nice, and it would make a good demo program - except that I presume there are likely to be copyright/trademark issues with regard to the Raspberry Pi logo. Do you happen to know?

Quote:
If the perspective transform(s), which probably requires thousands of clock cycles per frame, can be offloaded to a matrix (and I believe it can!), then a performance boost will ensue.

I can't speak for RISC OS, but on my PC the plotting takes vastly longer than the perspective calculations (something like a factor of 20) so any improvement would be tiny.

Richard.
User IP Logged

David Williams
Developer

member is offline

Avatar

meh


PM

Gender: Male
Posts: 452
xx Re: Yet another starfield
« Reply #7 on: Apr 2nd, 2015, 10:23pm »

on Apr 2nd, 2015, 10:18pm, g4bau wrote:
That's nice, and it would make a good demo program - except that I presume there are likely to be copyright/trademark issues with regard to the Raspberry Pi logo. Do you happen to know?


They have something to say about it here, I think:

http://www.raspberrypi.org/trademark-rules/


David.
--
User IP Logged

David Williams
Developer

member is offline

Avatar

meh


PM

Gender: Male
Posts: 452
xx Re: Yet another starfield
« Reply #8 on: Apr 28th, 2015, 9:30pm »

Code:
      REM 3D Starfield II

      *FLOAT 64
      MODE 8
      OFF

      N% = 1000

      DIM X%(N%-1), Y%(N%-1), Z%(N%-1)
      boxSz% = 40000
      boxSz_2% = boxSz% DIV 2
      maxZ_1 = 1 / boxSz%

      FOR I% = 0 TO N%-1
        X%(I%) = RND( boxSz% ) - boxSz_2% - 1
        Y%(I%) = RND( boxSz% ) - boxSz_2% - 1
        Z%(I%) = boxSz_2% * (1 - I%/(N%-1))
      NEXT I%

      REM Division table needed for ARM BBC BASIC version
      REM (using this is probably slower for BB4W)
      DIM divTbl( boxSz% )
      divTbl(0) = 0
      FOR I% = 1 TO boxSz%
        divTbl(I%) = 1/I%
      NEXT I%

      ORIGIN 640, 512
      GCOL 1
      TIME = 0

      *REFRESH OFF

      REPEAT
        CLS
        FOR J% = 1 TO 5
          T% = TIME
          X% = boxSz_2% * SIN(2*PI*T%/1700)*SIN(4*PI*T%/3000 + 1.5)*SIN(9*PI*T%/9022 - 2.3)
          Y% = boxSz_2% * COS(3*PI*T%/1830)*COS(3*PI*T%/3400 + 1.2)*SIN(5*PI*T%/9812 - 3.1)
          Z% = boxSz_2% * SIN(2*PI*T%/1455)*SIN(6*PI*T%/3702 - 2.1)*SIN(3*PI*T%/10800 + 1.2)
          FOR I% = 0 TO N%-1
            dZ% = Z%(I%) - Z%
            IF dZ% > 100 THEN
              z = 1000 * divTbl(dZ%)
              x% = (X%(I%) - X%) * z
              IF ABS(x%) < 640 THEN
                y% = (Y%(I%) - Y%) * z
                IF ABS(y%) < 512 THEN
                  i = 1 - dZ%*maxZ_1
                  col% = 256*i*i
                  COLOUR 1, col%, col%, col%
                  CIRCLE FILL 2*x%, 2*y%, 12
                ENDIF
              ENDIF
            ENDIF
          NEXT I%
        NEXT J%
        *REFRESH
        SYS "Sleep", 5
      UNTIL FALSE
 




User IP Logged

rtr2
Guest
xx Re: Yet another starfield
« Reply #9 on: Apr 30th, 2015, 09:08am »

on Apr 28th, 2015, 9:30pm, David Williams wrote:
REM Division table needed for ARM BBC BASIC version
REM (using this is probably slower for BB4W)

I tried to benchmark that:

Code:
      DIM divTbl(40000)
      FOR I% = 1 TO 40000
        divTbl(I%) = 1/I%
      NEXT I%

      TIME = 0
      FOR J%=1 TO 100 : FOR I%=1 TO 40000 : A = divTbl(I%) : NEXT : NEXT
      PRINT "Using lookup table: ";TIME

      TIME = 0
      FOR J%=1 TO 100 : FOR I%=1 TO 40000 : A = 1/I% : NEXT : NEXT
      PRINT "Using division    : ";TIME 

Which gave (using BB4W v6.00a):

Code:
Using lookup table: 311
Using division    : 270 

So although the table is a little slower, there's not much in it.

Richard.
User IP Logged

David Williams
Developer

member is offline

Avatar

meh


PM

Gender: Male
Posts: 452
xx Re: Yet another starfield
« Reply #10 on: Apr 30th, 2015, 4:34pm »

on Apr 30th, 2015, 09:08am, g4bau wrote:
Which gave (using BB4W v6.00a):

Code:
Using lookup table: 311
Using division    : 270 

So although the table is a little slower, there's not much in it.


Thanks.

Going by ARM BBC BASIC on a Raspberry Pi 2, using a division table is, at best, about 34% faster (which surprised me - I thought it would be faster than that - perhaps upwards of 50%). At worst, if reading essentially random entries (5-byte floats) from a large division table (too big to fit in the CPU's L1 (or L2?) cache), it's only 1 or 2% faster. So, in real-world use I'm guessing around 20 to 25% faster on average.

For really speed-critical stuff, I've found that a division table of fixed-point integers to be worthwhile (with ARM BBC BASIC), when accuracy isn't too important.


David.
--
« Last Edit: Apr 30th, 2015, 7:27pm by David Williams » 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