252 lines
7.7 KiB
Odin
252 lines
7.7 KiB
Odin
package main
|
|
|
|
import "base:runtime"
|
|
import "base:intrinsics"
|
|
|
|
import "core:log"
|
|
import "core:mem"
|
|
import "core:time"
|
|
import "core:fmt"
|
|
import "core:testing"
|
|
import "core:strings"
|
|
import "core:path/filepath"
|
|
import "core:math"
|
|
import "core:math/linalg"
|
|
import "core:os"
|
|
import "core:math/rand"
|
|
|
|
import stbi "vendor:stb/image"
|
|
|
|
import sa "sokol/app"
|
|
import sh "sokol/helpers"
|
|
|
|
import "ecs"
|
|
import program_config "config"
|
|
|
|
Vec2 :: ecs.Vec2
|
|
Vec3 :: ecs.Vec3
|
|
Vec4 :: ecs.Vec4
|
|
|
|
Globals :: struct {
|
|
coordinator: ecs.Coordinator,
|
|
input_system: ^ecs.InputSystem,
|
|
physics_system: ^ecs.PhysicsSystem,
|
|
camera_system: ^ecs.CameraSystem,
|
|
render_system: ^ecs.RenderSystem,
|
|
|
|
time_since_cube: f32,
|
|
current_color: i32,
|
|
}
|
|
g: ^Globals
|
|
|
|
default_context: runtime.Context
|
|
tracking_allocator: mem.Tracking_Allocator
|
|
|
|
main :: proc() {
|
|
context.logger = log.create_console_logger()
|
|
|
|
mem.tracking_allocator_init(&tracking_allocator, context.allocator)
|
|
context.allocator = mem.tracking_allocator(&tracking_allocator)
|
|
|
|
default_context = context
|
|
|
|
sa.run({
|
|
window_title = program_config.WINDOW_TITLE,
|
|
|
|
allocator = sa.Allocator(sh.allocator(&default_context)),
|
|
logger = sa.Logger(sh.logger(&default_context)),
|
|
|
|
init_cb = init_cb,
|
|
frame_cb = frame_cb,
|
|
cleanup_cb = cleanup_cb,
|
|
event_cb = event_cb,
|
|
})
|
|
}
|
|
|
|
init_cb :: proc "c" () {
|
|
context = default_context
|
|
|
|
sa.show_mouse(false)
|
|
sa.lock_mouse(true)
|
|
|
|
g = new(Globals)
|
|
ecs.coordinator_init(&g.coordinator)
|
|
|
|
create_scene()
|
|
}
|
|
|
|
frame_cb:: proc "c" () {
|
|
context = default_context
|
|
|
|
dt := f32(sa.frame_duration())
|
|
|
|
g.time_since_cube += dt
|
|
if g.time_since_cube >= program_config.SPAWN_INTERVAL {
|
|
g.time_since_cube = 0
|
|
create_cube()
|
|
}
|
|
|
|
ecs.physics_system_update(g.physics_system, &g.coordinator, dt)
|
|
ecs.camera_system_update(g.camera_system, &g.coordinator, dt)
|
|
ecs.render_system_update(g.render_system, &g.coordinator)
|
|
|
|
ecs.input_system_mouse_reset(g.input_system, &g.coordinator)
|
|
}
|
|
|
|
cleanup_cb :: proc "c" () {
|
|
context = default_context
|
|
|
|
ecs.render_system_delete(g.render_system, &g.coordinator)
|
|
|
|
ecs.coordinator_delete(&g.coordinator)
|
|
free(g)
|
|
|
|
reset_tracking_allocator(&tracking_allocator)
|
|
}
|
|
|
|
event_cb :: proc "c" (event: ^sa.Event) {
|
|
context = default_context
|
|
|
|
ecs.input_system_update(g.input_system, &g.coordinator, event)
|
|
}
|
|
|
|
create_cube :: proc() {
|
|
entity := ecs.coordinator_create_entity(&g.coordinator)
|
|
|
|
ecs.coordinator_add_component(
|
|
&g.coordinator,
|
|
ecs.GravityComponent{
|
|
ecs.Vec3{ 0.0, program_config.GRAVITY_CONSTANT, 0.0 }
|
|
},
|
|
entity
|
|
)
|
|
ecs.coordinator_add_component(
|
|
&g.coordinator,
|
|
ecs.RigidBodyComponent{
|
|
velocity = ecs.Vec3{ 0.0, 0.0, 0.0 },
|
|
acceleration = ecs.Vec3{ 0.0, 0.0, 0.0 },
|
|
},
|
|
entity
|
|
)
|
|
ecs.coordinator_add_component(
|
|
&g.coordinator,
|
|
ecs.TransformComponent{
|
|
position = Vec3{
|
|
f32(rand.int_max(program_config.SPAWN_AREA)),
|
|
10,
|
|
f32(rand.int_max(program_config.SPAWN_AREA)),
|
|
},
|
|
rotation = ecs.Vec3{ 0.0, 0.0, 0.0 },
|
|
scale = ecs.Vec3{ 1.0, 1.0, 1.0 },
|
|
},
|
|
entity
|
|
)
|
|
ecs.coordinator_add_component(
|
|
&g.coordinator,
|
|
ecs.ColorComponent{
|
|
color = program_config.CUBE_COLORS[g.current_color]
|
|
},
|
|
entity
|
|
)
|
|
g.current_color += 1
|
|
g.current_color %= i32(len(program_config.CUBE_COLORS))
|
|
|
|
ecs.coordinator_add_component(
|
|
&g.coordinator,
|
|
ecs.MeshComponent{
|
|
mesh_id = .Cube
|
|
},
|
|
entity
|
|
)
|
|
ecs.coordinator_add_component(
|
|
&g.coordinator,
|
|
ecs.MaterialComponent{
|
|
material_id = .Cube
|
|
},
|
|
entity
|
|
)
|
|
}
|
|
|
|
create_scene :: proc() {
|
|
coordinator := &g.coordinator
|
|
|
|
ecs.coordinator_register_component(coordinator, ecs.GravityComponent)
|
|
ecs.coordinator_register_component(coordinator, ecs.RigidBodyComponent)
|
|
ecs.coordinator_register_component(coordinator, ecs.TransformComponent)
|
|
ecs.coordinator_register_component(coordinator, ecs.ColorComponent)
|
|
ecs.coordinator_register_component(coordinator, ecs.CameraComponent)
|
|
ecs.coordinator_register_component(coordinator, ecs.MaterialComponent)
|
|
ecs.coordinator_register_component(coordinator, ecs.MeshComponent)
|
|
ecs.coordinator_register_component(coordinator, ecs.InputComponent)
|
|
|
|
g.physics_system = ecs.coordinator_register_system(coordinator, ecs.PhysicsSystem)
|
|
signature := ecs.signature_make()
|
|
ecs.signature_set(&signature, ecs.coordinator_get_component_id(coordinator, ecs.GravityComponent))
|
|
ecs.signature_set(&signature, ecs.coordinator_get_component_id(coordinator, ecs.RigidBodyComponent))
|
|
ecs.signature_set(&signature, ecs.coordinator_get_component_id(coordinator, ecs.TransformComponent))
|
|
ecs.coordinator_set_system_signature(coordinator, ecs.PhysicsSystem, signature)
|
|
|
|
g.render_system = ecs.coordinator_register_system(coordinator, ecs.RenderSystem)
|
|
ecs.signature_clear(&signature)
|
|
ecs.signature_set(&signature, ecs.coordinator_get_component_id(coordinator, ecs.TransformComponent))
|
|
ecs.signature_set(&signature, ecs.coordinator_get_component_id(coordinator, ecs.ColorComponent))
|
|
ecs.signature_set(&signature, ecs.coordinator_get_component_id(coordinator, ecs.MeshComponent))
|
|
ecs.signature_set(&signature, ecs.coordinator_get_component_id(coordinator, ecs.MaterialComponent))
|
|
ecs.coordinator_set_system_signature(coordinator, ecs.RenderSystem, signature)
|
|
|
|
g.camera_system = ecs.coordinator_register_system(coordinator, ecs.CameraSystem)
|
|
ecs.signature_clear(&signature)
|
|
ecs.signature_set(&signature, ecs.coordinator_get_component_id(coordinator, ecs.CameraComponent))
|
|
ecs.signature_set(&signature, ecs.coordinator_get_component_id(coordinator, ecs.InputComponent))
|
|
ecs.coordinator_set_system_signature(coordinator, ecs.CameraSystem, signature)
|
|
|
|
g.input_system = ecs.coordinator_register_system(coordinator, ecs.InputSystem)
|
|
ecs.signature_clear(&signature)
|
|
ecs.signature_set(&signature, ecs.coordinator_get_component_id(coordinator, ecs.InputComponent))
|
|
ecs.coordinator_set_system_signature(coordinator, ecs.InputSystem, signature)
|
|
|
|
user_entity := ecs.coordinator_create_entity(coordinator)
|
|
ecs.coordinator_add_component(
|
|
coordinator,
|
|
ecs.CameraComponent{
|
|
position = program_config.START_POSITION,
|
|
target = { 0, 0, 1 },
|
|
look = { 0, 0 },
|
|
movement_speed = program_config.MOVEMENT_SPEED,
|
|
look_sensitivity = program_config.LOOK_SENSITIVITY,
|
|
},
|
|
user_entity
|
|
)
|
|
|
|
ecs.coordinator_add_component(
|
|
coordinator,
|
|
ecs.InputComponent{
|
|
key_down = {},
|
|
mouse_movement = Vec2{ 0, 0 }
|
|
},
|
|
user_entity
|
|
)
|
|
|
|
ecs.render_system_init(g.render_system, user_entity)
|
|
}
|
|
|
|
reset_tracking_allocator :: proc(track: ^mem.Tracking_Allocator) {
|
|
clean := true
|
|
if len(track.allocation_map) > 0 {
|
|
fmt.eprintfln("=== %v allocations not freed: ===", len(track.allocation_map))
|
|
for _, entry in track.allocation_map {
|
|
fmt.eprintf("- %v bytes @ %v\n", entry.size, entry.location)
|
|
}
|
|
clean = false
|
|
}
|
|
if len(track.bad_free_array) > 0 {
|
|
fmt.eprintfln("=== %v incorrect frees: ===", len(track.bad_free_array))
|
|
for entry in track.bad_free_array {
|
|
fmt.eprintf("- %p @ %v\n", entry.memory, entry.location)
|
|
}
|
|
clean = false
|
|
}
|
|
if clean do fmt.printfln("=== No memory leaked ===")
|
|
|
|
mem.tracking_allocator_destroy(track)
|
|
}
|