Fire anim...

Share your advanced PureBasic knowledge/code with the community.
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Fire anim...

Post by Olli »

( [Escape] key to quit... )

Code: Select all

DisableDebugger
InitSprite()
InitKeyboard()
ExamineDesktops()
OpenScreen(DesktopWidth(0), DesktopHeight(0), 32, "")
CreateSprite(0, ScreenWidth() / 4, ScreenHeight() / 4)
Procedure drawAdditivePixel(xArea, yArea, wArea, hArea, ci)
    x = xArea + Random(wArea - 1)
    y = yArea + Random(hArea - 1)
    pc = ci & $FFFFFFFF
    nc = ci >> 32 & $FFFFFFFF
    ic = Point(x, y)
    r = Red(ic)
    g = Green(ic)
    b = Blue(ic)
    pr = Red(pc)
    pg = Green(pc)
    pb = Blue(pc)
    nr = Red(nc)
    ng = Green(nc)
    nb = Blue(nc)
    r + pr - nr
    g + pg - ng
    b + pb - nb
    If r > 255: r = 0: EndIf
    If g > 255: g = 0: EndIf
    If b > 255: b = 0: EndIf
    If r < 0: r = 0: EndIf
    If g < 0: g = 0: EndIf
    If b < 0: b = 0: EndIf
    c = RGB(r, g, b)
    delta0 = 1
    delta1 = 2
    LineXY(x - delta0*2, y - delta0, x, y, c)
    LineXY(x, y, x + delta0, y - delta0, c)
    LineXY(x, y - delta1, x, y, c)
EndProcedure
Procedure drawBox(x, y, w, h, c)
        Box(x, y, w, h, c)
EndProcedure
Procedure updateFloor(sprite, *draw, xScale.D, yScale.D, wScale.D, hScale.D, c, times = 1)
    If StartDrawing(SpriteOutput(sprite) )
        x.I = Int(OutputWidth() * xScale)
        y.I = Int(OutputHeight() * yScale)
        w.I = Int(OutputWidth() * wScale)
        h.I = Int(OutputHeight() * hScale)
        For i = 1 To times
            CallFunctionFast(*draw, x, y, w, h, c)
        Next
        StopDrawing()
    EndIf
EndProcedure
updateFloor(0, @drawBox(), 0.0, 0.0, 1.0, 1.0, RGB($FF, $FF, $00) )
updateFloor(0, @drawAdditivePixel(), 0.0, 0.0, 1.0, 1.0, RGB(2, 0, 1) << 32 | RGB(8, 8, 8), 1 << 15)
ZoomSprite(0, ScreenWidth(), ScreenHeight() )
SpriteQuality(1)
Repeat
    Delay(2)
    ClearScreen(0)
    ExamineKeyboard()
    updateFloor(0, @drawAdditivePixel(), 0.0, 0.0, 1.0, 1.0, RGB(0, 0, 0) << 32 | RGB(1, 1, 1), 1 << 15)
    DisplaySprite(0, 0, 0)
    FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
User avatar
Caronte3D
Addict
Addict
Posts: 1027
Joined: Fri Jan 22, 2016 5:33 pm
Location: Some Universe

Re: Fire anim...

Post by Caronte3D »

Nice!

BTW, I replaced "<< 32" with "<< 31" :wink:
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Re: Fire anim...

Post by Olli »

You can change what you want in this code : the initial goal was a texture to show an old paper material !! :lol:

After having got what I wanted (an old paper texture which took one year per second), I decided to change a little bit. And so !

However, what I forget in this code, is the work 0n X64... It should be written ci.Q for X86...

Theorically you are right :
32-bits right shift = " >> 32"
32-bits left shift = " << 31"
[Edit] nop : 32 everywhere, right shift as left shift. Maybe, did you try a new effect...
Bitblazer
Enthusiast
Enthusiast
Posts: 733
Joined: Mon Apr 10, 2017 6:17 pm
Location: Germany
Contact:

Re: Fire anim...

Post by Bitblazer »

The fire effect is a rather old standard effects in the demoscene. You may want to check out this or this for example. Fine tune it and it will look pretty nice and nowadays easily possible in real-time without even using hand optimized assembler.

Usually people start with a fire effect and later turn it into fullscreen tunnel fly-throughs that use the fire effect as wall texture.
webpage - discord chat links -> purebasic GPT4All
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Re: Fire anim...

Post by Olli »

Interested links. Thank you bitblazer. For my code, it s a share, no great technic. A color is picked randomly in the area (screen here). The color is increased, and a pattern is drawn. The pattern is a trident. Not a lot of control of what it happens !

