terrain chunks render and allocate properly

stable
Ivory 2025-01-10 06:23:56 -05:00
parent 7a54564597
commit 7e0e3f7501
5 changed files with 77 additions and 39 deletions

25
.vscode/launch.json vendored 100644
View File

@ -0,0 +1,25 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "./zig-out/bin/hadean",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"preLaunchTask": "build",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}

15
.vscode/tasks.json vendored 100644
View File

@ -0,0 +1,15 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"type": "shell",
"command": "zig build",
"problemMatcher": [],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}

View File

@ -37,8 +37,8 @@ pub var sdl_data: SDL_Data = .{
var gpa = std.heap.GeneralPurposeAllocator(.{}); var gpa = std.heap.GeneralPurposeAllocator(.{});
var allocator = gpa.allocator(); var allocator = gpa.allocator();
pub var window_width: i32 = 800; pub var window_width: i32 = 1280;
pub var window_height: i32 = 600; pub var window_height: i32 = 720;
const SceneLoadFunction = *const fn (*Scene) Allocator.Error!void; const SceneLoadFunction = *const fn (*Scene) Allocator.Error!void;
var scene_arena = ArenaAllocator.init(std.heap.page_allocator); var scene_arena = ArenaAllocator.init(std.heap.page_allocator);

View File

@ -4,6 +4,7 @@ const engine = @import("engine");
const std = @import("std"); const std = @import("std");
const c = @import("c"); const c = @import("c");
const ArrayListUnmanaged = std.ArrayListUnmanaged; const ArrayListUnmanaged = std.ArrayListUnmanaged;
const ArrayList = std.ArrayList;
const AutoHashMapUnmanaged = std.AutoHashMapUnmanaged; const AutoHashMapUnmanaged = std.AutoHashMapUnmanaged;
const Entity = engine.Entity; const Entity = engine.Entity;
const Tag = engine.Tag; const Tag = engine.Tag;
@ -50,9 +51,9 @@ pub fn init(allocator: Allocator) !Scene {
// //
return Scene { return Scene {
.arena = arena, .arena = arena,
.entities = try ArrayListUnmanaged(Entity).initCapacity(arena.allocator(), 10), .entities = ArrayListUnmanaged(Entity) {},
.entities_to_add = try ArrayListUnmanaged(Entity).initCapacity(arena.allocator(), 10), .entities_to_add = ArrayListUnmanaged(Entity) {},
.mouse_listeners = try ArrayListUnmanaged(MouseListener).initCapacity(arena.allocator(), 10), .mouse_listeners = ArrayListUnmanaged(MouseListener) {},
.tagged_entities = std.AutoHashMapUnmanaged(Tag, Entity) {}, .tagged_entities = std.AutoHashMapUnmanaged(Tag, Entity) {},
}; };
} }

View File

