diff options
| author | OsCoder <oscoder@lczimmermann.eu> | 2026-07-22 23:21:40 +0200 |
|---|---|---|
| committer | OsCoder <oscoder@lczimmermann.eu> | 2026-07-22 23:21:40 +0200 |
| commit | 400b321f8799f369cf26cf611462598117004ced (patch) | |
| tree | 85bc676bd110edc57c2faa7461f23b5eb1099cc1 /solar_map.v | |
| download | solar_map-400b321f8799f369cf26cf611462598117004ced.tar.xz solar_map-400b321f8799f369cf26cf611462598117004ced.zip | |
initial commit
Diffstat (limited to 'solar_map.v')
| -rw-r--r-- | solar_map.v | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/solar_map.v b/solar_map.v new file mode 100644 index 0000000..eea0faf --- /dev/null +++ b/solar_map.v @@ -0,0 +1,168 @@ +module solar_map + +import os +import time +import render + +pub type SpaceBody = render.SpaceBody + +// Convert a SpaceBody into a 64-byte Little-Endian array +fn body_to_bytes(b SpaceBody) []u8 { + mut bytes := []u8{cap: 64} + + bytes << u32_to_bytes(b.id) + bytes << u32_to_bytes(b.parent_id) + bytes << i64_to_bytes(b.rel_x) + bytes << i64_to_bytes(b.rel_y) + bytes << i64_to_bytes(b.rel_z) + bytes << u32_to_bytes(b.radius) + bytes << b.body_type + bytes << b.flags[0] + bytes << b.flags[1] + bytes << b.flags[2] + + for i in 0 .. 24 { + bytes << b.comment[i] + } + + return bytes +} + +// Reconstruct a SpaceBody from a 64-byte slice +fn body_from_bytes(data []u8) SpaceBody { + mut flags_arr := [3]u8{} + flags_arr[0] = data[37] + flags_arr[1] = data[38] + flags_arr[2] = data[39] + + mut comment_arr := [24]u8{} + for i in 0 .. 24 { + comment_arr[i] = data[40 + i] + } + + return SpaceBody{ + id: bytes_to_u32(data[0..4]) + parent_id: bytes_to_u32(data[4..8]) + rel_x: bytes_to_i64(data[8..16]) + rel_y: bytes_to_i64(data[16..24]) + rel_z: bytes_to_i64(data[24..32]) + radius: bytes_to_u32(data[32..36]) + body_type: data[36] + flags: flags_arr + comment: comment_arr + } +} + +// Public API function to process a CSV file, output binary data, and optionally render a BMP image +pub fn process_galaxy(csv_path string, generate_image bool) ! { + struct_size := int(sizeof(SpaceBody)) + + if !os.exists(csv_path) { + return error('File not found: ${csv_path}') + } + + // 1. Parse CSV + sw_parse := time.new_stopwatch() + lines := os.read_lines(csv_path)! + + mut bodies := []SpaceBody{cap: lines.len - 1} + + for i := 1; i < lines.len; i++ { + line := lines[i].trim_space() + if line == '' { + continue + } + + parts := line.split(',') + if parts.len < 7 { + continue + } + + mut flag_val := u8(0) + if parts.len >= 8 { + flag_val = parts[7].u8() + } + + mut body := SpaceBody{ + id: parts[0].u32() + parent_id: parts[1].u32() + rel_x: parts[2].i64() + rel_y: parts[3].i64() + rel_z: parts[4].i64() + radius: parts[5].u32() + body_type: parts[6].u8() + flags: [flag_val, u8(0), u8(0)]! + } + + if parts.len >= 9 { + comment_str := parts[8].trim_space() + mut bytes_to_copy := comment_str.len + if bytes_to_copy > 24 { + bytes_to_copy = 24 + } + for j := 0; j < bytes_to_copy; j++ { + body.comment[j] = comment_str[j] + } + } + + bodies << body + } + println('CSV parsed in: ${sw_parse.elapsed().microseconds()} µs') + + // 2. Write binary data + bin_path := csv_path.replace('.csv', '.bin') + mut bytes_to_write := []u8{cap: bodies.len * struct_size} + for body in bodies { + bytes_to_write << body_to_bytes(body) + } + os.write_file(bin_path, bytes_to_write.bytestr())! + + // 3. Load binary data back (Fast Load validation) + sw_load := time.new_stopwatch() + bin_bytes := os.read_bytes(bin_path)! + body_count := bin_bytes.len / struct_size + + mut loaded_bodies := []SpaceBody{cap: body_count} + for i in 0 .. body_count { + offset := i * struct_size + loaded_bodies << body_from_bytes(bin_bytes[offset .. offset + struct_size]) + } + println('Binary loaded in: ${sw_load.elapsed().microseconds()} µs') + + // 4. Render BMP image if requested + if generate_image { + bmp_path := csv_path.replace('.csv', '.bmp') + sw_render := time.new_stopwatch() + render.draw_bodies_to_bmp(loaded_bodies, bmp_path, 1920, 600)! + println('Image successfully rendered to "${bmp_path}" in ${sw_render.elapsed().microseconds()} µs') + } +} + +// Helper functions for Little-Endian conversions +fn u32_to_bytes(v u32) []u8 { + return [u8(v), u8(v >> 8), u8(v >> 16), u8(v >> 24)] +} + +fn i64_to_bytes(v i64) []u8 { + u := u64(v) + return [ + u8(u), + u8(u >> 8), + u8(u >> 16), + u8(u >> 24), + u8(u >> 32), + u8(u >> 40), + u8(u >> 48), + u8(u >> 56), + ] +} + +fn bytes_to_u32(b []u8) u32 { + return u32(b[0]) | (u32(b[1]) << 8) | (u32(b[2]) << 16) | (u32(b[3]) << 24) +} + +fn bytes_to_i64(b []u8) i64 { + u := u64(b[0]) | (u64(b[1]) << 8) | (u64(b[2]) << 16) | (u64(b[3]) << 24) | + (u64(b[4]) << 32) | (u64(b[5]) << 40) | (u64(b[6]) << 48) | (u64(b[7]) << 56) + return i64(u) +} |
