import {
decompile = "decompile:";
- VAL_TYPES = "decompile:VAL_TYPES";
Ui = "ui:Ui";
UiRegion = "ui:UiRegion";
render_text = "ui:render_text";
+ scissor_points = "utils:scissor_points";
pprint = "lualib.pprint";
}
+TEXT_COLORS = {
+ keyword = { 0.7, 0.7, 1.0 };
+ value = { 0.8, 1.0, 0.8 };
+ text = { 0.9, 0.9, 0.9 };
+ jumppoint = { 1, 0.5, 0.5 };
+
+ header_background = { 0.1, 0.1, 0.1 };
+ background = { 0.15, 0.15, 0.15 };
+}
+
function build_func_header_text(func, mod)
local text = {}
- table.insert(text, { text = "[" .. func.funcidx .. "] ", color = { 0, 0, 0 } })
- table.insert(text, { text = func.name, color = { 0, 0, 1 } })
- table.insert(text, { text = ": ", color = { 0, 0, 0 } })
+ table.insert(text, { text = "[" .. func.funcidx .. "] ", color = TEXT_COLORS.text })
+ table.insert(text, { text = func.name, color = TEXT_COLORS.keyword })
+ table.insert(text, { text = ": ", color = TEXT_COLORS.text })
local type_ = func.type_
for _, t in ipairs(type_.param_types) do
- table.insert(text, { text = t .. " ", color = { 0, 0, 0 } })
+ table.insert(text, { text = t .. " " })
end
if #type_.param_types == 0 then
- table.insert(text, { text = "void ", color = { 0, 0, 0 } })
+ table.insert(text, { text = "void " })
end
- table.insert(text, { text = "-> ", color = { 0, 0, 0 } })
+ table.insert(text, { text = "-> " })
for _, t in ipairs(type_.result_types) do
- table.insert(text, { text = t .. " ", color = { 0, 0, 0 } })
+ table.insert(text, { text = t .. " " })
end
if #type_.result_types == 0 then
- table.insert(text, { text = "void", color = { 0, 0, 0 } })
+ table.insert(text, { text = "void" })
end
table.insert(text, { newline = true })
function add_line_number(textlist, newline)
if newline == nil then newline = true end
table.insert(textlist, { newline = newline })
- table.insert(textlist, { text = ("%4d"):format(line), color = { 0.3, 0.3, 0.3 }, background = { 0.7, 0.7, 0.7 }, post_indent = true })
- table.insert(textlist, { text = " ", color = { 0, 0, 0 }, post_indent = true })
+ table.insert(textlist, { text = ("%4d"):format(line), color = TEXT_COLORS.text, background = TEXT_COLORS.header_background, post_indent = true })
+ table.insert(textlist, { text = " ", post_indent = true })
line = line + 1
end
function instr_to_text(textlist, instr, func, mod)
if instr[1] == "block" then
- table.insert(textlist, { text = "block", color = { 1, 0, 0 }, change_indent = 1 })
for _, ins in ipairs(instr.instrs) do
- add_line_number(textlist)
instr_to_text(textlist, ins, func, mod)
+ add_line_number(textlist)
end
- table.insert(textlist, { change_indent = -1 })
+ table.insert(textlist, { text = "label ", color = TEXT_COLORS.jumppoint })
+ table.insert(textlist, { text = instr.label, color = TEXT_COLORS.value })
+
elseif instr[1] == "loop" then
- table.insert(textlist, { text = "loop", color = { 1, 0, 0 }, change_indent = 1 })
+ table.insert(textlist, { text = "loop ", color = TEXT_COLORS.jumppoint })
+ table.insert(textlist, { text = instr.label, color = TEXT_COLORS.value, change_indent = 1 })
+
for _, ins in ipairs(instr.instrs) do
add_line_number(textlist)
instr_to_text(textlist, ins, func, mod)
table.insert(textlist, { change_indent = -1 })
elseif instr[1] == "if" then
- table.insert(textlist, { text = "if", color = { 1, 0, 0 }, change_indent = 1 })
+ table.insert(textlist, { text = "if", color = TEXT_COLORS.jumppoint, change_indent = 1 })
for _, ins in ipairs(instr.instrs) do
add_line_number(textlist)
instr_to_text(textlist, ins, func, mod)
if #instr.else_instrs > 0 then
add_line_number(textlist)
- table.insert(textlist, { text = "else", color = { 1, 0, 0 }, change_indent = 1 })
- for _, ins in ipairs(instr.instrs) do
+ table.insert(textlist, { text = "else", color = TEXT_COLORS.jumppoint, change_indent = 1 })
+ for _, ins in ipairs(instr.else_instrs) do
add_line_number(textlist)
instr_to_text(textlist, ins, func, mod)
end
end
elseif instr[1] == "call" then
- table.insert(textlist, { text = instr[1] .. " ", color = { 0, 0, 1 } })
- table.insert(textlist, { text = mod.funcs[instr.x].name, color = { 0, 0.5, 0 } })
+ table.insert(textlist, { text = instr[1] .. " ", color = TEXT_COLORS.keyword })
+ table.insert(textlist, { text = mod.funcs[instr.x].name, color = TEXT_COLORS.value })
elseif instr[1]:match("local") then
- table.insert(textlist, { text = instr[1] .. " ", color = { 0, 0, 1 } })
- table.insert(textlist, { text = func.locals[instr.x + 1].name, color = { 0, 0.5, 0 } })
+ table.insert(textlist, { text = instr[1] .. " ", color = TEXT_COLORS.keyword })
+ table.insert(textlist, { text = func.locals[instr.x + 1].name, color = TEXT_COLORS.value })
else
- table.insert(textlist, { text = instr[1] .. " ", color = { 0, 0, 1 } })
+ table.insert(textlist, { text = instr[1] .. " ", color = TEXT_COLORS.keyword })
if instr.x then
if type(instr.x) == "table" then
if instr.x[1] == "memarg" then
table.insert(textlist, {
- text = ("align=0x%03x offset=0x%08x"):format(instr.x.align, instr.x.offset);
- color = { 0, 0.5, 0 }
+ text = ("align=0x%02x offset=0x%04x"):format(instr.x.align, instr.x.offset);
+ color = TEXT_COLORS.value
})
end
+
+ if instr.x[1] == "labelidx" then
+ table.insert(textlist, { text = instr.x.block.label .. " ", color = TEXT_COLORS.value })
+ table.insert(textlist, { text = ("[0x%02x]"):format(instr.x.labelidx), color = TEXT_COLORS.text })
+ end
else
- table.insert(textlist, { text = tostring(instr.x), color = { 0, 0.5, 0 } })
+ table.insert(textlist, { text = tostring(instr.x), color = TEXT_COLORS.value })
end
end
end
local text = {}
line = 1
- table.insert(text, { text = "Locals:", color = { 0, 0, 1 }, newline = true, change_indent = 2 })
+ table.insert(text, { text = " Locals:", color = TEXT_COLORS.keyword, newline = true, change_indent = 2 })
for _, loc in ipairs(func.locals) do
- table.insert(text, { text = loc.type_ .. " " .. loc.name, color = { 0, 0, 0 }, newline = true })
+ table.insert(text, { text = loc.type_ .. " " .. loc.name, color = TEXT_COLORS.text , newline = true })
end
if #func.locals == 0 then
- table.insert(text, { text = "no locals", color = { 1, 0, 0 }, newline = true })
+ table.insert(text, { text = "no locals", color = TEXT_COLORS.text, newline = true })
end
table.insert(text, { newline = true, change_indent = -2 })
- table.insert(text, { text = "Body:", color = { 0, 0, 1 } })
+ table.insert(text, { text = " Body:", color = TEXT_COLORS.keyword })
for _, instr in ipairs(func.body) do
add_line_number(text)
instr_to_text(text, instr, func, mod)
end
- -- table.remove(text, #text)
-
return text
end
DraggableRect.init(self, x, y, 400, 400)
self.header_text = build_func_header_text(func, mod)
- self.body_text = build_func_body_text(func, mod)
+ if func.body then
+ self.body_text = build_func_body_text(func, mod)
+ else
+ self.rect.h = 48
+ self.body_text = {
+ { text = "imported function", color = TEXT_COLORS.text }
+ }
+ end
self.scroll = 0
end;
ondrag = function(self, button, x, y, dx, dy)
DraggableRect.ondrag(self, button, x, y, dx, dy)
- if button == 2 then
+ if y >= 24 and button == 2 then
self.rect.w = math.max(100, x)
self.rect.h = math.max(22, y)
end
draw = function(self)
love.graphics.setColor(0, 0, 0)
love.graphics.rectangle("fill", 0, 0, self.rect.w, self.rect.h)
- love.graphics.setColor(1, 1, 1)
+ love.graphics.setColor(self.selected and TEXT_COLORS.background or TEXT_COLORS.header_background)
love.graphics.rectangle("fill", 2, 2, self.rect.w - 4, self.rect.h - 4)
- love.graphics.setColor(0.8, 0.8, 0.8)
+ love.graphics.setColor(TEXT_COLORS.header_background)
love.graphics.rectangle("fill", 2, 2, self.rect.w - 4, 18)
- local sx, sy = love.graphics.transformPoint(0, 0)
- love.graphics.intersectScissor(sx, sy, self.rect.w, self.rect.h)
+ love.graphics.intersectScissor(scissor_points(0, 0, self.rect.w, self.rect.h))
local x, y = render_text(2, 2, self.header_text)
- local sx, sy = love.graphics.transformPoint(2, y - 1)
- love.graphics.intersectScissor(sx, sy, self.rect.w - 4, self.rect.h - 22)
- render_text(2, y + 4 - self.scroll, self.body_text)
+ if self.body_text then
+ love.graphics.intersectScissor(scissor_points(2, y - 1, self.rect.w - 4, self.rect.h - 22))
+ render_text(2, y + 4 - self.scroll, self.body_text)
+ end
end;
}
ui_region.rect.w = 1200
ui_region.rect.h = 900
ui_region.background_color = { 0.1, 0.1, 0.1 }
- ui_region.line_color = { 0.2, 0.2, 0.2 }
-
- -- ui_region:add_object(DraggableRect(100, 100, 100, 100))
- -- ui_region:add_object(DraggableRect(200, 100, 100, 100))
- -- ui_region:add_object(DraggableRect(300, 100, 100, 100))
- -- ui_region:add_object(DraggableRect(400, 100, 300, 100))
+ ui_region.line_color = { 0.15, 0.15, 0.2 }
local x = 0
local y = 0
for _, func in pairs(mod.funcs) do
- if func.body then
- local block = FunctionBlock(func, x, y)
- block.order = 600 - y
- ui_region:add_object(block)
- y = y + 20
- end
+ local block = FunctionBlock(func, x, y)
+ block.order = 600 - y
+ ui_region:add_object(block)
+ y = y + 20
end
ui:add_region(ui_region)
Rectangle = "utils:Rectangle";
uuid = "utils:uuidv4";
revipairs = "utils:revipairs";
+ scissor_points = "utils:scissor_points";
}
class "Ui" {
draw = function(self)
for _, region in ipairs(self.regions) do
love.graphics.push()
- love.graphics.setScissor(region.rect.x, region.rect.y, region.rect.w, region.rect.h)
+ love.graphics.setScissor(scissor_points(region.rect.x, region.rect.y, region.rect.w, region.rect.h))
love.graphics.translate(region.rect.x, region.rect.y)
region:draw()
love.graphics.pop()
end;
_obj_rect = function(self, obj)
- return Rectangle(
- obj.rect.x + self.offset.x,
- obj.rect.y + self.offset.y,
- obj.rect.w, obj.rect.h)
+ return obj.rect
+ end;
+
+ _transform_mouse = function(self, x, y)
+ return
+ ((x + self.rect.x) - self.rect.w / 2) / self.zoom + self.rect.w / 2 - self.offset.x - self.rect.x,
+ ((y + self.rect.y) - self.rect.h / 2) / self.zoom + self.rect.h / 2 - self.offset.y - self.rect.y
+ end;
+
+ onmousedown = function(self, button, x, y)
+ print(x, y)
+ local mx, my = self:_transform_mouse(x, y)
+ print(mx, my)
+ UiRegion.onmousedown(self, button, mx, my)
+ end;
+
+ onmouseup = function(self, button, x, y)
+ local mx, my = self:_transform_mouse(x, y)
+ UiRegion.onmouseup(self, button, mx, my)
end;
onmousemove = function(self, x, y, dx, dy)
- UiRegion.onmousemove(self, x, y, dx, dy)
+ local mx, my = self:_transform_mouse(x, y)
+ UiRegion.onmousemove(self, mx, my, dx / self.zoom, dy / self.zoom)
if self.is_mouse_down and self.selected_object == nil then
- self.offset.x = self.offset.x + dx
- self.offset.y = self.offset.y + dy
+ self.offset.x = self.offset.x + dx / self.zoom
+ self.offset.y = self.offset.y + dy / self.zoom
end
end;
if self.selected_object == nil then
self.zoom = self.zoom * (dy > 0 and 1.05 or (1 / 1.05))
if self.zoom >= 1 then self.zoom = 1 end
+ if self.zoom <= (1 / 1.05) ^ 20 then self.zoom = (1 / 1.05) ^ 20 end
end
end;
UiRegion.update(self, dt)
if self.active then
- local speed = 300
+ local speed = 300 / self.zoom
if love.keyboard.isDown "left" then
self.offset.x = self.offset.x + speed * dt
end
local tmpbgcolor = self.background_color
self.background_color = nil
+ love.graphics.translate(self.rect.w / 2, self.rect.h / 2)
+ love.graphics.scale(self.zoom, self.zoom)
+ love.graphics.translate(-self.rect.w / 2, -self.rect.h / 2)
+
+
local xoff = self.offset.x
local yoff = self.offset.y
local spacing = 64
while yoff <= -spacing do yoff = yoff + spacing end
love.graphics.setColor(self.line_color)
- for x = 0, 40 do
- love.graphics.line(x * spacing + xoff, 0, x * spacing + xoff, self.rect.h)
+ for x = -40, 80 do
+ love.graphics.line(x * spacing + xoff, -self.rect.h, x * spacing + xoff, self.rect.h * 2)
end
- for y = 0, 40 do
- love.graphics.line(0, y * spacing + yoff, self.rect.w, y * spacing + yoff)
+ for y = -40, 80 do
+ love.graphics.line(-self.rect.w, y * spacing + yoff, self.rect.w * 2, y * spacing + yoff)
end
love.graphics.translate(self.offset.x, self.offset.y)
self.rect = Rectangle(0, 0, 0, 0)
self.uuid = uuid()
self.selected = false
- self.order = math.random(1, 128)
+ self.order = math.random(1, 1024)
end;
onclick = function(self, button, x, y) end;
love.graphics.rectangle("fill", x, y, programming_font:getWidth(txt.text), fheight + 2);
end
- love.graphics.setColor(txt.color)
+ if txt.color then
+ love.graphics.setColor(txt.color)
+ end
love.graphics.print(printed, x, y)
x = x + programming_font:getWidth(printed)