tech demo

Discussions related to graphics (2D and 3D), animation and games programming
David Williams

Re: tech demo

Post by David Williams »

Bored employee syndrome strikes again.

https://youtu.be/yai1srcKc1A

Code: Select all

      REM Semi-Realistic Kaleidoscope
      REM Requires BB4W & GfxLib2
      REM
      REM Note that this program uses a *very* inefficient means of achieving a kaleidoscope effect!

      *ESC OFF

      MODE 8 : OFF

      ScrW% = 640
      ScrH% = 512

      INSTALL @lib$ + "GFXLIB2.BBC"
      PROCInitGFXLIB(g{}, 0)

      DIM g2{} = g{}
      g2{} = g{}

      INSTALL @lib$+"GFXLIB_modules\ClrLG.bbc"             : PROCInitModule(0)
      INSTALL @lib$+"GFXLIB_modules\DrawFilledCircle.bbc"  : PROCInitModule(0)
      INSTALL @lib$+"GFXLIB_modules\BPlotRotateScale2.bbc" : PROCInitModule(0)
      INSTALL @lib$+"GFXLIB_modules\PlotRotateScale2.bbc"  : PROCInitModule(0)
      INSTALL @lib$+"GFXLIB_modules\Copy.bbc"              : PROCInitModule(0)
      INSTALL @lib$+"GFXLIB_modules\BPlotFlip.bbc"         : PROCInitModule(0)
      INSTALL @lib$+"GFXLIB_modules\PlotFlip.bbc"          : PROCInitModule(0)
      INSTALL @lib$+"GFXLIB_modules\ReplaceColour.bbc"     : PROCInitModule(0)

      nDiscs% = 100
      DIM disc{( nDiscs%-1 ) move%, x, y, r, x2, y2, dx, dy, rgb}

      imgSz% = 512
      img% = FNmalloc(4 * imgSz%^2)

      maskSz% = 256
      maskBm% = FNmalloc(4 * maskSz%^2)

      bm1Sz% = 256
      bm1% = FNmalloc(4 * bm1Sz%^2)

      bm2Sz% = 256
      bm2% = FNmalloc(4 * bm2Sz%^2)

      REM Create equilateral triangle mask bitmap:
      SYS GFXLIB_SaveAndSetDispVars%, g{}, maskBm%, maskSz%, maskSz%
      FOR Y% = 0 TO maskSz%-1
        w = Y%*TANRAD30
        IF w <= maskSz%/2 THEN
          SYS GFXLIB_Line%, g{}, 0, Y%, maskSz%/2-w, Y%, &808080
          SYS GFXLIB_Line%, g{}, maskSz%/2+w, Y%, maskSz%-1, Y%, &808080
        ELSE
          SYS GFXLIB_Line%, g{}, 0, Y%, maskSz%-1, Y%, &808080
        ENDIF
      NEXT Y%
      SYS GFXLIB_RestoreDispVars%, g{}

      REM Initialise discs:
      FOR I% = 0 TO nDiscs%-1
        disc{(I%)}.move% = FALSE
        disc{(I%)}.x = RND(ScrW%)
        disc{(I%)}.y = RND(ScrH%)
        disc{(I%)}.r = 8 + RND(20)
        CASE RND(12) OF
          WHEN  1 : disc{(I%)}.rgb = &FF0000
          WHEN  2 : disc{(I%)}.rgb = &00FF00
          WHEN  3 : disc{(I%)}.rgb = &0000FF
          WHEN  4 : disc{(I%)}.rgb = &FF00FF
          WHEN  5 : disc{(I%)}.rgb = &FFFF00
          WHEN  6 : disc{(I%)}.rgb = &00FFFF
          WHEN  7 : disc{(I%)}.rgb = &FF8000
          WHEN  8 : disc{(I%)}.rgb = &0080FF
          WHEN  9 : disc{(I%)}.rgb = &00FF80
          WHEN 10 : disc{(I%)}.rgb = &80FF00
          WHEN 11 : disc{(I%)}.rgb = &8080FF
          WHEN 12 : disc{(I%)}.rgb = &FFFFFF
        ENDCASE
      NEXT I%

      TIME = 0

      moveDiscsTime% = 500

      *REFRESH OFF

      REPEAT
  
        T% = TIME
  
        REM Rotational angle of discs bitmap:
        angle = 720*SIN(T%/1000 + PI/5*SIN(T%/1050+0.345))*SIN(T%/950 + PI/8*SIN(T%/800-1.25))
  
        REM Draw discs and update their positions:
        SYS GFXLIB_SaveAndSetDispVars%, g{}, img%, imgSz%, imgSz%
        SYS GFXLIB_Clr%, g{}, 0
        FOR I% = 0 TO nDiscs%-1
          SYS GFXLIB_DrawFilledCircle%, g{}, disc{(I%)}.x, disc{(I%)}.y, disc{(I%)}.r+3, &010101
          SYS GFXLIB_DrawFilledCircle%, g{}, disc{(I%)}.x, disc{(I%)}.y, disc{(I%)}.r, disc{(I%)}.rgb
          IF disc{(I%)}.move% THEN
            disc{(I%)}.x += disc{(I%)}.dx
            disc{(I%)}.y += disc{(I%)}.dy
            IF (disc{(I%)}.x - disc{(I%)}.x2)^2 +  (disc{(I%)}.y - disc{(I%)}.y2)^2 < 0.5^2 THEN
              disc{(I%)}.move% = FALSE
            ENDIF
          ENDIF
        NEXT I%
        SYS GFXLIB_RestoreDispVars%, g{}
  
        REM If it's time to move the discs, then set new target positions:
        IF TIME > moveDiscsTime% THEN
          FOR I% = 0 TO nDiscs%-1
            disc{(I%)}.move% = TRUE
            disc{(I%)}.x2 = RND(ScrW%)
            disc{(I%)}.y2 = RND(ScrH%)
            dx = disc{(I%)}.x2 - disc{(I%)}.x
            dy = disc{(I%)}.y2 - disc{(I%)}.y
            len = SQR( dx^2 + dy^2 )
            disc{(I%)}.dx = dx / len
            disc{(I%)}.dy = dy / len
          NEXT I%
          moveDiscsTime% = TIME + 1000 + RND(1000)
        ENDIF
  
        REM Draw the rotating disc image bitmap:
        SYS GFXLIB_BPlotRotateScale2%, g{}, img%, imgSz%, imgSz%, ScrW%/2, ScrH%/2, &10000*angle, &10000
  
        REM Draw the equilateral triangle mask bitmap:
        SYS GFXLIB_Plot%, g{}, maskBm%, maskSz%, maskSz%, (ScrW%-maskSz%)/2, ScrH%/2
  
        REM Copy mask bitmap to a temp buffer (bm1%):
        SYS GFXLIB_SaveAndSetDispVars%, g2{}, bm1%, bm1Sz%, bm1Sz%
        SYS GFXLIB_Copy%, g{}, g2.bmBuffAddr%, g2.bmBuffW%, g2.bmBuffH%, (ScrW%-maskSz%)/2, ScrH%/2
        SYS GFXLIB_RestoreDispVars%, g2{}
  
        REM Replace the grey masking colour with black:
        SYS GFXLIB_ReplaceColour%, bm1%, bm1Sz%, bm1Sz%, &808080, &000000
  
        REM Copy a vertically flipped version of bm1 into bm2:
        SYS GFXLIB_SaveAndSetDispVars%, g{}, bm2%, bm2Sz%, bm2Sz%
        SYS GFXLIB_BPlotFlip%, g{}, bm1%, bm1Sz%, bm1Sz%, 0, 0, 1
        SYS GFXLIB_RestoreDispVars%, g{}
  
        REM Clear the window (actually fill it with a colour gradient):
        SYS GFXLIB_ClrLG%, g{}, &208020, &202080
  
        REM Draw top thee equilateral triangle bitmaps:
        SYS GFXLIB_Plot%, g{}, bm1%, bm1Sz%, bm1Sz%, (ScrW%-maskSz%)/2, ScrH%/2
        SYS GFXLIB_PlotRotateScale2%, g{}, bm2%, bm2Sz%, bm2Sz%, ScrW%/2+108, ScrH%/2+65, 60*&10000, &10000
        SYS GFXLIB_PlotRotateScale2%, g{}, bm2%, bm2Sz%, bm2Sz%, ScrW%/2-109, ScrH%/2+65,-60*&10000, &10000
  
        REM Draw the bottom three:
        SYS GFXLIB_PlotFlip%, g{}, bm1%, bm1Sz%, bm1Sz%, (ScrW%-maskSz%)/2, 5, 2
        SYS GFXLIB_PlotRotateScale2%, g{}, bm1%, bm1Sz%, bm1Sz%, ScrW%/2+108, ScrH%/2-60, (180-60)*&10000, &10000
        SYS GFXLIB_PlotRotateScale2%, g{}, bm1%, bm1Sz%, bm1Sz%, ScrW%/2-109, ScrH%/2-60, (180+60)*&10000, &10000
  
        REM Draw enclosing hexagon:
        FOR R% = 256 TO 258
          FOR I% = 0 TO 5
            x1 = 319 + R%*COSRAD(60 * I%)
            y1 = 258 + R%*SINRAD(60 * I%)
            x2 = 319 + R%*COSRAD(60 * (I%+1))
            y2 = 258 + R%*SINRAD(60 * (I%+1))
            SYS GFXLIB_Line%, g{}, x1, y1, x2, y2, &000001
          NEXT I%
        NEXT R%
  
        PROCdisplay
  
      UNTIL FALSE

