Page 1 of 2 12 LastLast
Results 1 to 10 of 17

Thread: Fire effect from Doom port for original Playstation :D

  1. #1
    Super Moderator Petr Schreiber's Avatar
    Join Date
    Aug 2005
    Location
    Brno - Czech Republic
    Posts
    7,128
    Rep Power
    732

    Lightbulb Fire effect from Doom port for original Playstation :D

    Fabien Sanglard posted quite cool analysis of fire effect, used for PSX port of the original Doom.

    It is a fascinating read, highly recommended.

    I ported the code to thinBasic, with some slight modifications. It could be optimized way better, but the effect pretty pretty:
    ' Code adapted from http://fabiensanglard.net/doom_fire_psx/index.html and slightly modified
    
    
    uses "ui"
    
    
    type DoomPsxFire
    
    
      fire_width  as int32
      fire_height as int32
    
    
      palette(37) as int32  ' Holds palette of fire colors
      fire()      as Int32  ' Holds indices referencing the paletter
    
    
      function _Create(fire_width as int32, fire_height as int32)
        me.fire_width  = fire_width
        me.fire_height = fire_height
        
        me.palette(1)  = bgr(0x07,0x07,0x07), bgr(0x1F,0x07,0x07), bgr(0x2F,0x0F,0x07), bgr(0x47,0x0F,0x07), bgr(0x57,0x17,0x07), bgr(0x67,0x1F,0x07),
                         bgr(0x77,0x1F,0x07), bgr(0x8F,0x27,0x07), bgr(0x9F,0x2F,0x07), bgr(0xAF,0x3F,0x07), bgr(0xBF,0x47,0x07), bgr(0xC7,0x47,0x07),
                         bgr(0xDF,0x4F,0x07), bgr(0xDF,0x57,0x07), bgr(0xDF,0x57,0x07), bgr(0xD7,0x5F,0x07), bgr(0xD7,0x5F,0x07), bgr(0xD7,0x67,0x0F),
                         bgr(0xCF,0x6F,0x0F), bgr(0xCF,0x77,0x0F), bgr(0xCF,0x7F,0x0F), bgr(0xCF,0x87,0x17), bgr(0xC7,0x87,0x17), bgr(0xC7,0x8F,0x17),
                         bgr(0xC7,0x97,0x1F), bgr(0xBF,0x9F,0x1F), bgr(0xBF,0x9F,0x1F), bgr(0xBF,0xA7,0x27), bgr(0xBF,0xA7,0x27), bgr(0xBF,0xAF,0x2F),
                         bgr(0xB7,0xAF,0x2F), bgr(0xB7,0xB7,0x2F), bgr(0xB7,0xB7,0x37), bgr(0xCF,0xCF,0x6F), bgr(0xDF,0xDF,0x9F), bgr(0xEF,0xEF,0xC7), bgr(0xFF,0xFF,0xFF)
        
        redim me.fire(me.fire_width*me.fire_height)
        
        int32 i
        
        ' Initialize screen
        for i = 1 to me.fire_width
          me.fire(i) = 37 ' Initial color, just for one row
        next
        
        for i = me.fire_width+1 to me.fire_width*me.fire_height
          me.fire(i) = 1  ' Background color
        next
      end function
      
      function DoFire()
        int32 x, y
        for x = 1 to me.fire_width
          for y = 1 to me.fire_height-1
            me.SpreadFire((y-1) * me.fire_width + x)
          Next
        Next
      end function
      
      ' --
      
      function SpreadFire(src as int32)
        int32 rand = rnd(0, 3) and 3
        int32 target_pixel = minMax(src + rand - 2 + me.FIRE_WIDTH, 1, ubound(me.fire))
        me.fire(target_pixel) = minmax(me.fire(src) - (rand and 1), 1, 37)
      end function
      
      function GetBitmap() as String
        dim trueColors(me.fire_width * me.fire_height) as Int32
        
        int32 fire_index, true_color_index
        int32 fire_color_index
        
        ' We need to convert palette colors to real colors
        for fire_index = ubound(me.fire) to 1 step -1
            fire_color_index = me.fire(fire_index)
    
    
            incr true_color_index
            trueColors(true_color_index) = me.palette(fire_color_index)
        next
    
    
        ' Once the conversion is done, we lick part of the memory to get bitmap
        return peek$(VarPtr(trueColors(1)), sizeof(int32) * countof(trueColors))
      end function
    
    
    end type
    
    
    %FIRE_WIDTH  = 128
    %FIRE_HEIGHT = 96
    
    
    function TBMain()
    
    
      uint32 hCanvas = Canvas_Window("Doom PSX Fire", 100, 100, %FIRE_WIDTH, %FIRE_HEIGHT)
      Canvas_attach(hCanvas, 0, FALSE)
    
    
      dim doom as DoomPsxFire(%FIRE_WIDTH, %FIRE_HEIGHT)
    
    
      while IsWindow(hCanvas)
    
    
        doom.DoFire()
        
        Canvas_BitmapSet(doom.GetBitmap(), %FIRE_WIDTH, %FIRE_HEIGHT)
        Canvas_Redraw
        
      wend
       
      Canvas_Window End
      
    end Function
    

    Petr
    Attached Files Attached Files
    Last edited by Petr Schreiber; 28-05-2019 at 11:25.
    Learn 3D graphics with ThinBASIC, learn TBGL!
    Windows 10 64bit - Intel Core i5-3350P @ 3.1GHz - 16 GB RAM - NVIDIA GeForce GTX 1050 Ti 4GB

  2. #2
    thinBasic author ErosOlmi's Avatar
    Join Date
    Sep 2004
    Location
    Milan - Italy
    Age
    57
    Posts
    8,777
    Rep Power
    10
    Thanks a lot Petr!
    A great example to push thinBasic at its limits.
    Calling thousand of times script functions is not the best for thinBasic

    Here I've got a little speed improve merging 2 functions into one in such a way to avoid function calling thousand of times per second. Code i less elegant but is faster
    I will use this example to see if I can improve Core engine to parse UDT elements

    ' Code adapted from http://fabiensanglard.net/doom_fire_psx/index.html and slightly modified
    
    uses "ui"
    
    type DoomPsxFire
    
      fire_width  as int32
      fire_height as int32
    
    
      palette(37) as int32  ' Holds palette of fire colors
      fire()      as Int32  ' Holds indices referencing the paletter
    
    
      function _Create(fire_width as int32, fire_height as int32)
        me.fire_width  = fire_width
        me.fire_height = fire_height
        
        me.palette(1)  = bgr(0x07,0x07,0x07), bgr(0x1F,0x07,0x07), bgr(0x2F,0x0F,0x07), bgr(0x47,0x0F,0x07), bgr(0x57,0x17,0x07), bgr(0x67,0x1F,0x07),
                         bgr(0x77,0x1F,0x07), bgr(0x8F,0x27,0x07), bgr(0x9F,0x2F,0x07), bgr(0xAF,0x3F,0x07), bgr(0xBF,0x47,0x07), bgr(0xC7,0x47,0x07),
                         bgr(0xDF,0x4F,0x07), bgr(0xDF,0x57,0x07), bgr(0xDF,0x57,0x07), bgr(0xD7,0x5F,0x07), bgr(0xD7,0x5F,0x07), bgr(0xD7,0x67,0x0F),
                         bgr(0xCF,0x6F,0x0F), bgr(0xCF,0x77,0x0F), bgr(0xCF,0x7F,0x0F), bgr(0xCF,0x87,0x17), bgr(0xC7,0x87,0x17), bgr(0xC7,0x8F,0x17),
                         bgr(0xC7,0x97,0x1F), bgr(0xBF,0x9F,0x1F), bgr(0xBF,0x9F,0x1F), bgr(0xBF,0xA7,0x27), bgr(0xBF,0xA7,0x27), bgr(0xBF,0xAF,0x2F),
                         bgr(0xB7,0xAF,0x2F), bgr(0xB7,0xB7,0x2F), bgr(0xB7,0xB7,0x37), bgr(0xCF,0xCF,0x6F), bgr(0xDF,0xDF,0x9F), bgr(0xEF,0xEF,0xC7), 
                         bgr(0xFF,0xFF,0xFF)
        
        redim me.fire(me.fire_width * me.fire_height)
        
        int32 i
        
        ' Initialize screen
        for i = 1 to me.fire_width
          me.fire(i) = 37 ' Initial color, just for one row
        next
        
        for i = me.fire_width + 1 to me.fire_width * me.fire_height
          me.fire(i) = 1  ' Background color
        next
      end function
      
      function DoFire()
        static x, y as Int32
        static rand         as int32
        static target_pixel as int32
        static src          as int32
        
        for x = 1 to me.fire_width
          for y = 1 to me.fire_height-1
            'me.SpreadFire((y-1) * me.fire_width + x)
            
    
            src = (y-1) * me.fire_width + x
            rand         = rnd(0, 3) and 3
            target_pixel = minMax(src + rand - 2 + me.FIRE_WIDTH, 1, ubound(me.fire))
    
            me.fire(target_pixel) = minmax(me.fire(src) - (rand and 1), 1, 37)
    
          Next
        Next
      end function
      
     ' ' --
    '  function SpreadFire(src as int32) as long
    '    static rand         as int32
    '    static target_pixel as int32
    '    
    '    rand         = rnd(0, 3) and 3
    '    target_pixel = minMax(src + rand - 2 + me.FIRE_WIDTH, 1, ubound(me.fire))
    '
    '    me.fire(target_pixel) = minmax(me.fire(src) - (rand and 1), 1, 37)
    '    
    '  end function
      
      function GetBitmap() as String
        static trueColors(me.fire_width * me.fire_height) as Int32
    
        Int32 fire_index, true_color_index
        int32 fire_color_index 
    
        ' We need to convert palette colors to real colors
        for fire_index = ubound(me.fire) to 1 step -1
            fire_color_index = me.fire(fire_index)
    
            incr true_color_index
            trueColors(true_color_index) = me.palette(fire_color_index)
        next
    
        '---Once the conversion is done, we lick part of the memory to get bitmap
        function = peek$(VarPtr(trueColors(1)), sizeof(int32) * countof(trueColors))
        
      end function
    
    
    end type
    
    
    %FIRE_WIDTH  = 160
    %FIRE_HEIGHT = 120
    
    
    function TBMain()
    
    
      uint32 hCanvas = Canvas_Window("Doom PSX Fire", 100, 100, %FIRE_WIDTH, %FIRE_HEIGHT)
      Canvas_attach(hCanvas, 0, FALSE)
    
    
      dim doom as DoomPsxFire(%FIRE_WIDTH, %FIRE_HEIGHT)
    
    
      while IsWindow(hCanvas)
    
    
        doom.DoFire()
        
        Canvas_BitmapSet(doom.GetBitmap(), %FIRE_WIDTH, %FIRE_HEIGHT)
        Canvas_Redraw
        
      wend
       
      Canvas_Window End
      
    end Function
    
    Attached Images Attached Images
    Attached Files Attached Files
    Last edited by ErosOlmi; 28-05-2019 at 14:51.
    www.thinbasic.com | www.thinbasic.com/community/ | help.thinbasic.com
    Windows 10 Pro for Workstations 64bit - 32 GB - Intel(R) Xeon(R) W-10855M CPU @ 2.80GHz - NVIDIA Quadro RTX 3000

  3. #3

    Question

    Quote Originally Posted by ErosOlmi View Post
    Calling thousand of times script functions is not the best for thinBasic
    would Memoization be relevant here ?
    ThinBasic 1.11.6.0 ALPHA - Windows 8.1 x64

  4. #4
    Super Moderator Petr Schreiber's Avatar
    Join Date
    Aug 2005
    Location
    Brno - Czech Republic
    Posts
    7,128
    Rep Power
    732
    Hi DirectuX,

    very cool idea - as the functions modify global state of the object (indicating a bit of code smell), I presume memoization would be more difficult to setup here.


    Petr
    Learn 3D graphics with ThinBASIC, learn TBGL!
    Windows 10 64bit - Intel Core i5-3350P @ 3.1GHz - 16 GB RAM - NVIDIA GeForce GTX 1050 Ti 4GB

  5. #5
    Super Moderator Petr Schreiber's Avatar
    Join Date
    Aug 2005
    Location
    Brno - Czech Republic
    Posts
    7,128
    Rep Power
    732
    Further speedup achieved by reducing two nested for/next loops to a single one. Gave me 10%+ extra performance:
      function DoFire()
        static rand         as int32
        static target_pixel as int32
        static src          as int32
        
        static top as int32 = (me.fire_width-1) * me.fire_height
        for src = 1 to top
            rand         = rnd(0, 3) and 3
            target_pixel = minMax(src + rand - 2 + me.FIRE_WIDTH, 1, ubound(me.fire))
    
    
            me.fire(target_pixel) = minmax(me.fire(src) - (rand and 1), 1, 37)
        Next
      end function
    
    Further optimization could lead to avoid calling rnd every time, and using some pre generated "randoms", already with "-2 + me.fire_width" included.


    Petr
    Learn 3D graphics with ThinBASIC, learn TBGL!
    Windows 10 64bit - Intel Core i5-3350P @ 3.1GHz - 16 GB RAM - NVIDIA GeForce GTX 1050 Ti 4GB

  6. #6
    Quote Originally Posted by Petr Schreiber View Post
    Further speedup achieved by reducing two nested for/next loops to a single one. Gave me 10%+ extra performance:
            target_pixel = minMax(src + rand - 2 + me.FIRE_WIDTH, 1, ubound(me.fire))
    
    ubound(me.fire) can also be stored in a variable before iterating

    and.. what about Oxygen ?

    Edit: Seems I can't put together thinbasic's SharedArray.tbasic oxygen sample script and UDTs
    Last edited by DirectuX; 29-05-2019 at 22:20.
    ThinBasic 1.11.6.0 ALPHA - Windows 8.1 x64

  7. #7
    me.fire is a dynamic array. To access it as a parameter , I found that oxygen had to use 2 additional levels of indirection.

  8. #8
    thinBasic author ErosOlmi's Avatar
    Join Date
    Sep 2004
    Location
    Milan - Italy
    Age
    57
    Posts
    8,777
    Rep Power
    10
    Quote Originally Posted by DirectuX View Post
    ubound(me.fire) can also be stored in a variable before iterating

    and.. what about Oxygen ?

    Edit: Seems I can't put together thinbasic's SharedArray.tbasic oxygen sample script and UDTs
    I'm using this Petr example to make further tests.
    I found some problems in thinBasic thanks to this example.

    For example
    VARPTR(me.fire(1))
    
    is wrong sorry about that.

    Instead of returning a pointer to first data element of the dynamic array it returns the pointer of location inside Me where Fire pointer array structure is located (that is a pointer to the array data structure)
    So I'm making some fix and will release soon.
    Last edited by ErosOlmi; 30-05-2019 at 10:40.
    www.thinbasic.com | www.thinbasic.com/community/ | help.thinbasic.com
    Windows 10 Pro for Workstations 64bit - 32 GB - Intel(R) Xeon(R) W-10855M CPU @ 2.80GHz - NVIDIA Quadro RTX 3000

  9. #9
    Here is my oxygen-supported code keeping as close to Petr's original code as possible

    The canvas is 4 times larger, but the cpu time is 0%
    Attached Files Attached Files
    Last edited by Charles Pegge; 30-05-2019 at 13:34.

  10. #10
    Super Moderator Petr Schreiber's Avatar
    Join Date
    Aug 2005
    Location
    Brno - Czech Republic
    Posts
    7,128
    Rep Power
    732
    Hi Charles,

    nice to see you again

    I get "unidentified instruction: uses" error for your example.


    Petr
    Learn 3D graphics with ThinBASIC, learn TBGL!
    Windows 10 64bit - Intel Core i5-3350P @ 3.1GHz - 16 GB RAM - NVIDIA GeForce GTX 1050 Ti 4GB

Page 1 of 2 12 LastLast

Similar Threads

  1. no water effect ;)
    By Lionheart008 in forum TBGL General
    Replies: 11
    Last Post: 09-05-2009, 09:54
  2. little sphero and effect example with entities
    By Lionheart008 in forum TBGL General
    Replies: 7
    Last Post: 08-04-2009, 14:20
  3. 4 Port 3D Viewer
    By Charles Pegge in forum Programs
    Replies: 2
    Last Post: 21-03-2009, 09:05
  4. Very simple particle effect
    By Petr Schreiber in forum TBGL Scripts and Projects
    Replies: 5
    Last Post: 20-01-2008, 11:31
  5. C&C original a free download now
    By kryton9 in forum Gaming
    Replies: 3
    Last Post: 13-09-2007, 08:28

Members who have read this thread: 0

There are no members to list at the moment.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •