A vector graphics engine and editing software built in pico-8.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
vectorator/update_logic.lua

171 lines
4.1 KiB

--update logic
function _init()
show_path_handles = true
use_linked_editing = false
record_list = {}
last_edit_pane = 3
current_pane = 3
banks = get_banks(m)
end
function _update()
if btn(5) then
if (btnp(0)) current_pane -= 1
if (btnp(1)) current_pane += 1
if (current_pane > 3) current_pane = 3
if (current_pane < 1) current_pane = 1
if btnp(2) then
if holding ~= nil then
add_node(m, holding)
elseif under ~= nil and current_pane == 3 then
add_node(m, under)
end
end
if btnp(3) then
if holding ~= nil then
remove_node(m, holding, not use_linked_editing)
elseif under ~= nil and current_pane == 3 then
remove_node(m, under, not use_linked_editing)
end
end
else
r_pane_update()
end
l_pane_update()
toolkit_update()
end
--a function to make execution
--records
function add_to_record_list(state, operation)
local record = {}
if (#state.stack == 0) return
record.step = #record_list + 1
record.address = {}
record.address[1] = state.stack[#state.stack][1]
record.address[2] = state.stack[#state.stack][2]-1
record.operation = operation
record.state = deep_copy(state)
record.handle = handle_from_operation(operation, state)
add(record_list, record)
end
function handle_from_operation(operation, state)
local handle = {}
handle.position = {}
handle.position[1] = state.position[1]
handle.position[2] = state.position[2]
handle.sprite = 1
if operation[1] == "scale" then
handle.position[1] -= 8
handle.position[2] -= 8
handle.sprite = 19
elseif operation[1] == "rotate" then
dx = 10*cos(state.rotation)
dy = 10*sin(state.rotation)
handle.position[1] += dx
handle.position[2] += dy
handle.sprite = 3
elseif operation[1] == "place" then
handle.sprite = 2
end
return handle
end
function perform_edit(m, record, dx, dy, transformed)
edit(m, record, dx, dy, transformed)
if not use_linked_editing then
next_step = record_list[record.step+1]
cur_op = record.operation[1]
next_op = next_step.operation[1]
if ((next_op == "draw" or next_op == "move")
and (cur_op == "draw" or cur_op == "move")) then
edit(m, next_step, -dx, -dy, transformed)
end
end
end
function edit(mem, record, cursor_x, cursor_y, transformed)
state = record.state
bank = record.address[1]
line_no = record.address[2]
-- very important to transform *back* into the space of the instruction coordinates
dx = (1.0/state.scale) * (cursor_x*cos(-state.rotation) - cursor_y*sin(-state.rotation))
dy = (1.0/state.scale) * (cursor_x*sin(-state.rotation) + cursor_y*cos(-state.rotation))
-- we need to allow for this.
if not transformed then
dx = cursor_x
dy = cursor_y
end
if (record.operation[1] == "jump") return
if (record.operation[1] == "rotate") then
mem[bank][line_no][2] += 0.01*cursor_y
end
if (record.operation[1] == "scale") then
mem[bank][line_no][2] += 0.02*cursor_y
end
if (record.operation[1] == "return") return
if (record.operation[1] == "draw"
or record.operation[1] == "move"
or record.operation[1] == "place"
or record.operation[1] == "draw_abs") then
mem[bank][line_no][2] += dx
mem[bank][line_no][3] += dy
end
end
function add_node(m, record)
address = record.address
cur_op = record.operation
next_op = m[address[1]][address[2]+1]
if next_op[1] == "draw" then
new_op = {"draw", next_op[2]/2, next_op[3]/2}
next_op[2] = next_op[2]/2
next_op[3] = next_op[3]/2
add(m[address[1]], new_op, address[2]+1)
elseif next_op[1] == "return" or
next_op[1] == "jump" or
next_op[1] == "scale" or
next_op[1] == "rotate" then
new_op = {"draw", cur_op[2]/2, cur_op[3]/2}
add(m[address[1]], new_op, address[2]+1)
end
end
function remove_node(m, record, linked_editing)
address = record.address
cur_op = record.operation
next_op = m[address[1]][address[2]+1]
if next_op[1] == "draw" or
next_op[1] == "move" then
if linked_editing then
next_op[2] += cur_op[2]
next_op[3] += cur_op[3]
end
end
deli(m[address[1]], address[2])
end