Author Topic: ScriptBasic GFX  (Read 18492 times)

Support

  • Administrator
  • *****
  • Posts: 1
    • View Profile
ScriptBasic GFX
« on: February 25, 2014, 11:26:29 pm »
I have created a ScriptBasic extension module from the SDL_gfx library. Attached are the binary and examples for Ubuntu 64 bit and Windows 32 bit. This version is primary for testing the SDL_gfx interface. It only supports the main screen surface at this time. The next installment will have a surface management system which any function can act upon. This will be the lead-in to sprites. The current source to the ScriptBasic GFX extension module is on the C BASIC Bitbucket Repository and can be built using the ScriptBasic 2.1 header files. SDL 1.2 installed is a prerequisite.



' ScriptBasic GFX - Alpha Circles

IMPORT gfx.inc

scrn = gfx::Window(640, 480, "ScriptBasic GFX - Alpha Circles")
' Random Value Arrays
RANDOMIZE(gfx::Time())
FOR i = 0 TO 512
  rx[i] = RND() % 640
  ry[i] = 60 + RND() % 480 - 80
  rz[i] = RND() % 64
  rr[i] = RND() AND  255
  rg[i] = RND() AND  255
  rb[i] = RND() AND  255
  af = rx[i] / 640
  ra[i] = INT(255 * af)
NEXT

ts = gfx::Time()
FOR i = 0 TO 512
  gfx::filledCircleRGBA scrn, rx[i], ry[i], rz[i], rr[i], rg[i], rb[i], ra[i]
NEXT
te = gfx::Time()
gfx::stringColor scrn, 20, 15, "Time: " & FORMAT("%.4f",(te-ts)/1000) & " Seconds." & CHR(0), 0xffffffff
gfx::Update
WHILE gfx::KeyName(1) <> "+escape"
WEND
gfx::Close
 


' ScriptBasic GFX - Alpha Thick Line

IMPORT gfx.inc

scrn = gfx::Window(640, 480, "ScriptBasic GFX - Alpha Thick Line")
' Random Value Arrays
RANDOMIZE(gfx::Time())
FOR i = 0 TO 512
  rx[i] = RND() % 640
  ry[i] = 60 + RND() % 480 - 80
  lw[i] = 2 + RND() % 7
  rr[i] = RND() AND  255
  rg[i] = RND() AND  255
  rb[i] = RND() AND  255
  af = rx[i] / 640
  ra[i] = INT(255 * af)
NEXT
ts = gfx::Time()
FOR i = 0 TO 512 STEP 5
  gfx::thickLineRGBA scrn, rx[i], ry[i], rx[i+1], ry[i+1], lw[i], rr[i], rg[i], rb[i], ra[i]
NEXT
te = gfx::Time()
gfx::stringColor scrn, 20, 15,"Time: " & FORMAT("%.4f",(te-ts)/1000) & " Seconds." & CHR(0), 0xffffffff
gfx::Update
WHILE gfx::KeyName(1) <> "+escape"
WEND
gfx::Close
 



' ScriptBasic GFX - Alpha Bezier Curve

IMPORT gfx.inc

' Random Value Arrays
scrn = gfx::Window(640, 480, "ScriptBasic GFX - Alpha Bezier")
RANDOMIZE(gfx::Time())
FOR i = 0 TO 512
  rx[i] = RND() % 640/2
  rxx[i] = 640/2 + rx[i]  
  ry[i] = 60 + RND() % 480 - 80
  lw[i] = 2 + RND() % 7
  rr[i] = RND() AND  255
  rg[i] = RND() AND  255
  rb[i] = RND() AND  255
  af = rx[i] / 640
  ra[i] = INT(255 * af)
NEXT
ts = gfx::Time()
FOR i = 0 TO 512-3 STEP 3
  a1[0] = rxx[i]
  a1[1] = rxx[i + 1]
  a1[2] = rxx[i + 2]
  a2[0] = ry[i]
  a2[1] = ry[i + 1]
  a2[2] = ry[i + 2]
  gfx::bezierRGBA scrn, a1, a2, 3, 100, rr[i], rg[i], rb[i], ra[i]
NEXT
te = gfx::Time()
gfx::stringColor scrn, 20, 15,"Time: " & FORMAT("%.4f",(te-ts)/1000) & " Seconds." & CHR(0), 0xffffffff
gfx::Update
WHILE gfx::KeyName(1) <> "+escape"
WEND
gfx::Close
 


' ScriptBasic GFX - Alpha Polygon

IMPORT gfx.inc

