-
Notifications
You must be signed in to change notification settings - Fork 500
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cosmic #641
Conversation
if(unicorn == this) { | ||
if(graphics->pen_type == PicoGraphics::PEN_RGB888) { | ||
uint32_t *p = (uint32_t *)graphics->frame_buffer; | ||
for(size_t j = 0; j < 32 * 32; j++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should just loop through y and x values here, since we already know their ranges and calculating them from j
is unnecessarily costly.
765a086
to
bac4a0b
Compare
Using ulab/numpy on the latest build (gosh I hope we don't blow the firmware size here) this code will get ~60FPS fire: import time
import random
from cosmic import CosmicUnicorn
from picographics import PicoGraphics, DISPLAY_COSMIC_UNICORN, PEN_P8
from ulab import numpy
import machine
# MAXIMUM OVERKILL
machine.freq(250_000_000)
gu = CosmicUnicorn()
graphics = PicoGraphics(DISPLAY_COSMIC_UNICORN, pen_type=PEN_P8)
PALETTE_SIZE = 8
# Create the fire palette
graphics.create_pen(0, 0, 0)
graphics.create_pen(0, 0, 0)
graphics.create_pen(20, 20, 20)
graphics.create_pen(100, 30, 0)
graphics.create_pen(180, 30, 0)
graphics.create_pen(220, 160, 0)
graphics.create_pen(255, 255, 180)
graphics.create_pen(255, 255, 220)
@micropython.native # noqa: F821
def update():
# take local references as it's quicker than accessing the global
# and we access it a lot in this method
_heat = heat
_randint = random.randint
_height = height
# clear the bottom row and then add a new fire seed to it
_heat[height - 1][:] = 0.0
_heat[height - 2][:] = 0.0
for c in range(fire_spawns):
x = _randint(0, width - 4) + 2
_heat[_height - 1][x - 1:x + 1] = 1.0
_heat[_height - 2][x - 1:x + 1] = 1.0
# y + 1, x
a = numpy.roll(_heat, -1, axis=0)
# y + 2, x
b = numpy.roll(_heat, -2, axis=0)
# y + 1
c = numpy.roll(_heat, -1, axis=0)
# y + 1, x - 1
d = numpy.roll(c, 1, axis=1)
e = numpy.roll(c, -1, axis=1)
# Average over 5 adjacent pixels and apply damping
_heat += a + b + d + e
_heat[:] *= damping_factor / 5.0
@micropython.native # noqa: F821
def draw():
memoryview(graphics)[:] = numpy.ndarray(heat[0:32, 0:32] * PALETTE_SIZE, dtype=numpy.uint8).tobytes()
gu.update(graphics)
width = CosmicUnicorn.WIDTH
height = CosmicUnicorn.HEIGHT + 4
heat = numpy.zeros((height, width))
fire_spawns = 5
damping_factor = 0.999
gu.set_brightness(0.5)
while True:
if gu.is_pressed(CosmicUnicorn.SWITCH_BRIGHTNESS_UP):
gu.adjust_brightness(+0.01)
if gu.is_pressed(CosmicUnicorn.SWITCH_BRIGHTNESS_DOWN):
gu.adjust_brightness(-0.01)
tstart = time.ticks_ms()
update()
tupdate = time.ticks_ms()
draw()
tfinish = time.ticks_ms()
total = tfinish - tstart
#print(f"Update: {tupdate-tstart}, Draw: {tfinish-tupdate}, Total: {tfinish-tstart}")
# pause for a moment (important or the USB serial device will fail)
# try to pace at 60fps or 30fps
if total > 1000 / 30:
time.sleep(0.0001)
elif total > 1000 / 60:
t = 1000 / 30 - total
time.sleep(t / 1000)
else:
t = 1000 / 60 - total
time.sleep(t / 1000) Palette could probably use a little finesse. |
Okay scratch that, now we have an extensible palette and everything's driven by numpy you can PUMP UP THE FIREEEEEEEE: import time
import random
from cosmic import CosmicUnicorn
from picographics import PicoGraphics, DISPLAY_COSMIC_UNICORN, PEN_P8
from ulab import numpy
import machine
# MAXIMUM OVERKILL
machine.freq(250_000_000)
gu = CosmicUnicorn()
graphics = PicoGraphics(DISPLAY_COSMIC_UNICORN, pen_type=PEN_P8)
# Number of random fire spawns
FIRE_SPAWNS = 5
# Fire damping
DAMPING_FACTOR = 0.98
# TURN UP THE HEEEAAT
HEAT = 3.0
# Create the fire palette
graphics.create_pen(0, 0, 0)
graphics.create_pen(0, 0, 0)
graphics.create_pen(20, 20, 20)
graphics.create_pen(50, 10, 0)
graphics.create_pen(180, 30, 0)
graphics.create_pen(220, 160, 0)
graphics.create_pen(255, 255, 180)
graphics.create_pen(255, 255, 220)
graphics.create_pen(0, 0, 255)
PALETTE_SIZE = 9 # Should match the number of colours defined above
# Bit of a buffer so SUPER HOT fire doesn't turn black
for x in range(10):
graphics.create_pen(255, 255, 255)
@micropython.native # noqa: F821
def update():
# take local references as it's quicker than accessing the global
# and we access it a lot in this method
_heat = heat
_randint = random.randint
_height = height
# clear the bottom row and then add a new fire seed to it
_heat[height - 1][:] = 0.0
_heat[height - 2][:] = 0.0
for c in range(FIRE_SPAWNS):
x = _randint(0, width - 4) + 2
_heat[_height - 1][x - 1:x + 1] = HEAT / 2.0
_heat[_height - 2][x - 1:x + 1] = HEAT
# y + 1, x
a = numpy.roll(_heat, -1, axis=0)
# y + 2, x
b = numpy.roll(_heat, -2, axis=0)
# y + 1
c = numpy.roll(_heat, -1, axis=0)
# y + 1, x - 1
d = numpy.roll(c, 1, axis=1)
e = numpy.roll(c, -1, axis=1)
# Average over 5 adjacent pixels and apply damping
_heat += a + b + d + e
_heat[:] *= DAMPING_FACTOR / 5.0
@micropython.native # noqa: F821
def draw():
memoryview(graphics)[:] = numpy.ndarray(heat[0:32, 0:32] * PALETTE_SIZE, dtype=numpy.uint8).tobytes()
gu.update(graphics)
width = CosmicUnicorn.WIDTH
height = CosmicUnicorn.HEIGHT + 4
heat = numpy.zeros((height, width))
gu.set_brightness(0.5)
while True:
if gu.is_pressed(CosmicUnicorn.SWITCH_BRIGHTNESS_UP):
gu.adjust_brightness(+0.01)
if gu.is_pressed(CosmicUnicorn.SWITCH_BRIGHTNESS_DOWN):
gu.adjust_brightness(-0.01)
tstart = time.ticks_ms()
update()
tupdate = time.ticks_ms()
draw()
tfinish = time.ticks_ms()
total = tfinish - tstart
#print(f"Update: {tupdate-tstart}, Draw: {tfinish-tupdate}, Total: {tfinish-tstart}")
# pause for a moment (important or the USB serial device will fail)
# try to pace at 60fps or 30fps
if total > 1000 / 30:
time.sleep(0.0001)
elif total > 1000 / 60:
t = 1000 / 30 - total
time.sleep(t / 1000)
else:
t = 1000 / 60 - total
time.sleep(t / 1000) |
1a8e4bf
to
f4015f1
Compare
TODODocumentationSame as Galactic? ExamplesNeeds some examples that demonstrate networking
|
9fbb258
to
ccf7fe4
Compare
started on MP driver removed duplacte audio_i2s.pio disabled GU lib options bug fixes bringing Picographics into line Update picographics.cpp fixing naming Cosmic to cosmic fixed H and W
updating demos other demos Update rainbow.py linting fixes Faster flames
drivers and MP implementation for Cosmic unicorn