summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/paintui/paintui.ha5
-rw-r--r--drawing/drawing.ha29
-rw-r--r--drawing/op.ha8
-rw-r--r--packet_reader/packet_reader.ha6
4 files changed, 36 insertions, 12 deletions
diff --git a/client/paintui/paintui.ha b/client/paintui/paintui.ha
index 212e16b..81fa7ca 100644
--- a/client/paintui/paintui.ha
+++ b/client/paintui/paintui.ha
@@ -51,8 +51,9 @@ export fn tick(
&& (mouse_pos.0 != pstate.last_mouse_pos.0
|| mouse_pos.1 != pstate.last_mouse_pos.1
|| (!pstate.last_mouse_pressed)))
- drawing::op_circle {
- pos = mouse_pos,
+ drawing::op_stroke {
+ pos1 = mouse_pos,
+ pos0 = (0,0),
radius = sizes[pstate.size_idx],
color = pstate.color,
}
diff --git a/drawing/drawing.ha b/drawing/drawing.ha
index 063577d..a7d9e1f 100644
--- a/drawing/drawing.ha
+++ b/drawing/drawing.ha
@@ -1,8 +1,7 @@
-use sdl2;
use fmt;
use io;
use endian;
-use math::random;
+use math;
export def CHUNKSIZE = 512;
@@ -53,6 +52,8 @@ export fn outline_picture(pic: *picture) void = {
fn min(a: i32, b: i32) i32 = if (a<b) a else b;
fn max(a: i32, b: i32) i32 = if (a<b) b else a;
+fn sign(x: i32) i32 = if (x < 0) -1 else if (x > 0) 1 else 0;
+fn abs(x: i32) i32 = if (x<0) -x else x;
// Draws a circle onto the picture, at given position radius color
// Clips at the boundaries of the picture to avoid overflow.
@@ -98,6 +99,23 @@ export fn circle_hollow(picture: *picture, c: pos, r: i32, color: u32) void = {
};
};
};
+
+export fn stroke(picture: *picture, c0: pos, c1: pos, r: i32, color: u32) void = {
+ const dx = c1.0 - c0.0;
+ const dy = c1.1 - c0.1;
+ const count = (abs(dx)+abs(dy))/r;
+ const sx = dx: f64 / (count-1): f64;
+ const sy = dy: f64 / (count-1): f64;
+
+ for (let i = 0i32; i < count; i += 1) {
+ const cx = c0.0 + math::roundf64(i:f64*sx):i32;
+ const cy = c0.1 + math::roundf64(i:f64*sy):i32;
+
+ circle(picture, (cx, cy), r, color);
+ };
+};
+
+// ehh should check bounding box instead of doing all pictures maybe
export fn perform(pictures: []picture, op: op) void = {
match (op) {
case let o: op_circle =>
@@ -109,5 +127,12 @@ export fn perform(pictures: []picture, op: op) void = {
(x - pic.world_pos.0, y - pic.world_pos.1): pos;
circle(pic, pos_within_pic, r: i32, c);
};
+ case let s: op_stroke =>
+ const col = s.color & 0xffffff;
+ for (const pic &.. pictures) {
+ const c0 = (s.pos0.0 - pic.world_pos.0, s.pos0.1 - pic.world_pos.1);
+ const c1 = (s.pos1.0 - pic.world_pos.0, s.pos1.1 - pic.world_pos.1);
+ stroke(pic, c0, c1, s.radius: i32, col);
+ };
};
};
diff --git a/drawing/op.ha b/drawing/op.ha
index aa7fac4..82a412f 100644
--- a/drawing/op.ha
+++ b/drawing/op.ha
@@ -11,7 +11,6 @@ export type op_stroke = struct {
pos1: pos,
color: u32,
radius: u8,
- count: u8,
};
export type op = (op_circle | op_stroke);
@@ -22,7 +21,6 @@ type op_type = enum u8 {
export type deser_fail = !void;
-
// return value must be freed... for now. ehh
export fn ser_op(op: op) []u8 = match (op) {
case let opc: op_circle => yield ser_op_circle(opc);
@@ -68,8 +66,8 @@ fn deser_op_circle(bytes: []u8) (op_circle|deser_fail) = {
};
};
-def SER_LEN_STROKE = 23;
-// type:1 pos0:8 pos1:8 color:4 radius:1 count:1
+def SER_LEN_STROKE = 22;
+// type:1 pos0:8 pos1:8 color:4 radius:1
fn ser_op_stroke(ops: op_stroke) []u8 = {
let buf: []u8 = alloc([0...], SER_LEN_STROKE);
buf[0] = op_type::STROKE;
@@ -79,7 +77,6 @@ fn ser_op_stroke(ops: op_stroke) []u8 = {
ser_pos(payload[8..16], ops.pos1);
endian::leputu32(payload[16..20], ops.color);
payload[20] = ops.radius;
- payload[21] = ops.count;
return buf;
};
fn deser_op_stroke(bytes: []u8) (op_stroke|deser_fail) = {
@@ -90,7 +87,6 @@ fn deser_op_stroke(bytes: []u8) (op_stroke|deser_fail) = {
pos1 = deser_pos(payload[8..16]),
color = endian::legetu32(payload[16..20]),
radius = payload[20],
- count = payload[21],
};
};
diff --git a/packet_reader/packet_reader.ha b/packet_reader/packet_reader.ha
index e4cbcf2..6d8c315 100644
--- a/packet_reader/packet_reader.ha
+++ b/packet_reader/packet_reader.ha
@@ -91,8 +91,10 @@ export fn next(pr: *packet_reader) (packet | done | error) = {
const payload = packet_bytes[8..];
switch (ty) {
case packet_type::DRAW_OP =>
- const op = drawing::deser_op(payload);
- return op: packet_drawop;
+ match (drawing::deser_op(payload)) {
+ case let o: drawing::op => return o;
+ case drawing::deser_fail => return "deser fail": error;
+ };
case packet_type::SEND_CHUNK =>
// return value is BORROWED from the BUFFER
const pos_bytes = payload[0..8];