@ -18,7 +18,8 @@ var prng = std.rand.DefaultPrng.init(0);
const Camera = @import("Camera.zig"); const Camera = @import("Camera.zig");
const assets = @import("assets.zig"); const assets = @import("assets.zig");
pub const CHUNK_SIZE = 48; // pub const CHUNK_SIZE = 48;
pub const CHUNK_SIZE = 24;
const CHUNK_LENGTH = CHUNK_SIZE * CHUNK_SIZE; const CHUNK_LENGTH = CHUNK_SIZE * CHUNK_SIZE;
const tile_size: usize = 16; const tile_size: usize = 16;
@ -29,15 +30,27 @@ const GROWTH_RATE: f32 = 0.5;
chunks: std.ArrayList(*Chunk), chunks: std.ArrayList(*Chunk),
generator: WorldGenerator, generator: WorldGenerator,
camera: *Camera = undefined, camera: *Camera = undefined,
scene: ?*Scene = null, scene: *Scene = undefined,
allocator: Allocator,
pub fn create(allocator: Allocator, seed: i64) !*Terrain {
const self: *Terrain = try allocator.create(Terrain);
self.* = Terrain {
.chunks = std.ArrayList(*Chunk).init(allocator),
.generator = try WorldGenerator.create(seed),
};
return self;
}
pub fn start(self: *Terrain, scene: *Scene) void { pub fn start(self: *Terrain, scene: *Scene) void {
self.camera = scene.get(engine.Tag.CAMERA, Camera); self.camera = scene.get(engine.Tag.CAMERA, Camera);
self.camera.set_focus(Vec2f.create(CHUNK_SIZE / 2, CHUNK_SIZE / 2)); self.camera.set_focus(Vec2f.create(CHUNK_SIZE / 2, CHUNK_SIZE / 2));
self.scene = scene; self.scene = scene;
for (self.chunks.items) |chunk| scene.add(Entity.from(chunk, .{})) catch unreachable; self.gen_chunk(Vec2i { .x = 0, .y = 0 }) catch @panic("OOM");
self.gen_chunk(Vec2i { .x = -1, .y = 0 }) catch @panic("OOM");
// for (self.chunks.items) |chunk| scene.add(Entity.from(chunk, .{})) catch unreachable;
} }
fn contrast(n: f32, blend_strength: f32) f32 { fn contrast(n: f32, blend_strength: f32) f32 {
@ -53,26 +66,15 @@ fn contrast(n: f32, blend_strength: f32) f32 {
} }
fn gen_chunk(self: *Terrain, chunk_pos: Vec2i) !void { fn gen_chunk(self: *Terrain, chunk_pos: Vec2i) !void {
std.debug.assert(self.scene != undefined);
std.debug.print("[Terrain:gen_chunk] ({}, {})\n", .{ chunk_pos.x, chunk_pos.y }); std.debug.print("[Terrain:gen_chunk] ({}, {})\n", .{ chunk_pos.x, chunk_pos.y });
const chunk = try Chunk.generate(self.allocator, chunk_pos, &self.generator); const chunk: *Chunk = try Chunk.generate(self.scene.arena.allocator(), chunk_pos, &self.generator);
try self.chunks.append(chunk); try self.chunks.append(chunk);
// gen chunk sometimes happens before start // gen chunk sometimes happens before start
if(self.scene) |scene| try scene.add(Entity.from(chunk, .{})); try self.scene.add(Entity.from(chunk, .{}));
} }
pub fn create(allocator: Allocator, seed: i64) !*Terrain {
var self: *Terrain = try allocator.create(Terrain);
self.* = Terrain {
.chunks = std.ArrayList(*Chunk).init(allocator),
.generator = try WorldGenerator.create(seed),
.allocator = allocator,
};
try self.gen_chunk(Vec2i.ZERO);
try self.gen_chunk(Vec2i { .x = -1, .y = 0 });
return self;
}
pub fn destroy(self: *const Terrain) void { pub fn destroy(self: *const Terrain) void {
self.generator.destroy(); self.generator.destroy();
@ -161,7 +163,6 @@ const Chunk = struct {
chunk_pos: Vec2i, chunk_pos: Vec2i,
chunk_pos_world: Vec2i, chunk_pos_world: Vec2i,
camera: *Camera = undefined, camera: *Camera = undefined,
allocator: Allocator,
pub fn generate(allocator: Allocator, chunk_pos: Vec2i, generator: *const WorldGenerator) !*Chunk { pub fn generate(allocator: Allocator, chunk_pos: Vec2i, generator: *const WorldGenerator) !*Chunk {
var self = try allocator.create(Chunk); var self = try allocator.create(Chunk);
@ -172,8 +173,6 @@ const Chunk = struct {
.y = chunk_pos.y * CHUNK_SIZE, .y = chunk_pos.y * CHUNK_SIZE,
}, },
.tiles = try allocator.alloc(Tile, CHUNK_LENGTH), .tiles = try allocator.alloc(Tile, CHUNK_LENGTH),
// .tiles = try Entity.allocate_array(Tile, CHUNK_LENGTH, Tile.NULL),
.allocator = allocator,
}; };
self.generate_tiles(generator); self.generate_tiles(generator);
@ -181,10 +180,6 @@ const Chunk = struct {
return self; return self;
} }
pub fn destroy(self: *const Chunk) void {
self.allocator.free(self.tiles);
}
pub fn entity(self: *Chunk) Entity { pub fn entity(self: *Chunk) Entity {
return Entity.init(self, .{ return Entity.init(self, .{
.layer = Layer.FLOOR .layer = Layer.FLOOR
@ -208,22 +203,24 @@ const Chunk = struct {
var rect_test: c.SDL_FRect = .{}; var rect_test: c.SDL_FRect = .{};
pub fn draw(self: *const Chunk, layer: Layer) void { pub fn draw(self: *const Chunk, layer: Layer) void {
const chunk_offset_x = self.chunk_pos.x * Terrain.CHUNK_SIZE;
const chunk_offset_y = self.chunk_pos.y * Terrain.CHUNK_SIZE;
switch (layer) { switch (layer) {
.FLOOR => { .FLOOR => {
for(0..CHUNK_LENGTH) |idx| { for(0..CHUNK_LENGTH) |idx| {
const tile = self.tiles[idx]; const tile = self.tiles[idx];
const x, const y = index_to_xy(@intCast(idx)); const x, const y = index_to_xy(@intCast(idx));
const rect = Recti.from_xywh(x, y, 1, 1); const rect = Recti.from_xywh(x + chunk_offset_x, y + chunk_offset_y, 1, 1);
const sprite = assets.terrain[0][tile.texture_idx]; const sprite = assets.terrain[0][tile.texture_idx];
self.camera.draw_sprite_i(sprite, rect, tile.grass_color); // self.camera.draw_sprite_i(sprite, rect, tile.grass_color);
// switch(tile.texture_idx) { switch(tile.texture_idx) {
// 0 => self.camera.draw_sprite_i(sprite, rect, Layer.FLOOR, Color.WHITE), 0 => self.camera.draw_sprite_i(sprite, rect, Color.WHITE),
// 1 => self.camera.draw_sprite_i(sprite, rect, Layer.FLOOR, Color.RED), 1 => self.camera.draw_sprite_i(sprite, rect, Color.RED),
// 2 => self.camera.draw_sprite_i(sprite, rect, Layer.FLOOR, Color.GREEN), 2 => self.camera.draw_sprite_i(sprite, rect, Color.GREEN),
// 3 => self.camera.draw_sprite_i(sprite, rect, Layer.FLOOR, Color.BLUE), 3 => self.camera.draw_sprite_i(sprite, rect, Color.BLUE),
// else => {} else => {}
// } }
} }
}, },
else => {}, else => {},