Raspberry BASIC

Author Topic: Nim Introduction  (Read 6234 times)

John Spikowski

  • BASIC Developer
  • ***
  • Posts: 234
    • View Profile
    • ScriptBasic
Nim Introduction
« on: December 07, 2019, 04:25:35 AM »
I was able to get the IUP distribution I built for the RPi and Nim to  work together. A "Hello Nim" of sorts.

Code: Text
  1. import iup
  2.  
  3. proc btn_click(ih:PIhandle):cint {.cdecl.}=
  4.     iup.message("Popup", "You clicked the button!")
  5.  
  6. discard iup.open(nil, nil)
  7.  
  8. var btn = iup.button("Click me!", nil)
  9. discard iup.setCallback(btn, "ACTION", cast[ICallback](btn_click))
  10.  
  11. var dlg = iup.dialog(iup.vbox(btn, nil))
  12. iup.setAttribute(dlg, "TITLE", "iupTabs")
  13.  
  14. discard iup.showXY(dlg, IUP_CENTER, IUP_CENTER)
  15. discard iup.mainLoop()
  16.  
  17. iup.close()
  18.  


pi@RPi4B:~/pui/iup-master/examples $ nim c -d:release callbacks.nim
Hint: used config file '/etc/nim/nim.cfg' [Conf]
Hint: system [Processing]
Hint: callbacks [Processing]
Hint: iup [Processing]
CC: iup_callbacks
CC: stdlib_system
CC: stdlib_iup
Hint:  [Link]
Hint: operation successful (13356 lines compiled; 4.586 sec total; 10.758MiB peakmem; Release Build) [SuccessX]
pi@RPi4B:~/pui/iup-master/examples $ ls -l
total 72
-rwxr-xr-x 1 pi pi 59180 Dec  6 20:17 callbacks
-rw-r--r-- 1 pi pi   413 Nov  4 02:39 callbacks.nim
-rw-r--r-- 1 pi pi   576 Nov  4 02:39 menu.nim
-rw-r--r-- 1 pi pi  1023 Nov  4 02:39 tabs.nim
pi@RPi4B:~/pui/iup-master/examples $ ./callbacks

« Last Edit: December 11, 2019, 08:02:18 AM by John Spikowski »
ScriptBasic Project Manager/Facilitator

John Spikowski

  • BASIC Developer
  • ***
  • Posts: 234
    • View Profile
    • ScriptBasic
Re: Nim Fibo
« Reply #1 on: December 07, 2019, 05:34:13 AM »
A Fibo Nim example for our RPI  forum friends.

Code: Text
  1. import math
  2.  
  3. proc Fibonacci(n: int): int64 =
  4.   var fn = float64(n)
  5.   var p: float64 = (1.0 + sqrt(5.0)) / 2.0
  6.   var q: float64 = 1.0 / p
  7.   return int64((pow(p, fn) + pow(q, fn)) / sqrt(5.0))
  8.  
  9. echo Fibonacci(78)
  10.  


pi@RPi4B:~/nim-dev/examples $ nim c -d:release fibo78.nim
Hint: used config file '/etc/nim/nim.cfg' [Conf]
Hint: system [Processing]
Hint: fibo78 [Processing]
Hint: math [Processing]
Hint: bitops [Processing]
CC: fibo78
CC: stdlib_system
CC: stdlib_math
CC: stdlib_bitops
Hint:  [Link]
Hint: operation successful (13698 lines compiled; 4.051 sec total; 10.754MiB peakmem; Release Build) [SuccessX]
pi@RPi4B:~/nim-dev/examples $ timex ./fibo78
8944394323791488
0.00user 0.00system 0:00.00elapsed 83%CPU (0avgtext+0avgdata 1292maxresident)k
0inputs+0outputs (0major+98minor)pagefaults 0swaps
pi@RPi4B:~/nim-dev/examples $ time ./fibo78
8944394323791488

real   0m0.008s
user   0m0.008s
sys   0m0.001s
pi@RPi4B:~/nim-dev/examples $


There is a GMP extension for Nim that I might give the 1mil fibo a shot with.

Nim GMP

Code: Text
  1. import gmp
  2.  
  3. var
  4.   a,b: mpz_t
  5.  
  6. discard mpz_init_set_str(a.addr,"9999999999999999999999999999999999999999999999999999999999999999999",10)
  7. discard mpz_init_set_str(b.addr,"10000000000000000000000000000000000000000000000000000000000000000000",10)
  8. mpz_add(a.addr,a.addr,b.addr)
  9. echo mpz_get_str(nil,10,a.addr)
  10.  