I wanted an old textured paper : I got a forest... :lol:
I wanted to change : I got a fire :mrgreen:
So finally, I have my old textured paper too. So I am happy. Instead of delete the intermediate code, I share it !
User avatar
Caronte3D
Addict
Addict
Posts: 1027
Joined: Fri Jan 22, 2016 5:33 pm
Location: Some Universe

Re: Fire anim...

Post by Caronte3D »

Olli wrote: Mon Jul 25, 2022 6:17 amMaybe, did you try a new effect...
No, I changed it because doesn't compile on x86 at least:

[22:03:19] [COMPILER] Line 11: The specified number is incorrect for '<<' or '>>' operators (must be 0-31).
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Re: Fire anim...

Post by Olli »

Caronte3D wrote: Tue Jul 26, 2022 9:06 pm
Olli wrote: Mon Jul 25, 2022 6:17 amMaybe, did you try a new effect...
No, I changed it because doesn't compile on x86 at least:

[22:03:19] [COMPILER] Line 11: The specified number is incorrect for '<<' or '>>' operators (must be 0-31).
Ok, I apologize : I must tell the compiler it is a 64-bits integer whatever the CPU range. So I must add ci.Q in the arguments of the procedure drawAdditivePixel(). Thank you very much for your feed back info.
To try to be forgiven for this mistake, I share this new version :

Code: Select all

DisableDebugger
InitSprite()
InitKeyboard()
ExamineDesktops()
OpenScreen(DesktopWidth(0), DesktopHeight(0), 32, "")
CreateSprite(0, ScreenWidth() / 4 * 4, ScreenHeight() / 4 * 4)
Procedure drawAdditivePixel(xArea, yArea, wArea, hArea, ci.Q)
    x = xArea + Random(wArea - 1)
    y = yArea + Random(hArea - 1)
    pc = ci & $FFFFFFFF
    id.d = 20 * Cos(ElapsedMilliseconds() / 5000)
    ii = id
    nc = ci >> (32 + ii) & $FFFFFFFF
    ic = Point(x, y)
    r = Red(ic)
    g = Green(ic)
    b = Blue(ic)
    pr = Red(pc)
    pg = Green(pc)
    pb = Blue(pc)
    nr = Red(nc)
    ng = Green(nc)
    nb = Blue(nc)
    r + pr - nr
    g + pg - ng
    b + pb - nb
    If r > 255: r = 0: EndIf
    If g > 255: g = 0: EndIf
    If b > 255: b = 0: EndIf
    If r < 0: r = 0: EndIf
    If g < 0: g = 0: EndIf
    If b < 0: b = 0: EndIf
    c = RGB(r, g, b)
    delta0 = 1
    delta1 = 2
    cx = xArea + wArea / 2
    cy = yArea + hArea / 2
    sca.d = Sqr(Sqr(Sqr((x-cx)*(x-cx) + (cy-y)*(cy-y) ) ) )
    If sca <> 0.0
        sca = 16 / sca
    EndIf
    ia.d = ATan2(x - cx, cy - y) * Pow(sca, 1 / (1 + (ElapsedMilliseconds() / 7000) ) ) - #PI / 2 + #PI * Sin(ElapsedMilliseconds() / 11000)
    ja.d = ia - #PI / 2
    ix.d = Cos(ia)*sca
    iy.d = -Sin(ia)*sca
    jx.d = Cos(ja)*sca
    jy.d = -Sin(ja)*sca
    LineXY(x, y, x + delta0 * (-2) * ix + (-delta0) * jx, y + delta0 * (-2) * iy + (-delta0) * jy, c)
    LineXY(x, y, x + delta0 * ix + (-delta0) * jx, y + delta0 * iy + (-delta0) * jy, c)
    LineXY(x, y, x + (- delta1) * jx, y + (- delta1) * jy, c)
EndProcedure
Procedure drawBox(x, y, w, h, c)
        Box(x, y, w, h, c)
EndProcedure
Procedure updateFloor(sprite, *draw, xScale.D, yScale.D, wScale.D, hScale.D, c, times = 1)
    If StartDrawing(SpriteOutput(sprite) )
        x.I = Int(OutputWidth() * xScale)
        y.I = Int(OutputHeight() * yScale)
        w.I = Int(OutputWidth() * wScale)
        h.I = Int(OutputHeight() * hScale)
        For i = 1 To times
            CallFunctionFast(*draw, x, y, w, h, c)
        Next
        StopDrawing()
    EndIf
