Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
-- multiple effects ?
engine.name = "TestSine"
local effects = {
tremolo={
name="tremolo"
},
fuzz={
name="fuzz"
},
hall_reverb={
name="hall reverb"
}
}
-- todo: use the parameters, not a local
local gloom_state = {
effects={
{effect_id="tremolo", on=true},
{effect_id="fuzz", on=true},
{effect_id="hall_reverb", on=false},
{effect_id="tremolo", on=true},
{effect_id="fuzz", on=false},
{effect_id="hall_reverb", on=true},
{effect_id="tremolo", on=false},
{effect_id="fuzz", on=true}
},
selected=2,
mode="top"
}
local pedal_sprite = {
{10, 10, 10, 10, 10, 10, 10, 10, 10},
{10, 0, 0, 0, 0, 0, 0, 0, 10},
{10, 0, 5, 0, 5, 0, 5, 0, 10},
{10, 0, 0, 0, 0, 0, 0, 0, 10},
{10, 10, 10, 10, 10, 10, 10, 10, 10},
{10, 0, 0, 0, 0, 0, 0, 0, 10},
{10, 0, 10, 10, 10, 10, 10, 0, 10},
{10, 0, 10, 10, 10, 10, 10, 0, 10},
{10, 0, 10, 10, 10, 10, 10, 0, 10},
{10, 0, 10, 10, 10, 10, 10, 0, 10},
{10, 0, 10, 10, 10, 10, 10, 0, 10},
{10, 0, 0, 0, 0, 0, 0, 0, 10},
{10, 10, 10, 10, 10, 10, 10, 10, 10},
}
local pedal_off_sprite = {
{10, 10, 10, 10, 10, 10, 10, 10, 10},
{10, 0, 0, 0, 0, 0, 0, 0, 10},
{10, 0, 5, 0, 5, 0, 5, 0, 10},
{10, 0, 0, 0, 0, 0, 0, 0, 10},
{10, 10, 10, 10, 10, 10, 10, 10, 10},
{10, 0, 0, 0, 0, 0, 0, 0, 10},
{10, 0, 10, 10, 10, 10, 10, 0, 10},
{10, 0, 10, 5, 10, 5, 10, 0, 10},
{10, 0, 10, 10, 5, 10, 10, 0, 10},
{10, 0, 10, 5, 10, 5, 10, 0, 10},
{10, 0, 10, 10, 10, 10, 10, 0, 10},
{10, 0, 0, 0, 0, 0, 0, 0, 10},
{10, 10, 10, 10, 10, 10, 10, 10, 10},
}
local bubble_tail_sprite = {
{10, 0, 0, 0, 0, 0, 10},
{ 0, 10, 0, 0, 0, 10, 0},
{ 0, 0, 10, 0, 10, 0, 0},
{ 0, 0, 0, 10, 0, 0, 0}
}
local add_sprite = {
{ 0, 0, 0, 0, 2, 10, 10, 2, 0, 0, 0, 0},
{ 0, 0, 0, 0, 10, 6, 6, 10, 0, 0, 0, 0},
{ 0, 0, 0, 0, 10, 6, 6, 10, 0, 0, 0, 0},
{ 0, 0, 0, 2, 10, 6, 6, 10, 0, 0, 0, 0},
{ 2, 10, 10, 10, 10, 6, 6, 10, 10, 10, 10, 2},
{10, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 10},
{10, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 10},
{ 0, 10, 10, 10, 10, 6, 6, 10, 10, 10, 10, 2},
{ 0, 0, 0, 0, 10, 6, 6, 10, 0, 0, 0, 0},
{ 0, 0, 0, 0, 10, 6, 6, 10, 0, 0, 0, 0},
{ 0, 0, 0, 0, 10, 6, 6, 10, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 10, 10, 0, 0, 0, 0, 0},
}
local minus_sprite = {
{ 2, 10, 10, 0, 0, 0, 0, 0, 10, 10, 2},
{10, 6, 6, 10, 0, 0, 0, 10, 6, 6, 10},
{10, 6, 6, 6, 10, 2, 10, 6, 6, 6, 10},
{ 0, 10, 6, 6, 6, 10, 6, 6, 6, 10, 0},
{ 0, 0, 10, 6, 6, 6, 6, 6, 10, 0, 0},
{ 0, 0, 2, 10, 6, 6, 6, 10, 2, 0, 0},
{ 0, 0, 10, 6, 6, 6, 6, 6, 10, 0, 0},
{ 0, 10, 6, 6, 6, 10, 6, 6, 6, 10, 0},
{10, 6, 6, 6, 10, 2, 10, 6, 6, 6, 10},
{10, 6, 6, 10, 0, 0, 0, 10, 6, 6, 10},
{ 2, 10, 10, 0, 0, 0, 0, 0, 10, 10, 2},
}
function blit(x, y, bitmap, p)
for i=1,#bitmap do
for j=1,#bitmap[i] do
local level = bitmap[i][j]
if p and p.brightness then
level = level * p.brightness
end
screen.level(math.floor(level))
screen.pixel(x + j, y + i)
screen.fill()
end
end
end
function selected_effect()
if gloom_state.selected == 1 or gloom_state.selected > (#gloom_state.effects + 1) then
return nil
end
return gloom_state.selected - 1
end
function selected_add()
return gloom_state.selected == 1
end
function selected_minus()
return gloom_state.selected == #gloom_state.effects + 2
end
function init()
engine.hz(100)
end
function draw_toplevel_effect(p)
local brightness = 0.2
if p.selected then
bubble({x=p.x, y=p.y, text=effects[p.effect.effect_id].name})
brightness = 1
end
local sprite = pedal_sprite
if not p.effect.on then
sprite = pedal_off_sprite
end
blit(p.x, p.y, sprite, {brightness=brightness})
return #pedal_sprite[1] + 1
end
-- todo center this better
function draw_toplevel_effects(p)
local total = p.x
for i=1, #(gloom_state.effects) do
screen.level(p.level)
screen.move(total, p.y + p.height / 2)
total = total + p.space
screen.line(total + 1, p.y + p.height / 2)
screen.stroke()
total = total + draw_toplevel_effect({
effect=gloom_state.effects[i],
x=total,
y=p.y,
selected=selected_effect() == i,
})
end
screen.level(p.level)
screen.move(total, p.y + p.height / 2)
screen.line(total + p.space + 1, p.y + p.height / 2)
screen.stroke()
end
local bubble_width = 80
function bubble(p)
local line_height = 10
-- complicated logic to make it so
-- that the bubble doesn't go off-screen
local center_x = p.x + #pedal_sprite[1] / 2
local max_x = 128 - bubble_width
local x = math.min(math.max(center_x - bubble_width / 2, 1), max_x)
screen.level(10)
screen.rect(x, p.y - line_height - 5, bubble_width, line_height)
screen.move(x + bubble_width / 2, p.y - line_height + 2)
screen.text_center(p.text)
screen.stroke()
blit(p.x + #pedal_sprite[1] / 2 - 3, p.y - line_height + 3, bubble_tail_sprite)
end
function draw_plus_and_minus()
local add_brightness = 0.2
local minus_brightness = 0.2
if selected_add() then
bubble({x=2, y=40, text="add an effect..."})
add_brightness = 1
end
if selected_minus() then
bubble({x=117, y=40, text="...or delete one!"})
minus_brightness = 1
end
blit(0, 40, add_sprite, {brightness=add_brightness})
blit(116, 40, minus_sprite, {brightness=minus_brightness})
end
function redraw()
screen.clear()
screen.aa(0)
screen.line_width(1)
if gloom_state.mode == "top" or gloom_state.mode == "delete" then
local expected_width = #gloom_state.effects * #pedal_sprite[1] + (#gloom_state.effects + 1) * 2
draw_toplevel_effects({x=15 + (90 - expected_width) / 2, y=40, height=13, space=2, level=2})
draw_plus_and_minus()
if gloom_state.mode == "delete" then
screen.level(10)
screen.move(64, 15)
screen.text_center("delete which?")
screen.stroke()
end
elseif gloom_state.mode == "add" then
screen.level(10)
screen.move(64, 15)
screen.text_center("add what?")
screen.move(64, 25)
screen.text_center("(looks like nothing)")
screen.stroke()
end
screen.update()
end
-- todo little mode library
-- ideally: message until you press a key / rotate an encoder
function enter_top()
gloom_state.mode = "top"
gloom_state.selected = 2
end
function enter_delete()
gloom_state.mode = "delete"
gloom_state.selected = 2
end
function enter_add()
gloom_state.mode = "add"
gloom_state.selected = 2
end
function toggle_effect()
gloom_state.effects[selected_effect()].on
= not gloom_state.effects[selected_effect()].on
end
function enc(n, d)
if gloom_state.mode == "top" then
if n == 2 then
gloom_state.selected = gloom_state.selected + (d / math.abs(d))
gloom_state.selected = math.min(math.max(1, gloom_state.selected), #gloom_state.effects + 2)
-- for over/underflow, instead:
-- gloom_state.selected = ((gloom_state.selected - 1) % #gloom_state.effects) + 1;
end
end
if gloom_state.mode == "delete" then
if n == 2 then
-- separate scrolling logic that limits to the effects, i.e. not including +/x
gloom_state.selected = gloom_state.selected + (d / math.abs(d))
gloom_state.selected = math.min(math.max(2, gloom_state.selected), #gloom_state.effects + 1)
-- for over/underflow, instead:
-- gloom_state.selected = ((gloom_state.selected - 1) % #gloom_state.effects) + 1;
end
end
redraw()
end
function key(n,z)
if z == 0 then
if gloom_state.mode == "top" then
if n == 3 and selected_add() then
enter_add()
end
if n == 3 and selected_minus() then
enter_delete()
end
if n == 2 and selected_effect() then
toggle_effect()
end
elseif gloom_state.mode == "delete" then
if n == 2 then
enter_top()
end
if n == 3 and selected_add() then
enter_add()
end
if n == 3 and selected_minus() then
enter_delete()
end
if n == 3 and selected_effect() then
if #gloom_state.effects ~= 1 then
-- todo message about this
table.remove(gloom_state.effects, selected_effect())
enter_top()
end
end
elseif gloom_state.mode == "add" then
if n == 2 then
enter_top()
end
end
redraw()
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.