pi@RPi4B:~/nim-dev/examples $ nim c -d:release bigintadd.nim
Hint: used config file '/etc/nim/nim.cfg' [Conf]
Hint: system [Processing]
Hint: bigintadd [Processing]
Hint: gmp [Processing]
CC: bigintadd
CC: stdlib_system
CC: stdlib_gmp
Hint:  [Link]
Hint: operation successful (13250 lines compiled; 3.834 sec total; 10.766MiB peakmem; Release Build) [SuccessX]
pi@RPi4B:~/nim-dev/examples $ ls -l bigintadd
-rwxr-xr-x 1 pi pi 52240 Dec  6 23:35 bigintadd
pi@RPi4B:~/nim-dev/examples $ ./bigintadd
19999999999999999999999999999999999999999999999999999999999999999999
pi@RPi4B:~/nim-dev/examples $


« Last Edit: December 07, 2019, 07:38:10 AM by John Spikowski »
ScriptBasic Project Manager/Facilitator

John Spikowski

  • BASIC Developer
  • ***
  • Posts: 234
    • View Profile
    • ScriptBasic
Re: Nim SQLite
« Reply #2 on: December 08, 2019, 02:42:34 AM »
This is an example of the SQLite Nim extension.

Code: Text
  1. # Nim SQLite
  2.  
  3. import tiny_sqlite
  4. import options
  5.  
  6. let db = openDatabase("./test.db")
  7.  
  8. db.exec("DROP TABLE IF EXISTS Person")
  9.  
  10. db.execScript("""
  11.   CREATE TABLE Person(
  12.     name TEXT,
  13.     age INTEGER
  14.   );
  15. """)
  16.  
  17. db.exec("""
  18.     INSERT INTO Person(name, age)
  19.     VALUES(?, ?)
  20. """, "John Doe", 55)
  21.  
  22. let rows = db.rows("SELECT name, age FROM Person")
  23. let (name, age) = rows[0].unpack((Option[string], Option[int]))
  24.  
  25. echo "Name: ", name.get
  26. echo " Age: ", age.get
  27.  
  28. db.close
  29.  


pi@RPi4B:~/nim-dev/examples $ nim c -d:release tsql.nim
Hint: used config file '/etc/nim/nim.cfg' [Conf]
Hint: system [Processing]
Hint: tsql [Processing]
Hint: tiny_sqlite [Processing]
Hint: strutils [Processing]
Hint: parseutils [Processing]
Hint: math [Processing]
Hint: bitops [Processing]
Hint: algorithm [Processing]
Hint: unicode [Processing]
Hint: options [Processing]
Hint: typetraits [Processing]
Hint: macros [Processing]
Hint: sqlite_wrapper [Processing]
Hint:  [Link]
Hint: operation successful (22575 lines compiled; 1.740 sec total; 25.605MiB peakmem; Release Build) [SuccessX]
pi@RPi4B:~/nim-dev/examples $ ls -l tsql
-rwxr-xr-x 1 pi pi 88084 Dec  7 20:07 tsql
pi@RPi4B:~/nim-dev/examples $ timex ./tsql
Name: John Doe
 Age: 55
0.00user 0.00system 0:00.05elapsed 32%CPU (0avgtext+0avgdata 2368maxresident)k
0inputs+144outputs (0major+159minor)pagefaults 0swaps
pi@RPi4B:~/nim-dev/examples $

« Last Edit: December 08, 2019, 04:08:56 AM by John Spikowski »
ScriptBasic Project Manager/Facilitator

John Spikowski

  • BASIC Developer
  • ***
  • Posts: 234
    • View Profile
    • ScriptBasic
Re: Nim SDL2 gfx
« Reply #3 on: December 09, 2019, 04:44:06 AM »
An example using  Nim SDL2 gfx primitives.

