tech demo

Discussions related to graphics (2D and 3D), animation and games programming
Repton
Posts: 42
Joined: Tue 22 May 2018, 13:51

tech demo

Post by Repton »

https://www.youtube.com/watch?v=AiHyTJs ... tqikhZqo4M

using draw commands how would this example be replicated
David Williams

Re: tech demo

Post by David Williams »

Code: Select all

      MODE 8 : OFF

      WinW% = @vdu%!208
      WinH% = @vdu%!212

      delay% = 32

      min_d = 8.0
      max_d = 20.0

      DIM list{(delay%-1) x1, y1, x2, y2}
      DIM line{x1, y1, x2, y2, dx1, dy1, dx2, dy2}

      line.x1 = RND(WinW%)-1
      line.y1 = RND(WinH%)-1
      line.x2 = RND(WinW%)-1
      line.y2 = RND(WinH%)-1

      line.dx1 = FNd * SGN(RND-RND)
      line.dy1 = FNd * SGN(RND-RND)
      line.dx2 = FNd * SGN(RND-RND)
      line.dy2 = FNd * SGN(RND-RND)

      @vdu%!248 = 8 : REM set line thickness

      colChgTime% = 0

      TIME = 0

      REPEAT
  
        GCOL 0
  
        LINE 2*list{(delay%-1)}.x1, 2*list{(delay%-1)}.y1, \
        \ 2*list{(delay%-1)}.x2, 2*list{(delay%-1)}.y2
  
        LINE 2*list{(delay%-1)}.x1, 2*(WinH%-list{(delay%-1)}.y1), \
        \ 2*list{(delay%-1)}.x2, 2*(WinH%-list{(delay%-1)}.y2)
  
        LINE 2*(WinW%-list{(delay%-1)}.x1), 2*list{(delay%-1)}.y1, \
        \ 2*(WinW%-list{(delay%-1)}.x2), 2*list{(delay%-1)}.y2
  
        LINE 2*(WinW%-list{(delay%-1)}.x1), 2*(WinH%-list{(delay%-1)}.y1), \
        \ 2*(WinW%-list{(delay%-1)}.x2), 2*(WinH%-list{(delay%-1)}.y2)
  
        FOR I% = delay%-1 TO 1 STEP -1
          list{(I%)}.x1 = list{(I%-1)}.x1
          list{(I%)}.y1 = list{(I%-1)}.y1
          list{(I%)}.x2 = list{(I%-1)}.x2
          list{(I%)}.y2 = list{(I%-1)}.y2
        NEXT I%
  
        list{(0)}.x1 = line.x1
        list{(0)}.y1 = line.y1
        list{(0)}.x2 = line.x2
        list{(0)}.y2 = line.y2
  
        IF TIME >= colChgTime% THEN
          CASE RND(10) OF
            WHEN 1 : COLOUR 1, 255, 0, 0
            WHEN 2 : COLOUR 1, 0, 255, 0
            WHEN 3 : COLOUR 1, 0, 0, 255
            WHEN 4 : COLOUR 1, 255, 255, 0
            WHEN 5 : COLOUR 1, 255, 0, 255
            WHEN 6 : COLOUR 1, 0, 255, 255
            WHEN 7 : COLOUR 1, 128, 255, 128
            WHEN 8 : COLOUR 1, 255, 128, 0
            WHEN 9 : COLOUR 1, 255, 0, 128
            WHEN 10 : COLOUR 1, 0, 128, 255
          ENDCASE
          colChgTime% = TIME + 100 + RND(400)
        ENDIF
  
        GCOL 3, 1
        LINE 2*line.x1, 2*line.y1, 2*line.x2, 2*line.y2
        LINE 2*line.x1, 2*(WinH%-line.y1), 2*line.x2, 2*(WinH%-line.y2)
        LINE 2*(WinW%-line.x1), 2*line.y1, 2*(WinW%-line.x2), 2*line.y2
        LINE 2*(WinW%-line.x1), 2*(WinH%-line.y1), 2*(WinW%-line.x2), 2*(WinH%-line.y2)
  
        line.x1 += line.dx1
        line.y1 += line.dy1
        line.x2 += line.dx2
        line.y2 += line.dy2
  
        chg_dx1% = FALSE
        chg_dy1% = FALSE
        chg_dx2% = FALSE
        chg_dy2% = FALSE
  
        IF line.x1 < 0 THEN line.x1 = 0 : chg_dx1% = TRUE
        IF line.x1 > WinW% THEN line.x1 = WinW% : chg_dx1% = TRUE
        IF line.y1 < 0 THEN line.y1 = 0 : chg_dy1% = TRUE
        IF line.y1 > WinH% THEN line.y1 = WinH% : chg_dy1% = TRUE
        IF line.x2 < 0 THEN line.x2 = 0 : chg_dx2% = TRUE
        IF line.x2 > WinW% THEN line.x2 = WinW% : chg_dx2% = TRUE
        IF line.y2 < 0 THEN line.y2 = 0 : chg_dy2% = TRUE
        IF line.y2 > WinH% THEN line.y2 = WinH% : chg_dy2% = TRUE
  
        IF chg_dx1% THEN line.dx1 = -FNd * SGNline.dx1
        IF chg_dy1% THEN line.dy1 = -FNd * SGNline.dy1
        IF chg_dx2% THEN line.dx2 = -FNd * SGNline.dx2
        IF chg_dy2% THEN line.dy2 = -FNd * SGNline.dy2
  
        WAIT 8
  
      UNTIL FALSE
      END

      DEF FNd = (min_d + (max_d-min_d) * RND(1))