EndProcedure
updateFloor(0, @drawBox(), 0.0, 0.0, 1.0, 1.0, RGB($FF, $FF, $00) )
updateFloor(0, @drawAdditivePixel(), 0.0, 0.0, 1.0, 1.0, RGB(2, 0, 1) << 32 | RGB(8, 8, 8), 1 << 15)
ZoomSprite(0, ScreenWidth(), ScreenHeight() )
SpriteQuality(1)
Repeat
    Delay(2)
    ClearScreen(0)
    ExamineKeyboard()
    updateFloor(0, @drawAdditivePixel(), 0.0, 0.0, 1.0, 1.0, RGB(0, 0, 0) << 32 | RGB(1, 1, 1), 1 << 16)
    DisplaySprite(0, 0, 0)
    FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Re: Fire anim...

Post by Olli »

caronte3d wrote:22:03:19] [COMPILER] Line 11: The specified number is incorrect for '<<' or '>>' operators (must be 0-31).
"must be 0-31"
arg... This means you will actually see a black and white anim...
User avatar
Caronte3D
Addict
Addict
Posts: 1027
Joined: Fri Jan 22, 2016 5:33 pm
Location: Some Universe

Re: Fire anim...

Post by Caronte3D »

Yes, the effect seems nice, but the colors are wrong
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Re: Fire anim...

Post by Olli »

I thank before, that Fred solves this bug. If I remember, the subject has been seen in 2015, however I am not sure of the year...

But this allows me to think about this problem : maybe I do a mistake on x64 too.

What it is sure is a >> b must be deleted and replaced with a heap of things...
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Re: Fire anim...

Post by Olli »

I will find a slower solver for this bit shift problem. In tje wait, here is a demo a friend shew 5 years ago. I never had armstrad (nor amiga). And I find this impressive (code size).
https://www.youtube.com/watch?v=22wSm4y27Wk
User avatar
Caronte3D
Addict
Addict
Posts: 1027
Joined: Fri Jan 22, 2016 5:33 pm
Location: Some Universe

Re: Fire anim...

Post by Caronte3D »

I was an Amiga Scene coder 30 years ago :shock: and... yes the things we accomplish with so few resources was awesome at times :D
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Re: Fire anim...

Post by Olli »

I hope you do not worry. I will be back. Only 1 bit shift, I already would be there. But for such beautiful color changes, these are any bits wave shift...
BarryG
Addict
Addict
Posts: 3292
Joined: Thu Apr 18, 2019 8:17 am

Re: Fire anim...

Post by BarryG »

Caronte3D wrote: Fri Aug 05, 2022 7:40 amI was an Amiga Scene coder 30 years ago
Any way we can see some of your work? Maybe a YouTube video; or even better, an ADF file? Would love to see it.
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Re: Fire anim...

Post by Olli »

@caronte3d

I think you can replace this original line...

Code: Select all

nc = ci >> (32 + ii) & $FFFFFFFF
with this new line...

Code: Select all

nc.q = RSQ(@ci, (32 + ii) ) & $FFFFFFFF
... and insert in the head of the code this procedure

Code: Select all

Procedure RSQ(*qw, shift)
   ! mov ecx, [p.v_shift]
   ! mov ebp, [p.p_qw]
   ! mov eax, [ebp + 4]
   ! shrd [ebp], eax, cL
   ! shr eax, cL
   ! mov [ebp + 4], eax
EndProcedure
RSQ(*quadword, bitshift) has normally the same behaviour than this in X64 :

Code: Select all

A.q >> i.i
RSQ = (R)ight (S)hift (Q)uadword

Even if useless in this subject, here is the (L)eft (S)hift (Q)uadword procedure :

Code: Select all

Procedure LSQ(*qw, shift)
   ! mov ecx, [p.v_shift]
   ! mov ebp, [p.p_qw]
   ! mov eax, [ebp]
   ! shld [ebp + 4], eax, cL
   ! shl eax, cL
   ! mov [ebp], eax
EndProcedure
Note, the 2 procedures access to the quad variable are done through its address.

Code: Select all

; Quad bit shift on X86 - Example
Define.q x = $FE00000CD0000001
LSQ(@x, 4)
Debug Hex(x) ; should return $E00000CD00000010
RSQ(@x, 4)
Debug Hex(x) ; should return $FE00000CD0000001
I thank you a lot for the time you have given to me, by testing my codes. If errors, or other, do not hesitate to tell me.
Post Reply