summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drawing.ha32
-rw-r--r--main.ha44
2 files changed, 55 insertions, 21 deletions
diff --git a/drawing.ha b/drawing.ha
index 804aee4..5812109 100644
--- a/drawing.ha
+++ b/drawing.ha
@@ -1,4 +1,5 @@
use sdl2;
+use fmt;
// 2d position, x and y
type pos = (i32, i32);
@@ -7,13 +8,20 @@ type drawing_state = struct {
// is the mouse button held down?
drawing: bool,
pos: pos,
- picture: *picture,
+ pictures: []picture,
};
type picture = struct {
+ // the surface data as u32s
d: *[*]u32,
w: size,
h: size,
+
+ // backreference to the surface whose data we're using
+ surf: *sdl2::SDL_Surface,
+
+ pos: pos,
+
};
// Returns array index of the pixel at position pos.
@@ -33,10 +41,12 @@ fn pidx(pic: *picture, pos: pos) size = {
fn pic_set(pic: *picture, pos: pos, val: u32) void =
pic.d[pidx(pic,pos)] = val;
-fn picture_from_surface(surf: *sdl2::SDL_Surface) picture = picture {
+fn picture_from_surface(surf: *sdl2::SDL_Surface, pos: pos) picture = picture {
w = surf.w: size,
h = surf.h: size,
d = (surf.pixels as *opaque: *[*]u32),
+ surf = surf,
+ pos = pos,
};
fn clear_picture(pic: *picture, color: u32) void = {
@@ -57,14 +67,15 @@ 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;
-// Draws a circle onto the dstate's picture, at given position radius color
+// Draws a circle onto the picture, at given position radius color
// Clips at the boundaries of the picture to avoid overflow.
-fn circle(dstate: *drawing_state, c: pos, r: i32, color: u32) void = {
+fn circle(picture: *picture, c: pos, r: i32, color: u32) void = {
+ // fmt::printfln("C {} {} {} {:x}",c.0,c.1,r,color)!;
const (cx,cy) = c;
const ymin = max(0, cy-r);
- const ymax = min(dstate.picture.h:i32-1, cy+r);
+ const ymax = min(picture.h:i32-1, cy+r);
const xmin = max(0, cx-r);
- const xmax = min(dstate.picture.w:i32-1, cx+r);
+ const xmax = min(picture.w:i32-1, cx+r);
const r2 = r*r + r;
@@ -73,12 +84,17 @@ fn circle(dstate: *drawing_state, c: pos, r: i32, color: u32) void = {
for (let x = xmin; x<=xmax; x+=1) {
const xd = x-cx;
if (yd*yd + xd*xd <= r2) {
- pic_set(dstate.picture, (x,y), color);
+ pic_set(picture, (x,y), color);
};
};
};
};
fn do_drawing(dstate: *drawing_state) void = {
- if (dstate.drawing) circle(dstate, dstate.pos, 20, 0xff0088);
+ if (dstate.drawing) for (let i = 0z; i < 4; i+=1) {
+ const pic = &dstate.pictures[i];
+ const p = (dstate.pos.0 - pic.pos.0, dstate.pos.1 - pic.pos.1);
+ circle(pic, p, 20, 0xff0088);
+ };
};
+
diff --git a/main.ha b/main.ha
index 9035053..09fd30f 100644
--- a/main.ha
+++ b/main.ha
@@ -2,6 +2,9 @@ use fmt;
use sdl2;
use math;
+def CHUNKSIZE = 512;
+def NCHUNKS = 4;
+
export fn main() void = {
sdl2::SDL_Init(sdl2::SDL_INIT_VIDEO)!;
defer sdl2::SDL_Quit();
@@ -11,19 +14,30 @@ export fn main() void = {
const wsurf = sdl2::SDL_GetWindowSurface(win)!;
- const xsurf = sdl2::SDL_CreateRGBSurface(0,
- 512, 512, 32, 0xff0000, 0xff00, 0xff, 0)!;
+ const offs: [_]pos = [
+ (0,0), (0,CHUNKSIZE), (CHUNKSIZE,0), (CHUNKSIZE,CHUNKSIZE),
+ ];
+
+ let pictures: []picture = alloc([],NCHUNKS);
+ for (let i = 0z; i < NCHUNKS; i +=1){
+ const surf = sdl2::SDL_CreateRGBSurface(0,
+ CHUNKSIZE, CHUNKSIZE, 32, 0xff0000, 0xff00, 0xff, 0)!;
+ append(pictures, picture_from_surface(surf, offs[i]));
+ };
let dstate = drawing_state {
drawing = false,
pos = (0,0),
- picture = &picture_from_surface(xsurf)
+ pictures = pictures,
};
let camera_pos: pos = (25, 50);
- clear_picture(dstate.picture, 0xffffff);
- outline_picture(dstate.picture);
+ for (let i = 0z; i < 4; i += 1) {
+ const p = &dstate.pictures[i];
+ clear_picture(p, 0xffffff);
+ outline_picture(p);
+ };
let quit = false;
let n = 0;
@@ -38,22 +52,20 @@ export fn main() void = {
case sdl2::SDL_EventType::MOUSEBUTTONDOWN,
sdl2::SDL_EventType::MOUSEBUTTONUP =>
const edata = ev.button;
- dstate.pos = (edata.x, edata.y);
+ dstate.pos = (edata.x + camera_pos.0, edata.y + camera_pos.1);
if (edata.button == 1)
dstate.drawing = (edata.state == 1);
case sdl2::SDL_EventType::MOUSEMOTION =>
const edata = ev.motion;
- dstate.pos = (edata.x, edata.y);
+ dstate.pos = (edata.x + camera_pos.0, edata.y + camera_pos.1);
case => void;
};
movement(&camera_pos);
-
do_drawing(&dstate);
-
- sdl2::SDL_BlitSurface(xsurf, null, wsurf, &sdl2::SDL_Rect {
- x = camera_pos.0, y = camera_pos.1, ...
- })!;
+
+ for (let i = 0z; i < len(dstate.pictures); i+=1)
+ render_picture(&dstate.pictures[i], wsurf, camera_pos);
sdl2::SDL_UpdateWindowSurface(win)!;
n += 1;
@@ -61,6 +73,13 @@ export fn main() void = {
};
};
+fn render_picture(pic: *picture, winsurf: *sdl2::SDL_Surface, camera_pos: pos) void = {
+ sdl2::SDL_BlitSurface(pic.surf, null, winsurf, &sdl2::SDL_Rect{
+ x = pic.pos.0 - camera_pos.0, y = pic.pos.1 - camera_pos.1, ...
+ })!;
+};
+
+
def SPEED = 17;
def DIAG_SPEED = 12; // thereabouts
@@ -80,4 +99,3 @@ fn movement(pos: *pos) void = {
pos.1 += dy * speed;
};
-