RichardRussell

Re: tech demo

Post by RichardRussell »

David Williams wrote: Tue 03 Dec 2019, 21:57

Code: Select all

      @vdu%!248 = 8 : REM set line thickness
For cross-platform compatibility I'd strongly recommend setting the line thickness in a more portable fashion:

Code: Select all

      VDU 23,23,8| : REM set line thickness
With that change it runs fine in BBCSDL as well as BB4W (v6.12a), but replacing WAIT 5 with *REFRESH can take advantage of the display refresh synchronisation that BBCSDL supports.
svein
Posts: 60
Joined: Tue 03 Apr 2018, 19:34

Re: tech demo

Post by svein »

Here's another idea, not as good, but shorter code.
Svein

Code: Select all

      IF INKEY$(-256)="W" THEN w=2 ELSE w=1
      MODE 8
      cx=640
      cy=480
      b=480
      rr=4
      *REFRESH OFF
      REPEAT
        a=RND(15)
        x=RND(b) : x1=RND(b)
        y=RND(b) : y1=RND(b)
        s1=RND(b) : s2=RND(b)
        IF s1<s2 THEN s=10 ELSE s=-10
        FOR dx=s1 TO s2 STEP s
          VDU 23,23,1|
          GCOL a
          LINE cx-x+dx,cy-y+dx,cx-x1+dx,cy-y1+dx
          LINE cx-x+dx,cy+y-dx,cx-x1+dx,cy+y1-dx
          LINE cx+x-dx,cy-y+dx,cx+x1-dx,cy-y1+dx
          LINE cx+x-dx,cy+y-dx,cx+x1-dx,cy+y1-dx
          r+=rr : IF r<0 OR r>cx THEN rr=-rr
          VDU 23,23,4| : GCOL 0 : CIRCLE cx,cy,r
          *REFRESH
          WAIT w
        NEXT
      UNTIL 0
David Williams

Re: tech demo

Post by David Williams »

Different method:

