Demo in PB?

Everything else that doesn't fall into one of the other PB categories.
User avatar
Mindphazer
Enthusiast
Enthusiast
Posts: 527
Joined: Mon Sep 10, 2012 10:41 am
Location: Savoie

Re: Demo in PB?

Post by Mindphazer »

Nice demos miso, thanks !!
And i'm glad and honoured to be included to your greetings :D
MacBook Pro 16" M4 Pro - 24 Gb - MacOS 26.1 - Iphone 17 Pro Max - iPad at home
...and unfortunately... Windows at work...
miso
Enthusiast
Enthusiast
Posts: 674
Joined: Sat Oct 21, 2023 4:06 pm
Location: Hungary

Re: Demo in PB?

Post by miso »

Thanks Mindphaser. I already see some mistakes in the code. The sin lookup table is mathematically incorrect. (but so small difference at the overflowing part, that it isn't visible.)
User avatar
moulder61
Enthusiast
Enthusiast
Posts: 216
Joined: Sun Sep 19, 2021 6:16 pm
Location: U.K.

Re: Demo in PB?

Post by moulder61 »

@miso,
Your suggestion worked for example 3. :D

@Mindphazer,
I didn't notice you did a demo first! Yours is very nice too. Thanks for sharing. 8)

Moulder.
"If it ain't broke, fix it until it is!

This message is brought to you thanks to SenselessComments.com

My PB stuff for Linux: "https://u.pcloud.link/publink/show?code ... z3MR0T3jyV
miso
Enthusiast
Enthusiast
Posts: 674
Joined: Sat Oct 21, 2023 4:06 pm
Location: Hungary

Re: Demo in PB?

Post by miso »

Made a reusable module with some demostyle movements. Of course it has a correct sintable.
This is standalone and organized.

Code: Select all

DeclareModule tool
  Structure s_pointF
    x.f
    y.f
  EndStructure
  
  Structure s_pointI
    x.i
    y.i
  EndStructure
  
  Global Blank.i
  Global Full.i

  
  Declare ministart2d(wTitle.s)
  Declare minicheckevents()
  Declare msRadomSeed_Set(seed.q)
  Declare.q RadomSeed_Get(seed.q)
  Declare msRandom(min.i, max.i)
  Declare msRandomize()
  Declare.f LERP(a.f, b.f, t.f)
  Declare.f INVLERP(a.f, b.f, v.f)
  Declare.f Remap(iMin.f, iMAX.f, oMin.f, oMax.f, v.f)  
  Declare.f smoothmotion(x.f, targetx.f)
  Declare.f smoothstep256(a.a)
  Declare.f Sin256(a.a)
  Declare.f Cos256(a.a)
  Declare CirclePosF(cx.i, cy.i, r.i, phase.a, *result.s_pointF)
  Declare CirclePosI(cx.i, cy.i, r.i, phase.a, *result.s_pointI)
  Declare EllipsePosF(cx.i, cy.i, r1.i, r2, phase.a, *result.s_pointF)
  Declare EllipsePosI(cx.i, cy.i, r1.i, r2.i, phase.a, *result.s_pointI)
  Declare PingPongVF(x.i, y.i, r.i, phase.a, *result.s_pointF)
  Declare PingPongVI(x.i, y.i, r.i, phase.a, *result.s_pointI)
  Declare PingPongHF(x.i, y.i, r.i, phase.a, *result.s_pointF)
  Declare PingPongHI(x.i, y.i, r.i, phase.a, *result.s_pointI)
  Declare spiralPosF(cx.i, cy.i, r0.i, r1.i, phase.a, *result.s_pointF)
  Declare spiralPosI(cx.i, cy.i, r0.i, r1.i, phase.a, *result.s_pointI)
  Declare.i CircleReveal(SpriteId.i, Phase.a)
  Declare.i CircleHide(SpriteId.i, Phase.a)

  
EndDeclareModule

Module tool
  EnableExplicit
  ;===========================================
  ;Windowed fullscreen quickstart
  ;===========================================
  Procedure ministart2d(wTitle.s)
    InitSprite():InitKeyboard():InitMouse():UsePNGImageDecoder():UsePNGImageEncoder():UseJPEGImageDecoder():UseJPEGImageEncoder()
    ExamineDesktops()
    OpenWindow(0, 0, 0, DesktopUnscaledX(DesktopWidth(0)), DesktopUnscaledY(DesktopHeight(0)), wTitle, #PB_Window_ScreenCentered|#PB_Window_BorderLess)
    OpenWindowedScreen(WindowID(0), 0, 0, WindowWidth(0) * DesktopResolutionX() , WindowHeight(0) * DesktopResolutionY(), 0, 0, 0, #PB_Screen_WaitSynchronization)
  EndProcedure
  
  ;===========================================
  ;Quickly handles flipbuffers, window events, 
  ;keyboard and mouse, esc And mouse middle 
  ;quits For short programs/tests
  ;===========================================
  Procedure minicheckevents()
    FlipBuffers()
    While WindowEvent() : Wend
    ClearScreen(RGBA(0,0,0,255)) ;Linux Fix at the moment
	  ExamineKeyboard()
	  ExamineMouse()
	  MouseDeltaX()                ;Linux Fix at the moment
	  If KeyboardPushed(#PB_Key_Escape) Or MouseButton(#PB_MouseButton_Middle) : End : EndIf
  EndProcedure

  
  
  ;==============================================
  ;Random 
  ;This is 4 times slower than PB builtin one!
  ;Randomize is second based, that is a Warn!
  ;Not for cryptography!
  ;Still has its uses, designed to be able
  ;to know the seed without computation
  ;Can get the random value from seed+n or
  ;seed-n, can accept negative numbers,
  ;min - max is swappable.
  ;msRandom(1,100) is the same as msRandom(100,1)
  ;==============================================
  #MAJORSEED = $a7129B0134C2D728
  #MINORSEED = $1DC8FA4510E6C352
  
  Global msrandomSeed.q
  msrandomSeed = Date()
  
  ;==============================================
  ;Sets the seed (Quad)
  ;==============================================
  Procedure msRadomSeed_Set(seed.q)
    msrandomSeed = seed
  EndProcedure
  
  ;==============================================
  ;Get the seed (Quad)
  ;==============================================
  Procedure.q RadomSeed_Get(seed.q)
    ProcedureReturn msrandomSeed
  EndProcedure
  
  ;==============================================
  ;Generates a random number (Int)
  ;min and max can be swapped
  ;==============================================
  Procedure msRandom(min.i, max.i)
    Protected temp.q
    If max < min   :   Swap min,max   :   EndIf
    temp = msrandomSeed
    temp = temp ! (temp << 13)
    temp = temp ! (temp >> 17)
    temp = temp ! (temp << 5)
    temp & $7FFFFFFFFFFFFFFF
    msrandomSeed + 1
    ProcedureReturn min + (temp  %  (max - min + 1))
  EndProcedure
  
  ;FIXME
  ;=====================================================
  ;Randomize the seed. This is not really works randomly
  ;as seeds steps one at a time, date() steps 1 at 
  ;a second.
  ;=====================================================
  Procedure msRandomize()
    msrandomseed ! ElapsedMilliseconds() << 7
    msrandomseed ! Date() >> 7
    msrandomSeed ! (msRandomSeed >> 30)
    msrandomSeed * #MINORSEED
    msrandomseed ! ((msRandomSeed >> 27))
    msrandomSeed * #MAJORSEED
    msrandomseed ! ((msRandomSeed >> 31))
  EndProcedure
  
  ;==============================================
  ;Precreating sin256 Lookup Table
  ;This one is correct mathematically
  ;Automatically created if module is included
  ;==============================================
  Define i.i
  Global Dim sin256LUT.f(255)
  For i = 0 To 255
    sin256LUT(i) = Sin(2 * #PI * i / 256)
  Next i
  
  ;==============================================
  ;Precreating smoothstep256 Lookup Table
  ;Automatically created if module is included
  ;==============================================
  Define t.f
  Global Dim smoothstep256LUT.f(255)
  For i = 0 To 255
    t = i / 255
    SmoothStep256LUT(i)=  t  *  t  *  (3 - 2 * t)
  Next i
  
  ;==============================================
  ;Presets for alpha channel modifications
  ;Automatically sets if module is included
  ;==============================================
  Global Blank.i = RGBA(0,0,0,0)
  Global Full.i  = RGBA(0,0,0,255)
  
  ;==============================================
  ;Linear interpolation
  ;==============================================
  Procedure.f LERP(a.f, b.f, t.f)
    ProcedureReturn(((1.0 - t.f) * a) + (b * t))
  EndProcedure
  
  ;==============================================
  ;Inverted Linear interpolation
  ;==============================================
  Procedure.f INVLERP(a.f, b.f, v.f)
    If a = b : ProcedureReturn(1) : EndIf
    ProcedureReturn((v - a)  /  (b - a))
  EndProcedure
  
  ;==============================================
  ;Remap
  ;==============================================
  Procedure.f Remap(iMin.f, iMAX.f, oMin.f, oMax.f, v.f)  
    Define t.f
    t.f = INVLERP(iMin, iMAX, v)
    ProcedureReturn(LERP(oMin, oMax, t))
  EndProcedure
  
  ;==============================================
  ;Smooth motion, distance based, not time based
  ;==============================================
  Procedure.f smoothmotion(x.f, targetx.f)
    ProcedureReturn((0.9 * x.f) + (0.1 * targetx.f))
  EndProcedure
  
  ;==============================================
  ;Smoothstep, time/phase based, resolution 0-255
  ;==============================================
  Procedure.f smoothstep256(a.a)
    ProcedureReturn smoothstep256LUT(a)
  EndProcedure
  
  ;===============================================
  ;Sinus, angle/time/phase based, resolution 0-255
  ;===============================================
  Procedure.f Sin256(a.a)
    ProcedureReturn sin256LUT(a)
  EndProcedure
  
  ;=================================================
  ;CoSinus, angle/time/phase based, resolution 0-255
  ;sintable+64
  ;=================================================
  Procedure.f Cos256(a.a)
    a + 64
    ProcedureReturn sin256LUT(a)
  EndProcedure
  
  ;==================================================
  ;Position x,y (Float) in a circle center x,y radius
  ;based on angle/time/phase. Resolution 0-255
  ;==================================================
  Procedure CirclePosF(cx.i, cy.i, r.i, phase.a, *result.s_pointF)
    *result\x = sin256(phase) * r + cx
    *result\y = cos256(phase) * r + cy
  EndProcedure
  
  ;==================================================
  ;Position x,y (Int) in a circle center x,y radius
  ;based on angle/time/phase. Resolution 0-255
  ;==================================================
  Procedure CirclePosI(cx.i, cy.i, r.i, phase.a, *result.s_pointI)
    *result\x = sin256(phase) * r + cx
    *result\y = cos256(phase) * r + cy
  EndProcedure
  
  ;======================================================
  ;Position x,y (Float) in an ellipse center x,y, radius1
  ;radius 2, based on angle/time/phase. Resolution 0-255
  ;======================================================
  Procedure EllipsePosF(cx.i, cy.i, r1.i, r2, phase.a, *result.s_pointF)
    *result\x = sin256(phase) * r1 + cx
    *result\y = cos256(phase) * r2 + cy
  EndProcedure
  
  ;======================================================
  ;Position x,y (Int) in an ellipse center x,y, radius1
  ;radius 2, based on angle/time/phase. Resolution 0-255
  ;======================================================
  Procedure EllipsePosI(cx.i, cy.i, r1.i, r2.i, phase.a, *result.s_pointI)
    *result\x = sin256(phase) * r1 + cx
    *result\y = cos256(phase) * r2 + cy
  EndProcedure
  
  ;======================================================
  ;Position x,y (Float) of a vertical pingpong movement
  ;based on angle/time/phase. Resolution 0-255
  ;parameters: center x,y,radius, phase
  ;======================================================
  Procedure PingPongVF(x.i, y.i, r.i, phase.a, *result.s_pointF)
    *result\x = sin256(phase) * r + x
    *result\y = y
  EndProcedure
  
  ;======================================================
  ;Position x,y (Int) of a vertical pingpong movement
  ;based on angle/time/phase. Resolution 0-255
  ;parameters: center x,y,radius, phase
  ;======================================================
  Procedure PingPongVI(x.i, y.i, r.i, phase.a, *result.s_pointI)
    *result\x = sin256(phase) * r + x
    *result\y = y
  EndProcedure
  
  ;======================================================
  ;Position x,y (Float) of a horizontal pingpong movement
  ;based on angle/time/phase. Resolution 0-255
  ;parameters: center x,y,radius, phase
  ;======================================================
  Procedure PingPongHF(x.i, y.i, r.i, phase.a, *result.s_pointF)
    *result\x = x
    *result\y = cos256(phase) * r + y
  EndProcedure
  
  ;======================================================
  ;Position x,y (Int) of a horizontal pingpong movement
  ;based on angle/time/phase. Resolution 0-255
  ;parameters: center x,y,radius, phase
  ;======================================================
  Procedure PingPongHI(x.i, y.i, r.i, phase.a, *result.s_pointI)
    *result\x = x
    *result\y = cos256(phase) * r + y
  EndProcedure
  
  Procedure spiralPosF(cx.i, cy.i, r0.i, r1.i, phase.a, *result.s_pointF)
    Protected a.f, c.f, r.f, s.f
    s = sin256( phase )
    c = Cos256( phase )
    r = r0 + (r1 - r0) * (phase / 255)
    *result\x = cx + c * r
    *result\y = cy + s * r
  EndProcedure
  
  Procedure spiralPosI(cx.i, cy.i, r0.i, r1.i, phase.a, *result.s_pointI)
    Protected a.f, c.f, r.f, s.f
    s = sin256( phase )
    c = Cos256( phase )
    r = r0 + (r1 - r0) * (phase / 255)
    *result\x = cx + c * r
    *result\y = cy + s * r
  EndProcedure
  
  ;========================================================
  ;Reveals a sprite with a circle
  ;based on angle/time/phase. Resolution 0-255
  ;Modifies alpha channel, so works with background sprites
  ;========================================================
  Procedure.i CircleReveal(SpriteId.i, Phase.a)
    Protected dist.i, x, y
    If Not IsSprite( SpriteID ) : ProcedureReturn #False : EndIf 
  
    StartDrawing( SpriteOutput(Spriteid) )
    x=OutputWidth() / 2
    y=OutputHeight() / 2
    dist = Sqr( (x * x) + (y * y) ) + 5
    dist * smoothstep256(phase)
    
    DrawingMode(#PB_2DDrawing_AlphaChannel)
    Box(0, 0, OutputWidth(), OutputHeight(), Blank)
    Circle(x, y, dist, Full)
    StopDrawing()
  EndProcedure
  
  ;========================================================
  ;Hides a sprite with a circle
  ;based on angle/time/phase. Resolution 0-255
  ;Modifies alpha channel, so works with background sprites
  ;========================================================
  Procedure.i CircleHide(SpriteId.i, Phase.a)
    If Not IsSprite(SpriteID) : ProcedureReturn #False : EndIf
    Phase = 255 - Phase
    Circlereveal(SpriteID, Phase)
  EndProcedure

EndModule
A couple of usage example, mouse leftclick switches between them:

https://nextcloud.cloudns.ph/index.php/ ... 89L6EEykty
Joubarbe
Enthusiast
Enthusiast
Posts: 753
Joined: Wed Sep 18, 2013 11:54 am
Location: France

Re: Demo in PB?

Post by Joubarbe »

Thank you miso, that's really great! 🎉
Post Reply