-
Notifications
You must be signed in to change notification settings - Fork 41
Expand file tree
/
Copy pathfire.nim
More file actions
159 lines (134 loc) · 4.62 KB
/
Copy pathfire.nim
File metadata and controls
159 lines (134 loc) · 4.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#? replace(sub = "\t", by = " ")
# import std/lenientops
import std/random
import std/tables
import nico
# https://gist.github.com/emanuel-sanabria-developer/5793377
# Converts an HSL color value to RGB. Conversion formula
# adapted from http://en.wikipedia.org/wiki/HSL_color_space.
proc hsl2rgb( h8, s8, l8: int ): tuple =
let h = h8 / 255
let s = s8 / 255
let l = l8 / 255
var r, g, b: float
if s == 0:
r = l; g = l; b = l # achromatic
else:
proc hue2rgb( p, q, t: float ): float =
var t = t
if t < 0: t += 1
if t > 1: t -= 1
if t < 1 / 6: return p + ( q - p ) * 6 * t
if t < 1 / 2: return q
if t < 2 / 3: return p + ( q - p ) * ( 2 / 3 - t ) * 6
return p
let q = if l < 0.5: l * (1 + s) else: l + s - l * s
let p = 2 * l - q
r = hue2rgb( p, q, h + 1 / 3 )
g = hue2rgb( p, q, h)
b = hue2rgb( p, q, h - 1 / 3 )
return ( r * 255, g * 255, b * 255 )
proc loadPaletteFire( color: range[ 0 .. 4 ] ): Palette =
proc transferFunc( value: int ): int =
return min( 255, value * 2 )
# return int( sqrt( value / 255 ) * 255 )
var offset {.global.} = 0
var r, g, b: float
for i in 0 .. 255:
case color
of 0: # white - yellow - red
( r, g, b ) = hsl2rgb( int( i / 3 ), 255, transferFunc( i ) )
of 1: # white - yellow - green
( r, g, b ) = hsl2rgb( int( 1 * 255 / 3 - i / 3 ), 255, transferFunc( i ) )
of 2: # white - turquoise - blue
( r, g, b ) = hsl2rgb( int( 2 * 255 / 3 - i / 3 ), 255, transferFunc( i ) )
of 3: # white - magenta - red
( r, g, b ) = hsl2rgb( int( 3 * 255 / 3 - i / 3 ), 255, transferFunc( i ) )
of 4: # color cycle
# ( r, g, b ) = hsl2rgb( int( ( i + offset ) / 3 ) mod 256, 255, transferFunc( i ) )
( r, g, b ) = hsl2rgb( int( offset / 3 ) mod 256, 255, transferFunc( i ) )
result.data[ i ] = ( r.uint8, g.uint8, b.uint8 )
result.size = 256
offset += 1
proc keyPressed( keycode: Keycode ): bool =
var previousKeys {.global.} = initTable[ Keycode, bool ]()
let isKeyPressed = key( keycode )
result = isKeyPressed and not previousKeys.getOrDefault( keycode )
previousKeys[ keycode ] = isKeyPressed
proc gameInit() =
# setVSync( false )
# echo getVSync()
# cls()
fps( 20 )
setPalette( loadPaletteFire( 0 ) )
loadMusic( 0, "fire_1.ogg" )
music( 15, 0 ) # Needs to be rendered at 60 fps with the default audioBufferSize.
setAudioBufferSize( 1024 * 2 * 60 div fps() ) # So we adjust it to our needs.
setColor( 255 )
printc( "KEYS:", screenWidth / 2, screenHeight / 3, 5 )
printc( "S C M P", screenWidth / 2, 2 * screenHeight / 3, 5 )
proc gameUpdate( dt: Pfloat ) =
discard
const
width = 160
# width = 1200
height = 90
# height = 125
scale = 3
proc gameDraw() =
var frame {.global.}: int32 = -1
var fireArray {.global.}: array[ width, uint8 ]
var randomizeFire {.global.}: bool = true
frame += 1
# Toggle sound playback with s key:
if keyPressed( K_s ):
if getMusic( 15 ) == -1:
music( 15, 0 )
printc( "SND ON", screenWidth / 2, screenHeight / 2, 5 )
else:
music( 15, -1 )
printc( "SND OFF", screenWidth / 2, screenHeight / 2, 5 )
# Cycle fire color with c key:
var fireColor {.global.} = 0
if keyPressed( K_c ):
fireColor = ( fireColor + 1 ) mod 5
setPalette( loadPaletteFire( fireColor ) )
const colors = [ "ORANGE", "GREEN", "BLUE", "MAGENTA", "CYCLE" ]
printc( colors[ fireColor ], screenWidth / 2, screenHeight / 2, 5 )
if fireColor == 4:
setPalette( loadPaletteFire( 4 ) )
# Toggle message displaying with m key:
var showMessage {.global.}:bool = false
if keyPressed( K_m ):
showMessage = not showMessage
# Randomize fire every other frame.
if randomizeFire:
randomizeFire = false
for x in 0 ..< screenWidth:
fireArray[ x ] = rand( 255 ).uint8
else:
randomizeFire = not key( K_p ) # Pause fire with p key.
const border = 5
for x in border ..< screenWidth - border:
pset( x, screenHeight - 2, fireArray[ x ] )
pset( x, screenHeight - 1, fireArray[ x ] )
if showMessage:
const message = [ "", "", "HAPPY", "NEW", "YEAR", "2024", ":-)", ]
if frame mod ( fps() * 2 ) == 0:
setColor( 255 )
printc( message[ ( frame div ( fps() * 2 ) ) mod len( message ) ],
screenWidth / 2, screenHeight / 2, 5 )
# https://lodev.org/cgtutor/fire.html
for y in 0 ..< screenHeight - 2:
for x in 1 ..< screenWidth - 1:
let color = ( pget( x - 1, y + 1 ) + pget( x, y + 1 ) + pget( x + 1, y + 1 ) +
pget( x, y + 2 ) ) / 4.1
pset( x, y, color.int )
for x in border ..< screenWidth - border:
pset( x, screenHeight - 2, 255 )
pset( x, screenHeight - 1, 0 )
nico.init( "nico", "test" )
fixedSize( true )
integerScale( true )
nico.createWindow( "fire", width, height + 2, scale )
nico.run( gameInit, gameUpdate, gameDraw )