' Random Value Arrays
scrn = gfx::Window(640, 480, "ScriptBasic GFX - Alpha Polygon")
RANDOMIZE(gfx::Time())
FOR i = 0 TO 512
  rx[i] = RND() % 640/2
  rxx[i] = 640/2 + rx[i]  
  ry[i] = 60 + RND() % 480 - 80
  lw[i] = 2 + RND() % 7
  rr[i] = RND() AND  255
  rg[i] = RND() AND  255
  rb[i] = RND() AND  255
  af = rx[i] / 640
  ra[i] = INT(255 * af)
NEXT
ts = gfx::Time()
FOR i = 0 TO 128-5 STEP 5
  a1[0] = rxx[i]
  a1[1] = rxx[i + 1]
  a1[2] = rxx[i + 2]
  a1[3] = rxx[i + 3]
  a1[4] = rxx[i + 4]    
  a2[0] = ry[i]
  a2[1] = ry[i + 1]
  a2[2] = ry[i + 2]
  a2[3] = ry[i + 3]
  a2[4] = ry[i + 4]    
  gfx::polygonRGBA scrn, a1, a2, 5, rr[i], rg[i], rb[i], 255
NEXT
te = gfx::Time()
gfx::stringColor scrn, 20, 15,"Time: " & FORMAT("%.4f",(te-ts)/1000) & " Seconds." & CHR(0), 0xffffffff
gfx::Update
WHILE gfx::KeyName(1) <> "-escape"
WEND
gfx::Close
 


' ScriptBasic GFX - Textured Polygon

IMPORT gfx.inc

scrn = gfx::Window(640, 480, "ScriptBasic GFX - Texured Polygon")
a1[0] = 640/4
a1[1] = 640/2
a1[2] = a1[0] + a1[1]
a2[0] = 480/4*3
a2[1] = 480/4
a2[2] = a2[0]
gfx::texturedPolygon scrn, a1, a2, 3, "texture.bmp", 0, 0
gfx::Update
WHILE gfx::KeyName(1) <> "+escape"
WEND
gfx::Close
 


' ScriptBasic GFX - Fonts & Rotation

IMPORT gfx.inc
DECLARE SUB LoadFont ALIAS "loadstring" LIB "t"

font_5x7 = LoadFont("Fonts/5x7.fnt")
font_6x10 = LoadFont("Fonts/6x10.fnt")
font_7x13 = LoadFont("Fonts/7x13.fnt")
font_9x15 = LoadFont("Fonts/9x15.fnt")
font_10x20 = LoadFont("Fonts/10x20.fnt")

scrn = gfx::Window(640, 480, "ScriptBasic GFX - Font & Rotation")
gfx::FontRotation 0
gfx::SetFont font_5x7, 5, 7
gfx::stringColor scrn, 20, 20,"Font 5x7" & CHR(0), 0xffffffff
gfx::SetFont font_6x10, 6, 10
gfx::stringColor scrn, 20, 30,"Font 6x10" & CHR(0), 0xffffffff
gfx::SetFont font_7x13, 7, 13
gfx::stringColor scrn, 20, 40,"Font 7x13" & CHR(0), 0xffffffff
gfx::SetFont font_9x15, 9, 15
gfx::stringColor scrn, 20, 55,"Font 9x15" & CHR(0), 0xffffffff
gfx::SetFont font_10x20, 10, 20
gfx::FontRotation 2
gfx::stringColor scrn, 110, 70,"Font 10x20" & CHR(0), 0xffffffff
gfx::Update
WHILE gfx::KeyName(1) <> "+escape"
WEND
gfx::Close
 


' ScriptBasic GFX - Frame rate controlled circles

IMPORT gfx.inc

scrn = gfx::Window(640, 480, "ScriptBasic GFX - FPS Circles")
' Random Value Arrays
RANDOMIZE(gfx::Time())
FOR i = 0 TO 512
  rx[i] = RND() % 640
  ry[i] = 60 + RND() % 480 - 80
  rz[i] = RND() % 64
  rr[i] = RND() AND  255
  rg[i] = RND() AND  255
  rb[i] = RND() AND  255
  af = rx[i] / 640
  ra[i] = INT(255 * af)
NEXT
gfx::SDL_initFramerate
i = 0
REPEAT
  gfx::filledCircleRGBA scrn, rx[i], ry[i], rz[i], rr[i], rg[i], rb[i], 255
  i += 1
  IF i > 512 THEN i = 0
  gfx::Update
  gfx::SDL_framerateDelay
  gfx::stringColor scrn, 20, 15,"FPS: " & gfx::SDL_getFramerate() & CHR(0), 0xffffffff  
