aboutsummaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
authorubq323 <ubq323@ubq323.website>2024-04-13 15:12:17 +0100
committerubq323 <ubq323@ubq323.website>2024-04-13 15:12:17 +0100
commit7608e2967954104771b06612e4e6c21ca7811c9f (patch)
treef36f054130b880d0e71fff2d8014c5a3c4a7c39b /client
parente4b1dd28018a3462334c695dc11bd0e0f1e8122a (diff)
client have multiple chunks and recycle them when they are not visible
Diffstat (limited to 'client')
-rw-r--r--client/main.ha77
1 files changed, 60 insertions, 17 deletions
diff --git a/client/main.ha b/client/main.ha
index 4e6fb9f..28d6694 100644
--- a/client/main.ha
+++ b/client/main.ha
@@ -10,7 +10,10 @@ use unix::poll;
use packet_reader;
def CHUNKSIZE = 512;
-def NCHUNKS = 4;
+def NCHUNKS = 16;
+
+def WIN_H: i32 = 480;
+def WIN_W: i32 = 640;
export fn main() void = {
// sdl init stuff
@@ -22,11 +25,9 @@ export fn main() void = {
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 offs: []pos = [];
+ for (let x = -1; x < 3; x+=1) for (let y = -1; y < 3; y+=1)
+ append(offs, (x*CHUNKSIZE,y*CHUNKSIZE));
let pictures: []drawing::picture = alloc([],NCHUNKS);
let picture_surfaces: []*sdl2::SDL_Surface = alloc([], NCHUNKS);
@@ -36,7 +37,10 @@ export fn main() void = {
append(picture_surfaces, surf);
append(pictures, picture_from_surface(surf, offs[i]));
};
- for (const p &.. pictures) drawing::clear_picture(p, 0xffffff);
+ for (const p &.. pictures) {
+ drawing::clear_picture(p, 0x00ff00);
+ drawing::outline_picture(p);
+ };
// connect to server
@@ -64,6 +68,15 @@ export fn main() void = {
for (!quit) {
do_movement(&camera_pos);
+ // let nvis = 0;
+ // for (const pic &.. pictures) {
+ // if (is_picture_visible(camera_pos, pic)) {
+ // fmt::printfln(" {} {}",pic.world_pos.0, pic.world_pos.1)!;
+ // nvis += 1;
+ // };
+ // };
+ // fmt::printfln("{} visible",nvis)!;
+
let ev = sdl2::event { ... };
for (sdl2::SDL_PollEvent(&ev)! == 1) switch (ev.event_type) {
case sdl2::SDL_EventType::QUIT => quit = true;
@@ -101,26 +114,24 @@ export fn main() void = {
drawing::perform(pictures, opc);
case let packet: packet_reader::packet_sendchunk =>
fmt::println(packet.world_pos.0, packet.world_pos.1, len(packet.chunk_data))!;
- let did_set = false;
- for (let pic &.. pictures) {
- if (pic.world_pos.0 == packet.world_pos.0 && pic.world_pos.1 == packet.world_pos.1) {
- pic.d[..len(packet.chunk_data)] = packet.chunk_data[..];
- fmt::printfln("setting {},{}",pic.world_pos.0,pic.world_pos.1)!;
- did_set = true;
- break;
- };
- };
- if (!did_set) fmt::println("did not set anything {},{} ....",packet.world_pos.0,packet.world_pos.1)!;
+ assert(packet.world_pos.0 % CHUNKSIZE == 0
+ && packet.world_pos.1 % CHUNKSIZE == 0, "bad chunk world pos");
+ const pic = find_picture_for_chunkdata(camera_pos, packet.world_pos, pictures);
+ pic.world_pos = packet.world_pos;
+ pic.d[..len(packet.chunk_data)] = packet.chunk_data[..];
};
};
};
+ drawing::clear_picture(&picture_from_surface(wsurf,(9,9)), 0xff0000);
+
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);
@@ -160,3 +171,35 @@ fn do_movement(pos: *pos) void = {
pos.1 += dy * speed;
};
+fn is_picture_visible(camera_pos: pos, pic: *drawing::picture) bool = {
+ const s_min: pos = camera_pos;
+ const s_max: pos = (camera_pos.0 + WIN_W, camera_pos.1 + WIN_H);
+ const p_min: pos = pic.world_pos;
+ const p_max: pos = (pic.world_pos.0 + pic.w: i32, pic.world_pos.1 + pic.h: i32);
+ return (s_min.0 <= p_max.0 && s_max.0 >= p_min.0)
+ && (s_min.1 <= p_max.1 && s_max.1 >= p_min.1);
+};
+
+fn find_picture_for_chunkdata(camera_pos: pos, world_pos: pos, pictures: []drawing::picture) *drawing::picture = {
+ // if we have one with that exact worldpos, return that
+ // otherwise find one that isn't visible
+
+ let invisible: nullable *drawing::picture = null;
+
+ for (const pic &.. pictures) {
+ if (pic.world_pos.0 == world_pos.0 && pic.world_pos.1 == world_pos.1) {
+ return pic;
+ };
+ if (invisible == null && !is_picture_visible(camera_pos, pic)) invisible = pic;
+ };
+
+ match (invisible) {
+ case null => abort("couldn't find offscreen picture???");
+ case let p: *drawing::picture => return p;
+ };
+
+};
+
+
+
+