Code: Select all

      *HEX 64

      WinW% = 800
      WinH% = 600

      VDU 23, 22, WinW%; WinH%; 8, 16, 16, 0 : OFF

      VDU 23,23,8| : REM set line thickness

      IF POS

      delay% = 32

      min_d% = 8
      max_d% = 24
      chgColTime% = 0

      DIM line{(1) x1, y1, x2, y2, dx1, dy1, dx2, dy2}

      FOR I% = 0 TO 1
        line{(I%)}.x1 = WinW% * FNrnd(I%)
        line{(I%)}.y1 = WinH% * FNrnd(I%)
        line{(I%)}.x2 = WinW% * FNrnd(I%)
        line{(I%)}.y2 = WinH% * FNrnd(I%)
        line{(I%)}.dx1 = FNd(I%)
        line{(I%)}.dy1 = FNd(I%)
        line{(I%)}.dx2 = FNd(I%)
        line{(I%)}.dy2 = FNd(I%)
      NEXT I%

      TIME = 0

      *REFRESH OFF

      REPEAT
  
        IF TIME >= chgColTime% THEN
          PROCSetRandomColour
          chgColTime% = TIME + 100 + RND(400)
        ENDIF
  
        FOR I% = 0 TO 1
          IF I% = 0 OR (I% = 1 AND delay% = 0) THEN
            IF I% = 0 THEN GCOL 3,1 ELSE GCOL 0
            LINE 2*line{(I%)}.x1, 2*line{(I%)}.y1, 2*line{(I%)}.x2, 2*line{(I%)}.y2
            LINE 2*(WinW%-line{(I%)}.x1), 2*line{(I%)}.y1, 2*(WinW%-line{(I%)}.x2), 2*line{(I%)}.y2
            LINE 2*line{(I%)}.x1, 2*(WinH%-line{(I%)}.y1), 2*line{(I%)}.x2, 2*(WinH%-line{(I%)}.y2)
            LINE 2*(WinW%-line{(I%)}.x1), 2*(WinH%-line{(I%)}.y1), 2*(WinW%-line{(I%)}.x2), 2*(WinH%-line{(I%)}.y2)
            line{(I%)}.x1 += line{(I%)}.dx1
            line{(I%)}.y1 += line{(I%)}.dy1
            line{(I%)}.x2 += line{(I%)}.dx2
            line{(I%)}.y2 += line{(I%)}.dx2
            IF line{(I%)}.x1 < 0     line{(I%)}.x1 = 0     : line{(I%)}.dx1 = -FNd(I%) * SGNline{(I%)}.dx1
            IF line{(I%)}.x1 > WinW% line{(I%)}.x1 = WinW% : line{(I%)}.dx1 = -FNd(I%) * SGNline{(I%)}.dx1
            IF line{(I%)}.x2 < 0     line{(I%)}.x2 = 0     : line{(I%)}.dx2 = -FNd(I%) * SGNline{(I%)}.dx2
            IF line{(I%)}.x2 > WinW% line{(I%)}.x2 = WinW% : line{(I%)}.dx2 = -FNd(I%) * SGNline{(I%)}.dx2
            IF line{(I%)}.y1 < 0     line{(I%)}.y1 = 0     : line{(I%)}.dy1 = -FNd(I%) * SGNline{(I%)}.dy1
            IF line{(I%)}.y1 > WinH% line{(I%)}.y1 = WinH% : line{(I%)}.dy1 = -FNd(I%) * SGNline{(I%)}.dy1
            IF line{(I%)}.y2 < 0     line{(I%)}.y2 = 0     : line{(I%)}.dy2 = -FNd(I%) * SGNline{(I%)}.dy2
            IF line{(I%)}.y2 > WinH% line{(I%)}.y2 = WinH% : line{(I%)}.dy2 = -FNd(I%) * SGNline{(I%)}.dy2
          ENDIF
        NEXT I%
  
        IF delay% > 0 delay% -= 1
  
        *REFRESH
  
        WAIT 8
  
      UNTIL FALSE
      END

      DEF PROCSetRandomColour
      CASE RND(14) OF
        WHEN  1 : COLOUR 1, 255, 0, 0
        WHEN  2 : COLOUR 1, 0, 255, 0
        WHEN  3 : COLOUR 1, 0, 0, 255
        WHEN  4 : COLOUR 1, 255, 0, 255
        WHEN  5 : COLOUR 1, 255, 255, 0
        WHEN  6 : COLOUR 1, 0, 255, 255
        WHEN  7 : COLOUR 1, 255, 127, 0
        WHEN  8 : COLOUR 1, 255, 0, 127
        WHEN  9 : COLOUR 1, 127, 255, 0
        WHEN 10 : COLOUR 1, 127, 0, 255
        WHEN 11 : COLOUR 1, 0, 127, 255
        WHEN 12 : COLOUR 1, 255, 127, 127
        WHEN 13 : COLOUR 1, 127, 255, 127
        WHEN 14 : COLOUR 1, 127, 127, 255
      ENDCASE
      ENDPROC

      DEF FNd(I%) = min_d% + (max_d% - min_d%) * FNrnd(I%)

      DEF FNrnd(I%)
      PRIVATE F%, S%%() : DIM S%%(1)
      IF NOT F% THEN
        S%%(0) = RND OR (RND << 31)
        S%%(1) = S%%(0)
        F% = TRUE
      ENDIF
      S%%(I%) EOR= S%%(I%) << 13
      S%%(I%) EOR= S%%(I%) >>> 17
      S%%(I%) EOR= S%%(I%) << 5
      = (S%%(I%) AND &FFFFFFFF) / &FFFFFFFF