UNTIL gfx::KeyName(0) = "+escape"
gfx::Close
 


' ScriptBasic GFX - Alpha Pie

IMPORT gfx.inc

scrn = gfx::Window(640, 480, "ScriptBasic GFX - Alpha Pie")
' Random Value Arrays
RANDOMIZE(gfx::Time())
FOR i = 0 TO 512
  rx[i] = RND() % 640
  ry[i] = 60 + RND() % 480 - 80
  rz[i] = RND() % 100
  a1[i] = RND() % 360
  a2[i] = RND() % 360
  rr[i] = RND() AND  255
  rg[i] = RND() AND  255
  rb[i] = RND() AND  255
  af = rx[i] / 640
  ra[i] = INT(255 * af)
NEXT
ts = gfx::Time()
FOR i = 0 TO 512 STEP 2
  gfx::filledPieRGBA scrn, rx[i], ry[i], rz[i], a1[i], a2[i], rr[i], rg[i], rb[i], ra[i]
NEXT  
te = gfx::Time()
gfx::stringColor scrn, 20, 15,"Time: " & FORMAT("%.4f",(te-ts)/1000) & " Seconds." & CHR(0), 0xffffffff
gfx::Update scrn
WHILE gfx::KeyName(1) <> "+escape"
WEND
gfx::Close
 
I created a gfx.inc module IMPORT file for the ScriptBasic GFX extension module.

MODULE GFX

