aboutsummaryrefslogtreecommitdiff
path: root/client/main.ha
blob: 242a1017ed2b213fd9929a9d40b10626fc00ce50 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
use fmt;
use sdl2;
use math;
use net;
use net::dial;
use drawing;
use drawing::{pos};
use client::paintui;
use unix::poll;
use packet_reader;

def CHUNKSIZE = 512;
def NCHUNKS = 4;

export fn main() void = {
	// sdl init stuff
	sdl2::SDL_Init(sdl2::SDL_INIT_VIDEO)!;
	defer sdl2::SDL_Quit();

	const win = sdl2::SDL_CreateWindow("hi", sdl2::SDL_WINDOWPOS_UNDEFINED, sdl2::SDL_WINDOWPOS_UNDEFINED, 640, 480, sdl2::SDL_WindowFlags::NONE)!;
	defer sdl2::SDL_DestroyWindow(win);

	const wsurf = sdl2::SDL_GetWindowSurface(win)!;

	// create 4 pictures. later we will have more pictures
	// but for now there are just 4, and they are at fixed positions
	const offs: [_]pos = [
		(0,0), (0,CHUNKSIZE), (CHUNKSIZE,0), (CHUNKSIZE,CHUNKSIZE),
	];

	let pictures: []drawing::picture = alloc([],NCHUNKS);
	let picture_surfaces: []*sdl2::SDL_Surface = alloc([], NCHUNKS);
	for (let i = 0z; i < NCHUNKS; i +=1){
		const surf = sdl2::SDL_CreateRGBSurface(0,
			CHUNKSIZE, CHUNKSIZE, 32, 0xff0000, 0xff00, 0xff, 0)!;
		append(picture_surfaces, surf);
		append(pictures, picture_from_surface(surf, offs[i]));
	};
	for (const p &.. pictures) drawing::clear_picture(p, 0xffffff);


	// connect to server
	const conn = match(dial::dial("tcp","localhost","41460")) {
		case let c: net::socket => yield c;
		case let err: net::error =>
			fmt::fatal("couldn't connect to server:",net::strerror(err));
	};
	const pollfd: [1]poll::pollfd = [ poll::pollfd {
		fd = conn, events=poll::event::POLLIN, revents = 0
	}];
	const packet_reader = packet_reader::new();

	// paintui state
	let pstate = paintui::state { ... };

	let camera_pos: pos = (25, 50);
	let quit = false;
	let n = 0;
	let lasttime = sdl2::SDL_GetTicks();

	// in WORLD coords
	let mouse_pos: pos = (0,0);
	let mouse_down = false;
	for (!quit) {
		do_movement(&camera_pos);

		let ev = sdl2::event { ... };
		for (sdl2::SDL_PollEvent(&ev)! == 1) switch (ev.event_type) {
			case sdl2::SDL_EventType::QUIT => quit = true;
			case sdl2::SDL_EventType::KEYDOWN =>
				const keysym = ev.key.keysym.sym;
				if (keysym == sdl2::SDL_Keycode::ESCAPE) quit = true;
			case sdl2::SDL_EventType::MOUSEBUTTONDOWN,
					sdl2::SDL_EventType::MOUSEBUTTONUP =>
				const edata = ev.button;
				mouse_pos = (edata.x + camera_pos.0, edata.y + camera_pos.1);
				if (edata.button == 1)
					mouse_down = (edata.state == 1);
			case sdl2::SDL_EventType::MOUSEMOTION =>
				const edata = ev.motion;
				mouse_pos = (edata.x + camera_pos.0, edata.y + camera_pos.1);
			case => void;
		};


		match (paintui::tick(&pstate, mouse_pos, mouse_down)) {
		case void => yield;
		case let op: drawing::op =>
			drawing::perform(pictures, op);
			packet_reader::send(conn, op: packet_reader::packet_drawop)!;
		};

		const n = poll::poll(pollfd, poll::NONBLOCK)!;
		if (n > 0) {
			fmt::println("data available")!;
			packet_reader::read(&packet_reader, conn)!;
			for (const packet => packet_reader::next(&packet_reader)!) {
				match (packet) {
				case let op: packet_reader::packet_drawop =>
					const opc = op as drawing::op_circle;
					drawing::perform(pictures, opc);
				case =>
					abort("other packet not supported yet");
				};
			};
		};

		for (let i = 0z; i < len(pictures); i += 1) {
			const psurf = picture_surfaces[i];
			const pic = &pictures[i];
			render_picture(pic, psurf, wsurf, camera_pos);
		};

		sdl2::SDL_UpdateWindowSurface(win)!;
		n += 1;
		sdl2::SDL_Delay(1000/60);
	};
};

fn picture_from_surface(surf: *sdl2::SDL_Surface, world_pos: pos) drawing::picture = drawing::picture {
	w = surf.w: size,
	h = surf.h: size,
	d = (surf.pixels as *opaque: *[*]u32),
	world_pos = world_pos,
};

fn render_picture(pic: *drawing::picture, surf: *sdl2::SDL_Surface, winsurf: *sdl2::SDL_Surface, camera_pos: pos) void = {
	sdl2::SDL_BlitSurface(surf, null, winsurf, &sdl2::SDL_Rect{
		x = pic.world_pos.0 - camera_pos.0, y = pic.world_pos.1 - camera_pos.1, ...
	})!;
};


def SPEED = 17;
def DIAG_SPEED = 12;  // thereabouts

fn do_movement(pos: *pos) void = {
	const kb = sdl2::SDL_GetKeyboardState();
	let dx = 0;
	let dy = 0;
	if (kb[sdl2::SDL_Scancode::W]) dy -= 1;
	if (kb[sdl2::SDL_Scancode::S]) dy += 1;
	if (kb[sdl2::SDL_Scancode::A]) dx -= 1;
	if (kb[sdl2::SDL_Scancode::D]) dx += 1;

	let speed = SPEED;
	if (dx != 0 && dy != 0) speed = DIAG_SPEED;

	pos.0 += dx * speed;
	pos.1 += dy * speed;
};