Perhaps a BBCSDL user (other than Richard for once!) could take up the challenge of doing a cross-platform version of this little graphical ditty? :)
RichardRussell

Re: tech demo

Post by RichardRussell »

David Williams wrote: Sat 14 Dec 2019, 05:43Perhaps a BBCSDL user (other than Richard for once!) could take up the challenge of doing a cross-platform version of this little graphical ditty? :)
Whilst I would be delighted, to say the least, if somebody else was indeed able to convert it to run in BBCSDL (on all platforms), I think we both know that is highly unlikely at this stage. Hopefully it will happen one day, when a few more people have gained experience of the SDL2 API, but not now. But who knows, maybe somebody is going to prove me wrong. :o

So if you don't want me to publish a conversion that's fine, but I don't think it's reasonable to expect me not to do it for my own satisfaction.
David Williams

Re: tech demo

Post by David Williams »

RichardRussell wrote: Sat 14 Dec 2019, 18:30 So if you don't want me to publish a conversion that's fine, but I don't think it's reasonable to expect me not to do it for my own satisfaction.
I had no such expectation (just for the record). Go ahead and publish your BBCSDL conversion whenever you're ready. :)


David.
--
RichardRussell

Re: tech demo

Post by RichardRussell »

David Williams wrote: Sun 15 Dec 2019, 03:14Go ahead and publish your BBCSDL conversion whenever you're ready. :)
OK (listing below). It's actually slightly easier using SDL2 (no need for the bm2 bitmap), principally because there's a function (SDL_RenderCopyEx) which can both rotate and flip, which means it's ideally suited to drawing the six triangular segments of the hexagon without an extra step. I've also done everything anti-aliased (including the triangular mask), because I could, and in this application it's nice to achieve 'perfect' symmetry. The speed is impacted somewhat, so you may want to reduce the number of discs on a slow machine.