Code: Text
  1. # ex205_sdl_gfx_primitives.nim
  2. # ============================
  3. # VIDEO / Drawing geometric primitives provided by sdl_gfx_primitives
  4. # -------------------------------------------------------------------
  5.  
  6.  
  7. import
  8.     random,
  9.     sdl2/sdl, sdl2/sdl_image as img,
  10.     sdl2/sdl_gfx_primitives as gfx, sdl2/sdl_gfx_primitives_font as font
  11.  
  12.  
  13. const
  14.   Title = "SDL2 App"
  15.   ScreenW = 640 # Window width
  16.   ScreenH = 480 # Window height
  17.   WindowFlags = 0
  18.   RendererFlags = sdl.RendererAccelerated or sdl.RendererPresentVsync
  19.  
  20.  
  21. type
  22.   App = ref AppObj
  23.   AppObj = object
  24.     window*: sdl.Window # Window pointer
  25.     renderer*: sdl.Renderer # Rendering state pointer
  26.  
  27.  
  28.   Image = ref ImageObj
  29.   ImageObj = object of RootObj
  30.     texture: sdl.Texture # Image texture
  31.     w, h: int # Image dimensions
  32.  
  33.  
  34. #########
  35. # IMAGE #
  36. #########
  37.  
  38. proc newImage(): Image = Image(texture: nil, w: 0, h: 0)
  39. proc free(obj: Image) = sdl.destroyTexture(obj.texture)
  40. proc w(obj: Image): int {.inline.} = return obj.w
  41. proc h(obj: Image): int {.inline.} = return obj.h
  42.  
  43. # blend
  44. proc blend(obj: Image): sdl.BlendMode =
  45.   var blend: sdl.BlendMode
  46.   if obj.texture.getTextureBlendMode(addr(blend)) == 0:
  47.     return blend
  48.   else:
  49.     return sdl.BlendModeBlend
  50.  
  51. proc `blend=`(obj: Image, mode: sdl.BlendMode) {.inline.} =
  52.   discard obj.texture.setTextureBlendMode(mode)
  53.  
  54. # alpha
  55. proc alpha(obj: Image): int =
  56.   var alpha: uint8
  57.   if obj.texture.getTextureAlphaMod(addr(alpha)) == 0:
  58.     return alpha
  59.   else:
  60.     return 255
  61.  
  62. proc `alpha=`(obj: Image, alpha: int) =
  63.   discard obj.texture.setTextureAlphaMod(alpha.uint8)
  64.  
  65.  
  66. # Load image from file
  67. # Return true on success or false, if image can't be loaded
  68. proc load(obj: Image, renderer: sdl.Renderer, file: string): bool =
  69.   result = true
  70.   # Load image to texture
  71.   obj.texture = renderer.loadTexture(file)
  72.   if obj.texture == nil:
  73.     sdl.logCritical(sdl.LogCategoryError,
  74.                     "Can't load image %s: %s",
  75.                     file, img.getError())
  76.     return false
  77.   # Get image dimensions
  78.   var w, h: cint
  79.   if obj.texture.queryTexture(nil, nil, addr(w), addr(h)) != 0:
  80.     sdl.logCritical(sdl.LogCategoryError,
  81.                     "Can't get texture attributes: %s",
  82.                     sdl.getError())
  83.     sdl.destroyTexture(obj.texture)
  84.     return false
  85.   obj.w = w
  86.   obj.h = h
  87.  
  88.  
  89. # Render texture to screen
  90. proc render(obj: Image, renderer: sdl.Renderer, x, y: int): bool =
  91.   var rect = sdl.Rect(x: x, y: y, w: obj.w, h: obj.h)
  92.   if renderer.renderCopy(obj.texture, nil, addr(rect)) == 0:
  93.     return true
  94.   else:
  95.     return false
  96.  
  97.  
  98. # Render transformed texture to screen
  99. proc renderEx(obj: Image, renderer: sdl.Renderer, x, y: int,
  100.               w = 0, h = 0, angle = 0.0, centerX = -1, centerY = -1,
  101.               flip = sdl.FlipNone): bool =
  102.   var
  103.     rect = sdl.Rect(x: x, y: y, w: obj.w, h: obj.h)
  104.     centerObj = sdl.Point(x: centerX, y: centerY)
  105.     center: ptr sdl.Point = nil
  106.   if w != 0: rect.w = w
  107.   if h != 0: rect.h = h
  108.   if not (centerX == -1 and centerY == -1): center = addr(centerObj)
  109.   if renderer.renderCopyEx(obj.texture, nil, addr(rect),
  110.                            angle, center, flip) == 0:
  111.     return true
  112.   else:
  113.     return false
  114.  
  115.  
  116. ##########
  117. # COMMON #
  118. ##########
  119.  
  120. # Initialization sequence
  121. proc init(app: App): bool =
  122.   # Init SDL
  123.   if sdl.init(sdl.InitVideo) != 0:
  124.     sdl.logCritical(sdl.LogCategoryError,
  125.                     "Can't initialize SDL: %s",
  126.                     sdl.getError())
  127.     return false
  128.  
  129.   # Init SDL_Image
  130.   if img.init(img.InitPng) == 0:
  131.     sdl.logCritical(sdl.LogCategoryError,
  132.                     "Can't initialize SDL_Image: %s",
  133.                     img.getError())
  134.  
  135.   # Create window
  136.   app.window = sdl.createWindow(
  137.     Title,
  138.     sdl.WindowPosUndefined,
  139.     sdl.WindowPosUndefined,
  140.     ScreenW,
  141.     ScreenH,
  142.     WindowFlags)
  143.   if app.window == nil:
  144.     sdl.logCritical(sdl.LogCategoryError,
  145.                     "Can't create window: %s",
  146.                     sdl.getError())
  147.     return false
  148.  
  149.   # Create renderer
  150.   app.renderer = sdl.createRenderer(app.window, -1, RendererFlags)
  151.   if app.renderer == nil:
  152.     sdl.logCritical(sdl.LogCategoryError,
  153.                     "Can't create renderer: %s",
  154.                     sdl.getError())
  155.     return false
  156.  
  157.   # Set draw color
  158.   if app.renderer.setRenderDrawColor(0x00, 0x00, 0x00, 0xFF) != 0:
  159.     sdl.logWarn(sdl.LogCategoryVideo,
  160.                 "Can't set draw color: %s",
  161.                 sdl.getError())
  162.     return false
  163.  
  164.   sdl.logInfo(sdl.LogCategoryApplication, "SDL initialized successfully")
  165.   randomize()
  166.   return true
  167.  
  168.  
  169. # Shutdown sequence
  170. proc exit(app: App) =
  171.   app.renderer.destroyRenderer()
  172.   app.window.destroyWindow()
  173.   img.quit()
  174.   sdl.logInfo(sdl.LogCategoryApplication, "SDL shutdown completed")
  175.   sdl.quit()
  176.  
  177.  
  178. # Event handling
  179. # Return true on app shutdown request, otherwise return false
  180. proc events(pressed: var seq[sdl.Keycode]): bool =
  181.   result = false
  182.   var e: sdl.Event
  183.   if pressed.len > 0:
  184.     pressed = @[]
  185.  
  186.   while sdl.pollEvent(addr(e)) != 0:
  187.  
  188.     # Quit requested
  189.     if e.kind == sdl.Quit:
  190.       return true
  191.  
  192.     # Key pressed
  193.     elif e.kind == sdl.KeyDown:
  194.       # Add pressed key to sequence
  195.       pressed.add(e.key.keysym.sym)
  196.  
  197.       # Exit on Escape key press
  198.       if e.key.keysym.sym == sdl.K_Escape:
  199.         return true
  200.  
  201.  
  202. ########
  203. # MAIN #
  204. ########
  205.  
  206. var
  207.   app = App(window: nil, renderer: nil)
  208.   done = false # Main loop exit condition
  209.   pressed: seq[sdl.Keycode] = @[] # Pressed keys
  210.  
  211. if init(app):
  212.  
  213.   # Generate random colors palette
  214.   var rnd: array[256, sdl.Color]
  215.   for i in 0..255:
  216.     rnd[i].r = rand(255).uint8
  217.     rnd[i].g = rand(255).uint8
  218.     rnd[i].b = rand(255).uint8
  219.     rnd[i].a = 255
  220.     if rnd[i].r < 32 and rnd[i].g < 32 and rnd[i].b < 32:
  221.       rnd[i].r = uint8(255 - rnd[i].r)
  222.       rnd[i].g = uint8(255 - rnd[i].g)
  223.       rnd[i].b = uint8(255 - rnd[i].b)
  224.  
  225.   # Load font
  226.   gfx.gfxPrimitivesSetFont(addr(font.gfxPrimitivesFontData), 8, 8)
  227.  
  228.   # Main loop
  229.   while not done:
  230.     # Clear screen with draw color
  231.     discard app.renderer.setRenderDrawColor(0x00, 0x00, 0x00, 0xFF)
  232.     if app.renderer.renderClear() != 0:
  233.       sdl.logWarn(sdl.LogCategoryVideo,
  234.                   "Can't clear screen: %s",
  235.                   sdl.getError())
  236.  
  237.     # Drawing
  238.  
  239.     # Point
  240.     discard app.renderer.pixelRGBA(
  241.       x = 10, y = 10,
  242.       rnd[0].r, rnd[0].g, rnd[0].b, rnd[0].a)
  243.  
  244.     # Horizontal line
  245.     discard app.renderer.hlineRGBA(
  246.       x1 = 10, x2 = 110, y = 20,
  247.       rnd[1].r, rnd[1].g, rnd[1].b, rnd[1].a)
  248.  
  249.     # Vertical line
  250.     discard app.renderer.vlineRGBA(
  251.       x = 120, y1 = 10, y2 = 470,
  252.       rnd[2].r, rnd[2].g, rnd[2].b, rnd[2].a)
  253.  
  254.     # Rectangle
  255.     discard app.renderer.rectangleRGBA(
  256.       x1 = 10, y1 = 30, x2 = 110, y2 = 60,
  257.       rnd[3].r, rnd[3].g, rnd[3].b, rnd[3].a)
  258.  
  259.     # Rounded rectangle
  260.     discard app.renderer.roundedRectangleRGBA(
  261.       x1 = 10, y1 = 70,  x2 = 110, y2 = 100, rad = 10,
  262.       rnd[4].r, rnd[4].g, rnd[4].b, rnd[4].a)
  263.  
  264.     # Box
  265.     discard app.renderer.boxRGBA(
  266.       x1 = 10, y1 = 110, x2 = 110, y2 = 140,
  267.       rnd[5].r, rnd[5].g, rnd[5].b, rnd[5].a)
  268.  
  269.     # RoundedBox
  270.     discard app.renderer.roundedBoxRGBA(
  271.       x1 = 10, y1 = 150, x2 = 110, y2 = 180, rad = 10,
  272.       rnd[6].r, rnd[6].g, rnd[6].b, rnd[6].a)
  273.  
  274.     # Line
  275.     discard app.renderer.lineRGBA(
  276.       x1 = 10, y1 = 190, x2 = 110, y2 = 210,
  277.       rnd[7].r, rnd[7].g, rnd[7].b, rnd[7].a)
  278.  
  279.     # Anti-aliased line
  280.     discard app.renderer.aalineRGBA(
  281.       x1 = 10, y1 = 200, x2 = 110, y2 = 220,
  282.       rnd[8].r, rnd[8].g, rnd[8].b, rnd[8].a)
  283.  
  284.     # Thick line
  285.     discard app.renderer.thickLineRGBA(
  286.       x1 = 10, y1 = 210, x2 = 110, y2 = 230, width = 5,
  287.       rnd[9].r, rnd[9].g, rnd[9].b, rnd[9].a)
  288.  
  289.     # Circle
  290.     discard app.renderer.circleRGBA(
  291.       x = 60, y = 280, rad = 50,
  292.       rnd[10].r, rnd[10].g, rnd[10].b, rnd[10].a)
  293.  
  294.     # Arc
  295.     discard app.renderer.arcRGBA(
  296.       x = 60, y = 300, rad = 50, start = 30, finish = 150,
  297.       rnd[11].r, rnd[11].g, rnd[11].b, rnd[11].a)
  298.  
  299.     # Anti-aliased circle
  300.     discard app.renderer.aacircleRGBA(
  301.       x = 60, y = 420, rad = 50,
  302.       rnd[12].r, rnd[12].g, rnd[12].b, rnd[12].a)
  303.  
  304.     # Filled circle
  305.     discard app.renderer.filledCircleRGBA(
  306.       x = 180, y = 60, rad = 50,
  307.       rnd[13].r, rnd[13].g, rnd[13].b, rnd[13].a)
  308.  
  309.     # Ellipse
  310.     discard app.renderer.ellipseRGBA(
  311.       x = 180, y = 135, rx = 50, ry = 15,
  312.       rnd[14].r, rnd[14].g, rnd[14].b, rnd[14].a)
  313.  
  314.     # Anti-aliased ellipse
  315.     discard app.renderer.aaellipseRGBA(
  316.       x = 180, y = 180, rx = 50, ry = 15,
  317.       rnd[15].r, rnd[15].g, rnd[15].b, rnd[15].a)
  318.  
  319.     # Filled ellipse
  320.     discard app.renderer.filledEllipseRGBA(
  321.       x = 180, y = 225, rx = 50, ry = 15,
  322.       rnd[16].r, rnd[16].g, rnd[16].b, rnd[16].a)
  323.  
  324.     # Pie
  325.     discard app.renderer.pieRGBA(
  326.       x = 180, y = 260, rad = 50, start = 30, finish = 150,
  327.       rnd[17].r, rnd[17].g, rnd[17].b, rnd[17].a)
  328.  
  329.     # Filled pie
  330.     discard app.renderer.filledPieRGBA(
  331.       x = 180, y = 320, rad = 50, start = 30, finish = 150,
  332.       rnd[18].r, rnd[18].g, rnd[18].b, rnd[18].a)
  333.  
  334.     # Trigon
  335.     discard app.renderer.trigonRGBA(
  336.       x1 = 130, y1 = 380, x2 = 230, y2 = 390, x3 = 130, y3 = 410,
  337.       rnd[19].r, rnd[19].g, rnd[19].b, rnd[19].a)
  338.  
  339.     # Anti-aliased trigon
  340.     discard app.renderer.aatrigonRGBA(
  341.       x1 = 130, y1 = 420, x2 = 230, y2 = 400, x3 = 230, y3 = 430,
  342.       rnd[20].r, rnd[20].g, rnd[20].b, rnd[20].a)
  343.  
  344.     # Filled trigon
  345.     discard app.renderer.filledTrigonRGBA(
  346.       x1 = 130, y1 = 430, x2 = 230, y2 = 440, x3 = 130, y3 = 460,
  347.       rnd[21].r, rnd[21].g, rnd[21].b, rnd[21].a)
  348.  
  349.     # Polygon
  350.     const polyN = 4
  351.     var polyX, polyY: array[polyN, int16]
  352.     polyX[0] = 260
  353.     polyY[0] = 10
  354.     polyX[1] = 350
  355.     polyY[1] = 20
  356.     polyX[2] = 340
  357.     polyY[2] = 40
  358.     polyX[3] = 250
  359.     polyY[3] = 30
  360.     discard app.renderer.polygonRGBA(
  361.       vx = addr(polyX[0]), vy = addr(polyY[0]), n = polyN,
  362.       rnd[22].r, rnd[22].g, rnd[22].b, rnd[22].a)
  363.  
  364.     # Anti-aliased polygon
  365.     polyY[0] = 50
  366.     polyY[1] = 60
  367.     polyY[2] = 80
  368.     polyY[3] = 70
  369.     discard app.renderer.aapolygonRGBA(
  370.       vx = addr(polyX[0]), vy = addr(polyY[0]), n = polyN,
  371.       rnd[23].r, rnd[23].g, rnd[23].b, rnd[23].a)
  372.  
  373.     # Filled polygon
  374.     polyY[0] = 90
  375.     polyY[1] = 100
  376.     polyY[2] = 120
  377.     polyY[3] = 110
  378.     discard app.renderer.filledPolygonRGBA(
  379.       vx = addr(polyX[0]), vy = addr(polyY[0]), n = polyN,
  380.       rnd[24].r, rnd[24].g, rnd[24].b, rnd[24].a)
  381.  
  382.     # Textured polygon
  383.     polyY[0] = 130
  384.     polyY[1] = 140
  385.     polyY[2] = 160
  386.     polyY[3] = 150
  387.     var polyTexture = img.load("img/img2.png")
  388.     discard app.renderer.texturedPolygon(
  389.       vx = addr(polyX[0]), vy = addr(polyY[0]), n = polyN,
  390.       polyTexture, 0, 0)
  391.  
  392.     # Bezier curve
  393.     const bezN = 4
  394.     var bezX, bezY: array[bezN, int16]
  395.     bezX[0] = 260
  396.     bezY[0] = 170
  397.     bezX[1] = 350
  398.     bezY[1] = 180
  399.     bezX[2] = 260
  400.     bezY[2] = 190
  401.     bezX[3] = 350
  402.     bezY[3] = 200
  403.     discard app.renderer.bezierRGBA(
  404.       vx = addr(bezX[0]), vy = addr(bezY[0]), n = bezN, s = 100,
  405.       rnd[25].r, rnd[25].g, rnd[25].b, rnd[25].a)
  406.  
  407.     # Character
  408.     discard app.renderer.characterRGBA(
  409.       x = 370, y = 10, 'A',
  410.       rnd[26].r, rnd[26].g, rnd[26].b, rnd[26].a)
  411.  
  412.     # String
  413.     discard app.renderer.stringRGBA(
  414.       x = 370, y = 30, "String",
  415.       rnd[27].r, rnd[27].g, rnd[27].b, rnd[27].a)
  416.  
  417.     # Update renderer
  418.     app.renderer.renderPresent()
  419.  
  420.     # Event handling
  421.     done = events(pressed)
  422.  
  423. # Shutdown
  424. exit(app)
  425.  
