diff options
Diffstat (limited to 'drawing')
-rw-r--r-- | drawing/drawing.ha | 27 | ||||
-rw-r--r-- | drawing/op.ha | 28 |
2 files changed, 44 insertions, 11 deletions
diff --git a/drawing/drawing.ha b/drawing/drawing.ha index fc59e1b..54a877b 100644 --- a/drawing/drawing.ha +++ b/drawing/drawing.ha @@ -77,15 +77,38 @@ export fn circle(picture: *picture, c: pos, r: i32, color: u32) void = { }; }; +export fn circle_hollow(picture: *picture, c: pos, r: i32, color: u32) void = { + const (cx,cy) = c; + const ymin = max(0, cy-r); + const ymax = min(picture.h:i32-1, cy+r); + const xmin = max(0, cx-r); + const xmax = min(picture.w:i32-1, cx+r); + + const r2l = r*r - r; + const r2u = r*r + r; + + for (let y = ymin; y<=ymax; y+=1) { + const yd = y-cy; + for (let x = xmin; x<=xmax; x+=1) { + const xd = x-cx; + const v = yd*yd + xd*xd; + if (r2l <= v && v <= r2u) { + pic_set(picture, (x,y), color); + }; + }; + }; +}; export fn perform(pictures: []picture, op: op) void = { match (op) { case op_other => abort("oopsy"); case let o: op_circle => - const x = o.0, y=o.1; + const x = o.pos.0, y=o.pos.1; + const r = o.radius; + const c = o.color & 0xffffff; for (const pic &.. pictures) { let pos_within_pic = (x - pic.world_pos.0, y - pic.world_pos.1): pos; - circle(pic, pos_within_pic, 20, 0xff0088); + circle(pic, pos_within_pic, r: i32, c); }; }; }; diff --git a/drawing/op.ha b/drawing/op.ha index acbca29..532fd75 100644 --- a/drawing/op.ha +++ b/drawing/op.ha @@ -1,25 +1,35 @@ use io; use endian; -export type op_circle = pos; +export type op_circle = struct { + pos: pos, + radius: u8, + color: u32 +}; export type op_other = void; export type op = (op_circle| op_other); +def SER_LEN: size = 13; + // return value must be freed... for now. ehh export fn ser_op(op: op) []u8 = { const opc = op as op_circle; - let buf: []u8 = alloc([0...],8); - endian::leputu32(buf[0..4], opc.0: u32); - endian::leputu32(buf[4..8], opc.1: u32); + let buf: []u8 = alloc([0...],SER_LEN); + endian::leputu32(buf[0..4], opc.pos.0: u32); + endian::leputu32(buf[4..8], opc.pos.1: u32); + endian::leputu32(buf[8..12], opc.color: u32); + buf[12] = opc.radius; return buf; }; export fn deser_op(bytes: []u8) op = { - assert(len(bytes) == 8, "wrong length somehow"); - return ( - endian::legetu32(bytes[0..4]): i32, - endian::legetu32(bytes[4..8]): i32, - ) : op_circle; + assert(len(bytes) == SER_LEN, "wrong length somehow"); + return op_circle { + pos = (endian::legetu32(bytes[0..4]): i32, + endian::legetu32(bytes[4..8]): i32), + color = endian::legetu32(bytes[8..12]), + radius = bytes[12], + }; }; |