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