Edit: Symmetry is fun:

Code: Select all

      *HEX 64

      WinW% = 800
      WinH% = 600

      VDU 23, 22, WinW%; WinH%; 8, 16, 16, 0 : OFF

      VDU 23,23,8| : REM set line thickness

      IF POS

      delay% = 32

      min_d% = 8
      max_d% = 24
      chgColTime% = 0

      DIM line{(1) x1, y1, x2, y2, dx1, dy1, dx2, dy2}

      FOR I% = 0 TO 1
        line{(I%)}.x1 = WinW% * FNrnd(I%)
        line{(I%)}.y1 = WinH% * FNrnd(I%)
        line{(I%)}.x2 = WinW% * FNrnd(I%)
        line{(I%)}.y2 = WinH% * FNrnd(I%)
        line{(I%)}.dx1 = FNd(I%)
        line{(I%)}.dy1 = FNd(I%)
        line{(I%)}.dx2 = FNd(I%)
        line{(I%)}.dy2 = FNd(I%)
      NEXT I%

      TIME = 0

      *REFRESH OFF

      REPEAT
  
        IF TIME >= chgColTime% THEN
          PROCSetRandomColour
          chgColTime% = TIME + 100 + RND(400)
        ENDIF
  
        FOR I% = 0 TO 1
          IF I% = 0 OR (I% = 1 AND delay% = 0) THEN
            IF I% = 0 THEN GCOL 3,1 ELSE GCOL 0
            LINE 2*line{(I%)}.x1, 2*line{(I%)}.y1, 2*line{(I%)}.x2, 2*line{(I%)}.y2
            LINE 2*line{(I%)}.y1, 2*line{(I%)}.x1, 2*line{(I%)}.y2, 2*line{(I%)}.x2
            LINE 2*(WinW%-line{(I%)}.x1), 2*line{(I%)}.y1, 2*(WinW%-line{(I%)}.x2), 2*line{(I%)}.y2
            LINE 2*(WinW%-line{(I%)}.y1), 2*line{(I%)}.x1, 2*(WinW%-line{(I%)}.y2), 2*line{(I%)}.x2
            LINE 2*line{(I%)}.x1, 2*(WinH%-line{(I%)}.y1), 2*line{(I%)}.x2, 2*(WinH%-line{(I%)}.y2)
            LINE 2*line{(I%)}.y1, 2*(WinH%-line{(I%)}.x1), 2*line{(I%)}.y2, 2*(WinH%-line{(I%)}.x2)
            LINE 2*(WinW%-line{(I%)}.x1), 2*(WinH%-line{(I%)}.y1), 2*(WinW%-line{(I%)}.x2), 2*(WinH%-line{(I%)}.y2)
            LINE 2*(WinW%-line{(I%)}.y1), 2*(WinH%-line{(I%)}.x1), 2*(WinW%-line{(I%)}.y2), 2*(WinH%-line{(I%)}.x2)
            line{(I%)}.x1 += line{(I%)}.dx1
            line{(I%)}.y1 += line{(I%)}.dy1
            line{(I%)}.x2 += line{(I%)}.dx2
            line{(I%)}.y2 += line{(I%)}.dx2
            IF line{(I%)}.x1 < 0     line{(I%)}.x1 = 0     : line{(I%)}.dx1 = -FNd(I%) * SGNline{(I%)}.dx1
            IF line{(I%)}.x1 > WinW% line{(I%)}.x1 = WinW% : line{(I%)}.dx1 = -FNd(I%) * SGNline{(I%)}.dx1
            IF line{(I%)}.x2 < 0     line{(I%)}.x2 = 0     : line{(I%)}.dx2 = -FNd(I%) * SGNline{(I%)}.dx2
            IF line{(I%)}.x2 > WinW% line{(I%)}.x2 = WinW% : line{(I%)}.dx2 = -FNd(I%) * SGNline{(I%)}.dx2
            IF line{(I%)}.y1 < 0     line{(I%)}.y1 = 0     : line{(I%)}.dy1 = -FNd(I%) * SGNline{(I%)}.dy1
            IF line{(I%)}.y1 > WinH% line{(I%)}.y1 = WinH% : line{(I%)}.dy1 = -FNd(I%) * SGNline{(I%)}.dy1
            IF line{(I%)}.y2 < 0     line{(I%)}.y2 = 0     : line{(I%)}.dy2 = -FNd(I%) * SGNline{(I%)}.dy2
            IF line{(I%)}.y2 > WinH% line{(I%)}.y2 = WinH% : line{(I%)}.dy2 = -FNd(I%) * SGNline{(I%)}.dy2
          ENDIF
        NEXT I%
  
        IF delay% > 0 delay% -= 1
  
        *REFRESH
  
        WAIT 8
  
      UNTIL FALSE
      END

      DEF PROCSetRandomColour
      CASE RND(14) OF
        WHEN  1 : COLOUR 1, 255, 0, 0
        WHEN  2 : COLOUR 1, 0, 255, 0
        WHEN  3 : COLOUR 1, 0, 0, 255
        WHEN  4 : COLOUR 1, 255, 0, 255
        WHEN  5 : COLOUR 1, 255, 255, 0
        WHEN  6 : COLOUR 1, 0, 255, 255
        WHEN  7 : COLOUR 1, 255, 127, 0
        WHEN  8 : COLOUR 1, 255, 0, 127
        WHEN  9 : COLOUR 1, 127, 255, 0
        WHEN 10 : COLOUR 1, 127, 0, 255
        WHEN 11 : COLOUR 1, 0, 127, 255
        WHEN 12 : COLOUR 1, 255, 127, 127
        WHEN 13 : COLOUR 1, 127, 255, 127
        WHEN 14 : COLOUR 1, 127, 127, 255
      ENDCASE
      ENDPROC

      DEF FNd(I%) = min_d% + (max_d% - min_d%) * FNrnd(I%)

      DEF FNrnd(I%)
      PRIVATE F%, S%%() : DIM S%%(1)
      IF NOT F% THEN
        S%%(0) = RND OR (RND << 31)
        S%%(1) = S%%(0)
        F% = TRUE
      ENDIF
      S%%(I%) EOR= S%%(I%) << 13
      S%%(I%) EOR= S%%(I%) >>> 17
      S%%(I%) EOR= S%%(I%) << 5
      = (S%%(I%) AND &FFFFFFFF) / &FFFFFFFF