DECLARE SUB    ::Window                    ALIAS     "gfx_Window"                    LIB  "gfx"
DECLARE SUB    ::Close                     ALIAS     "gfx_Close"                     LIB  "gfx"
DECLARE SUB    ::Update                    ALIAS     "gfx_Update"                    LIB  "gfx"
DECLARE SUB    ::ClearScreen               ALIAS     "gfx_ClearScreen"               LIB  "gfx"
DECLARE SUB    ::SDL_SetClipRect           ALIAS     "gfx_SDL_SetClipRect"           LIB  "gfx"
DECLARE SUB    ::Time                      ALIAS     "gfx_Time"                      LIB  "gfx"
DECLARE SUB    ::Shift                     ALIAS     "gfx_Shift"                     LIB  "gfx"
DECLARE SUB    ::Rotate                    ALIAS     "gfx_Rotate"                    LIB  "gfx"
DECLARE SUB    ::GetKey                    ALIAS     "gfx_GetKey"                    LIB  "gfx"
DECLARE SUB    ::WaitKey                   ALIAS     "gfx_WaitKey"                   LIB  "gfx"
DECLARE SUB    ::KeyName                   ALIAS     "gfx_KeyName"                   LIB  "gfx"
DECLARE SUB    ::Mouse                     ALIAS     "gfx_Mouse"                     LIB  "gfx"
DECLARE SUB    ::pixelColor                ALIAS     "gfx_pixelColor"                LIB  "gfx"
DECLARE SUB    ::pixelRGBA                 ALIAS     "gfx_pixelRGBA"                 LIB  "gfx"
DECLARE SUB    ::hlineColor                ALIAS     "gfx_hlineColor"                LIB  "gfx"
DECLARE SUB    ::hlineRGBA                 ALIAS     "gfx_hlineRGBA"                 LIB  "gfx"
DECLARE SUB    ::vlineColor                ALIAS     "gfx_vlineColor"                LIB  "gfx"
DECLARE SUB    ::vlineRGBA                 ALIAS     "gfx_vlineRGBA"                 LIB  "gfx"
DECLARE SUB    ::rectangleColor            ALIAS     "gfx_rectangleColor"            LIB  "gfx"
DECLARE SUB    ::rectangleRGBA             ALIAS     "gfx_rectangleRGBA"             LIB  "gfx"
DECLARE SUB    ::roundedRectangleColor     ALIAS     "gfx_roundedRectangleColor"     LIB  "gfx"
DECLARE SUB    ::roundedRectangleRGBA      ALIAS     "gfx_roundedRectangleRGBA"      LIB  "gfx"
DECLARE SUB    ::boxColor                  ALIAS     "gfx_boxColor"                  LIB  "gfx"
DECLARE SUB    ::boxRGBA                   ALIAS     "gfx_boxRGBA"                   LIB  "gfx"
DECLARE SUB    ::roundedBoxColor           ALIAS     "gfx_roundedBoxColor"           LIB  "gfx"
DECLARE SUB    ::roundedBoxRGBA            ALIAS     "gfx_roundedBoxRGBA"            LIB  "gfx"
DECLARE SUB    ::lineColor                 ALIAS     "gfx_lineColor"                 LIB  "gfx"
DECLARE SUB    ::lineRGBA                  ALIAS     "gfx_lineRGBA"                  LIB  "gfx"
DECLARE SUB    ::aalineColor               ALIAS     "gfx_aalineColor"               LIB  "gfx"
DECLARE SUB    ::aalineRGBA                ALIAS     "gfx_aalineRGBA"                LIB  "gfx"
DECLARE SUB    ::thickLineColor            ALIAS     "gfx_thickLineColor"            LIB  "gfx"
DECLARE SUB    ::thickLineRGBA             ALIAS     "gfx_thickLineRGBA"             LIB  "gfx"
DECLARE SUB    ::circleColor               ALIAS     "gfx_circleColor"               LIB  "gfx"
DECLARE SUB    ::circleRGBA                ALIAS     "gfx_circleRGBA"                LIB  "gfx"
DECLARE SUB    ::arcColor                  ALIAS     "gfx_arcColor"                  LIB  "gfx"
DECLARE SUB    ::arcRGBA                   ALIAS     "gfx_arcRGBA"                   LIB  "gfx"
DECLARE SUB    ::aacircleColor             ALIAS     "gfx_aacircleColor"             LIB  "gfx"
DECLARE SUB    ::aacircleRGBA              ALIAS     "gfx_aacircleRGBA"              LIB  "gfx"
DECLARE SUB    ::filledCircleColor         ALIAS     "gfx_filledCircleColor"         LIB  "gfx"
DECLARE SUB    ::filledCircleRGBA          ALIAS     "gfx_filledCircleRGBA"          LIB  "gfx"
DECLARE SUB    ::ellipseColor              ALIAS     "gfx_ellipseColor"              LIB  "gfx"
DECLARE SUB    ::ellipseRGBA               ALIAS     "gfx_ellipseRGBA"               LIB  "gfx"
DECLARE SUB    ::aaellipseColor            ALIAS     "gfx_aaellipseColor"            LIB  "gfx"
DECLARE SUB    ::aaellipseRGBA             ALIAS     "gfx_aaellipseRGBA"             LIB  "gfx"
DECLARE SUB    ::filledEllipseColor        ALIAS     "gfx_filledEllipseColor"        LIB  "gfx"
DECLARE SUB    ::filledEllipseRGBA         ALIAS     "gfx_filledEllipseRGBA"         LIB  "gfx"
DECLARE SUB    ::pieColor                  ALIAS     "gfx_pieColor"                  LIB  "gfx"
DECLARE SUB    ::pieRGBA                   ALIAS     "gfx_pieRGBA"                   LIB  "gfx"
DECLARE SUB    ::filledPieColor            ALIAS     "gfx_filledPieColor"            LIB  "gfx"
DECLARE SUB    ::filledPieRGBA             ALIAS     "gfx_filledPieRGBA"             LIB  "gfx"
DECLARE SUB    ::trigonColor               ALIAS     "gfx_trigonColor"               LIB  "gfx"
DECLARE SUB    ::trigonRGBA                ALIAS     "gfx_trigonRGBA"                LIB  "gfx"
DECLARE SUB    ::aatrigonColor             ALIAS     "gfx_aatrigonColor"             LIB  "gfx"
DECLARE SUB    ::aatrigonRGBA              ALIAS     "gfx_aatrigonRGBA"              LIB  "gfx"
DECLARE SUB    ::filledTrigonColor         ALIAS     "gfx_filledTrigonColor"         LIB  "gfx"
DECLARE SUB    ::filledTrigonRGBA          ALIAS     "gfx_filledTrigonRGBA"          LIB  "gfx"
DECLARE SUB    ::polygonColor              ALIAS     "gfx_polygonColor"              LIB  "gfx"
DECLARE SUB    ::polygonRGBA               ALIAS     "gfx_polygonRGBA"               LIB  "gfx"
DECLARE SUB    ::aapolygonColor            ALIAS     "gfx_aapolygonColor"            LIB  "gfx"
DECLARE SUB    ::aapolygonRGBA             ALIAS     "gfx_aapolygonRGBA"             LIB  "gfx"
DECLARE SUB    ::filledPolygonColor        ALIAS     "gfx_filledPolygonColor"        LIB  "gfx"
DECLARE SUB    ::filledPolygonRGBA         ALIAS     "gfx_filledPolygonRGBA"         LIB  "gfx"
DECLARE SUB    ::texturedPolygon           ALIAS     "gfx_texturedPolygon"           LIB  "gfx"
DECLARE SUB    ::bezierColor               ALIAS     "gfx_bezierColor"               LIB  "gfx"
DECLARE SUB    ::bezierRGBA                ALIAS     "gfx_bezierRGBA"                LIB  "gfx"
DECLARE SUB    ::SetFont                   ALIAS     "gfx_SetFont"                   LIB  "gfx"
DECLARE SUB    ::FontRotation              ALIAS     "gfx_FontRotation"              LIB  "gfx"
DECLARE SUB    ::characterColor            ALIAS     "gfx_characterColor"            LIB  "gfx"
DECLARE SUB    ::characterRGBA             ALIAS     "gfx_characterRGBA"             LIB  "gfx"
DECLARE SUB    ::stringColor               ALIAS     "gfx_stringColor"               LIB  "gfx"
DECLARE SUB    ::stringRGBA                ALIAS     "gfx_stringRGBA"                LIB  "gfx"
DECLARE SUB    ::SDL_initFramerate         ALIAS     "gfx_SDL_initFramerate"         LIB  "gfx"
DECLARE SUB    ::SDL_getFramerate          ALIAS     "gfx_SDL_getFramerate"          LIB  "gfx"
DECLARE SUB    ::SDL_setFramerate          ALIAS     "gfx_SDL_setFramerate"          LIB  "gfx"
DECLARE SUB    ::SDL_framerateDelay        ALIAS     "gfx_SDL_framerateDelay"        LIB  "gfx"
DECLARE SUB    ::CreateSurface             ALIAS     "gfx_CreateSurface"             LIB  "gfx"
DECLARE SUB    ::FreeSurface               ALIAS     "gfx_FreeSurface"               LIB  "gfx"
DECLARE SUB    ::BlitSurface               ALIAS     "gfx_BlitSurface"               LIB  "gfx"
DECLARE SUB    ::LoadBMP                   ALIAS     "gfx_LoadBMP"                   LIB  "gfx"