ScriptBasic Project Manager/Facilitator

John Spikowski

  • BASIC Developer
  • ***
  • Posts: 234
    • View Profile
    • ScriptBasic
Re: Nim SDL Transformations
« Reply #4 on: December 09, 2019, 05:07:30 AM »
Code: Text
  1. # ex202_transformations.nim
  2. # =========================
  3. # VIDEO / Transforming textures
  4. # -----------------------------
  5.  
  6.  
  7. import sdl2/sdl, sdl2/sdl_image as img
  8.  
  9.  
  10. const
  11.   Title = "SDL2 App"
  12.   ScreenW = 640 # Window width
  13.   ScreenH = 480 # Window height
  14.   WindowFlags = 0
  15.   RendererFlags = sdl.RendererAccelerated or sdl.RendererPresentVsync
  16.  
  17.  
  18. type
  19.   App = ref AppObj
  20.   AppObj = object
  21.     window*: sdl.Window # Window pointer
  22.     renderer*: sdl.Renderer # Rendering state pointer
  23.  
  24.  
  25.   Image = ref ImageObj
  26.   ImageObj = object of RootObj
  27.     texture: sdl.Texture # Image texture
  28.     w, h: int # Image dimensions
  29.  
  30.  
  31. #########
  32. # IMAGE #
  33. #########
  34.  
  35. proc newImage(): Image = Image(texture: nil, w: 0, h: 0)
  36. proc free(obj: Image) = sdl.destroyTexture(obj.texture)
  37. proc w(obj: Image): int {.inline.} = return obj.w
  38. proc h(obj: Image): int {.inline.} = return obj.h
  39.  
  40.  
  41. # Load image from file
  42. # Return true on success or false, if image can't be loaded
  43. proc load(obj: Image, renderer: sdl.Renderer, file: string): bool =
  44.   result = true
  45.   # Load image to texture
  46.   obj.texture = renderer.loadTexture(file)
  47.   if obj.texture == nil:
  48.     sdl.logCritical(sdl.LogCategoryError,
  49.                     "Can't load image %s: %s",
  50.                     file, img.getError())
  51.     return false
  52.   # Get image dimensions
  53.   var w, h: cint
  54.   if obj.texture.queryTexture(nil, nil, addr(w), addr(h)) != 0:
  55.     sdl.logCritical(sdl.LogCategoryError,
  56.                     "Can't get texture attributes: %s",
  57.                     sdl.getError())
  58.     sdl.destroyTexture(obj.texture)
  59.     return false
  60.   obj.w = w
  61.   obj.h = h
  62.  
  63.  
  64. # Render texture to screen
  65. proc render(obj: Image, renderer: sdl.Renderer, x, y: int): bool =
  66.   var rect = sdl.Rect(x: x, y: y, w: obj.w, h: obj.h)
  67.   if renderer.renderCopy(obj.texture, nil, addr(rect)) == 0:
  68.     return true
  69.   else:
  70.     return false
  71.  
  72.  
  73. # Render transformed texture to screen
  74. proc renderEx(obj: Image, renderer: sdl.Renderer, x, y: int,
  75.               w = 0, h = 0, angle = 0.0, centerX = -1, centerY = -1,
  76.               flip = sdl.FlipNone): bool =
  77.   var
  78.     rect = sdl.Rect(x: x, y: y, w: obj.w, h: obj.h)
  79.     centerObj = sdl.Point(x: centerX, y: centerY)
  80.     center: ptr sdl.Point = nil
  81.   if w != 0: rect.w = w
  82.   if h != 0: rect.h = h
  83.   if not (centerX == -1 and centerY == -1): center = addr(centerObj)
  84.   if renderer.renderCopyEx(obj.texture, nil, addr(rect),
  85.                            angle, center, flip) == 0:
  86.     return true
  87.   else:
  88.     return false
  89.  
  90.  
  91. ##########
  92. # COMMON #
  93. ##########
  94.  
  95. # Initialization sequence
  96. proc init(app: App): bool =
  97.   # Init SDL
  98.   if sdl.init(sdl.InitVideo) != 0:
  99.     sdl.logCritical(sdl.LogCategoryError,
  100.                     "Can't initialize SDL: %s",
  101.                     sdl.getError())
  102.     return false
  103.  
  104.   # Init SDL_Image
  105.   if img.init(img.InitPng) == 0:
  106.     sdl.logCritical(sdl.LogCategoryError,
  107.                     "Can't initialize SDL_Image: %s",
  108.                     img.getError())
  109.  
  110.   # Create window
  111.   app.window = sdl.createWindow(
  112.     Title,
  113.     sdl.WindowPosUndefined,
  114.     sdl.WindowPosUndefined,
  115.     ScreenW,
  116.     ScreenH,
  117.     WindowFlags)
  118.   if app.window == nil:
  119.     sdl.logCritical(sdl.LogCategoryError,
  120.                     "Can't create window: %s",
  121.                     sdl.getError())
  122.     return false
  123.  
  124.   # Create renderer
  125.   app.renderer = sdl.createRenderer(app.window, -1, RendererFlags)
  126.   if app.renderer == nil:
  127.     sdl.logCritical(sdl.LogCategoryError,
  128.                     "Can't create renderer: %s",
  129.                     sdl.getError())
  130.     return false
  131.  
  132.   # Set draw color
  133.   if app.renderer.setRenderDrawColor(0x00, 0x00, 0x00, 0xFF) != 0:
  134.     sdl.logWarn(sdl.LogCategoryVideo,
  135.                 "Can't set draw color: %s",
  136.                 sdl.getError())
  137.     return false
  138.  
  139.   sdl.logInfo(sdl.LogCategoryApplication, "SDL initialized successfully")
  140.   return true
  141.  
  142.  
  143. # Shutdown sequence
  144. proc exit(app: App) =
  145.   app.renderer.destroyRenderer()
  146.   app.window.destroyWindow()
  147.   img.quit()
  148.   sdl.logInfo(sdl.LogCategoryApplication, "SDL shutdown completed")
  149.   sdl.quit()
  150.  
  151.  
  152. # Event handling
  153. # Return true on app shutdown request, otherwise return false
  154. proc events(pressed: var seq[sdl.Keycode]): bool =
  155.   result = false
  156.   var e: sdl.Event
  157.   if pressed.len > 0:
  158.     pressed = @[]
  159.  
  160.   while sdl.pollEvent(addr(e)) != 0:
  161.  
  162.     # Quit requested
  163.     if e.kind == sdl.Quit:
  164.       return true
  165.  
  166.     # Key pressed
  167.     elif e.kind == sdl.KeyDown:
  168.       # Add pressed key to sequence
  169.       pressed.add(e.key.keysym.sym)
  170.  
  171.       # Exit on Escape key press
  172.       if e.key.keysym.sym == sdl.K_Escape:
  173.         return true
  174.  
  175.  
  176. ########
  177. # MAIN #
  178. ########
  179.  
  180. var
  181.   app = App(window: nil, renderer: nil)
  182.   done = false # Main loop exit condition
  183.   pressed: seq[sdl.Keycode] = @[] # Pressed keys
  184.  
  185. if init(app):
  186.  
  187.   # Load assets
  188.   var
  189.     image1 = newImage()
  190.   if not image1.load(app.renderer, "img/img1.png"):
  191.     done = true
  192.  
  193.   echo "-----------------------"
  194.   echo "|      Controls:      |"
  195.   echo "|---------------------|"
  196.   echo "| Q/A: change width   |"
  197.   echo "| W/S: change height  |"
  198.   echo "| E/D: rotate         |"
  199.   echo "| R/F: flip           |"
  200.   echo "-----------------------"
  201.  
  202.   # Transformations
  203.   const
  204.     sizeStep = 10
  205.     angleStep = 10
  206.   var
  207.     w = image1.w
  208.     h = image1.h
  209.     angle = 0.0
  210.     flip = sdl.FlipNone
  211.  
  212.   # Main loop
  213.   while not done:
  214.     # Clear screen with draw color
  215.     if app.renderer.renderClear() != 0:
  216.       sdl.logWarn(sdl.LogCategoryVideo,
  217.                   "Can't clear screen: %s",
  218.                   sdl.getError())
  219.  
  220.     # Render textures
  221.     if not image1.renderEx(app.renderer,
  222.                            ScreenW div 2 - w div 2,
  223.                            ScreenH div 2 - h div 2,
  224.                            w, h, angle, flip = flip):
  225.       sdl.logWarn(sdl.LogCategoryVideo,
  226.                   "Can't render image1: %s",
  227.                   sdl.getError())
  228.  
  229.     # Event handling
  230.     done = events(pressed)
  231.  
  232.     # Process input
  233.     if K_q in pressed: w += sizeStep
  234.     if K_a in pressed: w -= sizeStep
  235.     if K_w in pressed: h += sizeStep
  236.     if K_s in pressed: h -= sizeStep
  237.     if K_e in pressed: angle += angleStep
  238.     if K_d in pressed: angle -= angleStep
  239.     if K_r in pressed:
  240.       if flip == sdl.FlipNone:
  241.         flip = sdl.FlipHorizontal
  242.       else:
  243.         flip = sdl.FlipNone
  244.     if K_f in pressed:
  245.       if flip == sdl.FlipNone:
  246.         flip = sdl.FlipVertical
  247.       else:
  248.         flip = sdl.FlipNone
  249.  
  250.     # Check bounds
  251.     if w <= 0: w = sizeStep
  252.     if h <= 0: h = sizeStep
  253.     if angle >= 360: angle -= 360
  254.     elif angle <= -360: angle += 360
  255.  
  256.     # Update renderer
  257.     app.renderer.renderPresent()
  258.  
  259.   # Free assets
  260.   free(image1)
  261.  
  262. # Shutdown
  263. exit(app)
  264.  