svein
Posts: 60
Joined: Tue 03 Apr 2018, 19:34

Re: tech demo

Post by svein »

Symmetric version.

Code: Select all

      MODE 8
      b=480
      rr=8
      *REFRESH OFF
      REPEAT
        a=RND(15)
        x=RND(b) : x1=RND(b)
        y=RND(b) : y1=RND(b)
        s1=RND(b) : s2=RND(b)
        IF s1<s2 THEN s=10 ELSE s=-10
        FOR dx=s1 TO s2 STEP s
          VDU 23,23,2|
          GCOL a
          FOR cx=320 TO 960 STEP 640
            FOR cy=240 TO 720 STEP 480
              LINE cx-x+dx,cy-y+dx,cx-x1+dx,cy-y1+dx
              LINE cx-x+dx,cy+y-dx,cx-x1+dx,cy+y1-dx
              LINE cx+x-dx,cy-y+dx,cx+x1-dx,cy-y1+dx
              LINE cx+x-dx,cy+y-dx,cx+x1-dx,cy+y1-dx
            NEXT
          NEXT
          cx=640 : cy=480
          r+=rr : IF r<0 OR r>SQR(cx^2+cy^2) THEN rr=-rr
          VDU 23,23,8| : GCOL 0 : CIRCLE cx,cy,r
          *REFRESH
          WAIT 3
        NEXT
      UNTIL 0
Edit: Antialiased version, BBCSDL only.