END MODULE
 
The following keyboard and mouse functions are available for polling and waiting for events.

  • gfx_Mouse(0) - Waits for mouse movement and returns X position.
  • gfx_Mouse(1) - Waits for mouse movement and returns Y position.
  • gfx_Mouse(2) - Polls for a mouse button press event and returns.
  • gfx_Mouse(3) - Waits for a mouse button to be pressed then returns.
  • gfx_GetKey(0) - Polls for a key press event and returns a unicode value
  • gfx_GetKey(1) - Waits for a key to be pressed then returns a unicode value
  • gfx_GetKey(2) - Polls for a key press event and returns a keycode value
  • gfx_GetKey(3) - Waits for a key to be pressed then returns a keycode value
  • gfx_GetKey(4) - Polls for a key press event and returns a scancode value
  • gfx_GetKey(5) - Waits for a key to be pressed then returns a scancode value
  • gfx_KeyName(0) - (not new) Polls for key up/down events and returns the key name with a +=dn / -=up prefix
  • gfx_KeyName(1) - (not new) Waits for a key up/down event and returns the key name with a +=dn / -=up prefix
  • gfx_ClearScreen(n) - Clears the screen with the passed (n) color value in the format of 0xRRGGBB



Here is an example of typing abc<left shift hold>ABC<ESC> for each of the gfx_GetKey(n) modes.

UNICODE
jrs@laptop:~/sb/sb22/sdl$ scriba getkey.sb
Unicode: 97 Character: a
Unicode: 98 Character: b
Unicode: 99 Character: c
Unicode: 0 Character:
Unicode: 65 Character: A
Unicode: 66 Character: B
Unicode: 67 Character: C
Unicode: 27 Character: 
jrs@laptop:~/sb/sb22/sdl$

KeyCode
jrs@laptop:~/sb/sb22/sdl$ scriba getkey.sb
Keycode: 97 Character: a
Keycode: 98 Character: b
Keycode: 99 Character: c
Keycode: 304 Character: 0
Keycode: 97 Character: a
Keycode: 98 Character: b
Keycode: 99 Character: c
Keycode: 27 Character: 
jrs@laptop:~/sb/sb22/sdl$

ScanCode
jrs@laptop:~/sb/sb22/sdl$ scriba getkey.sb
Scancode: 38 Character: &
Scancode: 56 Character: 8
Scancode: 54 Character: 6
Scancode: 50 Character: 2
Scancode: 38 Character: &
Scancode: 56 Character: 8
Scancode: 54 Character: 6
Scancode: 9 Character:
jrs@laptop:~/sb/sb22/sdl$

