###############################################################################ഀ ## burn-console.mshഀ ##ഀ ## Create a fire effect in MSH, using the Console text buffer as the renderingഀ ## surface.ഀ ##ഀ ## Great overview of the fire effect algorithm here: ഀ ## http://freespace.virgin.net/hugo.elias/models/m_fire.htmഀ ##ഀ ###############################################################################ഀ ഀ function mainഀ {ഀ ## Rather than a simple red fire, we'll introduce oranges and yellowsഀ ## by including Yellow as one of the base coloursഀ $colours = "Yellow","Red","DarkRed","Black"ഀ ഀ ## The four characters that we use to dither with, along with the ഀ ## percentage of the foreground colour that they showഀ $dithering = "█","▓","▒","░"ഀ $ditherFactor = 1,0.75,0.5,0.25ഀ ഀ ## Hold the palette. We actually store each entry as a BufferCell,ഀ ## since we need to retain a foreground colour, background colour,ഀ ## and dithering character.ഀ $palette = `ഀ @(new-object System.Management.Automation.Host.BufferCell) * 256ഀ ഀ ## Generate, then display, the paletteഀ clear-hostഀ generatePaletteഀ displayPaletteഀ ഀ ## Clean up and exitഀ $host.UI.RawUI.ForegroundColor = "Gray"ഀ $host.UI.RawUI.BackgroundColor = "Black"ഀ }ഀ ഀ ## Generates a palette of 256 colours. We create every combination of ഀ ## foreground colour, background colour, and dithering character, and thenഀ ## order them by their visual intensity.ഀ ##ഀ ## The visual intensity of a colour can be expressed by the NTSC luminance ഀ ## formula. That formula depicts the apparent brightness of a colour based on ഀ ## our eyes' sensitivity to different wavelengths that compose that colour.ഀ ## http://en.wikipedia.org/wiki/Luminance_%28video%29ഀ function generatePaletteഀ {ഀ ## The apparent intensities of our four primary colours.ഀ ## However, the formula under-represents the intensity of our straightഀ ## red colour, so we artificially inflate it.ഀ $luminances = 225.93,106.245,38.272,0ഀ $apparentBrightnesses = @{}ഀ ഀ ## Cycle through each foreground, background, and dither characterഀ ## combination. For each combination, find the apparent intensity of the ഀ ## foreground, and the apparent intensity of the background. Finally,ഀ ## weight the contribution of each based on how much of each colour theഀ ## dithering character shows.ഀ ## This provides an intensity range between zero and some maximum.ഀ ## For each apparent intensity, we store the colours and charactersഀ ## that create that intensity.ഀ $maxBrightness = 0ഀ for($fgColour = 0; $fgColour -lt $colours.Count; $fgColour++)ഀ {ഀ for($bgColour = 0; $bgColour -lt $colours.Count; $bgColour++)ഀ {ഀ for($ditherCharacter = 0; ഀ $ditherCharacter -lt $dithering.Count; ഀ $ditherCharacter++)ഀ {ഀ $apparentBrightness = `ഀ $luminances[$fgColour] * $ditherFactor[$ditherCharacter] +`ഀ $luminances[$bgColour] * ഀ (1 - $ditherFactor[$ditherCharacter])ഀ ഀ if($apparentBrightness -gt $maxBrightness) ഀ { ഀ $maxBrightness = $apparentBrightness ഀ }ഀ ഀ $apparentBrightnesses[$apparentBrightness] = `ഀ "$fgColour$bgColour$ditherCharacter"ഀ }ഀ }ഀ }ഀ ഀ ## Finally, we normalize our computed intesities into a pallete ofഀ ## 0 to 255. If a given intensity is 30% towards our maximum intensity,ഀ ## then it should be in the palette at 30% of index 255.ഀ $paletteIndex = 0ഀ foreach($key in ($apparentBrightnesses.Keys | sort))ഀ {ഀ $keyValue = $apparentBrightnesses[$key]ഀ doഀ {ഀ $character = $dithering[[Int32]::Parse($keyValue[2])]ഀ $fgColour = $colours[[Int32]::Parse($keyValue[0])]ഀ $bgColour = $colours[[Int32]::Parse($keyValue[1])]ഀ ഀ $bufferCell = `ഀ new-object System.Management.Automation.Host.BufferCell `ഀ $character, `ഀ $fgColour, `ഀ $bgColour, `ഀ "Complete"ഀ ഀ $palette[$paletteIndex] = $bufferCellഀ $paletteIndex++ഀ } while(($paletteIndex / 256) -lt ($key / $maxBrightness));ഀ }ഀ }ഀ ഀ ## Dump the palette to the screen.ഀ function displayPaletteഀ {ഀ for($paletteIndex = 254; $paletteIndex -ge 0; $paletteIndex--)ഀ {ഀ $bufferCell = $palette[$paletteIndex]ഀ $fgColor = $bufferCell.ForegroundColorഀ $bgColor = $bufferCell.BackgroundColorഀ $character = $bufferCell.Characterഀ ഀ $host.UI.RawUI.ForegroundColor = $fgColorഀ $host.UI.RawUI.BackgroundColor = $bgColorഀ write-host -noNewLine $characterഀ }ഀ ഀ write-hostഀ }ഀ ഀ . main