aboutsummaryrefslogtreecommitdiff
path: root/solar_map.v
diff options
context:
space:
mode:
authorOsCoder <oscoder@lczimmermann.eu>2026-07-22 23:21:40 +0200
committerOsCoder <oscoder@lczimmermann.eu>2026-07-22 23:21:40 +0200
commit400b321f8799f369cf26cf611462598117004ced (patch)
tree85bc676bd110edc57c2faa7461f23b5eb1099cc1 /solar_map.v
downloadsolar_map-400b321f8799f369cf26cf611462598117004ced.tar.xz
solar_map-400b321f8799f369cf26cf611462598117004ced.zip
initial commit
Diffstat (limited to 'solar_map.v')
-rw-r--r--solar_map.v168
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)
+}