gfx_KeyName (SDL_GetKeyName +keydown | -keyup)
jrs@laptop:~/sb/sb22/sdl$ scriba getkey.sb
Key Name: +a
Key Name: -a
Key Name: +b
Key Name: -b
Key Name: +c
Key Name: -c
Key Name: +left shift
Key Name: +a
Key Name: -a
Key Name: +b
Key Name: -b
Key Name: +c
Key Name: -c
Key Name: -left shift
Key Name: +escape
Key Name: -escape
jrs@laptop:~/sb/sb22/sdl$
« Last Edit: July 27, 2014, 07:39:55 am by support »

Support

  • Administrator
  • *****
  • Posts: 1
    • View Profile
Re: ScriptBasic GFX
« Reply #1 on: March 03, 2014, 03:45:52 am »
I have released the second build of the ScriptBasic GFX extension module. The highlights of this build is that all SDL_gfx drawing functions work with any surface and not just the main viewing screen as in the first release. You can create surfaces, blit them and load .bmp images to surfaces. A frame manager has been added and the main viewing screen is resizeable. I have enable double buffering and hardware assisted surface features. The main difference you will notice from the last version is that most functions require a surface handle. (main screen no longer assumed) I have attached the ScriptBasic GFX extension module binaries and example programs for both Windows 32 bit and Ubuntu 64 bit. Feedback and some contributed examples would be appreciated.


Support

  • Administrator
  • *****
  • Posts: 1
    • View Profile
Re: ScriptBasic GFX
« Reply #2 on: March 07, 2014, 05:04:26 am »
I have added a few more features and fixed an issue with the pixel format mask when returning a pixel color value. The Bitbucket C BASIC site has be updated with the latest source. I should mention that if you're trying to return the alpha channel of a pixel, you need to create a new surface first. I have spent a day trying to research and resolve retrieving alpha channel info from the initial surface created with the window container. Let me know if you find a solution and as always, feedback appreciated!

The following attachments contain only the updated ScriptBasic GFX extension module binary (gfx.so/dll) and the gfx.inc IMPORT file.
« Last Edit: March 07, 2014, 05:09:12 am by support »

Support

  • Administrator
  • *****
  • Posts: 1
    • View Profile
Re: ScriptBasic GFX
« Reply #3 on: March 08, 2014, 11:16:50 am »
Here are a few examples of using the latest version of the ScriptBasic GFX extension module.

     

Note: The image on the right is using an alpha value of 192 instead of 255.

Code: [Select]
'Peter's Pixel Test - SB GFX

IMPORT gfx.inc

vs = gfx::Window(320, 240, "Peter's Pixel Test - SB GFX")
s = gfx::CreateSurface(320, 240, 32)
RANDOMIZE(gfx::Time())
ts = gfx::Time()
FOR y = 0 TO 240
  FOR x = 0 TO 320
    r = RND() AND 255
    g = RND() AND 255
    b = RND() AND 255
    gfx::pixelRGBA s, x, y, r, g, b, 255
  NEXT
NEXT
  gfx::filledCircleColor s, 100, 100, 80, gfx::GetPixel(s, 20, 20)
  gfx::boxColor s, 100, 20, 80, 60, gfx::GetPixel(s, 10, 10)
te = gfx::Time()
gfx::stringColor s, 20, 215,"Time: " & FORMAT("%.4f",(te-ts)/1000) & " Seconds." & CHR(0), 0xffffffff
gfx::BlitSurface s, 0, vs, 0
gfx::Update
WHILE gfx::KeyName(1) <> "+escape"
WEND
gfx::Close



Note: This took 8 1/2 seconds using the ScriptBasic BBC extension module.

Code: [Select]
' ScriptBasic GFX - Fern

IMPORT gfx.inc

s = gfx::Window(640,500,"ScriptBasic GFX Fern")
RANDOMIZE(gfx::Time())

SPLITA STRING(3,"0") BY "" TO xy

Sub Fern
r = RND() % 100
IF r <= 10 THEN
   a = 0
   b = 0
   c = 0
   d = 0.16
   e = 0
   f = 0
ELSE IF r > 1 AND r <=86 THEN
   a = 0.85
   b = 0.04
   c = -.04
   d = 0.85
   e = 0
   f = 1.60
ELSE IF r > 86 AND r <=93 THEN
   a = 0.2
   b = -.26
   c = 0.23
   d = 0.22
   e = 0
   f = 0.16