pi@RPi4B:~/nim-dev/examples $ ./trans
INFO: SDL initialized successfully
-----------------------
|      Controls:      |
|---------------------|
| Q/A: change width   |
| W/S: change height  |
| E/D: rotate         |
| R/F: flip           |
-----------------------
ScriptBasic Project Manager/Facilitator

AIR

  • BASIC Developer
  • *
  • Posts: 16
  • Code Jockey
    • View Profile
Re: Nim IUP
« Reply #5 on: December 11, 2019, 06:22:18 AM »
Took you a while, but I'm glad you're finally taking NIM for a spin!

AIR.

John Spikowski

  • BASIC Developer
  • ***
  • Posts: 234
    • View Profile
    • ScriptBasic
Re: Nim Introduction
« Reply #6 on: December 11, 2019, 06:59:30 AM »
Yep. On the regret list. I should have listened to you years ago.

I hope to become as proficient with Nim as I am with SB.

My next example with Nim will be embedding ScriptBasic. It will be like a high level EVAL function. You pass it some SB code as text and it returns what you want from it. I don't want to leave my old friend behind. Actually this is what ScriptBasic was designed for, not a standalone BASIC interpreter

« Last Edit: December 11, 2019, 08:18:00 AM by John Spikowski »
ScriptBasic Project Manager/Facilitator

John Spikowski

  • BASIC Developer
  • ***
  • Posts: 234
    • View Profile
    • ScriptBasic
Re: Nim Introduction
« Reply #7 on: December 18, 2019, 03:02:08 AM »
Ubuntu wanted to install an older version of Nim via Synaptic. I thought I would give compiling it from source on the RPi 4B under Ubuntu 64 a try.


Hint: operation successful (121335 lines compiled; 46.147 sec total; 139.008MiB peakmem; Release Build) [SuccessX]

ubuntu@rpi4b:~/repo/Nim/bin$ nim --version
Nim Compiler Version 1.1.1 [Linux: arm64]
Compiled at 2019-12-18
Copyright (c) 2006-2019 by Andreas Rumpf

git hash: f9f55a23bbcb64824954ed83b60816499a7cc338
active boot switches: -d:release
ubuntu@rpi4b:~/repo/Nim/bin$


« Last Edit: December 18, 2019, 03:20:10 AM by John Spikowski »
ScriptBasic Project Manager/Facilitator