Code: Select all

      INSTALL @lib$+"aagfxlib"
      MODE 8
      b=480
      rr=8
      penwidth=2
      penstyle%=0
      *REFRESH OFF
      REPEAT
        pencolour%=((RND(230)+25)<<24)+(RND(255)<<16)+(RND(255)<<8)+RND(255)
        x=RND(b) : x1=RND(b)
        y=RND(b) : y1=RND(b)
        s1=RND(b) : s2=RND(b)
        IF s1<s2 THEN s=10 ELSE s=-10
        FOR dx=s1 TO s2 STEP s
          VDU 23,23,2|
          FOR cx=320 TO 960 STEP 640
            FOR cy=240 TO 720 STEP 480
              PROC_aaline(cx-x+dx,cy-y+dx,cx-x1+dx,cy-y1+dx,penwidth,pencolour%,penstyle%)
              PROC_aaline(cx-x+dx,cy+y-dx,cx-x1+dx,cy+y1-dx,penwidth,pencolour%,penstyle%)
              PROC_aaline(cx+x-dx,cy-y+dx,cx+x1-dx,cy-y1+dx,penwidth,pencolour%,penstyle%)
              PROC_aaline(cx+x-dx,cy+y-dx,cx+x1-dx,cy+y1-dx,penwidth,pencolour%,penstyle%)
            NEXT
          NEXT
          cx=640 : cy=480
          r+=rr : IF r<0 OR r>SQR(cx^2+cy^2) THEN rr=-rr
          VDU 23,23,8| : GCOL 0 : CIRCLE cx,cy,r
          *REFRESH
          WAIT 2
        NEXT
      UNTIL 0
RichardRussell

Re: tech demo

Post by RichardRussell »

svein wrote: Thu 05 Dec 2019, 10:45 Symmetric version.
Very nice. For your information, this code seems to be particularly wasteful of CPU time on my laptop PC when running in BBCSDL:

Code: Select all

          *REFRESH
          WAIT 3
I think, by bad luck, it's triggering a bit of a 'race' between the two threads (the interpreter thread and the UI thread). Changing it to this (BBCSDL only) reduces the overall CPU load from about 50% to about 10% here:

Code: Select all

      *REFRESH
      *REFRESH
I wouldn't say this is necessarily a typical behaviour, but it may suggest a general caution against mixing *REFRESH and WAIT in BBCSDL if you're concerned about CPU usage.
RichardRussell

Re: tech demo

Post by RichardRussell »

RichardRussell wrote: Thu 05 Dec 2019, 12:13I think, by bad luck, it's triggering a bit of a 'race' between the two threads (the interpreter thread and the UI thread).
Yep, what's happening is that while the interpreter thread is waiting in WAIT 3 (using very little CPU time) the UI thread is spinning like crazy using 100% CPU (core) time! When you do *REFRESH in BBCSDL, both the interpreter and UI threads wait for the display vsync, and CPU usage drops a lot.

So if you are wanting your program to run in both BB4W and BBCSDL, while using the CPU efficiently, use WAIT in BB4W and *REFRESH in BBCSDL but don't mix them. Obviously whether this really matters will depend on how long you expect to leave the program running.
svein
Posts: 60
Joined: Tue 03 Apr 2018, 19:34

Re: tech demo

Post by svein »

this code seems to be particularly wasteful of CPU time
*REFRESH
WAIT 3
Did a bit of testing on this.
And it seems WAIT 3 alone uses as much CPU power as the REFRESH/WAIT combo.
The NOWAIT library version had no effect.

BBCSDL's WAIT seems to behave different from what we are used to from BB4W ?

Svein
RichardRussell

Re: tech demo

Post by RichardRussell »

svein wrote: Thu 05 Dec 2019, 18:54And it seems WAIT 3 alone uses as much CPU power as the REFRESH/WAIT combo.
I posted an explanation before you replied, but it hasn't appeared yet because I am moderated* :cry:
BBCSDL's WAIT seems to behave different from what we are used to from BB4W ?
No, it works identically in both versions. It's *REFRESH that works differently: in BBCSDL it waits for the next display vSync (and whilst waiting both the interpreter and UI threads sleep) whereas in BB4W it doesn't wait at all - it just sets a flag and execution continues.

*Unfortunately the moderation process unavoidably changes the order in which posts appear and can give the impression that a post is in reply to something that it wasn't. My original proposal to the forum's admin was that those who complain about my posts could be moderated, so that a 'neutral third party' could judge whether their complaints were justified. He decided that I should be moderated instead!