ELSE
   a = -.15
   b = 0.28
   c = 0.26
   d = 0.24
   e = 0
   f = 0.44
END IF

newx = ((a * xy[1]) + (b * xy[2]) + e)
newy = ((c * xy[1]) + (d * xy[2]) + f)
xy[1] = newx
xy[2] = newy

gfx::pixelRGBA s, INT(xy[1]*40+300), INT(-xy[2]*40+450), 0, 210, 55, 255

END SUB

ts = gfx::Time()
FOR w=1 TO 100000
    Fern
NEXT
te = gfx::Time()
gfx::stringColor s, 20, 15, "Time: " & FORMAT("%.4f",(te-ts)/1000) & " Seconds." & CHR(0), 0xffffffff
gfx::Update
WHILE gfx::KeyName(1) <> "+escape"
WEND
gfx::Close



Code: [Select]
' ScriptBasic GFX - Mandelbrot

IMPORT gfx.inc

s = gfx::Window(640,480,"ScriptBasic GFX Mandelbrot")
ts = gfx::Time()
im = 510
z = 120
h = 480
w = 640
FOR y = 0 TO h - 1
  FOR x = 0 TO w - 1
    zx = 0
    zy = 0
    cx = (x - w / 2) / z
    cy = (y - h / 2) / z
    it = im
    WHILE zx * zx + zy * zy < 4 AND it > 0
      tp = zx * zx - zy * zy + cx
      zy = 2 * zx * zy + cy
      zx = tp
      it -= 1
    WEND
    gfx::PixelRGBA s, x, y, it * 12, it * 8, it * 4, 255
  NEXT
NEXT
te = gfx::Time()
gfx::stringColor s, 20, 15, "Time: " & FORMAT("%.4f",(te-ts)/1000) & " Seconds." & CHR(0), 0x000000ff
gfx::Update
WHILE gfx::KeyName(1) <> "+escape"
WEND
gfx::Close

Support

  • Administrator
  • *****
  • Posts: 1
    • View Profile
Re: ScriptBasic GFX
« Reply #4 on: March 09, 2014, 01:29:01 am »
Here is a Windows example using DLLC as the FFI and JIT virtual share object compiler. The Windows version of the GFX extension module takes about the same time as the Linux version. The Mandelbrot WHILE/WEND loop is an interpreter's nightmare.



Code: [Select]
' ScriptBasic GFX & DLLC - Mandelbrot

include "dllcinc.sb"

oxy = dllfile("/sb22/modules/oxygen.dll")

o2_basic = dllproc( oxy, "o2_basic i =(c*source) " )
o2_exec  = dllproc( oxy, "o2_exec  i =(i call)   " )
o2_error = dllproc( oxy, "o2_error c*=()         " )
o2_errno = dllproc( oxy, "o2_errno i =()         " )
o2_len   = dllproc( oxy, "o2_len   i =()         " )
o2_mode  = dllproc( oxy, "o2_mode     (i mode)   " )

dllcall(o2_mode,1)

src = """
extern

FUNCTION mandel(float cx,cy,sys it) as sys
  float zx,zy,tp
  WHILE zx * zx + zy * zy < 4 AND it > 0
    tp = zx * zx - zy * zy + cx
    zy = 2 * zx * zy + cy
    zx = tp
    it -= 1
  WEND
  return it
END FUNCTION

sub finish()
  terminate
end sub

function link(sys n) as sys
  select n
    case 0
      return @finish
    case 1
      return @mandel
  end select
end function

end extern

addr link
"""

dllcall(o2_basic, src)
dfn = dllcall(o2_exec,0)
mandel = dllproc(dfn,"mandel i = (f zre, f zim, i maxiter)", dllcald(dfn, 1))
finish = dllproc(dfn,"finish ()", dllcald(dfn, 0))

gfx = dllfile("SDL_gfx.dll")
sdl = dllfile("sdl.dll")

SDL_INIT     = dllproc(sdl, "SDL_Init i = (i flags)")
SDL_WINDOW   = dllproc(sdl, "SDL_SetVideoMode i = (i width, i height, i video_bpp, i videoflags)")
SDL_SETALPHA = dllproc(sdl, "SDL_SetAlpha i = (i surface, i flag, i alpha)")
SDL_TITLE    = dllproc(sdl, "SDL_WM_SetCaption (z title, z icon)")
SDL_WAIT     = dllproc(sdl, "SDL_Delay (i millsecs)")
SDL_TIME     = dllproc(sdl, "SDL_GetTicks i = ()")
SDL_CLIPRECT = dllproc(sdl, "SDL_SetClipRect (i surface, i* rect)")
GFX_PIXEL    = dllproc(gfx, "pixelRGBA i = (i surface, i x, i y, i r, i g, i b, i a)")
SDL_FLIP     = dllproc(sdl, "SDL_Flip i = (i screen)")
SDL_CLS      = dllproc(sdl, "SDL_FillRect i = (i surface, i* dstrect, i color)")
GFX_PRINT    = dllproc(gfx, "stringColor i = (i dst, i x, i y, c *s, i color)")
SDL_QUIT     = dllproc(sdl, "SDL_Quit ()")