Note that it needs SDL 2.0.6 or later (because of the use of a custom blend mode for masking) so currently won't run on the Android edition of BBCSDL, which is only 2.0.5.

https://www.youtube.com/watch?v=yCJnZurpTKw

Code: Select all

      REM Semi-Realistic Kaleidoscope
      REM By Richard Russell, http://www.rtrussell.co.uk/
      REM Adapted from an original program by David Williams
      REM Requires BBC BASIC for SDL 2.0 and SDL 2.0.6 or later

      *ESC OFF

      MODE 8 : OFF

      ScrW% = 640
      ScrH% = 512

      ON ERROR PROCcleanup : MODE 3 : PRINT REPORT$ " at line "; ERL : END
      ON CLOSE PROCcleanup : QUIT
      ON MOVE PROCresize(@msg%, @lparam%) : RETURN

      SDL_BLENDMODE_NONE = 0
      SDL_BLENDMODE_BLEND = 1
      SDL_TEXTUREACCESS_TARGET = 2
      SDL_BLENDFACTOR_ZERO = 1
      SDL_BLENDFACTOR_ONE = 2
      SDL_BLENDFACTOR_DST_ALPHA = 9
      SDL_BLENDOPERATION_ADD = 1
      CASE @platform% AND &F OF
        WHEN 0,1,2: PIXELFORMAT = &16362004 : REM ARGB8888
        WHEN 3,4:   PIXELFORMAT = &16762004 : REM ABGR8888
      ENDCASE

      INSTALL @lib$ + "aagfxlib"

      nDiscs% = 100
      DIM disc{( nDiscs%-1 ) move%, x, y, r, x2, y2, dx, dy, rgb}
      DIM rect{ x%, y%, w%, h% }, maskx(2), masky(2)

      SYS "SDL_SetHint", "SDL_RENDER_SCALE_QUALITY", "linear"
      SYS "SDL_ComposeCustomBlendMode", SDL_BLENDFACTOR_ONE, SDL_BLENDFACTOR_ZERO, SDL_BLENDOPERATION_ADD, \
      \   SDL_BLENDFACTOR_DST_ALPHA, SDL_BLENDFACTOR_ZERO, SDL_BLENDOPERATION_ADD TO BlendMode%

      imgSz% = 512
      SYS "SDL_CreateTexture", @memhdc%, PIXELFORMAT, SDL_TEXTUREACCESS_TARGET, imgSz%, imgSz% TO img%%
      SYS "SDL_SetTextureBlendMode", img%%, BlendMode% TO result%
      IF result% ERROR 100, "Custom Blend Mode not supported"

      bm1Sz% = 512
      SYS "SDL_CreateTexture", @memhdc%, PIXELFORMAT, SDL_TEXTUREACCESS_TARGET, bm1Sz%, bm1Sz% TO bm1%%
      SYS "SDL_SetTextureBlendMode", bm1%%, SDL_BLENDMODE_BLEND

      maskSz% = 512
      SYS "SDL_CreateTexture", @memhdc%, PIXELFORMAT, SDL_TEXTUREACCESS_TARGET, maskSz%, maskSz% TO mask%%
      SYS "SDL_SetTextureBlendMode", mask%%, SDL_BLENDMODE_NONE

      SYS "SDL_CreateTexture", @memhdc%, PIXELFORMAT, SDL_TEXTUREACCESS_TARGET, 1, 2 TO gradient%%
      SYS "SDL_SetHint", "SDL_RENDER_SCALE_QUALITY", "nearest"

      REM Create special textures:
      SYS "SDL_GetRenderTarget", @memhdc% TO target%%
      ON ERROR LOCAL IF FALSE THEN
        REM Create equilateral triangle mask texture:
        SYS "SDL_SetRenderTarget", @memhdc%, mask%%
        SYS "SDL_SetRenderDrawColor", @memhdc%, 0, 0, 0, 0
        SYS "SDL_RenderClear", @memhdc%
        maskx() = maskSz%, maskSz% - 512*SINRAD30, maskSz% + 512*SINRAD30
        masky() = maskSz%, maskSz% - 512*COSRAD30, maskSz% - 512*COSRAD30
        PROC_aapolygon(3, maskx(), masky(), &FF000000)
        REM Create two-pixel texture (for background gradient):
        SYS "SDL_SetRenderTarget", @memhdc%, gradient%%
        SYS "SDL_SetRenderDrawColor", @memhdc%, &20, &80, &20, &FF
        SYS "SDL_RenderClear", @memhdc%
        SYS "SDL_SetRenderDrawColor", @memhdc%, &20, &20, &80, &FF
        SYS "SDL_RenderDrawPoint", @memhdc%, 0, 0
      ELSE
        SYS "SDL_SetRenderTarget", @memhdc%, target%%
        RESTORE ERROR : ERROR ERR, REPORT$
      ENDIF : RESTORE ERROR
      SYS "SDL_SetRenderTarget", @memhdc%, target%%

      REM Initialise discs:
      FOR I% = 0 TO nDiscs%-1
        disc{(I%)}.move% = FALSE
        disc{(I%)}.x = 2*RND(imgSz%) - imgSz%
        disc{(I%)}.y = 2*RND(imgSz%) - imgSz%
        disc{(I%)}.r = 16 + RND(40)
        CASE RND(12) OF
          WHEN  1 : disc{(I%)}.rgb = &FFFF0000
          WHEN  2 : disc{(I%)}.rgb = &FF00FF00
          WHEN  3 : disc{(I%)}.rgb = &FF0000FF
          WHEN  4 : disc{(I%)}.rgb = &FFFF00FF
          WHEN  5 : disc{(I%)}.rgb = &FFFFFF00
          WHEN  6 : disc{(I%)}.rgb = &FF00FFFF
          WHEN  7 : disc{(I%)}.rgb = &FFFF8000
          WHEN  8 : disc{(I%)}.rgb = &FF0080FF
          WHEN  9 : disc{(I%)}.rgb = &FF00FF80
          WHEN 10 : disc{(I%)}.rgb = &FF80FF00
          WHEN 11 : disc{(I%)}.rgb = &FF8080FF
          WHEN 12 : disc{(I%)}.rgb = &FFFFFFFF
        ENDCASE
      NEXT I%

      TIME = 0

      moveDiscsTime% = 500

      *REFRESH OFF

      REPEAT

        T% = TIME

        REM Rotational angle# of discs texture:
        angle# = 720*SIN(T%/1000 + PI/5*SIN(T%/1050+0.345))*SIN(T%/950 + PI/8*SIN(T%/800-1.25))

        REM Draw discs and update their positions:
        SYS "SDL_GetRenderTarget", @memhdc% TO target%%
        ON ERROR LOCAL IF FALSE THEN
          SYS "SDL_SetRenderTarget", @memhdc%, img%%
          SYS "SDL_SetRenderDrawColor", @memhdc%, 0, 0, 0, 0
          SYS "SDL_RenderClear", @memhdc%
          FOR I% = 0 TO nDiscs%-1
            x = imgSz% + disc{(I%)}.x * COSRADangle# + disc{(I%)}.y * SINRADangle#
            y = imgSz% + disc{(I%)}.x * SINRADangle# - disc{(I%)}.y * COSRADangle#
            r = disc{(I%)}.r : w = 256
            IF y - r < imgSz% IF x + r > imgSz% - w IF x - r < imgSz% + w THEN
              PROC_aasector(x, y, r+3, r+3, 0, 360, &FF000000)
              PROC_aasector(x, y, r, r, 0, 360, disc{(I%)}.rgb)
            ENDIF
            IF disc{(I%)}.move% THEN
              disc{(I%)}.x += disc{(I%)}.dx
              disc{(I%)}.y += disc{(I%)}.dy
              IF (disc{(I%)}.x - disc{(I%)}.x2)^2 +  (disc{(I%)}.y - disc{(I%)}.y2)^2 < 0.5^2 THEN
                disc{(I%)}.move% = FALSE
              ENDIF
            ENDIF
          NEXT I%
          REM Mask using equilateral triangle mask texture:
          SYS "SDL_SetRenderTarget", @memhdc%, bm1%%
          SYS "SDL_SetRenderDrawColor", @memhdc%, 0, 0, 0, 0
          SYS "SDL_RenderClear", @memhdc%
          SYS "SDL_RenderCopy", @memhdc%, mask%%, FALSE, FALSE
          SYS "SDL_RenderCopy", @memhdc%, img%%, FALSE, FALSE
        ELSE
          SYS "SDL_SetRenderTarget", @memhdc%, target%%
          RESTORE ERROR : ERROR ERR, REPORT$
        ENDIF : RESTORE ERROR
        SYS "SDL_SetRenderTarget", @memhdc%, target%%

        REM If it's time to move the discs, then set new target positions:
        IF TIME > moveDiscsTime% THEN
          FOR I% = 0 TO nDiscs%-1
            disc{(I%)}.move% = TRUE
            disc{(I%)}.x2 = 2*RND(imgSz%) - imgSz%
            disc{(I%)}.y2 = 2*RND(imgSz%) - imgSz%
            dx = disc{(I%)}.x2 - disc{(I%)}.x
            dy = disc{(I%)}.y2 - disc{(I%)}.y
            dist = SQR( dx^2 + dy^2 )
            disc{(I%)}.dx = dx / dist
            disc{(I%)}.dy = dy / dist
          NEXT I%
          moveDiscsTime% = TIME + 1000 + RND(1000)
        ENDIF

        REM Clear the window (actually fill it with a colour gradient):
        rect.w% = ScrW%
        rect.h% = ScrH%
        rect.x% = 0
        rect.y% = 0
        SYS "SDL_RenderCopy", @memhdc%, gradient%%, FALSE, rect{}

        REM Draw six equilateral triangle textures:
        rect.w% = bm1Sz%
        rect.h% = bm1Sz%
        rect.x% = ScrW% DIV 2 - rect.w% DIV 2
        rect.y% = ScrH% DIV 2 - rect.h% DIV 2
        SYS "SDL_RenderCopy", @memhdc%, bm1%%, FALSE, rect{}

        angle# = 0
        IF @platform% AND &40 THEN
          IF angle#=0 ?(^angle#+7)=&80
          SYS "SDL_RenderCopyEx", @memhdc%, bm1%%, FALSE, rect{}, angle#, FALSE, 2
        ELSE
          SYS "SDL_RenderCopyEx", @memhdc%, bm1%%, FALSE, rect{}, !^angle#, !(^angle#+4), FALSE, 2
        ENDIF

        angle# = +60
        IF @platform% AND &40 THEN
          IF angle#=0 ?(^angle#+7)=&80
          SYS "SDL_RenderCopyEx", @memhdc%, bm1%%, FALSE, rect{}, angle#, FALSE, 3
        ELSE
          SYS "SDL_RenderCopyEx", @memhdc%, bm1%%, FALSE, rect{}, !^angle#, !(^angle#+4), FALSE, 3
        ENDIF

        angle# = -60
        IF @platform% AND &40 THEN
          IF angle#=0 ?(^angle#+7)=&80
          SYS "SDL_RenderCopyEx", @memhdc%, bm1%%, FALSE, rect{}, angle#, FALSE, 3
        ELSE
          SYS "SDL_RenderCopyEx", @memhdc%, bm1%%, FALSE, rect{}, !^angle#, !(^angle#+4), FALSE, 3
        ENDIF

        angle# = +60
        IF @platform% AND &40 THEN
          IF angle#=0 ?(^angle#+7)=&80
          SYS "SDL_RenderCopyEx", @memhdc%, bm1%%, FALSE, rect{}, angle#, FALSE, 1
        ELSE
          SYS "SDL_RenderCopyEx", @memhdc%, bm1%%, FALSE, rect{}, !^angle#, !(^angle#+4), FALSE, 1
        ENDIF

        angle# = -60
        IF @platform% AND &40 THEN
          IF angle#=0 ?(^angle#+7)=&80
          SYS "SDL_RenderCopyEx", @memhdc%, bm1%%, FALSE, rect{}, angle#, FALSE, 1
        ELSE
          SYS "SDL_RenderCopyEx", @memhdc%, bm1%%, FALSE, rect{}, !^angle#, !(^angle#+4), FALSE, 1
        ENDIF

        REM Draw enclosing hexagon:
        R% = 512
        FOR I% = 0 TO 5
          x1 = ScrW% + R%*COSRAD(60 * I%)
          y1 = ScrH% + R%*SINRAD(60 * I%)
          x2 = ScrW% + R%*COSRAD(60 * (I%+1))
          y2 = ScrH% + R%*SINRAD(60 * (I%+1))
          PROC_aaline(x1, y1, x2, y2, 4, &FF000000, 0)
        NEXT I%

        *REFRESH

      UNTIL FALSE
      END

      DEF PROCcleanup
      *REFRESH ON
      gradient%% += 0 : IF gradient%% SYS "SDL_DestroyTexture", gradient%%, @memhdc% : gradient%% = 0
      mask%% += 0     : IF mask%%     SYS "SDL_DestroyTexture", mask%%, @memhdc%     : mask%% = 0
      bm1%% += 0      : IF bm1%%      SYS "SDL_DestroyTexture", bm1%%, @memhdc%      : bm1%% = 0
      img%% += 0      : IF img%%      SYS "SDL_DestroyTexture", img%%, @memhdc%      : img%% = 0
      ENDPROC

      DEF PROCresize(M%, L%) IF M% <> 5 ENDPROC
      LOCAL W%, H%
      W% = L% AND &FFFF
      H% = L% >>> 16
      IF W%/H% > ScrW%/ScrH% THEN
        @zoom% = &8000 * H% / ScrH%
      ELSE
        @zoom% = &8000 * W% / ScrW%
      ENDIF
      IF @zoom% < &8000 @zoom% = &8000
      IF (@platform% AND 7) < 3 THEN
        @panx% = (ScrW% - W% * &8000 / @zoom%) / 2
        @pany% = (ScrH% - H% * &8000 / @zoom%) / 2
      ENDIF
      ENDPROC
David Williams

Re: tech demo

Post by David Williams »

RichardRussell wrote: Sun 15 Dec 2019, 10:48
David Williams wrote: Sun 15 Dec 2019, 03:14Go ahead and publish your BBCSDL conversion whenever you're ready. :)
OK (listing below).
Thanks, Richard. It runs well and looks nice on the 3 systems I ran it on (Windows, Linux Mint & Ubuntu, and a Raspberry Pi 4).

Here's some shaky hand-held video of the program running under Raspbian Buster on a Raspberry Pi 4:

https://www.youtube.com/watch?v=I9u9M7KHVgA
RichardRussell

Re: tech demo

Post by RichardRussell »

David Williams wrote: Sun 15 Dec 2019, 19:03 Here's some shaky hand-held video of the program running under Raspbian Buster on a Raspberry Pi 4:
Looks like it's managing a respectable frame rate too, which I wouldn't have expected. The program's a good test of the accuracy of aagfxlib's antialiased triangle plotting, and SDL's rotation and flipping. The fact that the 'joins' between the six segments (which are the 'overlap' of the two antialiased edges, theoretically 0.5 * 0.5 = 0.25 amplitude) are so thin and uniform shows that everything is remarkably precise, to a small fraction of a pixel! :o