GLOBAL CONST SDL_INIT_VIDEO = 0x00000020
GLOBAL CONST SDL_SWSURFACE  = 0x00000000
GLOBAL CONST SDL_SRCALPHA   = 0x00010000
GLOBAL CONST SDL_RESIZABLE  = 0x00000010

flags = SDL_SWSURFACE OR SDL_SRCALPHA OR SDL_RESIZABLE

dllcall(SDL_INIT, SDL_INIT_VIDEO)
screen = dllcall(SDL_WINDOW, 640, 480, 0, flags)
ok = dllcall(SDL_SETALPHA, screen, SDL_SRCALPHA, 0)
dllcall(SDL_TITLE, "ScriptBasic GFX & DLLC - Mandelbrot", 0)
' dllcall(SDL_CLS, screen, 0, 0xffffff)
ts = dllcall(SDL_TIME)
im = 510
z = 120
h = 480
w = 640
FOR y = 0 TO h -1
  FOR x = 0 TO w -1
    zx = 0
    zy = 0
    cx = (x - w / 2) / z
    cy = (y - h / 2) / z
    it = dllcall(mandel,cx,cy, im)
    dllcall(GFX_PIXEL, screen, x, y, it * 12, it * 8, it * 4, 255)
  NEXT
NEXT
te = dllcall(SDL_TIME)
dllcall(GFX_PRINT, screen, 20, 15, "Time: " & FORMAT("%.4f",(te-ts)/1000) & " Seconds." & CHR(0), 0x000000FF)
dllcall(SDL_FLIP, screen)
LINE INPUT WAIT
dllcall(SDL_QUIT)

Support

  • Administrator
  • *****
  • Posts: 1
    • View Profile
Re: ScriptBasic GFX
« Reply #5 on: March 09, 2014, 03:17:03 am »
Linux ScriptBasic got jealous.  :)

The Mandelbrot iterator function will be included in the next ScriptBasic GFX extension module build for Linux and Windows.



Code: [Select]
' ScriptBasic GFX - Mandelbrot

IMPORT gfx.inc

s = gfx::Window(640,480,"ScriptBasic GFX Mandelbrot")
ts = gfx::Time()
FOR y = 0 TO 479
  FOR x = 0 TO 639
    cx = (x - 320) / 120
    cy = (y - 240) / 120
    rit = gfx::Mandelbrot(cx, cy, 510)
    gfx::PixelRGBA s, x, y, rit * 12, rit * 8, rit * 4, 255
  NEXT
NEXT
te = gfx::Time()
gfx::stringColor s, 20, 15, "Time: " & FORMAT("%.4f",(te-ts)/1000) & " Seconds." & CHR(0), 0x000000ff
gfx::Update
WHILE gfx::KeyName(1) <> "+escape"
WEND
gfx::Close

interface.c (SB GFX ext. module)
Code: [Select]
besFUNCTION(gfx_Mandelbrot)
  DIM AS double cx, cy, zx, zy, tp;
  DIM AS int iter;
  besARGUMENTS("rri")
    AT cx, AT cy, AT iter
  besARGEND
  DEF_WHILE (zx * zx + zy * zy < 4 AND iter > 0)
  BEGIN_WHILE
    tp = zx * zx - zy * zy + cx;
    zy = 2 * zx * zy + cy;
    zx = tp;
    iter = iter - 1;
  WEND
  besRETURN_LONG(iter);
besEND

Quote
Critical orbits of complex numbers

Graphically speaking, a function of the form f (x) = x2 + c (where c is a complex number) is a special function under iteration.  If you plot the results of the iterations (starting at x = 0) in the complex plane, you obtain what is called the critical orbits of c.  If these critical orbits repeat (where the same point in the complex plane repeats), the complex number is in the Mandelbrot set.  If the critical orbits simply move further and further away from the origin, the complex numbers are not in the Mandelbrot set.
« Last Edit: March 09, 2014, 04:49:09 am by support »